package otto import ( "testing" "fmt" . "github.com/robertkrimen/terst" "math" "strings" ) func runTestWithOtto() (*Otto, func(string, ... interface{}) Value) { Otto := New() test := func(name string, expect... interface{}) Value { raise := false defer func(){ if caught := recover(); caught != nil { if raise { if len(expect) > 0 { Is(caught, expect[0]) } } else { dbg("Panic, caught:", caught) panic(caught) } } }() var value Value if isIdentifier(name) { value = Otto.getValue(name) } else { source := name index := strings.Index(source, "raise:") if index == 0 { raise = true source = source[6:] source = strings.TrimLeft(source, " ") } value = Otto.run(source) } value = Otto.runtime.GetValue(value) if len(expect) > 0 { Is(value, expect[0]) } return value } return Otto, test } func runTest() func(string, ... interface{}) Value { _, test := runTestWithOtto() return test } func TestTransformRegExp(t *testing.T) { Terst(t) Is(transformRegExp(`\\|'|\r|\n|\t|\u2028|\u2029`), `\\|'|\r|\n|\t|\x{2028}|\x{2029}`) } func TestOtto(t *testing.T) { Terst(t) test := runTest() test("xyzzy = 2", "2") test("xyzzy + 2", "4") test("xyzzy += 16", "18") test("xyzzy", "18") test(` (function(){ return 1 })() `, "1") test(` (function(){ return 1 }).call(this) `, "1") test(` (function(){ var result (function(){ result = -1 })() return result })() `, "-1") test(` var abc = 1 abc || (abc = -1) abc `, "1") test(` var abc = (function(){ 1 === 1 })() abc `, "undefined") } func TestSpeed(t *testing.T) { Terst(t) return test := underscoreTest() test(` size = 300000 if (false) { array = new Array(size) for (i = 0; i < array.length; i++) { array[i] = i } } else if (true) { Math.max.apply(Math, _.range(1, size)) } else if (true) { _.max(_.range(1,size)) } else { _.range(1,size) } `) } func TestOperator(t *testing.T) { Terst(t) Otto, test := runTestWithOtto() test("xyzzy = 1") test("xyzzy", "1") if true { Otto.Set("twoPlusTwo", func(FunctionCall) Value { return toValue(5) }); test("twoPlusTwo( 1 )", "5") test("1 + twoPlusTwo( 1 )", "6") test("-1 + twoPlusTwo( 1 )", "4") } test("result = 4") test("result", "4") test("result += 1") test("result", "5") test("result *= 2") test("result", "10") test("result /= 2") test("result", "5") test("result = 112.51 % 3.1") test("result", "0.9100000000000019") test("result = 'Xyzzy'") test("result", "Xyzzy") test("result = 'Xyz' + 'zy'") test("result", "Xyzzy") test("result = \"Xyzzy\"") test("result", "Xyzzy") test("result = 1; result = result") test("result", "1") test(` var result64 = 64 , result10 = 10 `) test("result64", "64") test("result10", "10") test(` result = 1; result += 1; `) test("result", "2") } func TestFunction(t *testing.T) { Terst(t) test := runTest() test(` result = 2 xyzzy = function() { result += 1 } xyzzy() `) test("result", "3") test(` xyzzy = function() { return 1 } result = xyzzy() `) test("result", "1") test(` xyzzy = function() {} result = xyzzy() `) test("result", "undefined") test(` xyzzy = function() { return 64 return 1 } result = xyzzy() `) test("result", "64") test(` result = 4 xyzzy = function() { result = 2 } xyzzy() `) test("result", "2") test(` result = 4 xyzzy = function() { var result result = 2 } xyzzy() `) test("result", "4") test(` xyzzy = function() { var result = 4 return result } result = xyzzy() `) test("result", "4") test(` xyzzy = function() { function test() { var result = 1 return result } return test() + 1 } result = xyzzy() + 1 `) test("result", "3") test(` xyzzy = function() { function test() { var result = 1 return result } _xyzzy = 2 var result = _xyzzy + test() + 1 return result } result = xyzzy() + 1 `) test("result", "5") test("_xyzzy", "2") test(` xyzzy = function(apple) { return 1 } result = xyzzy(1) `) test("result", "1") test(` xyzzy = function(apple) { return apple + 1 } result = xyzzy(2) `) test("result", "3") test(` { result = 1 result += 1; } `) test("result", "2") test(` var global = 1 outer = function() { var global = 2 var inner = function(){ return global } return inner() } result = outer() `) test("result", "2") test(` var apple = 1 var banana = function() { return apple } var cherry = function() { var apple = 2 return banana() } result = cherry() `) test("result", "1") } func TestIf(t *testing.T) { Terst(t) test := runTest() test(` if (1) { result = 1 } else { result = 0 } `) test("result", "1") test(` if (0) { result = 1 } else { result = 0 } `) test("result", "0") test(` result = 0 if (0) { result = 1 } `) test("result", "0") test(` result = 0 if (result) { result = 1 } `) test("result", "0") } func TestDoWhile(t *testing.T) { Terst(t) test := runTest() test(` limit = 4 result = 0 do { result = result + 1 limit = limit - 1 } while (limit) `) test("result", "4") } func TestWhile(t *testing.T) { Terst(t) test := runTest() test(` limit = 4 result = 0 while (limit) { result = result + 1 limit = limit - 1 } `) test("result", "4") } func TestContinueBreak(t *testing.T) { Terst(t) test := runTest() test(` limit = 4 result = 0 while (limit) { limit = limit - 1 if (limit) { } else { break } result = result + 1 } `) test("result", "3") test("limit", "0") test(` limit = 4 result = 0 while (limit) { limit = limit - 1 if (limit) { continue } else { break } result = result + 1 } `) test("result", "0") test(` limit = 4 result = 0 do { limit = limit - 1 if (limit) { continue } else { break } result = result + 1 } while (limit) `) test("result", "0") } func TestTryFinally(t *testing.T) { Terst(t) test := runTest() test(` try { result = 1 } finally { result = 2 } `) test("result", "2") } func TestTryCatch(t *testing.T) { Terst(t) test := runTest() test(` result = 1 try { throw 4 result = -1 } catch (xyzzy) { result += xyzzy + 1 } `) test("result", "6") test(` result = 1 try { try { throw 4 result = -1 } catch (xyzzy) { result += xyzzy + 1 throw 64 } } catch (xyzzy) { resultXyzzy = xyzzy result = -2 } `) test("resultXyzzy", "64") test("result", "-2") } func TestTryCatchError(t *testing.T) { Terst(t) test := runTest() test(` var abc try { 1() } catch (def) { abc = def } abc `, "TypeError: 1 is not a function") } func TestPositiveNegativeZero(t *testing.T) { Terst(t) test := runTest() test(`1/0`, "Infinity") test(`1/-0`, "-Infinity") test(` abc = -0 1/abc `, "-Infinity", ) } func TestDate(t *testing.T) { Terst(t) test := runTest() test(`Date`, "[function]") test(`new Date(0).toUTCString()`, "Thu, 01 Jan 1970 00:00:00 UTC") test(`new Date(1348616313).getTime()`, "1348616313") // TODO These shold be in local time test(`new Date(1348616313).toUTCString()`, "Fri, 16 Jan 1970 14:36:56 UTC") test(`abc = new Date(1348616313047); abc.toUTCString()`, "Tue, 25 Sep 2012 23:38:33 UTC") test(`abc.getFullYear()`, "2012") test(`abc.getUTCFullYear()`, "2012") test(`abc.getMonth()`, "8") // Remember, the JavaScript month is 0-based test(`abc.getUTCMonth()`, "8") test(`abc.getDate()`, "25") test(`abc.getUTCDate()`, "25") test(`abc.getDay()`, "2") test(`abc.getUTCDay()`, "2") test(`abc.getHours()`, "16") test(`abc.getUTCHours()`, "23") test(`abc.getMinutes()`, "38") test(`abc.getUTCMinutes()`, "38") test(`abc.getSeconds()`, "33") test(`abc.getUTCSeconds()`, "33") test(`abc.getMilliseconds()`, "47") // In honor of the 47% test(`abc.getUTCMilliseconds()`, "47") test(`abc.getTimezoneOffset()`, "420") if false { // TODO (When parsing is implemented) test(`new Date("Xyzzy").getTime()`, "NaN") } test(`abc.setFullYear(2011); abc.toUTCString()`, "Sun, 25 Sep 2011 23:38:33 UTC") test(`new Date(12564504e5).toUTCString()`, "Sun, 25 Oct 2009 06:00:00 UTC") test(`new Date(2009, 9, 25).toUTCString()`, "Sun, 25 Oct 2009 00:00:00 UTC") test(`+(new Date(2009, 9, 25))`, "1.2564288e+12") test(`abc = new Date(12564504e5); abc.setMilliseconds(2001); abc.toUTCString()`, "Sun, 25 Oct 2009 06:00:02 UTC") test(`abc = new Date(12564504e5); abc.setSeconds("61"); abc.toUTCString()`, "Sun, 25 Oct 2009 06:01:01 UTC") test(`abc = new Date(12564504e5); abc.setMinutes("61"); abc.toUTCString()`, "Sun, 25 Oct 2009 07:01:00 UTC") test(`abc = new Date(12564504e5); abc.setHours("5"); abc.toUTCString()`, "Sat, 24 Oct 2009 12:00:00 UTC") test(`abc = new Date(12564504e5); abc.setDate("26"); abc.toUTCString()`, "Tue, 27 Oct 2009 06:00:00 UTC") test(`abc = new Date(12564504e5); abc.setMonth(9); abc.toUTCString()`, "Sun, 25 Oct 2009 06:00:00 UTC") test(`abc = new Date(12564504e5); abc.setMonth("09"); abc.toUTCString()`, "Sun, 25 Oct 2009 06:00:00 UTC") test(`abc = new Date(12564504e5); abc.setMonth("10"); abc.toUTCString()`, "Wed, 25 Nov 2009 07:00:00 UTC") test(`abc = new Date(12564504e5); abc.setFullYear(2010); abc.toUTCString()`, "Mon, 25 Oct 2010 06:00:00 UTC") } func TestComparison(t *testing.T) { Terst(t) test := runTest() test("undefined = 1") test("undefined", "1") test("result = undefined == undefined") test("result", "true") test("result = undefined != undefined") test("result", "false") test("result = null == null") test("result", "true") test("result = null != null") test("result", "false") test("result = 0 == 1") test("result", "false") Is(negativeZero(), "-0") Is(positiveZero(), "0") IsTrue(math.Signbit(negativeZero())) IsTrue(positiveZero() == negativeZero()) test("result = 1 == 1") test("result", "true") test("result = 'Hello, World.' == 'Goodbye, World.'") test("result", "false") test("result = 'Hello, World.' == true") test("result", "false") test("result = 'Hello, World.' == false") test("result", "false") test("result = 'Hello, World.' == 1") test("result", "false") test("result = 1 == 'Hello, World.'") test("result", "false") Is(stringToFloat("-1"), -1) if false { fmt.Printf("Hello, World.: %v", toNumber(toValue("Hello, World."))) } test("result = 0+Object") test("result", "0[function]") } func TestComparisonRelational(t *testing.T) { Terst(t) test := runTest() test("result = 0 < 0") test("result", "false") test("result = 0 > 0") test("result", "false") test("result = 0 <= 0") test("result", "true") test("result = 0 >= 0") test("result", "true") test("result = ' 0' >= 0") test("result", "true") test("result = '_ 0' >= 0") test("result", "false") } func TestSwitch(t *testing.T) { Terst(t) test := runTest() test(` result = 0 switch (0) { default: result += 1 case 1: result += 2 case 2: result += 4 case 3: result += 8 } `) test("result", "15") test(` result = 0 switch (3) { default: result += 1 case 1: result += 2 case 2: result += 4 case 3: result += 8 } `) test("result", "8") test(` result = 0 switch (60) { case 1: result += 2 case 2: result += 4 case 3: result += 8 } `) test("result", "0") } func TestFor(t *testing.T) { Terst(t) test := runTest() test(` result = 7 for (i = 0; i < 3; i += 1) { result += 1 } `) test("result", "10") test(` result = 7 for (i = 0; i < 3; i += 1) { result += 1 if (i == 1) { break } } `) test("result", "9") test(` result = 7 for (i = 0; i < 3; i += 1) { if (i == 2) { continue } result += 1 } `) test("result", "9") } func TestArguments(t *testing.T) { Terst(t) test := runTest() test(` xyzzy = function() { return arguments[0] } result = xyzzy("xyzzy") `) test("result", "xyzzy") test(` xyzzy = function() { arguments[0] = "abcdef" return arguments[0] } result = xyzzy("xyzzy") `) test("result", "abcdef") test(` xyzzy = function(apple) { apple = "abcdef" return arguments[0] } result = xyzzy("xyzzy") `) test("result", "abcdef") test(` (function(){ return arguments })() `, "[object Arguments]") test(` (function(){ return arguments.length })() `, "0") test(` (function(){ return arguments.length })(1, 2, 4, 8, 10) `, "5") } func TestObjectLiteral(t *testing.T) { Terst(t) Otto := New() Otto.Run(` result = {} `) IsTrue(Otto.getValue("result").IsObject()) Otto.Run(` result = { xyzzy: "Nothing happens.", 0: 1 } `) Is(Otto.getValue("result")._object().GetValue("xyzzy"), "Nothing happens.") } func TestArrayLiteral(t *testing.T) { Terst(t) test := runTest() test(` result = [] `) IsTrue(test("result").IsObject()) test(` result = [ "Nothing happens.", 0, 1 ] `) Is(test("result")._object().GetValue("0"), "Nothing happens.") test(` xyzzy = [ "Nothing happens.", 0, 1 ] result = xyzzy[1] `) test("result", "0") test(` xyzzy = [ "Nothing happens.", 0, 1 ] xyzzy[10] = 2 _6 = xyzzy[6] result = xyzzy[10] `) test("result", "2") test("_6", "undefined") } func TestUnaryPrefix (t *testing.T) { Terst(t) test := runTest() test(` result = 0 ++result `) test("result", "1") test(` result = 0 --result `) test("result", "-1") } func TestUnaryPostfix (t *testing.T) { Terst(t) test := runTest() result := test(` result = 0 result++ result++ `) Is(result, "1") test("result", "2") result = test(` result = 0 result-- result-- `) Is(result, "-1") test("result", "-2") } func TestBinaryLogicalOperation (t *testing.T) { Terst(t) test := runTest() test(` abc = true def = false ghi = false jkl = false result = abc && def || ghi && jkl `) test("result", "false") test(` abc = true def = true ghi = false jkl = false result = abc && def || ghi && jkl `) test("result", "true") } func TestBinaryBitwiseOperation (t *testing.T) { Terst(t) test := runTest() test(` abc = 1 & 2 def = 1 & 3 ghi = 1 | 3 jkl = 1 ^ 2 mno = 1 ^ 3 `) test("abc", "0") test("def", "1") test("ghi", "3") test("jkl", "3") test("mno", "2") } func TestBinaryShiftOperation (t *testing.T) { Terst(t) test := runTest() test(` high = (1 << 30) - 1 + (1 << 30) low = -high - 1 abc = 23 << 1 def = -105 >> 1 ghi = 23 << 2 jkl = 1 >>> 31 mno = 1 << 64 pqr = 1 >> 2 stu = -2 >> 4 vwx = low >> 1 yz = low >>> 1 `) test("abc", "46") test("def", "-53") test("ghi", "92") test("jkl", "0") test("mno", "1") test("pqr", "0") test("stu", "-1") test("vwx", "-1073741824") test("yz", "1073741824") } func TestParenthesizing (t *testing.T) { Terst(t) test := runTest() test(` abc = 1 + 2 * 3 def = (1 + 2) * 3 ghi = !(false || true) jkl = !false || true `) test("abc", "7") test("def", "9") test("ghi", "false") test("jkl", "true") } func TestInstanceOf (t *testing.T) { Terst(t) test := runTest() test(` abc = {} instanceof Object `) test("abc", "true") } func TestIn (t *testing.T) { Terst(t) test := runTest() test(` abc = "prototype" in Object def = "xyzzy" in Object `) test("abc", "true") test("def", "false") } func TestForIn (t *testing.T) { Terst(t) test := runTest() test(` for (property in { a: 1 }) { abc = property } `) test("abc", "a") test(` for (property in new String("xyzzy")) { abc = property } `) test("abc", "4") } func TestAssignment(t *testing.T) { Terst(t) test := runTest() test(` abc = 1 def = abc `) test("abc", "1") test("def", "1") } func Testnew(t *testing.T) { Terst(t) test := runTest() test(` abc = new Boolean def = new Boolean(1) `) test("abc", "false") test("def", "true") } func TestConditional(t *testing.T) { Terst(t) test := runTest() test(` abc = true ? 1 : 0 def = 0 ? 2 : 3 `) test("abc", "1") test("def", "3") } func TestString(t *testing.T) { Terst(t) test := runTest() test(` abc = (new String("xyzzy")).length def = new String().length ghi = new String("Nothing happens.").length `) test("abc", "5") test("def", "0") test("ghi", "16") test(`"".length`, "0") } func TestArray(t *testing.T) { Terst(t) test := runTest() test(` abc = ""+[0, 1, 2, 3] def = [].toString() ghi = [null, 4, "null"].toString() `) test("abc", "0,1,2,3") test("def", "") test("ghi", ",4,null") test(`new Array(0).length`, "0") test(`new Array(11).length`, "11") test(`new Array(11, 1).length`, "2") } func TestArray_toString(t *testing.T) { Terst(t) { test := runTest() test(` Array.prototype.toString = function() { return "Nothing happens." } abc = Array.prototype.toString() def = [].toString() ghi = [null, 4, "null"].toString() `) test("abc", "Nothing happens.") test("def", "Nothing happens.") test("ghi", "Nothing happens.") } { test := runTest() test(` Array.prototype.join = undefined abc = Array.prototype.toString() def = [].toString() ghi = [null, 4, "null"].toString() `) test("abc", "[object Array]") test("def", "[object Array]") test("ghi", "[object Array]") } } func TestArray_concat(t *testing.T) { Terst(t) test := runTest() test(` abc = [0, 1, 2] def = [-1, -2, -3] ghi = abc.concat(def) jkl = abc.concat(def, 3, 4, 5) mno = def.concat(-4, -5, abc) `) test("ghi", "0,1,2,-1,-2,-3") test("jkl", "0,1,2,-1,-2,-3,3,4,5") test("mno", "-1,-2,-3,-4,-5,0,1,2") } func TestArray_splice(t *testing.T) { Terst(t) test := runTest() test(` abc = [0, 1, 2] def = abc.splice(1, 2, 3, 4, 5) ghi = [].concat(abc) jkl = ghi.splice(17, 21, 7, 8, 9) `) test("abc", "0,3,4,5") test("def", "1,2") test("ghi", "0,3,4,5,7,8,9") test("jkl", "") } func TestArray_shift(t *testing.T) { Terst(t) test := runTest() test(` abc = [0, 1, 2] def = abc.shift() ghi = [].concat(abc) jkl = abc.shift() mno = [].concat(abc) pqr = abc.shift() stu = [].concat(abc) vwx = abc.shift() `) test("abc", "") test("def", "0") test("ghi", "1,2") test("jkl", "1") test("mno", "2") test("pqr", "2") test("stu", "") test("vwx", "undefined") } func TestArray_push(t *testing.T) { Terst(t) test := runTest() test(` abc = [0] def = abc.push(1) ghi = [].concat(abc) jkl = abc.push(2,3,4) `) test("abc", "0,1,2,3,4") test("def", "2") test("ghi", "0,1") test("jkl", "5") } func TestArray_pop(t *testing.T) { Terst(t) test := runTest() test(` abc = [0,1] def = abc.pop() ghi = [].concat(abc) jkl = abc.pop() mno = [].concat(abc) pqr = abc.pop() `) test("abc", "") test("def", "1") test("ghi", "0") test("jkl", "0") test("mno", "") test("pqr", "undefined") } func TestArray_slice(t *testing.T) { Terst(t) test := runTest() test(` abc = [0,1,2,3] def = abc.slice() ghi = abc.slice(1) jkl = abc.slice(3,-1) mno = abc.slice(2,-1) pqr = abc.slice(-1, -10) `) test("def", "0,1,2,3") test("ghi", "1,2,3") test("jkl", "") test("mno", "2") test("pqr", "") test(`abc.slice(2, 2)`, "") test(`abc.slice(2, 3)`, "2") test(` abc = { 0: 0, 1: 1, 2: 2, 3: 3 } abc.length = 4 def = Array.prototype.slice.call(abc) ghi = Array.prototype.slice.call(abc,1) jkl = Array.prototype.slice.call(abc,3,-1) mno = Array.prototype.slice.call(abc,2,-1) pqr = Array.prototype.slice.call(abc,-1,-10) `) // Array.protoype.slice is generic test("def", "0,1,2,3") test("ghi", "1,2,3") test("jkl", "") test("mno", "2") test("pqr", "") } func TestArray_sliceArguments(t *testing.T) { Terst(t) test := runTest() test(` (function(){ return Array.prototype.slice.call(arguments, 1) })({}, 1, 2, 3) `, "1,2,3") } func TestArray_unshift(t *testing.T) { Terst(t) test := runTest() test(` abc = [] def = abc.unshift(0) ghi = [].concat(abc) jkl = abc.unshift(1,2,3,4) `) test("abc", "1,2,3,4,0") test("def", "1") test("ghi", "0") test("jkl", "5") } func TestArray_reverse(t *testing.T) { Terst(t) test := runTest() test(` abc = [0,1,2,3].reverse() def = [0,1,2].reverse() `) test("abc", "3,2,1,0") test("def", "2,1,0") } func TestArray_sort(t *testing.T) { Terst(t) test := runTest() test(` abc = [0,1,2,3].sort() def = [3,2,1,0].sort() ghi = [].sort() jkl = [0].sort() mno = [1,0].sort() pqr = [1,5,-10, 100, 8, 72, 401, 0.05].sort() stu = [1,5,-10, 100, 8, 72, 401, 0.05].sort(function(x, y){ return x == y ? 0 : x < y ? -1 : 1 }) `) test("abc", "0,1,2,3") test("def", "0,1,2,3") test("ghi", "") test("jkl", "0") test("mno", "0,1") test("pqr", "-10,0.05,1,100,401,5,72,8") test("stu", "-10,0.05,1,5,8,72,100,401") } func TestString_charAt(t *testing.T) { Terst(t) test := runTest() test(` abc = "xyzzy".charAt(0) def = "xyzzy".charAt(11) `) test("abc", "x") test("def", "") } func TestString_charCodeAt(t *testing.T) { Terst(t) test := runTest() test(` abc = "xyzzy".charCodeAt(0) def = "xyzzy".charCodeAt(11) `) test("abc", "120") test("def", "NaN") } func TestString_concat(t *testing.T) { Terst(t) test := runTest() test(`"".concat()`, "") test(`"".concat("abc", "def")`, "abcdef") test(`"".concat("abc", undefined, "def")`, "abcundefineddef") } func TestString_indexOf(t *testing.T) { Terst(t) test := runTest() test(`"".indexOf("")`, "0") test(`"".indexOf("", 11)`, "0") test(`"abc".indexOf("")`, "0") test(`"abc".indexOf("", 11)`, "3") test(`"abc".indexOf("a")`, "0") test(`"abc".indexOf("bc")`, "1") test(`"abc".indexOf("bc", 11)`, "-1") } func TestString_lastIndexOf(t *testing.T) { Terst(t) test := runTest() test(`"".lastIndexOf("")`, "0") test(`"".lastIndexOf("", 11)`, "0") test(`"abc".lastIndexOf("")`, "3") test(`"abc".lastIndexOf("", 11)`, "3") test(`"abc".lastIndexOf("a")`, "0") test(`"abc".lastIndexOf("bc")`, "1") test(`"abc".lastIndexOf("bc", 11)`, "1") test(`"abc".lastIndexOf("bc", 0)`, "-1") } func TestRegExp(t *testing.T) { Terst(t) test := runTest() test(` abc = new RegExp("abc").exec("123abc456") def = new RegExp("xyzzy").exec("123abc456") ghi = new RegExp("1(\\d+)").exec("123abc456") jkl = new RegExp("xyzzy").test("123abc456") mno = new RegExp("1(\\d+)").test("123abc456") `) test(`new RegExp("abc").exec("123abc456")`, "abc") test("def", "null") test("ghi", "123,23") test("jkl", "false") test("mno", "true") test(`new RegExp("abc").toString()`, "/abc/") test(`new RegExp("abc", "g").toString()`, "/abc/g") test(`new RegExp("abc", "mig").toString()`, "/abc/gim") test(`/abc/.toString()`, "/abc/") test(`/abc/gim.toString()`, "/abc/gim") test(`""+/abc/gi`, "/abc/gi") } func TestnewFunction(t *testing.T) { Terst(t) test := runTest() test(` new Function("return 11")() `, "11") test(` abc = 10 new Function("abc += 1")() abc `, "11") test(` new Function("a", "b", "c", "return b + 2")(10, 11, 12) `, "13") } func TestWith(t *testing.T) { Terst(t) test := runTest() test(` var def with({ abc: 9 }) { def = abc } def `, "9") test(` var def with({ abc: function(){ return 11 } }) { def = abc() } def `, "11") } func TestString_match(t *testing.T) { Terst(t) test := runTest() test(`"abc____abc_abc___".match(/__abc/)`, "__abc") test(`"abc___abc_abc__abc__abc".match(/abc/g)`, "abc,abc,abc,abc,abc") test(`"abc____abc_abc___".match(/__abc/g)`, "__abc") test(` abc = /abc/g "abc___abc_abc__abc__abc".match(abc) `, "abc,abc,abc,abc,abc") test(`abc.lastIndex`, "23") } func TestString_replace(t *testing.T) { Terst(t) test := runTest() test(`"abc_abc".replace(/abc/, "$&123")`, "abc123_abc") test(`"abc_abc".replace(/abc/g, "$&123")`, "abc123_abc123") test(`"abc_abc_".replace(/abc/g, "$&123")`, "abc123_abc123_") test(`"_abc_abc_".replace(/abc/g, "$&123")`, "_abc123_abc123_") test(`"abc".replace(/abc/, "$&123")`, "abc123") test(`"abc_".replace(/abc/, "$&123")`, "abc123_") test("\"^abc$\".replace(/abc/, \"$`def\")", "^^def$") test("\"^abc$\".replace(/abc/, \"def$`\")", "^def^$") test(`"_abc_abd_".replace(/ab(c|d)/g, "$1")`, "_c_d_") test(` "_abc_abd_".replace(/ab(c|d)/g, function(){ }) `, "_undefined_undefined_") } func TestString_search(t *testing.T) { Terst(t) test := runTest() test(`"abc".search(/abc/)`, "0") test(`"abc".search(/def/)`, "-1") test(`"abc".search(/c$/)`, "2") test(`"abc".search(/$/)`, "3") } func TestString_split(t *testing.T) { Terst(t) test := runTest() test(`"abc".split("", 1)`, "a") test(`"abc".split("", 2)`, "a,b") test(`"abc".split("", 3)`, "a,b,c") test(`"abc".split("", 4)`, "a,b,c") test(`"abc".split("", 11)`, "a,b,c") test(`"abc".split("", 0)`, "") test(`"abc".split("")`, "a,b,c") test(`"abc".split(undefined)`, "abc") test(`"__1__3_1__2__".split("_")`, ",,1,,3,1,,2,,") test(`"__1__3_1__2__".split(/_/)`, ",,1,,3,1,,2,,") test(`"ab".split(/a*/)`, ",b") test(`_ = "Aboldandcoded".split(/<(\/)?([^<>]+)>/)`, "A,,B,bold,/,B,and,,CODE,coded,/,CODE,") test(`_.length`, "13") test(`_[1] === undefined`, "true") test(`_[12] === ""`, "true") } func TestString_slice(t *testing.T) { Terst(t) test := runTest() test(`"abc".slice()`, "abc") test(`"abc".slice(0)`, "abc") test(`"abc".slice(0,11)`, "abc") test(`"abc".slice(0,-1)`, "ab") test(`"abc".slice(-1,11)`, "c") } func TestString_substring(t *testing.T) { Terst(t) test := runTest() test(`"abc".substring()`, "") test(`"abc".substring(0)`, "") test(`"abc".substring(0,11)`, "abc") test(`"abc".substring(11,0)`, "abc") test(`"abc".substring(0,-1)`, "") test(`"abc".substring(-1,11)`, "abc") test(`"abc".substring(11,1)`, "bc") } func TestString_toCase(t *testing.T) { Terst(t) test := runTest() test(`"abc".toLowerCase()`, "abc") test(`"ABC".toLowerCase()`, "abc") test(`"abc".toUpperCase()`, "ABC") test(`"ABC".toUpperCase()`, "ABC") } func TestMath_max(t *testing.T) { Terst(t) test := runTest() test(`Math.max(-11, -1, 0, 1, 2, 3, 11)`, "11") } func TestMath_min(t *testing.T) { Terst(t) test := runTest() test(`Math.min(-11, -1, 0, 1, 2, 3, 11)`, "-11") } func TestMath_ceil(t *testing.T) { Terst(t) test := runTest() test(`Math.ceil(-11)`, "-11") test(`Math.ceil(-0.5)`, "-0") test(`Math.ceil(1.5)`, "2") } func TestMath_floor(t *testing.T) { Terst(t) test := runTest() test(`Math.floor(-11)`, "-11") test(`Math.floor(-0.5)`, "-1") test(`Math.floor(1.5)`, "1") } func TestFunction_apply(t *testing.T) { Terst(t) test := runTest() test(`String.prototype.substring.length`, "2") test(`String.prototype.substring.apply("abc", [1, 11])`, "bc") } func TestFunction_call(t *testing.T) { Terst(t) test := runTest() test(`String.prototype.substring.length`, "2") test(`String.prototype.substring.call("abc", 1, 11)`, "bc") } func Test_typeof(t *testing.T) { Terst(t) test := runTest() test(`typeof abc`, "undefined") test(`typeof abc === 'undefined'`, "true") } func Test_PrimitiveValueObjectValue(t *testing.T) { Terst(t) test := runTest() Number11 := test(`new Number(11)`) Is(toFloat(Number11), "11") } func Test_eval(t *testing.T) { Terst(t) test := runTest() test(` abc = 1 `) test(` eval("abc += 1") `, "2") test(` (function(){ var abc = 11 eval("abc += 1") return abc })() `, "12") test(`abc`, "2") } func Test_isNaN(t *testing.T) { Terst(t) test := runTest() test(`isNaN(0)`, "false") test(`isNaN("Xyzzy")`, "true") test(`isNaN()`, "true") test(`isNaN(NaN)`, "true") test(`isNaN(Infinity)`, "false") } func Test_isFinite(t *testing.T) { Terst(t) test := runTest() test(`isFinite(0)`, "true") test(`isFinite("Xyzzy")`, "false") test(`isFinite()`, "false") test(`isFinite(NaN)`, "false") test(`isFinite(Infinity)`, "false") } func Test_parseInt(t *testing.T) { Terst(t) test := runTest() test(`parseInt("0")`, "0") test(`parseInt("11")`, "11") test(`parseInt(" 11")`, "11") test(`parseInt("11 ")`, "11") test(`parseInt(" 11 ")`, "11") test(`parseInt(" 11\n")`, "11") test(`parseInt(" 11\n", 16)`, "17") test(`parseInt("Xyzzy")`, "NaN") test(`parseInt("0x0a")`, "10") if false { test(`parseInt(" 0x11\n", 16)`, "17") // TODO parseInt should return 10 in this scenario test(`parseInt("0x0aXyzzy")`, "10") } } func Test_parseFloat(t *testing.T) { Terst(t) test := runTest() test(`parseFloat("0")`, "0") test(`parseFloat("11")`, "11") test(`parseFloat(" 11")`, "11") test(`parseFloat("11 ")`, "11") test(`parseFloat(" 11 ")`, "11") test(`parseFloat(" 11\n")`, "11") test(`parseFloat(" 11\n", 16)`, "11") test(`parseFloat("Xyzzy")`, "NaN") test(`parseFloat("0x0a")`, "NaN") test(`parseFloat("11.1")`, "11.1") if false { test(`parseFloat(" 0x11\n", 16)`, "17") // TODO parseFloat should return 10 in this scenario test(`parseFloat("0x0aXyzzy")`, "10") } } func Test_encodeURI(t *testing.T) { Terst(t) test := runTest() test(`encodeURI("http://example.com/ Nothing happens.")`, "http://example.com/%20Nothing%20happens.") test(`encodeURI("http://example.com/ _^#")`, "http://example.com/%20_%5E#") } func Test_encodeURIComponent(t *testing.T) { Terst(t) test := runTest() test(`encodeURIComponent("http://example.com/ Nothing happens.")`, "http%3A%2F%2Fexample.com%2F%20Nothing%20happens.") test(`encodeURIComponent("http://example.com/ _^#")`, "http%3A%2F%2Fexample.com%2F%20_%5E%23") } func Test_decodeURI(t *testing.T) { Terst(t) test := runTest() test(`decodeURI(encodeURI("http://example.com/ Nothing happens."))`, "http://example.com/ Nothing happens.") test(`decodeURI(encodeURI("http://example.com/ _^#"))`, "http://example.com/ _^#") test(`raise: decodeURI("http://example.com/ _^#%")`, "URIError: URI malformed") } func Test_decodeURIComponent(t *testing.T) { Terst(t) test := runTest() test(`decodeURIComponent(encodeURI("http://example.com/ Nothing happens."))`, "http://example.com/ Nothing happens.") test(`decodeURIComponent(encodeURI("http://example.com/ _^#"))`, "http://example.com/ _^#") } func TestError(t *testing.T) { Terst(t) test := runTest() test(`new URIError() instanceof URIError`, "true") test(` var abc try { decodeURI("http://example.com/ _^#%") } catch (def) { abc = def instanceof URIError } abc `, "true") } func TestTo(t *testing.T) { Terst(t) test := runTest() { value, _ := test(`"11"`).ToFloat() Is(value, float64(11)) } { value, _ := test(`"11"`).ToInteger() Is(value, int64(11)) value, _ = test(`1.1`).ToInteger() Is(value, int64(1)) } } func TestShouldError(t *testing.T) { Terst(t) test := runTest() test(`raise: xyzzy throw new TypeError("Nothing happens.") `, "ReferenceError: xyzzy is not defined") }