mirror of
https://github.com/robertkrimen/otto.git
synced 2025-12-24 12:58:05 +08:00
terst
* Update to latest github.com/robertkrimen/terst * Clean up testing
This commit is contained in:
2
Makefile
2
Makefile
@@ -3,11 +3,11 @@
|
||||
.PHONY: otto assets underscore
|
||||
|
||||
TESTS := \
|
||||
FunctionDeclarationInFunction \
|
||||
~
|
||||
|
||||
TEST := -v --run
|
||||
TEST := -v --run Test\($(subst $(eval) ,\|,$(TESTS))\)
|
||||
TEST := -v
|
||||
TEST := .
|
||||
|
||||
test: parser inline.go
|
||||
|
||||
1011
array_test.go
1011
array_test.go
File diff suppressed because it is too large
Load Diff
720
bug_test.go
720
bug_test.go
@@ -1,426 +1,433 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Test_262(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
// 11.13.1-1-1
|
||||
test := runTest()
|
||||
|
||||
test(`raise:
|
||||
eval("42 = 42;");
|
||||
`, "ReferenceError: Invalid left-hand side in assignment")
|
||||
// 11.13.1-1-1
|
||||
test(`raise:
|
||||
eval("42 = 42;");
|
||||
`, "ReferenceError: Invalid left-hand side in assignment")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue5(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`'abc' === 'def'`, false)
|
||||
test(`'\t' === '\r'`, false)
|
||||
test(`'abc' === 'def'`, false)
|
||||
test(`'\t' === '\r'`, false)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue13(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, tester := test()
|
||||
vm := tester.vm
|
||||
|
||||
otto, test := runTestWithOtto()
|
||||
value, err := vm.ToValue(map[string]interface{}{
|
||||
"string": "Xyzzy",
|
||||
"number": 42,
|
||||
"array": []string{"def", "ghi"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
value, err := otto.ToValue(map[string]interface{}{
|
||||
"string": "Xyzzy",
|
||||
"number": 42,
|
||||
"array": []string{"def", "ghi"},
|
||||
})
|
||||
if err != nil {
|
||||
FailNow(err)
|
||||
}
|
||||
fn, err := vm.Object(`
|
||||
(function(value){
|
||||
return ""+[value.string, value.number, value.array]
|
||||
})
|
||||
`)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
fn, err := otto.Object(`
|
||||
(function(value){
|
||||
return ""+[value.string, value.number, value.array]
|
||||
})
|
||||
`)
|
||||
if err != nil {
|
||||
FailNow(err)
|
||||
}
|
||||
result, err := fn.Value().Call(fn.Value(), value)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
is(result.toString(), "Xyzzy,42,def,ghi")
|
||||
|
||||
result, err := fn.Value().Call(fn.Value(), value)
|
||||
if err != nil {
|
||||
FailNow(err)
|
||||
}
|
||||
Is(result.toString(), "Xyzzy,42,def,ghi")
|
||||
|
||||
anything := struct {
|
||||
Abc interface{}
|
||||
}{
|
||||
Abc: map[string]interface{}{
|
||||
"def": []interface{}{
|
||||
[]interface{}{
|
||||
"a", "b", "c", "", "d", "e",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"jkl": "Nothing happens.",
|
||||
anything := struct {
|
||||
Abc interface{}
|
||||
}{
|
||||
Abc: map[string]interface{}{
|
||||
"def": []interface{}{
|
||||
[]interface{}{
|
||||
"a", "b", "c", "", "d", "e",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"jkl": "Nothing happens.",
|
||||
},
|
||||
},
|
||||
"ghi": -1,
|
||||
},
|
||||
"ghi": -1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
otto.Set("anything", anything)
|
||||
test(`
|
||||
[
|
||||
anything,
|
||||
"~",
|
||||
anything.Abc,
|
||||
"~",
|
||||
anything.Abc.def,
|
||||
"~",
|
||||
anything.Abc.def[1].jkl,
|
||||
"~",
|
||||
anything.Abc.ghi,
|
||||
];
|
||||
`, "[object Object],~,[object Object],~,a,b,c,,d,e,[object Object],~,Nothing happens.,~,-1",
|
||||
)
|
||||
vm.Set("anything", anything)
|
||||
test(`
|
||||
[
|
||||
anything,
|
||||
"~",
|
||||
anything.Abc,
|
||||
"~",
|
||||
anything.Abc.def,
|
||||
"~",
|
||||
anything.Abc.def[1].jkl,
|
||||
"~",
|
||||
anything.Abc.ghi,
|
||||
];
|
||||
`, "[object Object],~,[object Object],~,a,b,c,,d,e,[object Object],~,Nothing happens.,~,-1")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue16(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
otto, test := runTestWithOtto()
|
||||
test(`
|
||||
var def = {
|
||||
"abc": ["abc"],
|
||||
"xyz": ["xyz"]
|
||||
};
|
||||
def.abc.concat(def.xyz);
|
||||
`, "abc,xyz")
|
||||
|
||||
test(`
|
||||
var def = {
|
||||
"abc": ["abc"],
|
||||
"xyz": ["xyz"]
|
||||
};
|
||||
def.abc.concat(def.xyz);
|
||||
`, "abc,xyz")
|
||||
vm.Set("ghi", []string{"jkl", "mno"})
|
||||
|
||||
otto.Set("ghi", []string{"jkl", "mno"})
|
||||
test(`
|
||||
def.abc.concat(def.xyz).concat(ghi);
|
||||
`, "abc,xyz,jkl,mno")
|
||||
|
||||
test(`
|
||||
def.abc.concat(def.xyz).concat(ghi);
|
||||
`, "abc,xyz,jkl,mno")
|
||||
test(`
|
||||
ghi.concat(def.abc.concat(def.xyz));
|
||||
`, "jkl,mno,abc,xyz")
|
||||
|
||||
test(`
|
||||
ghi.concat(def.abc.concat(def.xyz));
|
||||
`, "jkl,mno,abc,xyz")
|
||||
vm.Set("pqr", []interface{}{"jkl", 42, 3.14159, true})
|
||||
|
||||
otto.Set("pqr", []interface{}{"jkl", 42, 3.14159, true})
|
||||
test(`
|
||||
pqr.concat(ghi, def.abc, def, def.xyz);
|
||||
`, "jkl,42,3.14159,true,jkl,mno,abc,[object Object],xyz")
|
||||
|
||||
test(`
|
||||
pqr.concat(ghi, def.abc, def, def.xyz);
|
||||
`, "jkl,42,3.14159,true,jkl,mno,abc,[object Object],xyz")
|
||||
|
||||
test(`
|
||||
pqr.concat(ghi, def.abc, def, def.xyz).length;
|
||||
`, 9)
|
||||
test(`
|
||||
pqr.concat(ghi, def.abc, def, def.xyz).length;
|
||||
`, 9)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue21(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
vm1 := New()
|
||||
vm1.Run(`
|
||||
abc = {}
|
||||
abc.ghi = "Nothing happens.";
|
||||
var jkl = 0;
|
||||
abc.def = function() {
|
||||
jkl += 1;
|
||||
return 1;
|
||||
}
|
||||
`)
|
||||
abc, err := vm1.Get("abc")
|
||||
is(err, nil)
|
||||
|
||||
otto1 := New()
|
||||
otto1.Run(`
|
||||
abc = {}
|
||||
abc.ghi = "Nothing happens.";
|
||||
var jkl = 0;
|
||||
abc.def = function() {
|
||||
jkl += 1;
|
||||
return 1;
|
||||
}
|
||||
`)
|
||||
abc, err := otto1.Get("abc")
|
||||
Is(err, nil)
|
||||
vm2 := New()
|
||||
vm2.Set("cba", abc)
|
||||
_, err = vm2.Run(`
|
||||
var pqr = 0;
|
||||
cba.mno = function() {
|
||||
pqr -= 1;
|
||||
return 1;
|
||||
}
|
||||
cba.def();
|
||||
cba.def();
|
||||
cba.def();
|
||||
`)
|
||||
is(err, nil)
|
||||
|
||||
otto2 := New()
|
||||
otto2.Set("cba", abc)
|
||||
_, err = otto2.Run(`
|
||||
var pqr = 0;
|
||||
cba.mno = function() {
|
||||
pqr -= 1;
|
||||
return 1;
|
||||
}
|
||||
cba.def();
|
||||
cba.def();
|
||||
cba.def();
|
||||
`)
|
||||
Is(err, nil)
|
||||
jkl, err := vm1.Get("jkl")
|
||||
is(err, nil)
|
||||
is(jkl, 3)
|
||||
|
||||
jkl, err := otto1.Get("jkl")
|
||||
Is(err, nil)
|
||||
is(jkl, 3)
|
||||
_, err = vm1.Run(`
|
||||
abc.mno();
|
||||
abc.mno();
|
||||
abc.mno();
|
||||
`)
|
||||
is(err, nil)
|
||||
|
||||
_, err = otto1.Run(`
|
||||
abc.mno();
|
||||
abc.mno();
|
||||
abc.mno();
|
||||
`)
|
||||
Is(err, nil)
|
||||
|
||||
pqr, err := otto2.Get("pqr")
|
||||
Is(err, nil)
|
||||
is(pqr, -3)
|
||||
pqr, err := vm2.Get("pqr")
|
||||
is(err, nil)
|
||||
is(pqr, -3)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue24(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
_, vm := test()
|
||||
|
||||
otto, _ := runTestWithOtto()
|
||||
|
||||
{
|
||||
otto.Set("abc", []string{"abc", "def", "ghi"})
|
||||
value, err := otto.Get("abc")
|
||||
Is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.([]string)
|
||||
Is(valid, true)
|
||||
vm.Set("abc", []string{"abc", "def", "ghi"})
|
||||
value, err := vm.Get("abc")
|
||||
is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.([]string)
|
||||
is(valid, true)
|
||||
|
||||
Is(value[0], "abc")
|
||||
Is(value[2], "ghi")
|
||||
is(value[0], "abc")
|
||||
is(value[2], "ghi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
otto.Set("abc", [...]string{"abc", "def", "ghi"})
|
||||
value, err := otto.Get("abc")
|
||||
Is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.([3]string)
|
||||
Is(valid, true)
|
||||
vm.Set("abc", [...]string{"abc", "def", "ghi"})
|
||||
value, err := vm.Get("abc")
|
||||
is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.([3]string)
|
||||
is(valid, true)
|
||||
|
||||
Is(value[0], "abc")
|
||||
Is(value[2], "ghi")
|
||||
is(value[0], "abc")
|
||||
is(value[2], "ghi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
otto.Set("abc", &[...]string{"abc", "def", "ghi"})
|
||||
value, err := otto.Get("abc")
|
||||
Is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(*[3]string)
|
||||
Is(valid, true)
|
||||
vm.Set("abc", &[...]string{"abc", "def", "ghi"})
|
||||
value, err := vm.Get("abc")
|
||||
is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(*[3]string)
|
||||
is(valid, true)
|
||||
|
||||
Is(value[0], "abc")
|
||||
Is(value[2], "ghi")
|
||||
is(value[0], "abc")
|
||||
is(value[2], "ghi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
otto.Set("abc", map[int]string{0: "abc", 1: "def", 2: "ghi"})
|
||||
value, err := otto.Get("abc")
|
||||
Is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(map[int]string)
|
||||
Is(valid, true)
|
||||
vm.Set("abc", map[int]string{0: "abc", 1: "def", 2: "ghi"})
|
||||
value, err := vm.Get("abc")
|
||||
is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(map[int]string)
|
||||
is(valid, true)
|
||||
|
||||
Is(value[0], "abc")
|
||||
Is(value[2], "ghi")
|
||||
is(value[0], "abc")
|
||||
is(value[2], "ghi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
otto.Set("abc", testStruct{Abc: true, Ghi: "Nothing happens."})
|
||||
value, err := otto.Get("abc")
|
||||
Is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(testStruct)
|
||||
Is(valid, true)
|
||||
vm.Set("abc", testStruct{Abc: true, Ghi: "Nothing happens."})
|
||||
value, err := vm.Get("abc")
|
||||
is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(testStruct)
|
||||
is(valid, true)
|
||||
|
||||
Is(value.Abc, true)
|
||||
Is(value.Ghi, "Nothing happens.")
|
||||
is(value.Abc, true)
|
||||
is(value.Ghi, "Nothing happens.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
otto.Set("abc", &testStruct{Abc: true, Ghi: "Nothing happens."})
|
||||
value, err := otto.Get("abc")
|
||||
Is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(*testStruct)
|
||||
Is(valid, true)
|
||||
vm.Set("abc", &testStruct{Abc: true, Ghi: "Nothing happens."})
|
||||
value, err := vm.Get("abc")
|
||||
is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(*testStruct)
|
||||
is(valid, true)
|
||||
|
||||
Is(value.Abc, true)
|
||||
Is(value.Ghi, "Nothing happens.")
|
||||
is(value.Abc, true)
|
||||
is(value.Ghi, "Nothing happens.")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue39(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
var abc = 0, def = [], ghi = function() {
|
||||
if (abc < 10) return ++abc;
|
||||
return undefined;
|
||||
}
|
||||
for (var jkl; (jkl = ghi());) def.push(jkl);
|
||||
def;
|
||||
`, "1,2,3,4,5,6,7,8,9,10")
|
||||
|
||||
test(`
|
||||
var abc = 0, def = [], ghi = function() {
|
||||
if (abc < 10) return ++abc;
|
||||
return undefined;
|
||||
}
|
||||
for (var jkl; (jkl = ghi());) def.push(jkl);
|
||||
def;
|
||||
`, "1,2,3,4,5,6,7,8,9,10")
|
||||
|
||||
test(`
|
||||
var abc = ["1", "2", "3", "4"];
|
||||
var def = [];
|
||||
for (var ghi; (ghi = abc.shift());) {
|
||||
def.push(ghi);
|
||||
}
|
||||
def;
|
||||
`, "1,2,3,4")
|
||||
test(`
|
||||
var abc = ["1", "2", "3", "4"];
|
||||
var def = [];
|
||||
for (var ghi; (ghi = abc.shift());) {
|
||||
def.push(ghi);
|
||||
}
|
||||
def;
|
||||
`, "1,2,3,4")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue64(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
defer mockTimeLocal(time.UTC)()
|
||||
defer mockTimeLocal(time.UTC)()
|
||||
|
||||
otto, test := runTestWithOtto()
|
||||
abc := map[string]interface{}{
|
||||
"time": time.Unix(0, 0),
|
||||
}
|
||||
vm.Set("abc", abc)
|
||||
|
||||
abc := map[string]interface{}{
|
||||
"time": time.Unix(0, 0),
|
||||
}
|
||||
otto.Set("abc", abc)
|
||||
def := struct {
|
||||
Public string
|
||||
private string
|
||||
}{
|
||||
"Public", "private",
|
||||
}
|
||||
vm.Set("def", def)
|
||||
|
||||
def := struct {
|
||||
Public string
|
||||
private string
|
||||
}{
|
||||
"Public", "private",
|
||||
}
|
||||
otto.Set("def", def)
|
||||
test(`"sec" in abc.time`, false)
|
||||
|
||||
test(`"sec" in abc.time`, false)
|
||||
test(`
|
||||
[ "Public" in def, "private" in def, def.Public, def.private ];
|
||||
`, "true,false,Public,")
|
||||
|
||||
test(`
|
||||
[ "Public" in def, "private" in def, def.Public, def.private ];
|
||||
`, "true,false,Public,")
|
||||
|
||||
test(`JSON.stringify(abc)`, `{"time":"1970-01-01T00:00:00Z"}`)
|
||||
test(`JSON.stringify(abc)`, `{"time":"1970-01-01T00:00:00Z"}`)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_7_3_1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test(`
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
eval("var test7_3_1\u2028abc = 66;");
|
||||
[ abc, typeof test7_3_1 ];
|
||||
`, "66,undefined")
|
||||
eval("var test7_3_1\u2028abc = 66;");
|
||||
[ abc, typeof test7_3_1 ];
|
||||
`, "66,undefined")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_7_3_3(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
test := runTest()
|
||||
test(`raise:
|
||||
eval("//\u2028 =;");
|
||||
`, "SyntaxError: Unexpected token =")
|
||||
tt(t, func() {
|
||||
test(`raise:
|
||||
eval("//\u2028 =;");
|
||||
`, "SyntaxError: Unexpected token =")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_S7_3_A2_1_T1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`raise:
|
||||
eval("'\u000Astr\u000Aing\u000A'")
|
||||
`, "SyntaxError: Unexpected token ILLEGAL")
|
||||
test(`raise:
|
||||
eval("'\u000Astr\u000Aing\u000A'")
|
||||
`, "SyntaxError: Unexpected token ILLEGAL")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_S7_8_3_A2_1_T1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
[ .0 === 0.0, .0, .1 === 0.1, .1 ]
|
||||
`, "true,0,true,0.1")
|
||||
test(`
|
||||
[ .0 === 0.0, .0, .1 === 0.1, .1 ]
|
||||
`, "true,0,true,0.1")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_S7_8_4_A4_2_T3(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
"\a"
|
||||
`, "a")
|
||||
test(`
|
||||
"\a"
|
||||
`, "a")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_S7_9_A1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
var def;
|
||||
abc: for (var i = 0; i <= 0; i++) {
|
||||
for (var j = 0; j <= 1; j++) {
|
||||
if (j === 0) {
|
||||
continue abc;
|
||||
} else {
|
||||
def = true;
|
||||
test(`
|
||||
var def;
|
||||
abc: for (var i = 0; i <= 0; i++) {
|
||||
for (var j = 0; j <= 1; j++) {
|
||||
if (j === 0) {
|
||||
continue abc;
|
||||
} else {
|
||||
def = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[ def, i, j ];
|
||||
`, ",1,0")
|
||||
[ def, i, j ];
|
||||
`, ",1,0")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_S7_9_A3(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
(function(){
|
||||
return
|
||||
1;
|
||||
})()
|
||||
`, "undefined")
|
||||
test(`
|
||||
(function(){
|
||||
return
|
||||
1;
|
||||
})()
|
||||
`, "undefined")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_7_3_10(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
eval("var \u0061\u0062\u0063 = 3.14159;");
|
||||
abc;
|
||||
`, 3.14159)
|
||||
test(`
|
||||
abc = undefined;
|
||||
eval("var \\u0061\\u0062\\u0063 = 3.14159;");
|
||||
abc;
|
||||
`, 3.14159)
|
||||
test(`
|
||||
eval("var \u0061\u0062\u0063 = 3.14159;");
|
||||
abc;
|
||||
`, 3.14159)
|
||||
|
||||
test(`
|
||||
abc = undefined;
|
||||
eval("var \\u0061\\u0062\\u0063 = 3.14159;");
|
||||
abc;
|
||||
`, 3.14159)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_bug(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
// 10.4.2-1-5
|
||||
test(`
|
||||
"abc\
|
||||
// 10.4.2-1-5
|
||||
test(`
|
||||
"abc\
|
||||
def"
|
||||
`, "abcdef")
|
||||
`, "abcdef")
|
||||
|
||||
test(`
|
||||
eval("'abc';\
|
||||
'def'")
|
||||
`, "def")
|
||||
test(`
|
||||
eval("'abc';\
|
||||
'def'")
|
||||
`, "def")
|
||||
|
||||
// S12.6.1_A10
|
||||
test(`
|
||||
// S12.6.1_A10
|
||||
test(`
|
||||
var abc = 0;
|
||||
do {
|
||||
if(typeof(def) === "function"){
|
||||
@@ -434,63 +441,64 @@ def"
|
||||
abc;
|
||||
`, 1)
|
||||
|
||||
// S12.7_A7
|
||||
test(`raise:
|
||||
abc:
|
||||
while (true) {
|
||||
eval("continue abc");
|
||||
}
|
||||
`, "SyntaxError: Undefined label 'abc'")
|
||||
|
||||
// S15.1.2.1_A3.3_T3
|
||||
test(`raise:
|
||||
eval("return");
|
||||
`, "SyntaxError: Illegal return statement")
|
||||
|
||||
// 15.2.3.3-2-33
|
||||
test(`
|
||||
var abc = { "AB\n\\cd": 1 };
|
||||
Object.getOwnPropertyDescriptor(abc, "AB\n\\cd").value;
|
||||
`, 1)
|
||||
|
||||
// S15.3_A2_T1
|
||||
test(`raise:
|
||||
Function.call(this, "var x / = 1;");
|
||||
`, "SyntaxError: Unexpected token /")
|
||||
|
||||
// ?
|
||||
test(`
|
||||
(function(){
|
||||
var abc = [];
|
||||
(function(){
|
||||
abc.push(0);
|
||||
abc.push(1);
|
||||
})(undefined);
|
||||
if ((function(){ return true; })()) {
|
||||
(function(){
|
||||
abc.push(2);
|
||||
})();
|
||||
// S12.7_A7
|
||||
test(`raise:
|
||||
abc:
|
||||
while (true) {
|
||||
eval("continue abc");
|
||||
}
|
||||
return abc;
|
||||
})();
|
||||
`, "0,1,2")
|
||||
`, "SyntaxError: Undefined label 'abc'")
|
||||
|
||||
if false {
|
||||
// 15.9.5.43-0-10
|
||||
// Should be an invalid date
|
||||
// S15.1.2.1_A3.3_T3
|
||||
test(`raise:
|
||||
eval("return");
|
||||
`, "SyntaxError: Illegal return statement")
|
||||
|
||||
// 15.2.3.3-2-33
|
||||
test(`
|
||||
date = new Date(1970, 0, -99999999, 0, 0, 0, 1);
|
||||
`, "")
|
||||
}
|
||||
var abc = { "AB\n\\cd": 1 };
|
||||
Object.getOwnPropertyDescriptor(abc, "AB\n\\cd").value;
|
||||
`, 1)
|
||||
|
||||
// S7.8.3_A1.2_T1
|
||||
test(`
|
||||
[ 0e1, 1e1, 2e1, 3e1, 4e1, 5e1, 6e1, 7e1, 8e1, 9e1 ];
|
||||
`, "0,10,20,30,40,50,60,70,80,90")
|
||||
// S15.3_A2_T1
|
||||
test(`raise:
|
||||
Function.call(this, "var x / = 1;");
|
||||
`, "SyntaxError: Unexpected token /")
|
||||
|
||||
// S15.10.2.7_A3_T2
|
||||
test(`
|
||||
var abc = /\s+abc\s+/.exec("\t abc def");
|
||||
[ abc.length, abc.index, abc.input, abc ];
|
||||
`, "1,0,\t abc def,\t abc ")
|
||||
// ?
|
||||
test(`
|
||||
(function(){
|
||||
var abc = [];
|
||||
(function(){
|
||||
abc.push(0);
|
||||
abc.push(1);
|
||||
})(undefined);
|
||||
if ((function(){ return true; })()) {
|
||||
(function(){
|
||||
abc.push(2);
|
||||
})();
|
||||
}
|
||||
return abc;
|
||||
})();
|
||||
`, "0,1,2")
|
||||
|
||||
if false {
|
||||
// 15.9.5.43-0-10
|
||||
// Should be an invalid date
|
||||
test(`
|
||||
date = new Date(1970, 0, -99999999, 0, 0, 0, 1);
|
||||
`, "")
|
||||
}
|
||||
|
||||
// S7.8.3_A1.2_T1
|
||||
test(`
|
||||
[ 0e1, 1e1, 2e1, 3e1, 4e1, 5e1, 6e1, 7e1, 8e1, 9e1 ];
|
||||
`, "0,10,20,30,40,50,60,70,80,90")
|
||||
|
||||
// S15.10.2.7_A3_T2
|
||||
test(`
|
||||
var abc = /\s+abc\s+/.exec("\t abc def");
|
||||
[ abc.length, abc.index, abc.input, abc ];
|
||||
`, "1,0,\t abc def,\t abc ")
|
||||
})
|
||||
}
|
||||
|
||||
198
builtin_test.go
198
builtin_test.go
@@ -1,134 +1,136 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestString_substr(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
[
|
||||
"abc".substr(0,1), // "a"
|
||||
"abc".substr(0,2), // "ab"
|
||||
"abc".substr(0,3), // "abc"
|
||||
"abc".substr(0,4), // "abc"
|
||||
"abc".substr(0,9), // "abc"
|
||||
];
|
||||
`, "a,ab,abc,abc,abc")
|
||||
test(`
|
||||
[
|
||||
"abc".substr(0,1), // "a"
|
||||
"abc".substr(0,2), // "ab"
|
||||
"abc".substr(0,3), // "abc"
|
||||
"abc".substr(0,4), // "abc"
|
||||
"abc".substr(0,9), // "abc"
|
||||
];
|
||||
`, "a,ab,abc,abc,abc")
|
||||
|
||||
test(`
|
||||
[
|
||||
"abc".substr(1,1), // "b"
|
||||
"abc".substr(1,2), // "bc"
|
||||
"abc".substr(1,3), // "bc"
|
||||
"abc".substr(1,4), // "bc"
|
||||
"abc".substr(1,9), // "bc"
|
||||
];
|
||||
`, "b,bc,bc,bc,bc")
|
||||
test(`
|
||||
[
|
||||
"abc".substr(1,1), // "b"
|
||||
"abc".substr(1,2), // "bc"
|
||||
"abc".substr(1,3), // "bc"
|
||||
"abc".substr(1,4), // "bc"
|
||||
"abc".substr(1,9), // "bc"
|
||||
];
|
||||
`, "b,bc,bc,bc,bc")
|
||||
|
||||
test(`
|
||||
[
|
||||
"abc".substr(2,1), // "c"
|
||||
"abc".substr(2,2), // "c"
|
||||
"abc".substr(2,3), // "c"
|
||||
"abc".substr(2,4), // "c"
|
||||
"abc".substr(2,9), // "c"
|
||||
];
|
||||
`, "c,c,c,c,c")
|
||||
test(`
|
||||
[
|
||||
"abc".substr(2,1), // "c"
|
||||
"abc".substr(2,2), // "c"
|
||||
"abc".substr(2,3), // "c"
|
||||
"abc".substr(2,4), // "c"
|
||||
"abc".substr(2,9), // "c"
|
||||
];
|
||||
`, "c,c,c,c,c")
|
||||
|
||||
test(`
|
||||
[
|
||||
"abc".substr(3,1), // ""
|
||||
"abc".substr(3,2), // ""
|
||||
"abc".substr(3,3), // ""
|
||||
"abc".substr(3,4), // ""
|
||||
"abc".substr(3,9), // ""
|
||||
];
|
||||
`, ",,,,")
|
||||
test(`
|
||||
[
|
||||
"abc".substr(3,1), // ""
|
||||
"abc".substr(3,2), // ""
|
||||
"abc".substr(3,3), // ""
|
||||
"abc".substr(3,4), // ""
|
||||
"abc".substr(3,9), // ""
|
||||
];
|
||||
`, ",,,,")
|
||||
|
||||
test(`
|
||||
[
|
||||
"abc".substr(0), // "abc"
|
||||
"abc".substr(1), // "bc"
|
||||
"abc".substr(2), // "c"
|
||||
"abc".substr(3), // ""
|
||||
"abc".substr(9), // ""
|
||||
];
|
||||
`, "abc,bc,c,,")
|
||||
test(`
|
||||
[
|
||||
"abc".substr(0), // "abc"
|
||||
"abc".substr(1), // "bc"
|
||||
"abc".substr(2), // "c"
|
||||
"abc".substr(3), // ""
|
||||
"abc".substr(9), // ""
|
||||
];
|
||||
`, "abc,bc,c,,")
|
||||
|
||||
test(`
|
||||
[
|
||||
"abc".substr(-9), // "abc"
|
||||
"abc".substr(-3), // "abc"
|
||||
"abc".substr(-2), // "bc"
|
||||
"abc".substr(-1), // "c"
|
||||
];
|
||||
`, "abc,abc,bc,c")
|
||||
test(`
|
||||
[
|
||||
"abc".substr(-9), // "abc"
|
||||
"abc".substr(-3), // "abc"
|
||||
"abc".substr(-2), // "bc"
|
||||
"abc".substr(-1), // "c"
|
||||
];
|
||||
`, "abc,abc,bc,c")
|
||||
|
||||
test(`
|
||||
[
|
||||
"abc".substr(-9, 1), // "a"
|
||||
"abc".substr(-3, 1), // "a"
|
||||
"abc".substr(-2, 1), // "b"
|
||||
"abc".substr(-1, 1), // "c"
|
||||
"abc".substr(-1, 2), // "c"
|
||||
];
|
||||
`, "a,a,b,c,c")
|
||||
test(`
|
||||
[
|
||||
"abc".substr(-9, 1), // "a"
|
||||
"abc".substr(-3, 1), // "a"
|
||||
"abc".substr(-2, 1), // "b"
|
||||
"abc".substr(-1, 1), // "c"
|
||||
"abc".substr(-1, 2), // "c"
|
||||
];
|
||||
`, "a,a,b,c,c")
|
||||
|
||||
test(`"abcd".substr(3, 5)`, "d")
|
||||
test(`"abcd".substr(3, 5)`, "d")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_builtin_escape(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
is(builtin_escape("abc"), "abc")
|
||||
|
||||
Is(builtin_escape("abc"), "abc")
|
||||
is(builtin_escape("="), "%3D")
|
||||
|
||||
Is(builtin_escape("="), "%3D")
|
||||
is(builtin_escape("abc=%+32"), "abc%3D%25+32")
|
||||
|
||||
Is(builtin_escape("abc=%+32"), "abc%3D%25+32")
|
||||
|
||||
Is(builtin_escape("世界"), "%u4E16%u754C")
|
||||
is(builtin_escape("世界"), "%u4E16%u754C")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_builtin_unescape(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
is(builtin_unescape("abc"), "abc")
|
||||
|
||||
Is(builtin_unescape("abc"), "abc")
|
||||
is(builtin_unescape("=%3D"), "==")
|
||||
|
||||
Is(builtin_unescape("=%3D"), "==")
|
||||
is(builtin_unescape("abc%3D%25+32"), "abc=%+32")
|
||||
|
||||
Is(builtin_unescape("abc%3D%25+32"), "abc=%+32")
|
||||
|
||||
Is(builtin_unescape("%u4E16%u754C"), "世界")
|
||||
is(builtin_unescape("%u4E16%u754C"), "世界")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGlobal_escape(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
[
|
||||
escape("abc"), // "abc"
|
||||
escape("="), // "%3D"
|
||||
escape("abc=%+32"), // "abc%3D%25+32"
|
||||
escape("\u4e16\u754c"), // "%u4E16%u754C"
|
||||
];
|
||||
`, "abc,%3D,abc%3D%25+32,%u4E16%u754C")
|
||||
test(`
|
||||
[
|
||||
escape("abc"), // "abc"
|
||||
escape("="), // "%3D"
|
||||
escape("abc=%+32"), // "abc%3D%25+32"
|
||||
escape("\u4e16\u754c"), // "%u4E16%u754C"
|
||||
];
|
||||
`, "abc,%3D,abc%3D%25+32,%u4E16%u754C")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGlobal_unescape(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
[
|
||||
unescape("abc"), // "abc"
|
||||
unescape("=%3D"), // "=="
|
||||
unescape("abc%3D%25+32"), // "abc=%+32"
|
||||
unescape("%u4E16%u754C"), // "世界"
|
||||
];
|
||||
`, "abc,==,abc=%+32,世界")
|
||||
test(`
|
||||
[
|
||||
unescape("abc"), // "abc"
|
||||
unescape("=%3D"), // "=="
|
||||
unescape("abc%3D%25+32"), // "abc=%+32"
|
||||
unescape("%u4E16%u754C"), // "世界"
|
||||
];
|
||||
`, "abc,==,abc=%+32,世界")
|
||||
})
|
||||
}
|
||||
|
||||
60
cmpl_test.go
60
cmpl_test.go
@@ -1,54 +1,54 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
|
||||
"github.com/robertkrimen/otto/parser"
|
||||
)
|
||||
|
||||
func Test_cmpl(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
vm := New()
|
||||
|
||||
vm := New()
|
||||
|
||||
test := func(src string, expect ...interface{}) {
|
||||
program, err := parser.ParseFile(nil, "", src, 0)
|
||||
Is(err, nil)
|
||||
{
|
||||
program := cmpl_parse(program)
|
||||
value := vm.runtime.cmpl_evaluate_nodeProgram(program)
|
||||
if len(expect) > 0 {
|
||||
is(value, expect[0])
|
||||
test := func(src string, expect ...interface{}) {
|
||||
program, err := parser.ParseFile(nil, "", src, 0)
|
||||
is(err, nil)
|
||||
{
|
||||
program := cmpl_parse(program)
|
||||
value := vm.runtime.cmpl_evaluate_nodeProgram(program)
|
||||
if len(expect) > 0 {
|
||||
is(value, expect[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test(``, Value{})
|
||||
test(``, Value{})
|
||||
|
||||
test(`var abc = 1; abc;`, 1)
|
||||
test(`var abc = 1; abc;`, 1)
|
||||
|
||||
test(`var abc = 1 + 1; abc;`, 2)
|
||||
test(`var abc = 1 + 1; abc;`, 2)
|
||||
|
||||
test(`1 + 2;`, 3)
|
||||
test(`1 + 2;`, 3)
|
||||
})
|
||||
}
|
||||
|
||||
func TestParse_cmpl(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
|
||||
test := func(src string) {
|
||||
program, err := parser.ParseFile(nil, "", src, 0)
|
||||
Is(err, nil)
|
||||
IsNot(cmpl_parse(program), nil)
|
||||
}
|
||||
test := func(src string) {
|
||||
program, err := parser.ParseFile(nil, "", src, 0)
|
||||
is(err, nil)
|
||||
is(cmpl_parse(program), "!=", nil)
|
||||
}
|
||||
|
||||
test(``)
|
||||
test(``)
|
||||
|
||||
test(`var abc = 1; abc;`)
|
||||
test(`var abc = 1; abc;`)
|
||||
|
||||
test(`
|
||||
function abc() {
|
||||
return;
|
||||
}
|
||||
`)
|
||||
test(`
|
||||
function abc() {
|
||||
return;
|
||||
}
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
598
date_test.go
598
date_test.go
@@ -1,482 +1,478 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
Time "time"
|
||||
"time"
|
||||
)
|
||||
|
||||
func mockTimeLocal(location *Time.Location) func() {
|
||||
local := Time.Local
|
||||
Time.Local = location
|
||||
func mockTimeLocal(location *time.Location) func() {
|
||||
local := time.Local
|
||||
time.Local = location
|
||||
return func() {
|
||||
Time.Local = local
|
||||
time.Local = local
|
||||
}
|
||||
}
|
||||
|
||||
// Passing or failing should not be dependent on what time zone we're in
|
||||
func mockUTC() func() {
|
||||
return mockTimeLocal(Time.UTC)
|
||||
return mockTimeLocal(time.UTC)
|
||||
}
|
||||
|
||||
func TestDate(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
time0 := time.Unix(1348616313, 47*1000*1000).Local()
|
||||
|
||||
time := Time.Unix(1348616313, 47*1000*1000).Local()
|
||||
check := func(run string, value int) {
|
||||
test(run, fmt.Sprintf("%d", value))
|
||||
}
|
||||
test(`Date`, "function Date() { [native code] }")
|
||||
test(`new Date(0).toUTCString()`, "Thu, 01 Jan 1970 00:00:00 UTC")
|
||||
test(`new Date(0).toGMTString()`, "Thu, 01 Jan 1970 00:00:00 GMT")
|
||||
if false {
|
||||
// TODO toLocale{Date,Time}String
|
||||
test(`new Date(0).toLocaleString()`, "")
|
||||
test(`new Date(0).toLocaleDateString()`, "")
|
||||
test(`new Date(0).toLocaleTimeString()`, "")
|
||||
}
|
||||
test(`new Date(1348616313).getTime()`, 1348616313)
|
||||
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.getYear()`, time0.Year()-1900)
|
||||
test(`abc.getFullYear()`, time0.Year())
|
||||
test(`abc.getUTCFullYear()`, 2012)
|
||||
test(`abc.getMonth()`, int(time0.Month())-1) // Remember, the JavaScript month is 0-based
|
||||
test(`abc.getUTCMonth()`, 8)
|
||||
test(`abc.getDate()`, time0.Day())
|
||||
test(`abc.getUTCDate()`, 25)
|
||||
test(`abc.getDay()`, int(time0.Weekday()))
|
||||
test(`abc.getUTCDay()`, 2)
|
||||
test(`abc.getHours()`, time0.Hour())
|
||||
test(`abc.getUTCHours()`, 23)
|
||||
test(`abc.getMinutes()`, time0.Minute())
|
||||
test(`abc.getUTCMinutes()`, 38)
|
||||
test(`abc.getSeconds()`, time0.Second())
|
||||
test(`abc.getUTCSeconds()`, 33)
|
||||
test(`abc.getMilliseconds()`, time0.Nanosecond()/(1000*1000)) // In honor of the 47%
|
||||
test(`abc.getUTCMilliseconds()`, 47)
|
||||
_, offset := time0.Zone()
|
||||
test(`abc.getTimezoneOffset()`, offset/-60)
|
||||
|
||||
test(`Date`, "function Date() { [native code] }")
|
||||
test(`new Date(0).toUTCString()`, "Thu, 01 Jan 1970 00:00:00 UTC")
|
||||
test(`new Date(0).toGMTString()`, "Thu, 01 Jan 1970 00:00:00 GMT")
|
||||
if false {
|
||||
// TODO toLocale{Date,Time}String
|
||||
test(`new Date(0).toLocaleString()`, "")
|
||||
test(`new Date(0).toLocaleDateString()`, "")
|
||||
test(`new Date(0).toLocaleTimeString()`, "")
|
||||
}
|
||||
test(`new Date(1348616313).getTime()`, "1348616313")
|
||||
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")
|
||||
check(`abc.getYear()`, time.Year()-1900)
|
||||
check(`abc.getFullYear()`, time.Year())
|
||||
check(`abc.getUTCFullYear()`, 2012)
|
||||
check(`abc.getMonth()`, int(time.Month())-1) // Remember, the JavaScript month is 0-based
|
||||
check(`abc.getUTCMonth()`, 8)
|
||||
check(`abc.getDate()`, time.Day())
|
||||
check(`abc.getUTCDate()`, 25)
|
||||
check(`abc.getDay()`, int(time.Weekday()))
|
||||
check(`abc.getUTCDay()`, 2)
|
||||
check(`abc.getHours()`, time.Hour())
|
||||
check(`abc.getUTCHours()`, 23)
|
||||
check(`abc.getMinutes()`, time.Minute())
|
||||
check(`abc.getUTCMinutes()`, 38)
|
||||
check(`abc.getSeconds()`, time.Second())
|
||||
check(`abc.getUTCSeconds()`, 33)
|
||||
check(`abc.getMilliseconds()`, time.Nanosecond()/(1000*1000)) // In honor of the 47%
|
||||
check(`abc.getUTCMilliseconds()`, 47)
|
||||
_, offset := time.Zone()
|
||||
check(`abc.getTimezoneOffset()`, offset/-60)
|
||||
test(`new Date("Xyzzy").getTime()`, math.NaN())
|
||||
|
||||
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))`, 1256428800000)
|
||||
|
||||
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))`, "1256428800000")
|
||||
format := "Mon, 2 Jan 2006 15:04:05 MST"
|
||||
|
||||
format := "Mon, 2 Jan 2006 15:04:05 MST"
|
||||
time1 := time.Unix(1256450400, 0)
|
||||
time0 = time.Date(time1.Year(), time1.Month(), time1.Day(), time1.Hour(), time1.Minute(), time1.Second(), time1.Nanosecond(), time1.Location()).UTC()
|
||||
|
||||
tme := Time.Unix(1256450400, 0)
|
||||
time = Time.Date(tme.Year(), tme.Month(), tme.Day(), tme.Hour(), tme.Minute(), tme.Second(), tme.Nanosecond(), tme.Location()).UTC()
|
||||
time0 = time.Date(time1.Year(), time1.Month(), time1.Day(), time1.Hour(), time1.Minute(), time1.Second(), 2001*1000*1000, time1.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setMilliseconds(2001); abc.toUTCString()`, time0.Format(format))
|
||||
|
||||
time = Time.Date(tme.Year(), tme.Month(), tme.Day(), tme.Hour(), tme.Minute(), tme.Second(), 2001*1000*1000, tme.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setMilliseconds(2001); abc.toUTCString()`, time.Format(format))
|
||||
time0 = time.Date(time1.Year(), time1.Month(), time1.Day(), time1.Hour(), time1.Minute(), 61, time1.Nanosecond(), time1.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setSeconds("61"); abc.toUTCString()`, time0.Format(format))
|
||||
|
||||
time = Time.Date(tme.Year(), tme.Month(), tme.Day(), tme.Hour(), tme.Minute(), 61, tme.Nanosecond(), tme.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setSeconds("61"); abc.toUTCString()`, time.Format(format))
|
||||
time0 = time.Date(time1.Year(), time1.Month(), time1.Day(), time1.Hour(), 61, time1.Second(), time1.Nanosecond(), time1.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setMinutes("61"); abc.toUTCString()`, time0.Format(format))
|
||||
|
||||
time = Time.Date(tme.Year(), tme.Month(), tme.Day(), tme.Hour(), 61, tme.Second(), tme.Nanosecond(), tme.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setMinutes("61"); abc.toUTCString()`, time.Format(format))
|
||||
time0 = time.Date(time1.Year(), time1.Month(), time1.Day(), 5, time1.Minute(), time1.Second(), time1.Nanosecond(), time1.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setHours("5"); abc.toUTCString()`, time0.Format(format))
|
||||
|
||||
time = Time.Date(tme.Year(), tme.Month(), tme.Day(), 5, tme.Minute(), tme.Second(), tme.Nanosecond(), tme.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setHours("5"); abc.toUTCString()`, time.Format(format))
|
||||
time0 = time.Date(time1.Year(), time1.Month(), 26, time1.Hour(), time1.Minute(), time1.Second(), time1.Nanosecond(), time1.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setDate("26"); abc.toUTCString()`, time0.Format(format))
|
||||
|
||||
time = Time.Date(tme.Year(), tme.Month(), 26, tme.Hour(), tme.Minute(), tme.Second(), tme.Nanosecond(), tme.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setDate("26"); abc.toUTCString()`, time.Format(format))
|
||||
time0 = time.Date(time1.Year(), 10, time1.Day(), time1.Hour(), time1.Minute(), time1.Second(), time1.Nanosecond(), time1.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setMonth(9); abc.toUTCString()`, time0.Format(format))
|
||||
test(`abc = new Date(12564504e5); abc.setMonth("09"); abc.toUTCString()`, time0.Format(format))
|
||||
|
||||
time = Time.Date(tme.Year(), 10, tme.Day(), tme.Hour(), tme.Minute(), tme.Second(), tme.Nanosecond(), tme.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setMonth(9); abc.toUTCString()`, time.Format(format))
|
||||
test(`abc = new Date(12564504e5); abc.setMonth("09"); abc.toUTCString()`, time.Format(format))
|
||||
time0 = time.Date(time1.Year(), 11, time1.Day(), time1.Hour(), time1.Minute(), time1.Second(), time1.Nanosecond(), time1.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setMonth("10"); abc.toUTCString()`, time0.Format(format))
|
||||
|
||||
time = Time.Date(tme.Year(), 11, tme.Day(), tme.Hour(), tme.Minute(), tme.Second(), tme.Nanosecond(), tme.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setMonth("10"); abc.toUTCString()`, time.Format(format))
|
||||
time0 = time.Date(2010, time1.Month(), time1.Day(), time1.Hour(), time1.Minute(), time1.Second(), time1.Nanosecond(), time1.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setFullYear(2010); abc.toUTCString()`, time0.Format(format))
|
||||
|
||||
time = Time.Date(2010, tme.Month(), tme.Day(), tme.Hour(), tme.Minute(), tme.Second(), tme.Nanosecond(), tme.Location()).UTC()
|
||||
test(`abc = new Date(12564504e5); abc.setFullYear(2010); abc.toUTCString()`, time.Format(format))
|
||||
test(`new Date("2001-01-01T10:01:02.000").getTime()`, 978343262000)
|
||||
|
||||
test(`new Date("2001-01-01T10:01:02.000").getTime()`, "978343262000")
|
||||
// Date()
|
||||
test(`typeof Date()`, "string")
|
||||
test(`typeof Date(2006, 1, 2)`, "string")
|
||||
|
||||
// Date()
|
||||
test(`typeof Date()`, "string")
|
||||
test(`typeof Date(2006, 1, 2)`, "string")
|
||||
test(`
|
||||
abc = Object.getOwnPropertyDescriptor(Date, "parse");
|
||||
[ abc.value === Date.parse, abc.writable, abc.enumerable, abc.configurable ];
|
||||
`, "true,true,false,true")
|
||||
|
||||
test(`
|
||||
abc = Object.getOwnPropertyDescriptor(Date, "parse");
|
||||
[ abc.value === Date.parse, abc.writable, abc.enumerable, abc.configurable ];
|
||||
`, "true,true,false,true")
|
||||
test(`
|
||||
abc = Object.getOwnPropertyDescriptor(Date.prototype, "toTimeString");
|
||||
[ abc.value === Date.prototype.toTimeString, abc.writable, abc.enumerable, abc.configurable ];
|
||||
`, "true,true,false,true")
|
||||
|
||||
test(`
|
||||
abc = Object.getOwnPropertyDescriptor(Date.prototype, "toTimeString");
|
||||
[ abc.value === Date.prototype.toTimeString, abc.writable, abc.enumerable, abc.configurable ];
|
||||
`, "true,true,false,true")
|
||||
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(Date, "prototype");
|
||||
[ [ typeof Date.prototype ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "object,false,false,false")
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(Date, "prototype");
|
||||
[ [ typeof Date.prototype ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "object,false,false,false")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_parse(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`Date.parse("2001-01-01T10:01:02.000")`, 978343262000)
|
||||
|
||||
test(`Date.parse("2001-01-01T10:01:02.000")`, "978343262000")
|
||||
test(`Date.parse("2006-01-02T15:04:05.000")`, 1136214245000)
|
||||
|
||||
test(`Date.parse("2006-01-02T15:04:05.000")`, "1136214245000")
|
||||
test(`Date.parse("2006")`, 1136073600000)
|
||||
|
||||
test(`Date.parse("2006")`, "1136073600000")
|
||||
test(`Date.parse("1970-01-16T14:36:56+00:00")`, 1348616000)
|
||||
|
||||
test(`Date.parse("1970-01-16T14:36:56+00:00")`, "1348616000")
|
||||
test(`Date.parse("1970-01-16T14:36:56.313+00:00")`, 1348616313)
|
||||
|
||||
test(`Date.parse("1970-01-16T14:36:56.313+00:00")`, "1348616313")
|
||||
test(`Date.parse("1970-01-16T14:36:56.000")`, 1348616000)
|
||||
|
||||
test(`Date.parse("1970-01-16T14:36:56.000")`, "1348616000")
|
||||
|
||||
test(`Date.parse.length`, 1)
|
||||
test(`Date.parse.length`, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_UTC(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`Date.UTC(2009, 9, 25)`, 1256428800000)
|
||||
|
||||
test(`Date.UTC(2009, 9, 25)`, "1256428800000")
|
||||
|
||||
test(`Date.UTC.length`, 7)
|
||||
test(`Date.UTC.length`, 7)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_now(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
// FIXME I think this too risky
|
||||
test(`+(""+Date.now()).substr(0, 10)`, float64(epochToInteger(timeToEpoch(time.Now()))/1000))
|
||||
|
||||
// FIXME I think this too risky
|
||||
test(`+(""+Date.now()).substr(0, 10)`, float64(epochToInteger(timeToEpoch(Time.Now()))/1000))
|
||||
|
||||
test(`Date.now() - Date.now(1,2,3) < 24 * 60 * 60`, true)
|
||||
test(`Date.now() - Date.now(1,2,3) < 24 * 60 * 60`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_toISOString(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`new Date(0).toISOString()`, "1970-01-01T00:00:00.000Z")
|
||||
test(`new Date(0).toISOString()`, "1970-01-01T00:00:00.000Z")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_toJSON(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`new Date(0).toJSON()`, "1970-01-01T00:00:00.000Z")
|
||||
test(`new Date(0).toJSON()`, "1970-01-01T00:00:00.000Z")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_setYear(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`new Date(12564504e5).setYear(96)`, 846223200000)
|
||||
|
||||
test(`new Date(12564504e5).setYear(96)`, 846223200000)
|
||||
test(`new Date(12564504e5).setYear(1996)`, 846223200000)
|
||||
|
||||
test(`new Date(12564504e5).setYear(1996)`, 846223200000)
|
||||
|
||||
test(`new Date(12564504e5).setYear(2000)`, 972453600000)
|
||||
test(`new Date(12564504e5).setYear(2000)`, 972453600000)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDateDefaultValue(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
var date = new Date();
|
||||
date + 0 === date.toString() + "0";
|
||||
`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_April1978(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
var abc = new Date(1978,3);
|
||||
[ abc.getYear(), abc.getMonth(), abc.valueOf() ];
|
||||
`, "78,3,260236800000")
|
||||
test(`
|
||||
var abc = new Date(1978,3);
|
||||
[ abc.getYear(), abc.getMonth(), abc.valueOf() ];
|
||||
`, "78,3,260236800000")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_setMilliseconds(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
abc = new Date();
|
||||
def = abc.setMilliseconds();
|
||||
[ abc, def ];
|
||||
`, "Invalid Date,NaN")
|
||||
test(`
|
||||
abc = new Date();
|
||||
def = abc.setMilliseconds();
|
||||
[ abc, def ];
|
||||
`, "Invalid Date,NaN")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_new(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
// FIXME?
|
||||
// This is probably incorrect, due to differences in Go date/time handling
|
||||
// versus ECMA date/time handling, but we'll leave this here for
|
||||
// future reference
|
||||
return
|
||||
|
||||
defer mockUTC()()
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
defer mockUTC()()
|
||||
|
||||
test(`
|
||||
[
|
||||
new Date(1899, 11).valueOf(),
|
||||
new Date(1899, 12).valueOf(),
|
||||
new Date(1900, 0).valueOf()
|
||||
]
|
||||
`, "-2211638400000,-2208960000000,-2208960000000")
|
||||
test(`
|
||||
[
|
||||
new Date(1899, 11).valueOf(),
|
||||
new Date(1899, 12).valueOf(),
|
||||
new Date(1900, 0).valueOf()
|
||||
]
|
||||
`, "-2211638400000,-2208960000000,-2208960000000")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDateComparison(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
var now0 = Date.now();
|
||||
var now1 = (new Date()).toString();
|
||||
[ now0 === now1, Math.abs(now0 - Date.parse(now1)) <= 1000 ];
|
||||
`, "false,true")
|
||||
test(`
|
||||
var now0 = Date.now();
|
||||
var now1 = (new Date()).toString();
|
||||
[ now0 === now1, Math.abs(now0 - Date.parse(now1)) <= 1000 ];
|
||||
`, "false,true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_setSeconds(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setSeconds(10, 12);
|
||||
|
||||
abc.setSeconds(10, 12);
|
||||
def.setSeconds(10);
|
||||
def.setMilliseconds(12);
|
||||
|
||||
def.setSeconds(10);
|
||||
def.setMilliseconds(12);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setUTCSeconds(10, 12);
|
||||
|
||||
abc.setUTCSeconds(10, 12);
|
||||
def.setUTCSeconds(10);
|
||||
def.setUTCMilliseconds(12);
|
||||
|
||||
def.setUTCSeconds(10);
|
||||
def.setUTCMilliseconds(12);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
test(`Date.prototype.setSeconds.length`, 2)
|
||||
test(`Date.prototype.setUTCSeconds.length`, 2)
|
||||
test(`Date.prototype.setSeconds.length`, 2)
|
||||
test(`Date.prototype.setUTCSeconds.length`, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_setMinutes(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setMinutes(8, 10, 12);
|
||||
|
||||
abc.setMinutes(8, 10, 12);
|
||||
def.setMinutes(8);
|
||||
def.setSeconds(10);
|
||||
def.setMilliseconds(12);
|
||||
|
||||
def.setMinutes(8);
|
||||
def.setSeconds(10);
|
||||
def.setMilliseconds(12);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setUTCMinutes(8, 10, 12);
|
||||
|
||||
abc.setUTCMinutes(8, 10, 12);
|
||||
def.setUTCMinutes(8);
|
||||
def.setUTCSeconds(10);
|
||||
def.setUTCMilliseconds(12);
|
||||
|
||||
def.setUTCMinutes(8);
|
||||
def.setUTCSeconds(10);
|
||||
def.setUTCMilliseconds(12);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
test(`Date.prototype.setMinutes.length`, 3)
|
||||
test(`Date.prototype.setUTCMinutes.length`, 3)
|
||||
test(`Date.prototype.setMinutes.length`, 3)
|
||||
test(`Date.prototype.setUTCMinutes.length`, 3)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_setHours(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setHours(6, 8, 10, 12);
|
||||
|
||||
abc.setHours(6, 8, 10, 12);
|
||||
def.setHours(6);
|
||||
def.setMinutes(8);
|
||||
def.setSeconds(10);
|
||||
def.setMilliseconds(12);
|
||||
|
||||
def.setHours(6);
|
||||
def.setMinutes(8);
|
||||
def.setSeconds(10);
|
||||
def.setMilliseconds(12);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setUTCHours(6, 8, 10, 12);
|
||||
|
||||
abc.setUTCHours(6, 8, 10, 12);
|
||||
def.setUTCHours(6);
|
||||
def.setUTCMinutes(8);
|
||||
def.setUTCSeconds(10);
|
||||
def.setUTCMilliseconds(12);
|
||||
|
||||
def.setUTCHours(6);
|
||||
def.setUTCMinutes(8);
|
||||
def.setUTCSeconds(10);
|
||||
def.setUTCMilliseconds(12);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
test(`Date.prototype.setHours.length`, 4)
|
||||
test(`Date.prototype.setUTCHours.length`, 4)
|
||||
test(`Date.prototype.setHours.length`, 4)
|
||||
test(`Date.prototype.setUTCHours.length`, 4)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_setMonth(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setMonth(6, 8);
|
||||
|
||||
abc.setMonth(6, 8);
|
||||
def.setMonth(6);
|
||||
def.setDate(8);
|
||||
|
||||
def.setMonth(6);
|
||||
def.setDate(8);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setUTCMonth(6, 8);
|
||||
|
||||
abc.setUTCMonth(6, 8);
|
||||
def.setUTCMonth(6);
|
||||
def.setUTCDate(8);
|
||||
|
||||
def.setUTCMonth(6);
|
||||
def.setUTCDate(8);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
test(`Date.prototype.setMonth.length`, 2)
|
||||
test(`Date.prototype.setUTCMonth.length`, 2)
|
||||
test(`Date.prototype.setMonth.length`, 2)
|
||||
test(`Date.prototype.setUTCMonth.length`, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_setFullYear(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setFullYear(1981, 6, 8);
|
||||
|
||||
abc.setFullYear(1981, 6, 8);
|
||||
def.setFullYear(1981);
|
||||
def.setMonth(6);
|
||||
def.setDate(8);
|
||||
|
||||
def.setFullYear(1981);
|
||||
def.setMonth(6);
|
||||
def.setDate(8);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
|
||||
test(`
|
||||
abc = new Date(1980, 10);
|
||||
def = new Date(abc);
|
||||
abc.setUTCFullYear(1981, 6, 8);
|
||||
|
||||
abc.setUTCFullYear(1981, 6, 8);
|
||||
def.setUTCFullYear(1981);
|
||||
def.setUTCMonth(6);
|
||||
def.setUTCDate(8);
|
||||
|
||||
def.setUTCFullYear(1981);
|
||||
def.setUTCMonth(6);
|
||||
def.setUTCDate(8);
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
abc.valueOf() === def.valueOf();
|
||||
`, true)
|
||||
|
||||
test(`Date.prototype.setFullYear.length`, 3)
|
||||
test(`Date.prototype.setUTCFullYear.length`, 3)
|
||||
test(`Date.prototype.setFullYear.length`, 3)
|
||||
test(`Date.prototype.setUTCFullYear.length`, 3)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDate_setTime(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
var abc = new Date(1999, 6, 1);
|
||||
var def = new Date();
|
||||
def.setTime(abc.getTime());
|
||||
[ def, abc.valueOf() == def.valueOf() ];
|
||||
`, "Thu, 01 Jul 1999 00:00:00 UTC,true")
|
||||
|
||||
test(`
|
||||
var abc = new Date(1999, 6, 1);
|
||||
var def = new Date();
|
||||
def.setTime(abc.getTime());
|
||||
[ def, abc.valueOf() == def.valueOf() ];
|
||||
`, "Thu, 01 Jul 1999 00:00:00 UTC,true")
|
||||
|
||||
test(`Date.prototype.setTime.length`, 1)
|
||||
test(`Date.prototype.setTime.length`, 1)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,63 +1,62 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestError(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
[ Error.prototype.name, Error.prototype.message, Error.prototype.hasOwnProperty("message") ];
|
||||
`, "Error,,true")
|
||||
test(`
|
||||
[ Error.prototype.name, Error.prototype.message, Error.prototype.hasOwnProperty("message") ];
|
||||
`, "Error,,true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestError_instanceof(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`(new TypeError()) instanceof Error`, true)
|
||||
test(`(new TypeError()) instanceof Error`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPanicValue(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
test := runTest()
|
||||
vm.Set("abc", func(call FunctionCall) Value {
|
||||
value, err := call.Otto.Run(`({ def: 3.14159 })`)
|
||||
is(err, nil)
|
||||
panic(value)
|
||||
})
|
||||
|
||||
failSet("abc", func(call FunctionCall) Value {
|
||||
value, err := call.Otto.Run(`({ def: 3.14159 })`)
|
||||
Is(err, nil)
|
||||
panic(value)
|
||||
test(`
|
||||
try {
|
||||
abc();
|
||||
}
|
||||
catch (err) {
|
||||
error = err;
|
||||
}
|
||||
[ error instanceof Error, error.message, error.def ];
|
||||
`, "false,,3.14159")
|
||||
})
|
||||
|
||||
test(`
|
||||
try {
|
||||
abc();
|
||||
}
|
||||
catch (err) {
|
||||
error = err;
|
||||
}
|
||||
[ error instanceof Error, error.message, error.def ];
|
||||
`, "false,,3.14159")
|
||||
}
|
||||
|
||||
func Test_catchPanic(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
vm := New()
|
||||
|
||||
otto, _ := runTestWithOtto()
|
||||
_, err := vm.Run(`
|
||||
A syntax error that
|
||||
does not define
|
||||
var;
|
||||
abc;
|
||||
`)
|
||||
is(err, "!=", nil)
|
||||
|
||||
_, err := otto.Run(`
|
||||
A syntax error that
|
||||
does not define
|
||||
var;
|
||||
abc;
|
||||
`)
|
||||
IsNot(err, nil)
|
||||
|
||||
_, err = otto.Call(`abc.def`, nil)
|
||||
IsNot(err, nil)
|
||||
_, err = vm.Call(`abc.def`, nil)
|
||||
is(err, "!=", nil)
|
||||
})
|
||||
}
|
||||
|
||||
406
function_test.go
406
function_test.go
@@ -1,192 +1,191 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFunction(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(Function, "prototype");
|
||||
[ [ typeof Function.prototype, typeof Function.prototype.length, Function.prototype.length ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "function,number,0,false,false,false")
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(Function, "prototype");
|
||||
[ [ typeof Function.prototype, typeof Function.prototype.length, Function.prototype.length ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "function,number,0,false,false,false")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_argumentList2parameterList(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
Is(argumentList2parameterList([]Value{toValue("abc, def"), toValue("ghi")}), []string{"abc", "def", "ghi"})
|
||||
tt(t, func() {
|
||||
is(argumentList2parameterList([]Value{toValue("abc, def"), toValue("ghi")}), []string{"abc", "def", "ghi"})
|
||||
})
|
||||
}
|
||||
|
||||
func TestFunction_new(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`raise:
|
||||
new Function({});
|
||||
`, "SyntaxError: Unexpected identifier")
|
||||
|
||||
test(`raise:
|
||||
new Function({});
|
||||
`, "SyntaxError: Unexpected identifier")
|
||||
test(`
|
||||
var abc = Function("def, ghi", "jkl", "return def+ghi+jkl");
|
||||
[ typeof abc, abc instanceof Function, abc("ab", "ba", 1) ];
|
||||
`, "function,true,abba1")
|
||||
|
||||
test(`
|
||||
var abc = Function("def, ghi", "jkl", "return def+ghi+jkl");
|
||||
[ typeof abc, abc instanceof Function, abc("ab", "ba", 1) ];
|
||||
`, "function,true,abba1")
|
||||
test(`raise:
|
||||
var abc = {
|
||||
toString: function() { throw 1; }
|
||||
};
|
||||
var def = {
|
||||
toString: function() { throw 2; }
|
||||
};
|
||||
var ghi = new Function(abc, def);
|
||||
ghi;
|
||||
`, "1")
|
||||
|
||||
test(`raise:
|
||||
var abc = {
|
||||
toString: function() { throw 1; }
|
||||
};
|
||||
var def = {
|
||||
toString: function() { throw 2; }
|
||||
};
|
||||
var ghi = new Function(abc, def);
|
||||
ghi;
|
||||
`, "1")
|
||||
// S15.3.2.1_A3_T10
|
||||
test(`raise:
|
||||
var abc = {
|
||||
toString: function() { return "z;x"; }
|
||||
};
|
||||
var def = "return this";
|
||||
var ghi = new Function(abc, def);
|
||||
ghi;
|
||||
`, "SyntaxError: Unexpected token ;")
|
||||
|
||||
// S15.3.2.1_A3_T10
|
||||
test(`raise:
|
||||
var abc = {
|
||||
toString: function() { return "z;x"; }
|
||||
};
|
||||
var def = "return this";
|
||||
var ghi = new Function(abc, def);
|
||||
ghi;
|
||||
`, "SyntaxError: Unexpected token ;")
|
||||
|
||||
test(`raise:
|
||||
var abc;
|
||||
var def = "return true";
|
||||
var ghi = new Function(null, def);
|
||||
ghi;
|
||||
`, "SyntaxError: Unexpected token null")
|
||||
test(`raise:
|
||||
var abc;
|
||||
var def = "return true";
|
||||
var ghi = new Function(null, def);
|
||||
ghi;
|
||||
`, "SyntaxError: Unexpected token null")
|
||||
})
|
||||
}
|
||||
|
||||
func TestFunction_apply(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`Function.prototype.apply.length`, 2)
|
||||
test(`String.prototype.substring.apply("abc", [1, 11])`, "bc")
|
||||
test(`Function.prototype.apply.length`, 2)
|
||||
test(`String.prototype.substring.apply("abc", [1, 11])`, "bc")
|
||||
})
|
||||
}
|
||||
|
||||
func TestFunction_call(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`Function.prototype.call.length`, 1)
|
||||
test(`String.prototype.substring.call("abc", 1, 11)`, "bc")
|
||||
test(`Function.prototype.call.length`, 1)
|
||||
test(`String.prototype.substring.call("abc", 1, 11)`, "bc")
|
||||
})
|
||||
}
|
||||
|
||||
func TestFunctionArguments(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
// Should not be able to delete arguments
|
||||
test(`
|
||||
function abc(def, arguments){
|
||||
delete def;
|
||||
return def;
|
||||
}
|
||||
abc(1);
|
||||
`, 1)
|
||||
|
||||
// Should not be able to delete arguments
|
||||
test(`
|
||||
function abc(def, arguments){
|
||||
delete def;
|
||||
return def;
|
||||
}
|
||||
abc(1);
|
||||
`, 1)
|
||||
// Again, should not be able to delete arguments
|
||||
test(`
|
||||
function abc(def){
|
||||
delete def;
|
||||
return def;
|
||||
}
|
||||
abc(1);
|
||||
`, 1)
|
||||
|
||||
// Again, should not be able to delete arguments
|
||||
test(`
|
||||
function abc(def){
|
||||
delete def;
|
||||
return def;
|
||||
}
|
||||
abc(1);
|
||||
`, 1)
|
||||
// Test typeof of a function argument
|
||||
test(`
|
||||
function abc(def, ghi, jkl){
|
||||
return typeof jkl
|
||||
}
|
||||
abc("1st", "2nd", "3rd", "4th", "5th");
|
||||
`, "string")
|
||||
|
||||
// Test typeof of a function argument
|
||||
test(`
|
||||
function abc(def, ghi, jkl){
|
||||
return typeof jkl
|
||||
}
|
||||
abc("1st", "2nd", "3rd", "4th", "5th");
|
||||
`, "string")
|
||||
|
||||
test(`
|
||||
function abc(def, ghi, jkl){
|
||||
arguments[0] = 3.14;
|
||||
arguments[1] = 'Nothing happens';
|
||||
arguments[2] = 42;
|
||||
if (3.14 === def && 'Nothing happens' === ghi && 42 === jkl)
|
||||
return true;
|
||||
}
|
||||
abc(-1, 4.2, 314);
|
||||
`, true)
|
||||
test(`
|
||||
function abc(def, ghi, jkl){
|
||||
arguments[0] = 3.14;
|
||||
arguments[1] = 'Nothing happens';
|
||||
arguments[2] = 42;
|
||||
if (3.14 === def && 'Nothing happens' === ghi && 42 === jkl)
|
||||
return true;
|
||||
}
|
||||
abc(-1, 4.2, 314);
|
||||
`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestFunctionDeclarationInFunction(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
// Function declarations happen AFTER parameter/argument declarations
|
||||
// That is, a function declared within a function will shadow/overwrite
|
||||
// declared parameters
|
||||
test := runTest()
|
||||
// Function declarations happen AFTER parameter/argument declarations
|
||||
// That is, a function declared within a function will shadow/overwrite
|
||||
// declared parameters
|
||||
|
||||
test(`
|
||||
function abc(def){
|
||||
return def;
|
||||
function def(){
|
||||
return 1;
|
||||
test(`
|
||||
function abc(def){
|
||||
return def;
|
||||
function def(){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
typeof abc();
|
||||
`, "function")
|
||||
typeof abc();
|
||||
`, "function")
|
||||
})
|
||||
}
|
||||
|
||||
func TestArguments_defineOwnProperty(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
var abc;
|
||||
var def = true;
|
||||
var ghi = {};
|
||||
(function (a, b, c) {
|
||||
Object.defineProperty(arguments, "0", {
|
||||
value: 42,
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
});
|
||||
Object.defineProperty(arguments, "1", {
|
||||
value: 3.14,
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
abc = Object.getOwnPropertyDescriptor(arguments, "0");
|
||||
for (var name in arguments) {
|
||||
ghi[name] = (ghi[name] || 0) + 1;
|
||||
if (name === "0") {
|
||||
def = false;
|
||||
test(`
|
||||
var abc;
|
||||
var def = true;
|
||||
var ghi = {};
|
||||
(function (a, b, c) {
|
||||
Object.defineProperty(arguments, "0", {
|
||||
value: 42,
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
});
|
||||
Object.defineProperty(arguments, "1", {
|
||||
value: 3.14,
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
abc = Object.getOwnPropertyDescriptor(arguments, "0");
|
||||
for (var name in arguments) {
|
||||
ghi[name] = (ghi[name] || 0) + 1;
|
||||
if (name === "0") {
|
||||
def = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}(0, 1, 2));
|
||||
[ abc.value, abc.writable, abc.enumerable, abc.configurable, def, ghi["1"] ];
|
||||
`, "42,false,false,false,true,1")
|
||||
}(0, 1, 2));
|
||||
[ abc.value, abc.writable, abc.enumerable, abc.configurable, def, ghi["1"] ];
|
||||
`, "42,false,false,false,true,1")
|
||||
})
|
||||
}
|
||||
|
||||
func TestFunction_bind(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
abc = function(){
|
||||
return "abc";
|
||||
};
|
||||
@@ -194,79 +193,80 @@ func TestFunction_bind(t *testing.T) {
|
||||
[ typeof def.prototype, typeof def.hasOwnProperty, def.hasOwnProperty("caller"), def.hasOwnProperty("arguments"), def() ];
|
||||
`, "object,function,true,true,abc")
|
||||
|
||||
test(`
|
||||
abc = function(){
|
||||
return arguments[1];
|
||||
};
|
||||
def = abc.bind(undefined, "abc");
|
||||
ghi = abc.bind(undefined, "abc", "ghi");
|
||||
[ def(), def("def"), ghi("def") ];
|
||||
`, ",def,ghi")
|
||||
test(`
|
||||
abc = function(){
|
||||
return arguments[1];
|
||||
};
|
||||
def = abc.bind(undefined, "abc");
|
||||
ghi = abc.bind(undefined, "abc", "ghi");
|
||||
[ def(), def("def"), ghi("def") ];
|
||||
`, ",def,ghi")
|
||||
|
||||
test(`
|
||||
var abc = function () {};
|
||||
var ghi;
|
||||
try {
|
||||
Object.defineProperty(Function.prototype, "xyzzy", {
|
||||
value: 1001,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
var def = abc.bind({});
|
||||
ghi = !def.hasOwnProperty("xyzzy") && ghi.xyzzy === 1001;
|
||||
} finally {
|
||||
delete Function.prototype.xyzzy;
|
||||
}
|
||||
[ ghi ];
|
||||
`, "true")
|
||||
test(`
|
||||
var abc = function () {};
|
||||
var ghi;
|
||||
try {
|
||||
Object.defineProperty(Function.prototype, "xyzzy", {
|
||||
value: 1001,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
var def = abc.bind({});
|
||||
ghi = !def.hasOwnProperty("xyzzy") && ghi.xyzzy === 1001;
|
||||
} finally {
|
||||
delete Function.prototype.xyzzy;
|
||||
}
|
||||
[ ghi ];
|
||||
`, "true")
|
||||
|
||||
test(`
|
||||
var abc = function (def, ghi) {};
|
||||
var jkl = abc.bind({});
|
||||
var mno = abc.bind({}, 1, 2);
|
||||
[ jkl.length, mno.length ];
|
||||
`, "2,0")
|
||||
test(`
|
||||
var abc = function (def, ghi) {};
|
||||
var jkl = abc.bind({});
|
||||
var mno = abc.bind({}, 1, 2);
|
||||
[ jkl.length, mno.length ];
|
||||
`, "2,0")
|
||||
|
||||
test(`raise:
|
||||
Math.bind();
|
||||
`, "TypeError: undefined is not a function")
|
||||
test(`raise:
|
||||
Math.bind();
|
||||
`, "TypeError: undefined is not a function")
|
||||
|
||||
test(`
|
||||
function construct(fn, arguments) {
|
||||
var bound = Function.prototype.bind.apply(fn, [null].concat(arguments));
|
||||
return new bound();
|
||||
}
|
||||
var abc = construct(Date, [1957, 4, 27]);
|
||||
Object.prototype.toString.call(abc);
|
||||
`, "[object Date]")
|
||||
test(`
|
||||
function construct(fn, arguments) {
|
||||
var bound = Function.prototype.bind.apply(fn, [null].concat(arguments));
|
||||
return new bound();
|
||||
}
|
||||
var abc = construct(Date, [1957, 4, 27]);
|
||||
Object.prototype.toString.call(abc);
|
||||
`, "[object Date]")
|
||||
|
||||
test(`
|
||||
var fn = function (x, y, z) {
|
||||
var result = {};
|
||||
result.abc = x + y + z;
|
||||
result.def = arguments[0] === "a" && arguments.length === 3;
|
||||
return result;
|
||||
};
|
||||
var newFn = Function.prototype.bind.call(fn, {}, "a", "b", "c");
|
||||
var result = new newFn();
|
||||
[ result.hasOwnProperty("abc"), result.hasOwnProperty("def"), result.abc, result.def ];
|
||||
`, "true,true,abc,true")
|
||||
test(`
|
||||
var fn = function (x, y, z) {
|
||||
var result = {};
|
||||
result.abc = x + y + z;
|
||||
result.def = arguments[0] === "a" && arguments.length === 3;
|
||||
return result;
|
||||
};
|
||||
var newFn = Function.prototype.bind.call(fn, {}, "a", "b", "c");
|
||||
var result = new newFn();
|
||||
[ result.hasOwnProperty("abc"), result.hasOwnProperty("def"), result.abc, result.def ];
|
||||
`, "true,true,abc,true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestFunction_toString(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`raise:
|
||||
Function.prototype.toString.call(undefined);
|
||||
`, "TypeError")
|
||||
|
||||
test(`raise:
|
||||
Function.prototype.toString.call(undefined);
|
||||
`, "TypeError")
|
||||
|
||||
test(`
|
||||
abc = function() { return -1 ;
|
||||
test(`
|
||||
abc = function() { return -1 ;
|
||||
}
|
||||
1;
|
||||
abc.toString();
|
||||
`, "function() { return -1 ;\n}")
|
||||
1;
|
||||
abc.toString();
|
||||
`, "function() { return -1 ;\n}")
|
||||
})
|
||||
}
|
||||
|
||||
510
global_test.go
510
global_test.go
@@ -1,7 +1,6 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
@@ -9,344 +8,345 @@ import (
|
||||
)
|
||||
|
||||
func TestGlobal(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
vm, test := runTestWithOtto()
|
||||
runtime := vm.runtime
|
||||
runtime := vm.vm.runtime
|
||||
|
||||
{
|
||||
call := func(object interface{}, src string, argumentList ...interface{}) Value {
|
||||
var tgt *Object
|
||||
switch object := object.(type) {
|
||||
case Value:
|
||||
tgt = object.Object()
|
||||
case *Object:
|
||||
tgt = object
|
||||
case *_object:
|
||||
tgt = toValue_object(object).Object()
|
||||
default:
|
||||
panic("Here be dragons.")
|
||||
{
|
||||
call := func(object interface{}, src string, argumentList ...interface{}) Value {
|
||||
var tgt *Object
|
||||
switch object := object.(type) {
|
||||
case Value:
|
||||
tgt = object.Object()
|
||||
case *Object:
|
||||
tgt = object
|
||||
case *_object:
|
||||
tgt = toValue_object(object).Object()
|
||||
default:
|
||||
panic("Here be dragons.")
|
||||
}
|
||||
value, err := tgt.Call(src, argumentList...)
|
||||
is(err, nil)
|
||||
return value
|
||||
}
|
||||
value, err := tgt.Call(src, argumentList...)
|
||||
Is(err, nil)
|
||||
return value
|
||||
|
||||
value := runtime.localGet("Object")._object().Call(UndefinedValue(), []Value{toValue(runtime.newObject())})
|
||||
is(value.IsObject(), true)
|
||||
is(value, "[object Object]")
|
||||
is(value._object().prototype == runtime.Global.ObjectPrototype, true)
|
||||
is(value._object().prototype == runtime.Global.Object.get("prototype")._object(), true)
|
||||
is(value._object().get("toString"), "function toString() { [native code] }")
|
||||
is(call(value.Object(), "hasOwnProperty", "hasOwnProperty"), false)
|
||||
|
||||
is(call(value._object().get("toString")._object().prototype, "toString"), "function () { [native code] }") // TODO Is this right?
|
||||
is(value._object().get("toString")._object().get("toString"), "function toString() { [native code] }")
|
||||
is(value._object().get("toString")._object().get("toString")._object(), "function toString() { [native code] }")
|
||||
|
||||
is(call(value._object(), "propertyIsEnumerable", "isPrototypeOf"), false)
|
||||
value._object().put("xyzzy", toValue_string("Nothing happens."), false)
|
||||
is(call(value, "propertyIsEnumerable", "isPrototypeOf"), false)
|
||||
is(call(value, "propertyIsEnumerable", "xyzzy"), true)
|
||||
is(value._object().get("xyzzy"), "Nothing happens.")
|
||||
|
||||
is(call(runtime.localGet("Object"), "isPrototypeOf", value), false)
|
||||
is(call(runtime.localGet("Object")._object().get("prototype"), "isPrototypeOf", value), true)
|
||||
is(call(runtime.localGet("Function"), "isPrototypeOf", value), false)
|
||||
|
||||
is(runtime.newObject().prototype == runtime.Global.Object.get("prototype")._object(), true)
|
||||
|
||||
abc := runtime.newBoolean(toValue_bool(true))
|
||||
is(toValue_object(abc), "true") // TODO Call primitive?
|
||||
|
||||
def := runtime.localGet("Boolean")._object().Construct(UndefinedValue(), []Value{})
|
||||
is(def, "false") // TODO Call primitive?
|
||||
}
|
||||
|
||||
value := runtime.localGet("Object")._object().Call(UndefinedValue(), []Value{toValue(runtime.newObject())})
|
||||
Is(value.IsObject(), true)
|
||||
Is(value, "[object Object]")
|
||||
Is(value._object().prototype == runtime.Global.ObjectPrototype, true)
|
||||
Is(value._object().prototype == runtime.Global.Object.get("prototype")._object(), true)
|
||||
Is(value._object().get("toString"), "function toString() { [native code] }")
|
||||
is(call(value.Object(), "hasOwnProperty", "hasOwnProperty"), false)
|
||||
test(`new Number().constructor == Number`, true)
|
||||
|
||||
is(call(value._object().get("toString")._object().prototype, "toString"), "function () { [native code] }") // TODO Is this right?
|
||||
Is(value._object().get("toString")._object().get("toString"), "function toString() { [native code] }")
|
||||
Is(value._object().get("toString")._object().get("toString")._object(), "function toString() { [native code] }")
|
||||
test(`this.hasOwnProperty`, "function hasOwnProperty() { [native code] }")
|
||||
|
||||
is(call(value._object(), "propertyIsEnumerable", "isPrototypeOf"), false)
|
||||
value._object().put("xyzzy", toValue_string("Nothing happens."), false)
|
||||
is(call(value, "propertyIsEnumerable", "isPrototypeOf"), false)
|
||||
is(call(value, "propertyIsEnumerable", "xyzzy"), true)
|
||||
Is(value._object().get("xyzzy"), "Nothing happens.")
|
||||
test(`eval.length === 1`, true)
|
||||
test(`eval.prototype === undefined`, true)
|
||||
test(`raise: new eval()`, "TypeError: function eval() { [native code] } is not a constructor")
|
||||
|
||||
is(call(runtime.localGet("Object"), "isPrototypeOf", value), false)
|
||||
is(call(runtime.localGet("Object")._object().get("prototype"), "isPrototypeOf", value), true)
|
||||
is(call(runtime.localGet("Function"), "isPrototypeOf", value), false)
|
||||
test(`
|
||||
[
|
||||
[ delete undefined, undefined ],
|
||||
[ delete NaN, NaN ],
|
||||
[ delete Infinity, Infinity ],
|
||||
];
|
||||
`, "false,,false,NaN,false,Infinity")
|
||||
|
||||
Is(runtime.newObject().prototype == runtime.Global.Object.get("prototype")._object(), true)
|
||||
test(`
|
||||
Object.getOwnPropertyNames(Function('return this')()).sort();
|
||||
`, "Array,Boolean,Date,Error,EvalError,Function,Infinity,JSON,Math,NaN,Number,Object,RangeError,ReferenceError,RegExp,String,SyntaxError,TypeError,URIError,console,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,escape,eval,isFinite,isNaN,parseFloat,parseInt,undefined,unescape")
|
||||
|
||||
abc := runtime.newBoolean(toValue_bool(true))
|
||||
Is(toValue_object(abc), "true") // TODO Call primitive?
|
||||
// __defineGetter__,__defineSetter__,__lookupGetter__,__lookupSetter__,constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf
|
||||
test(`
|
||||
Object.getOwnPropertyNames(Object.prototype).sort();
|
||||
`, "constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf")
|
||||
|
||||
def := runtime.localGet("Boolean")._object().Construct(UndefinedValue(), []Value{})
|
||||
Is(def, "false") // TODO Call primitive?
|
||||
}
|
||||
// arguments,caller,length,name,prototype
|
||||
test(`
|
||||
Object.getOwnPropertyNames(EvalError).sort();
|
||||
`, "length,prototype")
|
||||
|
||||
test(`new Number().constructor == Number`, true)
|
||||
test(`
|
||||
var abc = [];
|
||||
var def = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError];
|
||||
for (constructor in def) {
|
||||
abc.push(def[constructor] === def[constructor].prototype.constructor);
|
||||
}
|
||||
def = [Array, Boolean, Date, Function, Number, Object, RegExp, String, SyntaxError];
|
||||
for (constructor in def) {
|
||||
abc.push(def[constructor] === def[constructor].prototype.constructor);
|
||||
}
|
||||
abc;
|
||||
`, "true,true,true,true,true,true,true,true,true,true,true,true,true,true,true")
|
||||
|
||||
test(`this.hasOwnProperty`, "function hasOwnProperty() { [native code] }")
|
||||
test(`
|
||||
[ Array.prototype.constructor === Array, Array.constructor === Function ];
|
||||
`, "true,true")
|
||||
|
||||
test(`eval.length === 1`, true)
|
||||
test(`eval.prototype === undefined`, true)
|
||||
test(`raise: new eval()`, "TypeError: function eval() { [native code] } is not a constructor")
|
||||
test(`
|
||||
[ Number.prototype.constructor === Number, Number.constructor === Function ];
|
||||
`, "true,true")
|
||||
|
||||
test(`
|
||||
[
|
||||
[ delete undefined, undefined ],
|
||||
[ delete NaN, NaN ],
|
||||
[ delete Infinity, Infinity ],
|
||||
];
|
||||
`, "false,,false,NaN,false,Infinity")
|
||||
|
||||
test(`
|
||||
Object.getOwnPropertyNames(Function('return this')()).sort();
|
||||
`, "Array,Boolean,Date,Error,EvalError,Function,Infinity,JSON,Math,NaN,Number,Object,RangeError,ReferenceError,RegExp,String,SyntaxError,TypeError,URIError,console,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,escape,eval,isFinite,isNaN,parseFloat,parseInt,undefined,unescape")
|
||||
|
||||
// __defineGetter__,__defineSetter__,__lookupGetter__,__lookupSetter__,constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf
|
||||
test(`
|
||||
Object.getOwnPropertyNames(Object.prototype).sort();
|
||||
`, "constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf")
|
||||
|
||||
// arguments,caller,length,name,prototype
|
||||
test(`
|
||||
Object.getOwnPropertyNames(EvalError).sort();
|
||||
`, "length,prototype")
|
||||
|
||||
test(`
|
||||
var abc = [];
|
||||
var def = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError];
|
||||
for (constructor in def) {
|
||||
abc.push(def[constructor] === def[constructor].prototype.constructor);
|
||||
}
|
||||
def = [Array, Boolean, Date, Function, Number, Object, RegExp, String, SyntaxError];
|
||||
for (constructor in def) {
|
||||
abc.push(def[constructor] === def[constructor].prototype.constructor);
|
||||
}
|
||||
abc;
|
||||
`, "true,true,true,true,true,true,true,true,true,true,true,true,true,true,true")
|
||||
|
||||
test(`
|
||||
[ Array.prototype.constructor === Array, Array.constructor === Function ];
|
||||
`, "true,true")
|
||||
|
||||
test(`
|
||||
[ Number.prototype.constructor === Number, Number.constructor === Function ];
|
||||
`, "true,true")
|
||||
|
||||
test(`
|
||||
[ Function.prototype.constructor === Function, Function.constructor === Function ];
|
||||
`, "true,true")
|
||||
test(`
|
||||
[ Function.prototype.constructor === Function, Function.constructor === Function ];
|
||||
`, "true,true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGlobalLength(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
[ Object.length, Function.length, RegExp.length, Math.length ];
|
||||
`, "1,1,2,")
|
||||
test(`
|
||||
[ Object.length, Function.length, RegExp.length, Math.length ];
|
||||
`, "1,1,2,")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGlobalError(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
[ TypeError.length, TypeError(), TypeError("Nothing happens.") ];
|
||||
`, "1,TypeError,TypeError: Nothing happens.")
|
||||
|
||||
test(`
|
||||
[ TypeError.length, TypeError(), TypeError("Nothing happens.") ];
|
||||
`, "1,TypeError,TypeError: Nothing happens.")
|
||||
|
||||
test(`
|
||||
[ URIError.length, URIError(), URIError("Nothing happens.") ];
|
||||
`, "1,URIError,URIError: Nothing happens.")
|
||||
test(`
|
||||
[ URIError.length, URIError(), URIError("Nothing happens.") ];
|
||||
`, "1,URIError,URIError: Nothing happens.")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGlobalReadOnly(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Number.POSITIVE_INFINITY`, math.Inf(1))
|
||||
|
||||
test(`Number.POSITIVE_INFINITY`, math.Inf(1))
|
||||
test(`
|
||||
Number.POSITIVE_INFINITY = 1;
|
||||
`, 1)
|
||||
|
||||
test(`
|
||||
Number.POSITIVE_INFINITY = 1;
|
||||
`, 1)
|
||||
test(`Number.POSITIVE_INFINITY`, math.Inf(1))
|
||||
|
||||
test(`Number.POSITIVE_INFINITY`, math.Inf(1))
|
||||
|
||||
test(`
|
||||
Number.POSITIVE_INFINITY = 1;
|
||||
Number.POSITIVE_INFINITY;
|
||||
`, math.Inf(1))
|
||||
test(`
|
||||
Number.POSITIVE_INFINITY = 1;
|
||||
Number.POSITIVE_INFINITY;
|
||||
`, math.Inf(1))
|
||||
})
|
||||
}
|
||||
|
||||
func Test_isNaN(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`isNaN(0)`, false)
|
||||
test(`isNaN("Xyzzy")`, true)
|
||||
test(`isNaN()`, true)
|
||||
test(`isNaN(NaN)`, true)
|
||||
test(`isNaN(Infinity)`, false)
|
||||
|
||||
test(`isNaN(0)`, false)
|
||||
test(`isNaN("Xyzzy")`, true)
|
||||
test(`isNaN()`, true)
|
||||
test(`isNaN(NaN)`, true)
|
||||
test(`isNaN(Infinity)`, false)
|
||||
|
||||
test(`isNaN.length === 1`, true)
|
||||
test(`isNaN.prototype === undefined`, true)
|
||||
test(`isNaN.length === 1`, true)
|
||||
test(`isNaN.prototype === undefined`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_isFinite(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`isFinite(0)`, true)
|
||||
test(`isFinite("Xyzzy")`, false)
|
||||
test(`isFinite()`, false)
|
||||
test(`isFinite(NaN)`, false)
|
||||
test(`isFinite(Infinity)`, false)
|
||||
test(`isFinite(new Number(451));`, true)
|
||||
|
||||
test(`isFinite(0)`, true)
|
||||
test(`isFinite("Xyzzy")`, false)
|
||||
test(`isFinite()`, false)
|
||||
test(`isFinite(NaN)`, false)
|
||||
test(`isFinite(Infinity)`, false)
|
||||
test(`isFinite(new Number(451));`, true)
|
||||
|
||||
test(`isFinite.length === 1`, true)
|
||||
test(`isFinite.prototype === undefined`, true)
|
||||
test(`isFinite.length === 1`, true)
|
||||
test(`isFinite.prototype === undefined`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_parseInt(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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("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("Xyzzy")`, "NaN")
|
||||
test(`parseInt(" 0x11\n", 16)`, 17)
|
||||
test(`parseInt("0x0aXyzzy", 16)`, 10)
|
||||
test(`parseInt("0x1", 0)`, 1)
|
||||
test(`parseInt("0x10000000000000000000", 16)`, float64(75557863725914323419136))
|
||||
|
||||
test(`parseInt(" 0x11\n", 16)`, 17)
|
||||
test(`parseInt("0x0aXyzzy", 16)`, 10)
|
||||
test(`parseInt("0x1", 0)`, 1)
|
||||
test(`parseInt("0x10000000000000000000", 16)`, float64(75557863725914323419136))
|
||||
|
||||
test(`parseInt.length === 2`, true)
|
||||
test(`parseInt.prototype === undefined`, true)
|
||||
test(`parseInt.length === 2`, true)
|
||||
test(`parseInt.prototype === undefined`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_parseFloat(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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("11.1")`, 11.1)
|
||||
|
||||
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("11.1")`, 11.1)
|
||||
test(`parseFloat("Xyzzy")`, _NaN)
|
||||
|
||||
test(`parseFloat("Xyzzy")`, "NaN")
|
||||
test(`parseFloat(" 0x11\n", 16)`, 0)
|
||||
test(`parseFloat("0x0a")`, 0)
|
||||
test(`parseFloat("0x0aXyzzy")`, 0)
|
||||
test(`parseFloat("Infinity")`, _Infinity)
|
||||
test(`parseFloat("infinity")`, _NaN)
|
||||
test(`parseFloat("0x")`, 0)
|
||||
test(`parseFloat("11x")`, 11)
|
||||
test(`parseFloat("Infinity1")`, _Infinity)
|
||||
|
||||
test(`parseFloat(" 0x11\n", 16)`, 0)
|
||||
test(`parseFloat("0x0a")`, 0)
|
||||
test(`parseFloat("0x0aXyzzy")`, 0)
|
||||
test(`parseFloat("Infinity")`, "Infinity")
|
||||
test(`parseFloat("infinity")`, "NaN")
|
||||
test(`parseFloat("0x")`, 0)
|
||||
test(`parseFloat("11x")`, 11)
|
||||
test(`parseFloat("Infinity1")`, "Infinity")
|
||||
|
||||
test(`parseFloat.length === 1`, true)
|
||||
test(`parseFloat.prototype === undefined`, true)
|
||||
test(`parseFloat.length === 1`, true)
|
||||
test(`parseFloat.prototype === undefined`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_encodeURI(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`encodeURI("http://example.com/ Nothing happens.")`, "http://example.com/%20Nothing%20happens.")
|
||||
test(`encodeURI("http://example.com/ _^#")`, "http://example.com/%20_%5E#")
|
||||
test(`encodeURI(String.fromCharCode("0xE000"))`, "%EE%80%80")
|
||||
test(`encodeURI(String.fromCharCode("0xFFFD"))`, "%EF%BF%BD")
|
||||
test(`raise: encodeURI(String.fromCharCode("0xDC00"))`, "URIError: URI malformed")
|
||||
|
||||
test(`encodeURI("http://example.com/ Nothing happens.")`, "http://example.com/%20Nothing%20happens.")
|
||||
test(`encodeURI("http://example.com/ _^#")`, "http://example.com/%20_%5E#")
|
||||
test(`encodeURI(String.fromCharCode("0xE000"))`, "%EE%80%80")
|
||||
test(`encodeURI(String.fromCharCode("0xFFFD"))`, "%EF%BF%BD")
|
||||
test(`raise: encodeURI(String.fromCharCode("0xDC00"))`, "URIError: URI malformed")
|
||||
|
||||
test(`encodeURI.length === 1`, true)
|
||||
test(`encodeURI.prototype === undefined`, true)
|
||||
test(`encodeURI.length === 1`, true)
|
||||
test(`encodeURI.prototype === undefined`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_encodeURIComponent(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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")
|
||||
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)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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")
|
||||
test(`raise: decodeURI("%DF%7F")`, "URIError: URI malformed")
|
||||
for _, check := range strings.Fields("+ %3B %2F %3F %3A %40 %26 %3D %2B %24 %2C %23") {
|
||||
test(fmt.Sprintf(`decodeURI("%s")`, check), check)
|
||||
}
|
||||
|
||||
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")
|
||||
test(`raise: decodeURI("%DF%7F")`, "URIError: URI malformed")
|
||||
for _, check := range strings.Fields("+ %3B %2F %3F %3A %40 %26 %3D %2B %24 %2C %23") {
|
||||
test(fmt.Sprintf(`decodeURI("%s")`, check), check)
|
||||
}
|
||||
|
||||
test(`decodeURI.length === 1`, true)
|
||||
test(`decodeURI.prototype === undefined`, true)
|
||||
test(`decodeURI.length === 1`, true)
|
||||
test(`decodeURI.prototype === undefined`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_decodeURIComponent(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`decodeURIComponent(encodeURI("http://example.com/ Nothing happens."))`, "http://example.com/ Nothing happens.")
|
||||
test(`decodeURIComponent(encodeURI("http://example.com/ _^#"))`, "http://example.com/ _^#")
|
||||
|
||||
test(`decodeURIComponent(encodeURI("http://example.com/ Nothing happens."))`, "http://example.com/ Nothing happens.")
|
||||
test(`decodeURIComponent(encodeURI("http://example.com/ _^#"))`, "http://example.com/ _^#")
|
||||
test(`decodeURIComponent.length === 1`, true)
|
||||
test(`decodeURIComponent.prototype === undefined`, true)
|
||||
|
||||
test(`decodeURIComponent.length === 1`, true)
|
||||
test(`decodeURIComponent.prototype === undefined`, true)
|
||||
|
||||
test(`
|
||||
test(`
|
||||
var global = Function('return this')();
|
||||
var abc = Object.getOwnPropertyDescriptor(global, "decodeURIComponent");
|
||||
[ abc.value === global.decodeURIComponent, abc.writable, abc.enumerable, abc.configurable ];
|
||||
`, "true,true,false,true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGlobal_skipEnumeration(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
var found = [];
|
||||
for (var test in this) {
|
||||
if (false ||
|
||||
test === 'NaN' ||
|
||||
test === 'undefined' ||
|
||||
test === 'Infinity' ||
|
||||
false) {
|
||||
found.push(test)
|
||||
test(`
|
||||
var found = [];
|
||||
for (var test in this) {
|
||||
if (false ||
|
||||
test === 'NaN' ||
|
||||
test === 'undefined' ||
|
||||
test === 'Infinity' ||
|
||||
false) {
|
||||
found.push(test)
|
||||
}
|
||||
}
|
||||
}
|
||||
found.length;
|
||||
`, 0)
|
||||
found.length;
|
||||
`, 0)
|
||||
|
||||
test(`
|
||||
var found = [];
|
||||
for (var test in this) {
|
||||
if (false ||
|
||||
test === 'Object' ||
|
||||
test === 'Function' ||
|
||||
test === 'String' ||
|
||||
test === 'Number' ||
|
||||
test === 'Array' ||
|
||||
test === 'Boolean' ||
|
||||
test === 'Date' ||
|
||||
test === 'RegExp' ||
|
||||
test === 'Error' ||
|
||||
test === 'EvalError' ||
|
||||
test === 'RangeError' ||
|
||||
test === 'ReferenceError' ||
|
||||
test === 'SyntaxError' ||
|
||||
test === 'TypeError' ||
|
||||
test === 'URIError' ||
|
||||
false) {
|
||||
found.push(test)
|
||||
test(`
|
||||
var found = [];
|
||||
for (var test in this) {
|
||||
if (false ||
|
||||
test === 'Object' ||
|
||||
test === 'Function' ||
|
||||
test === 'String' ||
|
||||
test === 'Number' ||
|
||||
test === 'Array' ||
|
||||
test === 'Boolean' ||
|
||||
test === 'Date' ||
|
||||
test === 'RegExp' ||
|
||||
test === 'Error' ||
|
||||
test === 'EvalError' ||
|
||||
test === 'RangeError' ||
|
||||
test === 'ReferenceError' ||
|
||||
test === 'SyntaxError' ||
|
||||
test === 'TypeError' ||
|
||||
test === 'URIError' ||
|
||||
false) {
|
||||
found.push(test)
|
||||
}
|
||||
}
|
||||
}
|
||||
found.length;
|
||||
`, 0)
|
||||
found.length;
|
||||
`, 0)
|
||||
})
|
||||
}
|
||||
|
||||
271
json_test.go
271
json_test.go
@@ -1,184 +1,183 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkJSON_parse(b *testing.B) {
|
||||
otto := New()
|
||||
vm := New()
|
||||
for i := 0; i < b.N; i++ {
|
||||
otto.Run(`JSON.parse("1")`)
|
||||
otto.Run(`JSON.parse("[1,2,3]")`)
|
||||
otto.Run(`JSON.parse('{"a":{"x":100,"y":110},"b":[10,20,30],"c":"zazazaza"}')`)
|
||||
otto.Run(`JSON.parse("[1,2,3]", function(k, v) { return undefined })`)
|
||||
vm.Run(`JSON.parse("1")`)
|
||||
vm.Run(`JSON.parse("[1,2,3]")`)
|
||||
vm.Run(`JSON.parse('{"a":{"x":100,"y":110},"b":[10,20,30],"c":"zazazaza"}')`)
|
||||
vm.Run(`JSON.parse("[1,2,3]", function(k, v) { return undefined })`)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSON_parse(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
JSON.parse("1");
|
||||
`, 1)
|
||||
|
||||
test(`
|
||||
JSON.parse("1");
|
||||
`, 1)
|
||||
test(`
|
||||
JSON.parse("null");
|
||||
`, "null") // TODO Can we make this nil?
|
||||
|
||||
test(`
|
||||
JSON.parse("null");
|
||||
`, "null") // TODO Can we make this nil?
|
||||
test(`
|
||||
var abc = JSON.parse('"a\uFFFFbc"');
|
||||
[ abc[0], abc[2], abc[3], abc.length ];
|
||||
`, "a,b,c,4")
|
||||
|
||||
test(`
|
||||
var abc = JSON.parse('"a\uFFFFbc"');
|
||||
[ abc[0], abc[2], abc[3], abc.length ];
|
||||
`, "a,b,c,4")
|
||||
test(`
|
||||
JSON.parse("[1, 2, 3]");
|
||||
`, "1,2,3")
|
||||
|
||||
test(`
|
||||
JSON.parse("[1, 2, 3]");
|
||||
`, "1,2,3")
|
||||
test(`
|
||||
JSON.parse('{ "abc": 1, "def":2 }').abc;
|
||||
`, 1)
|
||||
|
||||
test(`
|
||||
JSON.parse('{ "abc": 1, "def":2 }').abc;
|
||||
`, 1)
|
||||
test(`
|
||||
JSON.parse('{ "abc": { "x": 100, "y": 110 }, "def": [ 10, 20 ,30 ], "ghi": "zazazaza" }').def;
|
||||
`, "10,20,30")
|
||||
|
||||
test(`
|
||||
JSON.parse('{ "abc": { "x": 100, "y": 110 }, "def": [ 10, 20 ,30 ], "ghi": "zazazaza" }').def;
|
||||
`, "10,20,30")
|
||||
test(`raise:
|
||||
JSON.parse("12\t\r\n 34");
|
||||
`, "SyntaxError: invalid character '3' after top-level value")
|
||||
|
||||
test(`raise:
|
||||
JSON.parse("12\t\r\n 34");
|
||||
`, "SyntaxError: invalid character '3' after top-level value")
|
||||
test(`
|
||||
JSON.parse("[1, 2, 3]", function() { return undefined });
|
||||
`, "undefined")
|
||||
|
||||
test(`
|
||||
JSON.parse("[1, 2, 3]", function() { return undefined });
|
||||
`, "undefined")
|
||||
test(`raise:
|
||||
JSON.parse("");
|
||||
`, "SyntaxError: unexpected end of JSON input")
|
||||
|
||||
test(`raise:
|
||||
JSON.parse("");
|
||||
`, "SyntaxError: unexpected end of JSON input")
|
||||
test(`raise:
|
||||
JSON.parse("[1, 2, 3");
|
||||
`, "SyntaxError: unexpected end of JSON input")
|
||||
|
||||
test(`raise:
|
||||
JSON.parse("[1, 2, 3");
|
||||
`, "SyntaxError: unexpected end of JSON input")
|
||||
test(`raise:
|
||||
JSON.parse("[1, 2, ; abc=10");
|
||||
`, "SyntaxError: invalid character ';' looking for beginning of value")
|
||||
|
||||
test(`raise:
|
||||
JSON.parse("[1, 2, ; abc=10");
|
||||
`, "SyntaxError: invalid character ';' looking for beginning of value")
|
||||
|
||||
test(`raise:
|
||||
JSON.parse("[1, 2, function(){}]");
|
||||
`, "SyntaxError: invalid character 'u' in literal false (expecting 'a')")
|
||||
test(`raise:
|
||||
JSON.parse("[1, 2, function(){}]");
|
||||
`, "SyntaxError: invalid character 'u' in literal false (expecting 'a')")
|
||||
})
|
||||
}
|
||||
|
||||
func TestJSON_stringify(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
defer mockUTC()()
|
||||
defer mockUTC()()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
JSON.stringify(function(){});
|
||||
`, "undefined")
|
||||
|
||||
test(`
|
||||
JSON.stringify(function(){});
|
||||
`, "undefined")
|
||||
test(`
|
||||
JSON.stringify(new Boolean(false));
|
||||
`, "false")
|
||||
|
||||
test(`
|
||||
JSON.stringify(new Boolean(false));
|
||||
`, "false")
|
||||
test(`
|
||||
JSON.stringify({a1: {b1: [1,2,3,4], b2: {c1: 1, c2: 2}}, a2: 'a2'}, null, -5);
|
||||
`, `{"a1":{"b1":[1,2,3,4],"b2":{"c1":1,"c2":2}},"a2":"a2"}`)
|
||||
|
||||
test(`
|
||||
JSON.stringify({a1: {b1: [1,2,3,4], b2: {c1: 1, c2: 2}}, a2: 'a2'}, null, -5);
|
||||
`, `{"a1":{"b1":[1,2,3,4],"b2":{"c1":1,"c2":2}},"a2":"a2"}`)
|
||||
test(`
|
||||
JSON.stringify(undefined);
|
||||
`, "undefined")
|
||||
|
||||
test(`
|
||||
JSON.stringify(undefined);
|
||||
`, "undefined")
|
||||
test(`
|
||||
JSON.stringify(1);
|
||||
`, "1")
|
||||
|
||||
test(`
|
||||
JSON.stringify(1);
|
||||
`, "1")
|
||||
test(`
|
||||
JSON.stringify("abc def");
|
||||
`, "\"abc def\"")
|
||||
|
||||
test(`
|
||||
JSON.stringify("abc def");
|
||||
`, "\"abc def\"")
|
||||
test(`
|
||||
JSON.stringify(3.14159);
|
||||
`, "3.14159")
|
||||
|
||||
test(`
|
||||
JSON.stringify(3.14159);
|
||||
`, "3.14159")
|
||||
test(`
|
||||
JSON.stringify([]);
|
||||
`, "[]")
|
||||
|
||||
test(`
|
||||
JSON.stringify([]);
|
||||
`, "[]")
|
||||
test(`
|
||||
JSON.stringify([1, 2, 3]);
|
||||
`, "[1,2,3]")
|
||||
|
||||
test(`
|
||||
JSON.stringify([1, 2, 3]);
|
||||
`, "[1,2,3]")
|
||||
test(`
|
||||
JSON.stringify([true, false, null]);
|
||||
`, "[true,false,null]")
|
||||
|
||||
test(`
|
||||
JSON.stringify([true, false, null]);
|
||||
`, "[true,false,null]")
|
||||
test(`
|
||||
JSON.stringify({
|
||||
abc: { x: 100, y: 110 },
|
||||
def: [ 10, 20, 30 ],
|
||||
ghi: "zazazaza"
|
||||
});
|
||||
`, `{"abc":{"x":100,"y":110},"def":[10,20,30],"ghi":"zazazaza"}`)
|
||||
|
||||
test(`
|
||||
JSON.stringify({
|
||||
abc: { x: 100, y: 110 },
|
||||
def: [ 10, 20, 30 ],
|
||||
ghi: "zazazaza"
|
||||
});
|
||||
`, `{"abc":{"x":100,"y":110},"def":[10,20,30],"ghi":"zazazaza"}`)
|
||||
test(`
|
||||
JSON.stringify([
|
||||
'e',
|
||||
{pluribus: 'unum'}
|
||||
], null, '\t');
|
||||
`, "[\n\t\"e\",\n\t{\n\t\t\"pluribus\": \"unum\"\n\t}\n]")
|
||||
|
||||
test(`
|
||||
JSON.stringify([
|
||||
'e',
|
||||
{pluribus: 'unum'}
|
||||
], null, '\t');
|
||||
`, "[\n\t\"e\",\n\t{\n\t\t\"pluribus\": \"unum\"\n\t}\n]")
|
||||
test(`
|
||||
JSON.stringify(new Date(0));
|
||||
`, `"1970-01-01T00:00:00.000Z"`)
|
||||
|
||||
test(`
|
||||
JSON.stringify(new Date(0));
|
||||
`, `"1970-01-01T00:00:00.000Z"`)
|
||||
test(`
|
||||
JSON.stringify([ new Date(0) ], function(key, value){
|
||||
return this[key] instanceof Date ? 'Date(' + this[key] + ')' : value
|
||||
});
|
||||
`, `["Date(Thu, 01 Jan 1970 00:00:00 UTC)"]`)
|
||||
|
||||
test(`
|
||||
JSON.stringify([ new Date(0) ], function(key, value){
|
||||
return this[key] instanceof Date ? 'Date(' + this[key] + ')' : value
|
||||
});
|
||||
`, `["Date(Thu, 01 Jan 1970 00:00:00 UTC)"]`)
|
||||
test(`
|
||||
JSON.stringify({
|
||||
abc: 1,
|
||||
def: 2,
|
||||
ghi: 3
|
||||
}, ['abc','def']);
|
||||
`, `{"abc":1,"def":2}`)
|
||||
|
||||
test(`
|
||||
JSON.stringify({
|
||||
abc: 1,
|
||||
def: 2,
|
||||
ghi: 3
|
||||
}, ['abc','def']);
|
||||
`, `{"abc":1,"def":2}`)
|
||||
test(`raise:
|
||||
var abc = {
|
||||
def: null
|
||||
};
|
||||
abc.def = abc;
|
||||
JSON.stringify(abc)
|
||||
`, "TypeError: Converting circular structure to JSON")
|
||||
|
||||
test(`raise:
|
||||
var abc = {
|
||||
def: null
|
||||
};
|
||||
abc.def = abc;
|
||||
JSON.stringify(abc)
|
||||
`, "TypeError: Converting circular structure to JSON")
|
||||
test(`raise:
|
||||
var abc= [ null ];
|
||||
abc[0] = abc;
|
||||
JSON.stringify(abc);
|
||||
`, "TypeError: Converting circular structure to JSON")
|
||||
|
||||
test(`raise:
|
||||
var abc= [ null ];
|
||||
abc[0] = abc;
|
||||
JSON.stringify(abc);
|
||||
`, "TypeError: Converting circular structure to JSON")
|
||||
test(`raise:
|
||||
var abc = {
|
||||
def: {}
|
||||
};
|
||||
abc.def.ghi = abc;
|
||||
JSON.stringify(abc)
|
||||
`, "TypeError: Converting circular structure to JSON")
|
||||
|
||||
test(`raise:
|
||||
var abc = {
|
||||
def: {}
|
||||
};
|
||||
abc.def.ghi = abc;
|
||||
JSON.stringify(abc)
|
||||
`, "TypeError: Converting circular structure to JSON")
|
||||
|
||||
test(`
|
||||
var ghi = { "pi": 3.14159 };
|
||||
var abc = {
|
||||
def: {}
|
||||
};
|
||||
abc.ghi = ghi;
|
||||
abc.def.ghi = ghi;
|
||||
JSON.stringify(abc);
|
||||
`, `{"def":{"ghi":{"pi":3.14159}},"ghi":{"pi":3.14159}}`)
|
||||
test(`
|
||||
var ghi = { "pi": 3.14159 };
|
||||
var abc = {
|
||||
def: {}
|
||||
};
|
||||
abc.ghi = ghi;
|
||||
abc.def.ghi = ghi;
|
||||
JSON.stringify(abc);
|
||||
`, `{"def":{"ghi":{"pi":3.14159}},"ghi":{"pi":3.14159}}`)
|
||||
})
|
||||
}
|
||||
|
||||
391
math_test.go
391
math_test.go
@@ -1,284 +1,303 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var _NaN = math.NaN()
|
||||
var _Infinity = math.Inf(1)
|
||||
|
||||
func TestMath_toString(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`Math.toString()`, "[object Math]")
|
||||
test(`Math.toString()`, "[object Math]")
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_abs(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.abs(NaN)`, _NaN)
|
||||
test(`Math.abs(2)`, 2)
|
||||
test(`Math.abs(-2)`, 2)
|
||||
test(`Math.abs(-Infinity)`, _Infinity)
|
||||
|
||||
test(`Math.abs(NaN)`, "NaN")
|
||||
test(`Math.abs(2)`, "2")
|
||||
test(`Math.abs(-2)`, "2")
|
||||
test(`Math.abs(-Infinity)`, "Infinity")
|
||||
test(`Math.acos(0.5)`, 1.0471975511965976)
|
||||
|
||||
test(`Math.acos(0.5)`, "1.0471975511965976")
|
||||
|
||||
test(`Math.abs('-1')`, "1")
|
||||
test(`Math.abs(-2)`, "2")
|
||||
test(`Math.abs(null)`, "0")
|
||||
test(`Math.abs("string")`, "NaN")
|
||||
test(`Math.abs()`, "NaN")
|
||||
test(`Math.abs('-1')`, 1)
|
||||
test(`Math.abs(-2)`, 2)
|
||||
test(`Math.abs(null)`, 0)
|
||||
test(`Math.abs("string")`, _NaN)
|
||||
test(`Math.abs()`, _NaN)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_acos(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.acos(NaN)`, "NaN")
|
||||
test(`Math.acos(2)`, "NaN")
|
||||
test(`Math.acos(-2)`, "NaN")
|
||||
test(`1/Math.acos(1)`, "Infinity")
|
||||
test(`Math.acos(NaN)`, _NaN)
|
||||
test(`Math.acos(2)`, _NaN)
|
||||
test(`Math.acos(-2)`, _NaN)
|
||||
test(`1/Math.acos(1)`, _Infinity)
|
||||
|
||||
test(`Math.acos(0.5)`, "1.0471975511965976")
|
||||
test(`Math.acos(0.5)`, 1.0471975511965976)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_asin(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.asin(NaN)`, "NaN")
|
||||
test(`Math.asin(2)`, "NaN")
|
||||
test(`Math.asin(-2)`, "NaN")
|
||||
test(`1/Math.asin(0)`, "Infinity")
|
||||
test(`1/Math.asin(-0)`, "-Infinity")
|
||||
test(`Math.asin(NaN)`, _NaN)
|
||||
test(`Math.asin(2)`, _NaN)
|
||||
test(`Math.asin(-2)`, _NaN)
|
||||
test(`1/Math.asin(0)`, _Infinity)
|
||||
test(`1/Math.asin(-0)`, -_Infinity)
|
||||
|
||||
test(`Math.asin(0.5)`, "0.5235987755982989")
|
||||
test(`Math.asin(0.5)`, 0.5235987755982989)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_atan(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.atan(NaN)`, "NaN")
|
||||
test(`1/Math.atan(0)`, "Infinity")
|
||||
test(`1/Math.atan(-0)`, "-Infinity")
|
||||
test(`Math.atan(Infinity)`, "1.5707963267948966")
|
||||
test(`Math.atan(-Infinity)`, "-1.5707963267948966")
|
||||
test(`Math.atan(NaN)`, _NaN)
|
||||
test(`1/Math.atan(0)`, _Infinity)
|
||||
test(`1/Math.atan(-0)`, -_Infinity)
|
||||
test(`Math.atan(Infinity)`, 1.5707963267948966)
|
||||
test(`Math.atan(-Infinity)`, -1.5707963267948966)
|
||||
|
||||
// freebsd/386 1.03 => 0.4636476090008061
|
||||
// darwin 1.03 => 0.46364760900080604
|
||||
test(`Math.atan(0.5).toPrecision(10)`, "0.463647609")
|
||||
// freebsd/386 1.03 => 0.4636476090008061
|
||||
// darwin 1.03 => 0.46364760900080604
|
||||
test(`Math.atan(0.5).toPrecision(10)`, "0.463647609")
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_atan2(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.atan2()`, "NaN")
|
||||
test(`Math.atan2(NaN)`, "NaN")
|
||||
test(`Math.atan2(0, NaN)`, "NaN")
|
||||
test(`Math.atan2()`, _NaN)
|
||||
test(`Math.atan2(NaN)`, _NaN)
|
||||
test(`Math.atan2(0, NaN)`, _NaN)
|
||||
|
||||
test(`Math.atan2(1, 0)`, "1.5707963267948966")
|
||||
test(`Math.atan2(1, -0)`, "1.5707963267948966")
|
||||
test(`Math.atan2(1, 0)`, 1.5707963267948966)
|
||||
test(`Math.atan2(1, -0)`, 1.5707963267948966)
|
||||
|
||||
test(`1/Math.atan2(0, 1)`, "Infinity")
|
||||
test(`1/Math.atan2(0, 0)`, "Infinity")
|
||||
test(`Math.atan2(0, -0)`, "3.141592653589793")
|
||||
test(`Math.atan2(0, -1)`, "3.141592653589793")
|
||||
test(`1/Math.atan2(0, 1)`, _Infinity)
|
||||
test(`1/Math.atan2(0, 0)`, _Infinity)
|
||||
test(`Math.atan2(0, -0)`, 3.141592653589793)
|
||||
test(`Math.atan2(0, -1)`, 3.141592653589793)
|
||||
|
||||
test(`1/Math.atan2(-0, 1)`, "-Infinity")
|
||||
test(`1/Math.atan2(-0, 0)`, "-Infinity")
|
||||
test(`Math.atan2(-0, -0)`, "-3.141592653589793")
|
||||
test(`Math.atan2(-0, -1)`, "-3.141592653589793")
|
||||
test(`1/Math.atan2(-0, 1)`, -_Infinity)
|
||||
test(`1/Math.atan2(-0, 0)`, -_Infinity)
|
||||
test(`Math.atan2(-0, -0)`, -3.141592653589793)
|
||||
test(`Math.atan2(-0, -1)`, -3.141592653589793)
|
||||
|
||||
test(`Math.atan2(-1, 0)`, "-1.5707963267948966")
|
||||
test(`Math.atan2(-1, -0)`, "-1.5707963267948966")
|
||||
test(`Math.atan2(-1, 0)`, -1.5707963267948966)
|
||||
test(`Math.atan2(-1, -0)`, -1.5707963267948966)
|
||||
|
||||
test(`1/Math.atan2(1, Infinity)`, "Infinity")
|
||||
test(`Math.atan2(1, -Infinity)`, "3.141592653589793")
|
||||
test(`1/Math.atan2(-1, Infinity)`, "-Infinity")
|
||||
test(`Math.atan2(-1, -Infinity)`, "-3.141592653589793")
|
||||
test(`1/Math.atan2(1, Infinity)`, _Infinity)
|
||||
test(`Math.atan2(1, -Infinity)`, 3.141592653589793)
|
||||
test(`1/Math.atan2(-1, Infinity)`, -_Infinity)
|
||||
test(`Math.atan2(-1, -Infinity)`, -3.141592653589793)
|
||||
|
||||
test(`Math.atan2(Infinity, 1)`, "1.5707963267948966")
|
||||
test(`Math.atan2(-Infinity, 1)`, "-1.5707963267948966")
|
||||
test(`Math.atan2(Infinity, 1)`, 1.5707963267948966)
|
||||
test(`Math.atan2(-Infinity, 1)`, -1.5707963267948966)
|
||||
|
||||
test(`Math.atan2(Infinity, Infinity)`, "0.7853981633974483")
|
||||
test(`Math.atan2(Infinity, -Infinity)`, "2.356194490192345")
|
||||
test(`Math.atan2(-Infinity, Infinity)`, "-0.7853981633974483")
|
||||
test(`Math.atan2(-Infinity, -Infinity)`, "-2.356194490192345")
|
||||
test(`Math.atan2(Infinity, Infinity)`, 0.7853981633974483)
|
||||
test(`Math.atan2(Infinity, -Infinity)`, 2.356194490192345)
|
||||
test(`Math.atan2(-Infinity, Infinity)`, -0.7853981633974483)
|
||||
test(`Math.atan2(-Infinity, -Infinity)`, -2.356194490192345)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_ceil(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.ceil(NaN)`, "NaN")
|
||||
test(`Math.ceil(+0)`, "0")
|
||||
test(`1/Math.ceil(-0)`, "-Infinity")
|
||||
test(`Math.ceil(Infinity)`, "Infinity")
|
||||
test(`Math.ceil(-Infinity)`, "-Infinity")
|
||||
test(`1/Math.ceil(-0.5)`, "-Infinity")
|
||||
test(`Math.ceil(NaN)`, _NaN)
|
||||
test(`Math.ceil(+0)`, 0)
|
||||
test(`1/Math.ceil(-0)`, -_Infinity)
|
||||
test(`Math.ceil(Infinity)`, _Infinity)
|
||||
test(`Math.ceil(-Infinity)`, -_Infinity)
|
||||
test(`1/Math.ceil(-0.5)`, -_Infinity)
|
||||
|
||||
test(`Math.ceil(-11)`, "-11")
|
||||
test(`Math.ceil(-0.5)`, "0")
|
||||
test(`Math.ceil(1.5)`, "2")
|
||||
test(`Math.ceil(-11)`, -11)
|
||||
test(`Math.ceil(-0.5)`, 0)
|
||||
test(`Math.ceil(1.5)`, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_cos(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.cos(NaN)`, "NaN")
|
||||
test(`Math.cos(+0)`, "1")
|
||||
test(`Math.cos(-0)`, "1")
|
||||
test(`Math.cos(Infinity)`, "NaN")
|
||||
test(`Math.cos(-Infinity)`, "NaN")
|
||||
test(`Math.cos(NaN)`, _NaN)
|
||||
test(`Math.cos(+0)`, 1)
|
||||
test(`Math.cos(-0)`, 1)
|
||||
test(`Math.cos(Infinity)`, _NaN)
|
||||
test(`Math.cos(-Infinity)`, _NaN)
|
||||
|
||||
test(`Math.cos(0.5)`, "0.8775825618903728")
|
||||
test(`Math.cos(0.5)`, 0.8775825618903728)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_exp(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.exp(NaN)`, "NaN")
|
||||
test(`Math.exp(+0)`, "1")
|
||||
test(`Math.exp(-0)`, "1")
|
||||
test(`Math.exp(Infinity)`, "Infinity")
|
||||
test(`Math.exp(-Infinity)`, "0")
|
||||
test(`Math.exp(NaN)`, _NaN)
|
||||
test(`Math.exp(+0)`, 1)
|
||||
test(`Math.exp(-0)`, 1)
|
||||
test(`Math.exp(Infinity)`, _Infinity)
|
||||
test(`Math.exp(-Infinity)`, 0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_floor(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.floor(NaN)`, "NaN")
|
||||
test(`Math.floor(+0)`, "0")
|
||||
test(`1/Math.floor(-0)`, "-Infinity")
|
||||
test(`Math.floor(Infinity)`, "Infinity")
|
||||
test(`Math.floor(-Infinity)`, "-Infinity")
|
||||
test(`Math.floor(NaN)`, _NaN)
|
||||
test(`Math.floor(+0)`, 0)
|
||||
test(`1/Math.floor(-0)`, -_Infinity)
|
||||
test(`Math.floor(Infinity)`, _Infinity)
|
||||
test(`Math.floor(-Infinity)`, -_Infinity)
|
||||
|
||||
test(`Math.floor(-11)`, "-11")
|
||||
test(`Math.floor(-0.5)`, "-1")
|
||||
test(`Math.floor(1.5)`, "1")
|
||||
test(`Math.floor(-11)`, -11)
|
||||
test(`Math.floor(-0.5)`, -1)
|
||||
test(`Math.floor(1.5)`, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_log(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.log(NaN)`, "NaN")
|
||||
test(`Math.log(-1)`, "NaN")
|
||||
test(`Math.log(+0)`, "-Infinity")
|
||||
test(`Math.log(-0)`, "-Infinity")
|
||||
test(`1/Math.log(1)`, "Infinity")
|
||||
test(`Math.log(Infinity)`, "Infinity")
|
||||
test(`Math.log(NaN)`, _NaN)
|
||||
test(`Math.log(-1)`, _NaN)
|
||||
test(`Math.log(+0)`, -_Infinity)
|
||||
test(`Math.log(-0)`, -_Infinity)
|
||||
test(`1/Math.log(1)`, _Infinity)
|
||||
test(`Math.log(Infinity)`, _Infinity)
|
||||
|
||||
test(`Math.log(0.5)`, "-0.6931471805599453")
|
||||
test(`Math.log(0.5)`, -0.6931471805599453)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_max(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.max(-11, -1, 0, 1, 2, 3, 11)`, "11")
|
||||
test(`Math.max(-11, -1, 0, 1, 2, 3, 11)`, 11)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_min(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.min(-11, -1, 0, 1, 2, 3, 11)`, "-11")
|
||||
test(`Math.min(-11, -1, 0, 1, 2, 3, 11)`, -11)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_pow(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.pow(0, NaN)`, "NaN")
|
||||
test(`Math.pow(0, 0)`, "1")
|
||||
test(`Math.pow(NaN, 0)`, "1")
|
||||
test(`Math.pow(0, -0)`, "1")
|
||||
test(`Math.pow(NaN, -0)`, "1")
|
||||
test(`Math.pow(NaN, 1)`, "NaN")
|
||||
test(`Math.pow(2, Infinity)`, "Infinity")
|
||||
test(`1/Math.pow(2, -Infinity)`, "Infinity")
|
||||
test(`Math.pow(1, Infinity)`, "NaN")
|
||||
test(`Math.pow(1, -Infinity)`, "NaN")
|
||||
test(`1/Math.pow(0.1, Infinity)`, "Infinity")
|
||||
test(`Math.pow(0.1, -Infinity)`, "Infinity")
|
||||
test(`Math.pow(Infinity, 1)`, "Infinity")
|
||||
test(`1/Math.pow(Infinity, -1)`, "Infinity")
|
||||
test(`Math.pow(-Infinity, 1)`, "-Infinity")
|
||||
test(`Math.pow(-Infinity, 2)`, "Infinity")
|
||||
test(`1/Math.pow(-Infinity, -1)`, "-Infinity")
|
||||
test(`1/Math.pow(-Infinity, -2)`, "Infinity")
|
||||
test(`1/Math.pow(0, 1)`, "Infinity")
|
||||
test(`Math.pow(0, -1)`, "Infinity")
|
||||
test(`1/Math.pow(-0, 1)`, "-Infinity")
|
||||
test(`1/Math.pow(-0, 2)`, "Infinity")
|
||||
test(`Math.pow(-0, -1)`, "-Infinity")
|
||||
test(`Math.pow(-0, -2)`, "Infinity")
|
||||
test(`Math.pow(-1, 0.1)`, "NaN")
|
||||
test(`Math.pow(0, NaN)`, _NaN)
|
||||
test(`Math.pow(0, 0)`, 1)
|
||||
test(`Math.pow(NaN, 0)`, 1)
|
||||
test(`Math.pow(0, -0)`, 1)
|
||||
test(`Math.pow(NaN, -0)`, 1)
|
||||
test(`Math.pow(NaN, 1)`, _NaN)
|
||||
test(`Math.pow(2, Infinity)`, _Infinity)
|
||||
test(`1/Math.pow(2, -Infinity)`, _Infinity)
|
||||
test(`Math.pow(1, Infinity)`, _NaN)
|
||||
test(`Math.pow(1, -Infinity)`, _NaN)
|
||||
test(`1/Math.pow(0.1, Infinity)`, _Infinity)
|
||||
test(`Math.pow(0.1, -Infinity)`, _Infinity)
|
||||
test(`Math.pow(Infinity, 1)`, _Infinity)
|
||||
test(`1/Math.pow(Infinity, -1)`, _Infinity)
|
||||
test(`Math.pow(-Infinity, 1)`, -_Infinity)
|
||||
test(`Math.pow(-Infinity, 2)`, _Infinity)
|
||||
test(`1/Math.pow(-Infinity, -1)`, -_Infinity)
|
||||
test(`1/Math.pow(-Infinity, -2)`, _Infinity)
|
||||
test(`1/Math.pow(0, 1)`, _Infinity)
|
||||
test(`Math.pow(0, -1)`, _Infinity)
|
||||
test(`1/Math.pow(-0, 1)`, -_Infinity)
|
||||
test(`1/Math.pow(-0, 2)`, _Infinity)
|
||||
test(`Math.pow(-0, -1)`, -_Infinity)
|
||||
test(`Math.pow(-0, -2)`, _Infinity)
|
||||
test(`Math.pow(-1, 0.1)`, _NaN)
|
||||
|
||||
test(`
|
||||
[ Math.pow(-1, +Infinity), Math.pow(1, Infinity) ];
|
||||
`, "NaN,NaN")
|
||||
test(`
|
||||
[ Math.pow(-1, +Infinity), Math.pow(1, Infinity) ];
|
||||
`, "NaN,NaN")
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_round(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.round(NaN)`, "NaN")
|
||||
test(`1/Math.round(0)`, "Infinity")
|
||||
test(`1/Math.round(-0)`, "-Infinity")
|
||||
test(`Math.round(Infinity)`, "Infinity")
|
||||
test(`Math.round(-Infinity)`, "-Infinity")
|
||||
test(`1/Math.round(0.1)`, "Infinity")
|
||||
test(`1/Math.round(-0.1)`, "-Infinity")
|
||||
test(`Math.round(NaN)`, _NaN)
|
||||
test(`1/Math.round(0)`, _Infinity)
|
||||
test(`1/Math.round(-0)`, -_Infinity)
|
||||
test(`Math.round(Infinity)`, _Infinity)
|
||||
test(`Math.round(-Infinity)`, -_Infinity)
|
||||
test(`1/Math.round(0.1)`, _Infinity)
|
||||
test(`1/Math.round(-0.1)`, -_Infinity)
|
||||
|
||||
test(`Math.round(3.5)`, "4")
|
||||
test(`Math.round(-3.5)`, "-3")
|
||||
test(`Math.round(3.5)`, 4)
|
||||
test(`Math.round(-3.5)`, -3)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_sin(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.sin(NaN)`, "NaN")
|
||||
test(`1/Math.sin(+0)`, "Infinity")
|
||||
test(`1/Math.sin(-0)`, "-Infinity")
|
||||
test(`Math.sin(Infinity)`, "NaN")
|
||||
test(`Math.sin(-Infinity)`, "NaN")
|
||||
test(`Math.sin(NaN)`, _NaN)
|
||||
test(`1/Math.sin(+0)`, _Infinity)
|
||||
test(`1/Math.sin(-0)`, -_Infinity)
|
||||
test(`Math.sin(Infinity)`, _NaN)
|
||||
test(`Math.sin(-Infinity)`, _NaN)
|
||||
|
||||
test(`Math.sin(0.5)`, "0.479425538604203")
|
||||
test(`Math.sin(0.5)`, 0.479425538604203)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_sqrt(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.sqrt(NaN)`, "NaN")
|
||||
test(`Math.sqrt(-1)`, "NaN")
|
||||
test(`1/Math.sqrt(+0)`, "Infinity")
|
||||
test(`1/Math.sqrt(-0)`, "-Infinity")
|
||||
test(`Math.sqrt(Infinity)`, "Infinity")
|
||||
test(`Math.sqrt(NaN)`, _NaN)
|
||||
test(`Math.sqrt(-1)`, _NaN)
|
||||
test(`1/Math.sqrt(+0)`, _Infinity)
|
||||
test(`1/Math.sqrt(-0)`, -_Infinity)
|
||||
test(`Math.sqrt(Infinity)`, _Infinity)
|
||||
|
||||
test(`Math.sqrt(2)`, "1.4142135623730951")
|
||||
test(`Math.sqrt(2)`, 1.4142135623730951)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMath_tan(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`Math.tan(NaN)`, "NaN")
|
||||
test(`1/Math.tan(+0)`, "Infinity")
|
||||
test(`1/Math.tan(-0)`, "-Infinity")
|
||||
test(`Math.tan(Infinity)`, "NaN")
|
||||
test(`Math.tan(-Infinity)`, "NaN")
|
||||
test(`Math.tan(NaN)`, _NaN)
|
||||
test(`1/Math.tan(+0)`, _Infinity)
|
||||
test(`1/Math.tan(-0)`, -_Infinity)
|
||||
test(`Math.tan(Infinity)`, _NaN)
|
||||
test(`Math.tan(-Infinity)`, _NaN)
|
||||
|
||||
test(`Math.tan(0.5)`, "0.5463024898437905")
|
||||
test(`Math.tan(0.5)`, 0.5463024898437905)
|
||||
})
|
||||
}
|
||||
|
||||
239
number_test.go
239
number_test.go
@@ -1,168 +1,167 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNumber(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(Number, "prototype");
|
||||
[ [ typeof Number.prototype ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "object,false,false,false")
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(Number, "prototype");
|
||||
[ [ typeof Number.prototype ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "object,false,false,false")
|
||||
})
|
||||
}
|
||||
|
||||
func TestNumber_toString(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
new Number(451).toString();
|
||||
`, "451")
|
||||
|
||||
test(`
|
||||
new Number(451).toString();
|
||||
`, "451")
|
||||
test(`
|
||||
new Number(451).toString(10);
|
||||
`, "451")
|
||||
|
||||
test(`
|
||||
new Number(451).toString(10);
|
||||
`, "451")
|
||||
test(`
|
||||
new Number(451).toString(8);
|
||||
`, "703")
|
||||
|
||||
test(`
|
||||
new Number(451).toString(8);
|
||||
`, "703")
|
||||
test(`raise:
|
||||
new Number(451).toString(1);
|
||||
`, "RangeError: RangeError: toString() radix must be between 2 and 36")
|
||||
|
||||
test(`raise:
|
||||
new Number(451).toString(1);
|
||||
`, "RangeError: RangeError: toString() radix must be between 2 and 36")
|
||||
test(`raise:
|
||||
new Number(451).toString(Infinity);
|
||||
`, "RangeError: RangeError: toString() radix must be between 2 and 36")
|
||||
|
||||
test(`raise:
|
||||
new Number(451).toString(Infinity);
|
||||
`, "RangeError: RangeError: toString() radix must be between 2 and 36")
|
||||
test(`
|
||||
new Number(NaN).toString()
|
||||
`, "NaN")
|
||||
|
||||
test(`
|
||||
new Number(NaN).toString()
|
||||
`, "NaN")
|
||||
test(`
|
||||
new Number(Infinity).toString()
|
||||
`, "Infinity")
|
||||
|
||||
test(`
|
||||
new Number(Infinity).toString()
|
||||
`, "Infinity")
|
||||
test(`
|
||||
new Number(Infinity).toString(16)
|
||||
`, "Infinity")
|
||||
|
||||
test(`
|
||||
new Number(Infinity).toString(16)
|
||||
`, "Infinity")
|
||||
|
||||
test(`
|
||||
[
|
||||
Number.prototype.toString(undefined),
|
||||
new Number().toString(undefined),
|
||||
new Number(0).toString(undefined),
|
||||
new Number(-1).toString(undefined),
|
||||
new Number(1).toString(undefined),
|
||||
new Number(Number.NaN).toString(undefined),
|
||||
new Number(Number.POSITIVE_INFINITY).toString(undefined),
|
||||
new Number(Number.NEGATIVE_INFINITY).toString(undefined)
|
||||
]
|
||||
`, "0,0,0,-1,1,NaN,Infinity,-Infinity")
|
||||
test(`
|
||||
[
|
||||
Number.prototype.toString(undefined),
|
||||
new Number().toString(undefined),
|
||||
new Number(0).toString(undefined),
|
||||
new Number(-1).toString(undefined),
|
||||
new Number(1).toString(undefined),
|
||||
new Number(Number.NaN).toString(undefined),
|
||||
new Number(Number.POSITIVE_INFINITY).toString(undefined),
|
||||
new Number(Number.NEGATIVE_INFINITY).toString(undefined)
|
||||
]
|
||||
`, "0,0,0,-1,1,NaN,Infinity,-Infinity")
|
||||
})
|
||||
}
|
||||
|
||||
func TestNumber_toFixed(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`new Number(451).toFixed(2)`, "451.00")
|
||||
test(`12345.6789.toFixed()`, "12346")
|
||||
test(`12345.6789.toFixed(1)`, "12345.7")
|
||||
test(`12345.6789.toFixed(6)`, "12345.678900")
|
||||
test(`(1.23e-20).toFixed(2)`, "0.00")
|
||||
test(`2.34.toFixed(1)`, "2.3") // FIXME Wtf? "2.3"
|
||||
test(`-2.34.toFixed(1)`, -2.3) // FIXME Wtf? -2.3
|
||||
test(`(-2.34).toFixed(1)`, "-2.3")
|
||||
|
||||
test(`new Number(451).toFixed(2)`, "451.00")
|
||||
test(`12345.6789.toFixed()`, "12346")
|
||||
test(`12345.6789.toFixed(1)`, "12345.7")
|
||||
test(`12345.6789.toFixed(6)`, "12345.678900")
|
||||
test(`(1.23e-20).toFixed(2)`, "0.00")
|
||||
test(`2.34.toFixed(1)`, "2.3")
|
||||
test(`-2.34.toFixed(1)`, "-2.3")
|
||||
test(`(-2.34).toFixed(1)`, "-2.3")
|
||||
test(`raise:
|
||||
new Number("a").toFixed(Number.POSITIVE_INFINITY);
|
||||
`, "RangeError: toFixed() precision must be between 0 and 20")
|
||||
|
||||
test(`raise:
|
||||
new Number("a").toFixed(Number.POSITIVE_INFINITY);
|
||||
`, "RangeError: toFixed() precision must be between 0 and 20")
|
||||
test(`
|
||||
[
|
||||
new Number(1e21).toFixed(),
|
||||
new Number(1e21).toFixed(0),
|
||||
new Number(1e21).toFixed(1),
|
||||
new Number(1e21).toFixed(1.1),
|
||||
new Number(1e21).toFixed(0.9),
|
||||
new Number(1e21).toFixed("1"),
|
||||
new Number(1e21).toFixed("1.1"),
|
||||
new Number(1e21).toFixed("0.9"),
|
||||
new Number(1e21).toFixed(Number.NaN),
|
||||
new Number(1e21).toFixed("some string")
|
||||
];
|
||||
`, "1e+21,1e+21,1e+21,1e+21,1e+21,1e+21,1e+21,1e+21,1e+21,1e+21")
|
||||
|
||||
test(`
|
||||
[
|
||||
new Number(1e21).toFixed(),
|
||||
new Number(1e21).toFixed(0),
|
||||
new Number(1e21).toFixed(1),
|
||||
new Number(1e21).toFixed(1.1),
|
||||
new Number(1e21).toFixed(0.9),
|
||||
new Number(1e21).toFixed("1"),
|
||||
new Number(1e21).toFixed("1.1"),
|
||||
new Number(1e21).toFixed("0.9"),
|
||||
new Number(1e21).toFixed(Number.NaN),
|
||||
new Number(1e21).toFixed("some string")
|
||||
];
|
||||
`, "1e+21,1e+21,1e+21,1e+21,1e+21,1e+21,1e+21,1e+21,1e+21,1e+21")
|
||||
|
||||
test(`raise:
|
||||
new Number(1e21).toFixed(Number.POSITIVE_INFINITY);
|
||||
`, "RangeError: toFixed() precision must be between 0 and 20")
|
||||
test(`raise:
|
||||
new Number(1e21).toFixed(Number.POSITIVE_INFINITY);
|
||||
`, "RangeError: toFixed() precision must be between 0 and 20")
|
||||
})
|
||||
}
|
||||
|
||||
func TestNumber_toExponential(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`new Number(451).toExponential(2)`, "4.51e+02")
|
||||
test(`77.1234.toExponential()`, "7.71234e+01")
|
||||
test(`77.1234.toExponential(4)`, "7.7123e+01")
|
||||
test(`77.1234.toExponential(2)`, "7.71e+01")
|
||||
test(`77 .toExponential()`, "7.7e+01")
|
||||
test(`new Number(451).toExponential(2)`, "4.51e+02")
|
||||
test(`77.1234.toExponential()`, "7.71234e+01")
|
||||
test(`77.1234.toExponential(4)`, "7.7123e+01")
|
||||
test(`77.1234.toExponential(2)`, "7.71e+01")
|
||||
test(`77 .toExponential()`, "7.7e+01")
|
||||
})
|
||||
}
|
||||
|
||||
func TestNumber_toPrecision(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`new Number(451).toPrecision()`, "451")
|
||||
test(`new Number(451).toPrecision(1)`, "5e+02")
|
||||
test(`5.123456.toPrecision()`, "5.123456")
|
||||
test(`5.123456.toPrecision(5)`, "5.1235")
|
||||
test(`5.123456.toPrecision(2)`, "5.1")
|
||||
test(`5.123456.toPrecision(1)`, "5")
|
||||
test(`new Number(451).toPrecision()`, "451")
|
||||
test(`new Number(451).toPrecision(1)`, "5e+02")
|
||||
test(`5.123456.toPrecision()`, "5.123456")
|
||||
test(`5.123456.toPrecision(5)`, "5.1235")
|
||||
test(`5.123456.toPrecision(2)`, "5.1")
|
||||
test(`5.123456.toPrecision(1)`, "5")
|
||||
})
|
||||
}
|
||||
|
||||
func TestNumber_toLocaleString(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
[
|
||||
new Number(451).toLocaleString(),
|
||||
new Number(451).toLocaleString(10),
|
||||
new Number(451).toLocaleString(8)
|
||||
];
|
||||
`, "451,451,703")
|
||||
test(`
|
||||
[
|
||||
new Number(451).toLocaleString(),
|
||||
new Number(451).toLocaleString(10),
|
||||
new Number(451).toLocaleString(8)
|
||||
];
|
||||
`, "451,451,703")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_toInteger(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
integer := toInteger(toValue(0.0))
|
||||
is(integer.valid(), true)
|
||||
is(integer.exact(), true)
|
||||
|
||||
integer := toInteger(toValue(0.0))
|
||||
Is(integer.valid(), true)
|
||||
Is(integer.exact(), true)
|
||||
|
||||
integer = toInteger(toValue(3.14159))
|
||||
Is(integer.valid(), true)
|
||||
Is(integer.exact(), false)
|
||||
integer = toInteger(toValue(3.14159))
|
||||
is(integer.valid(), true)
|
||||
is(integer.exact(), false)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_NaN(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`
|
||||
[ NaN === NaN, NaN == NaN ];
|
||||
`, "false,false")
|
||||
test(`
|
||||
[ NaN === NaN, NaN == NaN ];
|
||||
`, "false,false")
|
||||
})
|
||||
}
|
||||
|
||||
996
object_test.go
996
object_test.go
File diff suppressed because it is too large
Load Diff
@@ -1,49 +1,48 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOttoError(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
vm := New()
|
||||
|
||||
Otto := New()
|
||||
_, err := vm.Run(`throw "Xyzzy"`)
|
||||
is(err, "Xyzzy")
|
||||
|
||||
_, err := Otto.Run(`throw "Xyzzy"`)
|
||||
Is(err, "Xyzzy")
|
||||
_, err = vm.Run(`throw new TypeError()`)
|
||||
is(err, "TypeError")
|
||||
|
||||
_, err = Otto.Run(`throw new TypeError()`)
|
||||
Is(err, "TypeError")
|
||||
_, err = vm.Run(`throw new TypeError("Nothing happens.")`)
|
||||
is(err, "TypeError: Nothing happens.")
|
||||
|
||||
_, err = Otto.Run(`throw new TypeError("Nothing happens.")`)
|
||||
Is(err, "TypeError: Nothing happens.")
|
||||
_, err = ToValue([]byte{})
|
||||
is(err, "TypeError: Invalid value (slice): Missing runtime: [] ([]uint8)")
|
||||
|
||||
_, err = ToValue([]byte{})
|
||||
Is(err, "TypeError: Invalid value (slice): Missing runtime: [] ([]uint8)")
|
||||
_, err = vm.Run(`
|
||||
(function(){
|
||||
return abcdef.length
|
||||
})()
|
||||
`)
|
||||
is(err, "ReferenceError: abcdef is not defined")
|
||||
|
||||
_, err = Otto.Run(`
|
||||
(function(){
|
||||
return abcdef.length
|
||||
})()
|
||||
`)
|
||||
Is(err, "ReferenceError: abcdef is not defined")
|
||||
_, err = vm.Run(`
|
||||
function start() {
|
||||
}
|
||||
|
||||
_, err = Otto.Run(`
|
||||
function start() {
|
||||
}
|
||||
start()
|
||||
|
||||
start()
|
||||
xyzzy()
|
||||
`)
|
||||
is(err, "ReferenceError: xyzzy is not defined")
|
||||
|
||||
xyzzy()
|
||||
`)
|
||||
Is(err, "ReferenceError: xyzzy is not defined")
|
||||
_, err = vm.Run(`
|
||||
// Just a comment
|
||||
|
||||
_, err = Otto.Run(`
|
||||
// Just a comment
|
||||
|
||||
xyzzy
|
||||
`)
|
||||
Is(err, "ReferenceError: xyzzy is not defined")
|
||||
xyzzy
|
||||
`)
|
||||
is(err, "ReferenceError: xyzzy is not defined")
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
2223
otto_test.go
2223
otto_test.go
File diff suppressed because it is too large
Load Diff
@@ -1,41 +1,40 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_panic(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
// Test that property.value is set to something if writable is set
|
||||
// to something
|
||||
test(`
|
||||
var abc = [];
|
||||
Object.defineProperty(abc, "0", { writable: false });
|
||||
Object.defineProperty(abc, "0", { writable: false });
|
||||
"0" in abc;
|
||||
`, true)
|
||||
|
||||
// Test that property.value is set to something if writable is set
|
||||
// to something
|
||||
test(`
|
||||
var abc = [];
|
||||
Object.defineProperty(abc, "0", { writable: false });
|
||||
Object.defineProperty(abc, "0", { writable: false });
|
||||
"0" in abc;
|
||||
`, true)
|
||||
test(`raise:
|
||||
var abc = [];
|
||||
Object.defineProperty(abc, "0", { writable: false });
|
||||
Object.defineProperty(abc, "0", { value: false, writable: false });
|
||||
`, "TypeError")
|
||||
|
||||
test(`raise:
|
||||
var abc = [];
|
||||
Object.defineProperty(abc, "0", { writable: false });
|
||||
Object.defineProperty(abc, "0", { value: false, writable: false });
|
||||
`, "TypeError")
|
||||
// Test that a regular expression can contain \c0410 (CYRILLIC CAPITAL LETTER A)
|
||||
// without panicking
|
||||
test(`
|
||||
var abc = 0x0410;
|
||||
var def = String.fromCharCode(abc);
|
||||
new RegExp("\\c" + def).exec(def);
|
||||
`, "null")
|
||||
|
||||
// Test that a regular expression can contain \c0410 (CYRILLIC CAPITAL LETTER A)
|
||||
// without panicking
|
||||
test(`
|
||||
var abc = 0x0410;
|
||||
var def = String.fromCharCode(abc);
|
||||
new RegExp("\\c" + def).exec(def);
|
||||
`, "null")
|
||||
|
||||
// Test transforming a transformable regular expression without a panic
|
||||
test(`
|
||||
new RegExp("\\u0000");
|
||||
new RegExp("\\undefined").test("undefined");
|
||||
`, true)
|
||||
// Test transforming a transformable regular expression without a panic
|
||||
test(`
|
||||
new RegExp("\\u0000");
|
||||
new RegExp("\\undefined").test("undefined");
|
||||
`, true)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,375 +1,380 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
. "../terst"
|
||||
"../terst"
|
||||
"testing"
|
||||
|
||||
"github.com/robertkrimen/otto/file"
|
||||
"github.com/robertkrimen/otto/token"
|
||||
)
|
||||
|
||||
var tt = terst.Terst
|
||||
var is = terst.Is
|
||||
|
||||
func TestLexer(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
setup := func(src string) *_parser {
|
||||
parser := newParser("", src)
|
||||
return parser
|
||||
}
|
||||
|
||||
setup := func(src string) *_parser {
|
||||
parser := newParser("", src)
|
||||
return parser
|
||||
}
|
||||
|
||||
test := func(src string, test ...interface{}) {
|
||||
parser := setup(src)
|
||||
for len(test) > 0 {
|
||||
tkn, literal, idx := parser.scan()
|
||||
if len(test) > 0 {
|
||||
Is(tkn, test[0].(token.Token))
|
||||
test = test[1:]
|
||||
}
|
||||
if len(test) > 0 {
|
||||
Is(literal, test[0].(string))
|
||||
test = test[1:]
|
||||
}
|
||||
if len(test) > 0 {
|
||||
Is(idx, test[0].(int))
|
||||
test = test[1:]
|
||||
test := func(src string, test ...interface{}) {
|
||||
parser := setup(src)
|
||||
for len(test) > 0 {
|
||||
tkn, literal, idx := parser.scan()
|
||||
if len(test) > 0 {
|
||||
is(tkn, test[0].(token.Token))
|
||||
test = test[1:]
|
||||
}
|
||||
if len(test) > 0 {
|
||||
is(literal, test[0].(string))
|
||||
test = test[1:]
|
||||
}
|
||||
if len(test) > 0 {
|
||||
// FIXME terst, Fix this so that cast to file.Idx is not necessary?
|
||||
is(idx, file.Idx(test[0].(int)))
|
||||
test = test[1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test("",
|
||||
token.EOF, "", 1,
|
||||
)
|
||||
test("",
|
||||
token.EOF, "", 1,
|
||||
)
|
||||
|
||||
test("1",
|
||||
token.NUMBER, "1", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
test("1",
|
||||
token.NUMBER, "1", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
|
||||
test(".0",
|
||||
token.NUMBER, ".0", 1,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
test(".0",
|
||||
token.NUMBER, ".0", 1,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
|
||||
test("abc",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
test("abc",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
|
||||
test("abc(1)",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.LEFT_PARENTHESIS, "", 4,
|
||||
token.NUMBER, "1", 5,
|
||||
token.RIGHT_PARENTHESIS, "", 6,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
test("abc(1)",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.LEFT_PARENTHESIS, "", 4,
|
||||
token.NUMBER, "1", 5,
|
||||
token.RIGHT_PARENTHESIS, "", 6,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
|
||||
test(".",
|
||||
token.PERIOD, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
test(".",
|
||||
token.PERIOD, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
|
||||
test("===.",
|
||||
token.STRICT_EQUAL, "", 1,
|
||||
token.PERIOD, "", 4,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
test("===.",
|
||||
token.STRICT_EQUAL, "", 1,
|
||||
token.PERIOD, "", 4,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
|
||||
test(">>>=.0",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
token.NUMBER, ".0", 5,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
test(">>>=.0",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
token.NUMBER, ".0", 5,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
|
||||
test(">>>=0.0.",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
token.NUMBER, "0.0", 5,
|
||||
token.PERIOD, "", 8,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
test(">>>=0.0.",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
token.NUMBER, "0.0", 5,
|
||||
token.PERIOD, "", 8,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test("\"abc\"",
|
||||
token.STRING, "\"abc\"", 1,
|
||||
token.EOF, "", 6,
|
||||
)
|
||||
test("\"abc\"",
|
||||
token.STRING, "\"abc\"", 1,
|
||||
token.EOF, "", 6,
|
||||
)
|
||||
|
||||
test("abc = //",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
test("abc = //",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test("abc = 1 / 2",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NUMBER, "1", 7,
|
||||
token.SLASH, "", 9,
|
||||
token.NUMBER, "2", 11,
|
||||
token.EOF, "", 12,
|
||||
)
|
||||
test("abc = 1 / 2",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NUMBER, "1", 7,
|
||||
token.SLASH, "", 9,
|
||||
token.NUMBER, "2", 11,
|
||||
token.EOF, "", 12,
|
||||
)
|
||||
|
||||
test("xyzzy = 'Nothing happens.'",
|
||||
token.IDENTIFIER, "xyzzy", 1,
|
||||
token.ASSIGN, "", 7,
|
||||
token.STRING, "'Nothing happens.'", 9,
|
||||
token.EOF, "", 27,
|
||||
)
|
||||
test("xyzzy = 'Nothing happens.'",
|
||||
token.IDENTIFIER, "xyzzy", 1,
|
||||
token.ASSIGN, "", 7,
|
||||
token.STRING, "'Nothing happens.'", 9,
|
||||
token.EOF, "", 27,
|
||||
)
|
||||
|
||||
test("abc = !false",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NOT, "", 7,
|
||||
token.BOOLEAN, "false", 8,
|
||||
token.EOF, "", 13,
|
||||
)
|
||||
test("abc = !false",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NOT, "", 7,
|
||||
token.BOOLEAN, "false", 8,
|
||||
token.EOF, "", 13,
|
||||
)
|
||||
|
||||
test("abc = !!true",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NOT, "", 7,
|
||||
token.NOT, "", 8,
|
||||
token.BOOLEAN, "true", 9,
|
||||
token.EOF, "", 13,
|
||||
)
|
||||
test("abc = !!true",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NOT, "", 7,
|
||||
token.NOT, "", 8,
|
||||
token.BOOLEAN, "true", 9,
|
||||
token.EOF, "", 13,
|
||||
)
|
||||
|
||||
test("abc *= 1",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.MULTIPLY_ASSIGN, "", 5,
|
||||
token.NUMBER, "1", 8,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
test("abc *= 1",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.MULTIPLY_ASSIGN, "", 5,
|
||||
token.NUMBER, "1", 8,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test("if 1 else",
|
||||
token.IF, "if", 1,
|
||||
token.NUMBER, "1", 4,
|
||||
token.ELSE, "else", 6,
|
||||
token.EOF, "", 10,
|
||||
)
|
||||
test("if 1 else",
|
||||
token.IF, "if", 1,
|
||||
token.NUMBER, "1", 4,
|
||||
token.ELSE, "else", 6,
|
||||
token.EOF, "", 10,
|
||||
)
|
||||
|
||||
test("null",
|
||||
token.NULL, "null", 1,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
test("null",
|
||||
token.NULL, "null", 1,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
|
||||
test(`"\u007a\x79\u000a\x78"`,
|
||||
token.STRING, "\"\\u007a\\x79\\u000a\\x78\"", 1,
|
||||
token.EOF, "", 23,
|
||||
)
|
||||
test(`"\u007a\x79\u000a\x78"`,
|
||||
token.STRING, "\"\\u007a\\x79\\u000a\\x78\"", 1,
|
||||
token.EOF, "", 23,
|
||||
)
|
||||
|
||||
test(`"[First line \
|
||||
test(`"[First line \
|
||||
Second line \
|
||||
Third line\
|
||||
. ]"
|
||||
`,
|
||||
token.STRING, "\"[First line \\\nSecond line \\\n Third line\\\n. ]\"", 1,
|
||||
token.EOF, "", 53,
|
||||
)
|
||||
token.STRING, "\"[First line \\\nSecond line \\\n Third line\\\n. ]\"", 1,
|
||||
token.EOF, "", 53,
|
||||
)
|
||||
|
||||
test("/",
|
||||
token.SLASH, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
test("/",
|
||||
token.SLASH, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
|
||||
test("var abc = \"abc\uFFFFabc\"",
|
||||
token.VAR, "var", 1,
|
||||
token.IDENTIFIER, "abc", 5,
|
||||
token.ASSIGN, "", 9,
|
||||
token.STRING, "\"abc\uFFFFabc\"", 11,
|
||||
token.EOF, "", 22,
|
||||
)
|
||||
test("var abc = \"abc\uFFFFabc\"",
|
||||
token.VAR, "var", 1,
|
||||
token.IDENTIFIER, "abc", 5,
|
||||
token.ASSIGN, "", 9,
|
||||
token.STRING, "\"abc\uFFFFabc\"", 11,
|
||||
token.EOF, "", 22,
|
||||
)
|
||||
|
||||
test(`'\t' === '\r'`,
|
||||
token.STRING, "'\\t'", 1,
|
||||
token.STRICT_EQUAL, "", 6,
|
||||
token.STRING, "'\\r'", 10,
|
||||
token.EOF, "", 14,
|
||||
)
|
||||
test(`'\t' === '\r'`,
|
||||
token.STRING, "'\\t'", 1,
|
||||
token.STRICT_EQUAL, "", 6,
|
||||
token.STRING, "'\\r'", 10,
|
||||
token.EOF, "", 14,
|
||||
)
|
||||
|
||||
test(`var \u0024 = 1`,
|
||||
token.VAR, "var", 1,
|
||||
token.IDENTIFIER, "$", 5,
|
||||
token.ASSIGN, "", 12,
|
||||
token.NUMBER, "1", 14,
|
||||
token.EOF, "", 15,
|
||||
)
|
||||
test(`var \u0024 = 1`,
|
||||
token.VAR, "var", 1,
|
||||
token.IDENTIFIER, "$", 5,
|
||||
token.ASSIGN, "", 12,
|
||||
token.NUMBER, "1", 14,
|
||||
token.EOF, "", 15,
|
||||
)
|
||||
|
||||
test("10e10000",
|
||||
token.NUMBER, "10e10000", 1,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
test("10e10000",
|
||||
token.NUMBER, "10e10000", 1,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test(`var if var class`,
|
||||
token.VAR, "var", 1,
|
||||
token.IF, "if", 5,
|
||||
token.VAR, "var", 8,
|
||||
token.KEYWORD, "class", 12,
|
||||
token.EOF, "", 17,
|
||||
)
|
||||
test(`var if var class`,
|
||||
token.VAR, "var", 1,
|
||||
token.IF, "if", 5,
|
||||
token.VAR, "var", 8,
|
||||
token.KEYWORD, "class", 12,
|
||||
token.EOF, "", 17,
|
||||
)
|
||||
|
||||
test(`-0`,
|
||||
token.MINUS, "", 1,
|
||||
token.NUMBER, "0", 2,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
test(`-0`,
|
||||
token.MINUS, "", 1,
|
||||
token.NUMBER, "0", 2,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
|
||||
test(`.01`,
|
||||
token.NUMBER, ".01", 1,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
test(`.01`,
|
||||
token.NUMBER, ".01", 1,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
|
||||
test(`.01e+2`,
|
||||
token.NUMBER, ".01e+2", 1,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
test(`.01e+2`,
|
||||
token.NUMBER, ".01e+2", 1,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
|
||||
test(";",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
test(";",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
|
||||
test(";;",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.SEMICOLON, "", 2,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
test(";;",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.SEMICOLON, "", 2,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
|
||||
test("//",
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
test("//",
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
|
||||
test(";;//",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.SEMICOLON, "", 2,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
test(";;//",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.SEMICOLON, "", 2,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
|
||||
test("1",
|
||||
token.NUMBER, "1", 1,
|
||||
)
|
||||
test("1",
|
||||
token.NUMBER, "1", 1,
|
||||
)
|
||||
|
||||
test("12 123",
|
||||
token.NUMBER, "12", 1,
|
||||
token.NUMBER, "123", 4,
|
||||
)
|
||||
test("12 123",
|
||||
token.NUMBER, "12", 1,
|
||||
token.NUMBER, "123", 4,
|
||||
)
|
||||
|
||||
test("1.2 12.3",
|
||||
token.NUMBER, "1.2", 1,
|
||||
token.NUMBER, "12.3", 5,
|
||||
)
|
||||
test("1.2 12.3",
|
||||
token.NUMBER, "1.2", 1,
|
||||
token.NUMBER, "12.3", 5,
|
||||
)
|
||||
|
||||
test("/ /=",
|
||||
token.SLASH, "", 1,
|
||||
token.QUOTIENT_ASSIGN, "", 3,
|
||||
)
|
||||
test("/ /=",
|
||||
token.SLASH, "", 1,
|
||||
token.QUOTIENT_ASSIGN, "", 3,
|
||||
)
|
||||
|
||||
test(`"abc"`,
|
||||
token.STRING, `"abc"`, 1,
|
||||
)
|
||||
test(`"abc"`,
|
||||
token.STRING, `"abc"`, 1,
|
||||
)
|
||||
|
||||
test(`'abc'`,
|
||||
token.STRING, `'abc'`, 1,
|
||||
)
|
||||
test(`'abc'`,
|
||||
token.STRING, `'abc'`, 1,
|
||||
)
|
||||
|
||||
test("++",
|
||||
token.INCREMENT, "", 1,
|
||||
)
|
||||
test("++",
|
||||
token.INCREMENT, "", 1,
|
||||
)
|
||||
|
||||
test(">",
|
||||
token.GREATER, "", 1,
|
||||
)
|
||||
test(">",
|
||||
token.GREATER, "", 1,
|
||||
)
|
||||
|
||||
test(">=",
|
||||
token.GREATER_OR_EQUAL, "", 1,
|
||||
)
|
||||
test(">=",
|
||||
token.GREATER_OR_EQUAL, "", 1,
|
||||
)
|
||||
|
||||
test(">>",
|
||||
token.SHIFT_RIGHT, "", 1,
|
||||
)
|
||||
test(">>",
|
||||
token.SHIFT_RIGHT, "", 1,
|
||||
)
|
||||
|
||||
test(">>=",
|
||||
token.SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
)
|
||||
test(">>=",
|
||||
token.SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
)
|
||||
|
||||
test(">>>",
|
||||
token.UNSIGNED_SHIFT_RIGHT, "", 1,
|
||||
)
|
||||
test(">>>",
|
||||
token.UNSIGNED_SHIFT_RIGHT, "", 1,
|
||||
)
|
||||
|
||||
test(">>>=",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
)
|
||||
test(">>>=",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
)
|
||||
|
||||
test("1 \"abc\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.STRING, "\"abc\"", 3,
|
||||
)
|
||||
test("1 \"abc\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.STRING, "\"abc\"", 3,
|
||||
)
|
||||
|
||||
test(",",
|
||||
token.COMMA, "", 1,
|
||||
)
|
||||
test(",",
|
||||
token.COMMA, "", 1,
|
||||
)
|
||||
|
||||
test("1, \"abc\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.COMMA, "", 2,
|
||||
token.STRING, "\"abc\"", 4,
|
||||
)
|
||||
test("1, \"abc\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.COMMA, "", 2,
|
||||
token.STRING, "\"abc\"", 4,
|
||||
)
|
||||
|
||||
test("new abc(1, 3.14159);",
|
||||
token.NEW, "new", 1,
|
||||
token.IDENTIFIER, "abc", 5,
|
||||
token.LEFT_PARENTHESIS, "", 8,
|
||||
token.NUMBER, "1", 9,
|
||||
token.COMMA, "", 10,
|
||||
token.NUMBER, "3.14159", 12,
|
||||
token.RIGHT_PARENTHESIS, "", 19,
|
||||
token.SEMICOLON, "", 20,
|
||||
)
|
||||
test("new abc(1, 3.14159);",
|
||||
token.NEW, "new", 1,
|
||||
token.IDENTIFIER, "abc", 5,
|
||||
token.LEFT_PARENTHESIS, "", 8,
|
||||
token.NUMBER, "1", 9,
|
||||
token.COMMA, "", 10,
|
||||
token.NUMBER, "3.14159", 12,
|
||||
token.RIGHT_PARENTHESIS, "", 19,
|
||||
token.SEMICOLON, "", 20,
|
||||
)
|
||||
|
||||
test("1 == \"1\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.EQUAL, "", 3,
|
||||
token.STRING, "\"1\"", 6,
|
||||
)
|
||||
test("1 == \"1\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.EQUAL, "", 3,
|
||||
token.STRING, "\"1\"", 6,
|
||||
)
|
||||
|
||||
test("1\n[]\n",
|
||||
token.NUMBER, "1", 1,
|
||||
token.LEFT_BRACKET, "", 3,
|
||||
token.RIGHT_BRACKET, "", 4,
|
||||
)
|
||||
test("1\n[]\n",
|
||||
token.NUMBER, "1", 1,
|
||||
token.LEFT_BRACKET, "", 3,
|
||||
token.RIGHT_BRACKET, "", 4,
|
||||
)
|
||||
|
||||
test("1\ufeff[]\ufeff",
|
||||
token.NUMBER, "1", 1,
|
||||
token.LEFT_BRACKET, "", 5,
|
||||
token.RIGHT_BRACKET, "", 6,
|
||||
)
|
||||
test("1\ufeff[]\ufeff",
|
||||
token.NUMBER, "1", 1,
|
||||
token.LEFT_BRACKET, "", 5,
|
||||
token.RIGHT_BRACKET, "", 6,
|
||||
)
|
||||
|
||||
// ILLEGAL
|
||||
// ILLEGAL
|
||||
|
||||
test(`3ea`,
|
||||
token.ILLEGAL, "3e", 1,
|
||||
token.IDENTIFIER, "a", 3,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
test(`3ea`,
|
||||
token.ILLEGAL, "3e", 1,
|
||||
token.IDENTIFIER, "a", 3,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
|
||||
test(`3in`,
|
||||
token.ILLEGAL, "3", 1,
|
||||
token.IN, "in", 2,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
test(`3in`,
|
||||
token.ILLEGAL, "3", 1,
|
||||
token.IN, "in", 2,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
|
||||
test("\"Hello\nWorld\"",
|
||||
token.ILLEGAL, "", 1,
|
||||
token.IDENTIFIER, "World", 8,
|
||||
token.ILLEGAL, "", 13,
|
||||
token.EOF, "", 14,
|
||||
)
|
||||
test("\"Hello\nWorld\"",
|
||||
token.ILLEGAL, "", 1,
|
||||
token.IDENTIFIER, "World", 8,
|
||||
token.ILLEGAL, "", 13,
|
||||
token.EOF, "", 14,
|
||||
)
|
||||
|
||||
test("\u203f = 10",
|
||||
token.ILLEGAL, "", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NUMBER, "10", 7,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
test("\u203f = 10",
|
||||
token.ILLEGAL, "", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NUMBER, "10", 7,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test(`"\x0G"`,
|
||||
token.STRING, "\"\\x0G\"", 1,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
test(`"\x0G"`,
|
||||
token.STRING, "\"\\x0G\"", 1,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
. "../terst"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -13,7 +12,6 @@ import (
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
)
|
||||
|
||||
//func marshal(name string, children ...interface{}) map[string]interface{} {
|
||||
func marshal(name string, children ...interface{}) interface{} {
|
||||
if len(children) == 1 {
|
||||
if name == "" {
|
||||
@@ -194,47 +192,47 @@ func testMarshal(node interface{}) string {
|
||||
}
|
||||
|
||||
func TestParserAST(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
|
||||
test := func(inputOutput string) {
|
||||
match := matchBeforeAfterSeparator.FindStringIndex(inputOutput)
|
||||
input := strings.TrimSpace(inputOutput[0:match[0]])
|
||||
wantOutput := strings.TrimSpace(inputOutput[match[1]:])
|
||||
_, program, err := testParse(input)
|
||||
Is(err, nil)
|
||||
haveOutput := testMarshal(program)
|
||||
tmp0, tmp1 := bytes.Buffer{}, bytes.Buffer{}
|
||||
json.Indent(&tmp0, []byte(haveOutput), "\t\t", " ")
|
||||
json.Indent(&tmp1, []byte(wantOutput), "\t\t", " ")
|
||||
Is("\n\t\t"+tmp0.String(), "\n\t\t"+tmp1.String())
|
||||
}
|
||||
test := func(inputOutput string) {
|
||||
match := matchBeforeAfterSeparator.FindStringIndex(inputOutput)
|
||||
input := strings.TrimSpace(inputOutput[0:match[0]])
|
||||
wantOutput := strings.TrimSpace(inputOutput[match[1]:])
|
||||
_, program, err := testParse(input)
|
||||
is(err, nil)
|
||||
haveOutput := testMarshal(program)
|
||||
tmp0, tmp1 := bytes.Buffer{}, bytes.Buffer{}
|
||||
json.Indent(&tmp0, []byte(haveOutput), "\t\t", " ")
|
||||
json.Indent(&tmp1, []byte(wantOutput), "\t\t", " ")
|
||||
is("\n\t\t"+tmp0.String(), "\n\t\t"+tmp1.String())
|
||||
}
|
||||
|
||||
test(`
|
||||
---
|
||||
test(`
|
||||
---
|
||||
[]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
;
|
||||
---
|
||||
test(`
|
||||
;
|
||||
---
|
||||
[
|
||||
"EmptyStatement"
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
;;;
|
||||
---
|
||||
test(`
|
||||
;;;
|
||||
---
|
||||
[
|
||||
"EmptyStatement",
|
||||
"EmptyStatement",
|
||||
"EmptyStatement"
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
1; true; abc; "abc"; null;
|
||||
---
|
||||
test(`
|
||||
1; true; abc; "abc"; null;
|
||||
---
|
||||
[
|
||||
{
|
||||
"Literal": 1
|
||||
@@ -252,11 +250,11 @@ func TestParserAST(t *testing.T) {
|
||||
"Literal": null
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
{ 1; null; 3.14159; ; }
|
||||
---
|
||||
test(`
|
||||
{ 1; null; 3.14159; ; }
|
||||
---
|
||||
[
|
||||
{
|
||||
"BlockStatement": [
|
||||
@@ -273,11 +271,11 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
new abc();
|
||||
---
|
||||
test(`
|
||||
new abc();
|
||||
---
|
||||
[
|
||||
{
|
||||
"New": {
|
||||
@@ -288,11 +286,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
new abc(1, 3.14159)
|
||||
---
|
||||
test(`
|
||||
new abc(1, 3.14159)
|
||||
---
|
||||
[
|
||||
{
|
||||
"New": {
|
||||
@@ -310,11 +308,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
true ? false : true
|
||||
---
|
||||
test(`
|
||||
true ? false : true
|
||||
---
|
||||
[
|
||||
{
|
||||
"Conditional": {
|
||||
@@ -330,11 +328,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
true || false
|
||||
---
|
||||
test(`
|
||||
true || false
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
@@ -348,11 +346,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
0 + { abc: true }
|
||||
---
|
||||
test(`
|
||||
0 + { abc: true }
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
@@ -373,11 +371,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
1 == "1"
|
||||
---
|
||||
test(`
|
||||
1 == "1"
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
@@ -391,11 +389,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
abc(1)
|
||||
---
|
||||
test(`
|
||||
abc(1)
|
||||
---
|
||||
[
|
||||
{
|
||||
"Call": {
|
||||
@@ -410,10 +408,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
test(`
|
||||
Math.pow(3, 2)
|
||||
---
|
||||
`)
|
||||
|
||||
test(`
|
||||
Math.pow(3, 2)
|
||||
---
|
||||
[
|
||||
{
|
||||
"Call": {
|
||||
@@ -436,11 +435,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
1, 2, 3
|
||||
---
|
||||
test(`
|
||||
1, 2, 3
|
||||
---
|
||||
[
|
||||
{
|
||||
"Sequence": [
|
||||
@@ -456,22 +455,22 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
/ abc / gim;
|
||||
---
|
||||
test(`
|
||||
/ abc / gim;
|
||||
---
|
||||
[
|
||||
{
|
||||
"Literal": "/ abc / gim"
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
if (0)
|
||||
1;
|
||||
---
|
||||
test(`
|
||||
if (0)
|
||||
1;
|
||||
---
|
||||
[
|
||||
{
|
||||
"If": {
|
||||
@@ -484,13 +483,13 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
0+function(){
|
||||
return;
|
||||
}
|
||||
---
|
||||
test(`
|
||||
0+function(){
|
||||
return;
|
||||
}
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
@@ -510,21 +509,21 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
xyzzy // Ignore it
|
||||
// Ignore this
|
||||
// And this
|
||||
/* And all..
|
||||
test(`
|
||||
xyzzy // Ignore it
|
||||
// Ignore this
|
||||
// And this
|
||||
/* And all..
|
||||
|
||||
|
||||
|
||||
... of this!
|
||||
*/
|
||||
"Nothing happens."
|
||||
// And finally this
|
||||
---
|
||||
... of this!
|
||||
*/
|
||||
"Nothing happens."
|
||||
// And finally this
|
||||
---
|
||||
[
|
||||
{
|
||||
"Identifier": "xyzzy"
|
||||
@@ -533,11 +532,11 @@ func TestParserAST(t *testing.T) {
|
||||
"Literal": "\"Nothing happens.\""
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
((x & (x = 1)) !== 0)
|
||||
---
|
||||
test(`
|
||||
((x & (x = 1)) !== 0)
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
@@ -566,11 +565,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
{ abc: 'def' }
|
||||
---
|
||||
test(`
|
||||
{ abc: 'def' }
|
||||
---
|
||||
[
|
||||
{
|
||||
"BlockStatement": [
|
||||
@@ -585,12 +584,12 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
// This is not an object, this is a string literal with a label!
|
||||
({ abc: 'def' })
|
||||
---
|
||||
test(`
|
||||
// This is not an object, this is a string literal with a label!
|
||||
({ abc: 'def' })
|
||||
---
|
||||
[
|
||||
{
|
||||
"Object": [
|
||||
@@ -603,11 +602,11 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
[,]
|
||||
---
|
||||
test(`
|
||||
[,]
|
||||
---
|
||||
[
|
||||
{
|
||||
"Array": [
|
||||
@@ -615,11 +614,11 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
[,,]
|
||||
---
|
||||
test(`
|
||||
[,,]
|
||||
---
|
||||
[
|
||||
{
|
||||
"Array": [
|
||||
@@ -628,11 +627,11 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
({ get abc() {} })
|
||||
---
|
||||
test(`
|
||||
({ get abc() {} })
|
||||
---
|
||||
[
|
||||
{
|
||||
"Object": [
|
||||
@@ -647,11 +646,11 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
/abc/.source
|
||||
---
|
||||
test(`
|
||||
/abc/.source
|
||||
---
|
||||
[
|
||||
{
|
||||
"Dot": {
|
||||
@@ -662,13 +661,13 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
xyzzy
|
||||
test(`
|
||||
xyzzy
|
||||
|
||||
throw new TypeError("Nothing happens.")
|
||||
---
|
||||
throw new TypeError("Nothing happens.")
|
||||
---
|
||||
[
|
||||
{
|
||||
"Identifier": "xyzzy"
|
||||
@@ -690,16 +689,16 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
`)
|
||||
|
||||
// When run, this will call a type error to be thrown
|
||||
// This is essentially the same as:
|
||||
//
|
||||
// var abc = 1(function(){})()
|
||||
//
|
||||
test(`
|
||||
var abc = 1
|
||||
(function(){
|
||||
})()
|
||||
---
|
||||
// When run, this will call a type error to be thrown
|
||||
// This is essentially the same as:
|
||||
//
|
||||
// var abc = 1(function(){})()
|
||||
//
|
||||
test(`
|
||||
var abc = 1
|
||||
(function(){
|
||||
})()
|
||||
---
|
||||
[
|
||||
{
|
||||
"Var": [
|
||||
@@ -728,22 +727,22 @@ func TestParserAST(t *testing.T) {
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
"use strict"
|
||||
---
|
||||
test(`
|
||||
"use strict"
|
||||
---
|
||||
[
|
||||
{
|
||||
"Literal": "\"use strict\""
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
"use strict"
|
||||
abc = 1 + 2 + 11
|
||||
---
|
||||
test(`
|
||||
"use strict"
|
||||
abc = 1 + 2 + 11
|
||||
---
|
||||
[
|
||||
{
|
||||
"Literal": "\"use strict\""
|
||||
@@ -775,11 +774,11 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
abc = function() { 'use strict' }
|
||||
---
|
||||
test(`
|
||||
abc = function() { 'use strict' }
|
||||
---
|
||||
[
|
||||
{
|
||||
"Assign": {
|
||||
@@ -798,12 +797,12 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
for (var abc in def) {
|
||||
}
|
||||
---
|
||||
test(`
|
||||
for (var abc in def) {
|
||||
}
|
||||
---
|
||||
[
|
||||
{
|
||||
"ForIn": {
|
||||
@@ -820,14 +819,14 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
test(`
|
||||
abc = {
|
||||
'"': "'",
|
||||
"'": '"',
|
||||
}
|
||||
---
|
||||
test(`
|
||||
abc = {
|
||||
'"': "'",
|
||||
"'": '"',
|
||||
}
|
||||
---
|
||||
[
|
||||
{
|
||||
"Assign": {
|
||||
@@ -853,14 +852,14 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
test(`
|
||||
if (!abc && abc.jkl(def) && abc[0] === +abc[0] && abc.length < ghi) {
|
||||
}
|
||||
---
|
||||
test(`
|
||||
if (!abc && abc.jkl(def) && abc[0] === +abc[0] && abc.length < ghi) {
|
||||
}
|
||||
---
|
||||
[
|
||||
{
|
||||
"If": {
|
||||
@@ -926,5 +925,6 @@ func TestParserAST(t *testing.T) {
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,150 +1,149 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
. "../terst"
|
||||
"regexp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegExp(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
{
|
||||
// err
|
||||
test := func(input string, expect interface{}) {
|
||||
_, err := TransformRegExp(input)
|
||||
is(err, expect)
|
||||
}
|
||||
|
||||
{
|
||||
// err
|
||||
test := func(input string, expect interface{}) {
|
||||
_, err := TransformRegExp(input)
|
||||
Is(err, expect)
|
||||
test("[", "Unterminated character class")
|
||||
|
||||
test("(", "Unterminated group")
|
||||
|
||||
test("(?=)", "re2: Invalid (?=) <lookahead>")
|
||||
|
||||
test("(?=)", "re2: Invalid (?=) <lookahead>")
|
||||
|
||||
test("(?!)", "re2: Invalid (?!) <lookahead>")
|
||||
|
||||
// An error anyway
|
||||
test("(?=", "re2: Invalid (?=) <lookahead>")
|
||||
|
||||
test("\\1", "re2: Invalid \\1 <backreference>")
|
||||
|
||||
test("\\90", "re2: Invalid \\90 <backreference>")
|
||||
|
||||
test("\\9123456789", "re2: Invalid \\9123456789 <backreference>")
|
||||
|
||||
test("\\(?=)", "Unmatched ')'")
|
||||
|
||||
test(")", "Unmatched ')'")
|
||||
}
|
||||
|
||||
test("[", "Unterminated character class")
|
||||
{
|
||||
// err
|
||||
test := func(input, expect string, expectErr interface{}) {
|
||||
output, err := TransformRegExp(input)
|
||||
is(output, expect)
|
||||
is(err, expectErr)
|
||||
}
|
||||
|
||||
test("(", "Unterminated group")
|
||||
test("(?!)", "(?!)", "re2: Invalid (?!) <lookahead>")
|
||||
|
||||
test("(?=)", "re2: Invalid (?=) <lookahead>")
|
||||
test(")", "", "Unmatched ')'")
|
||||
|
||||
test("(?=)", "re2: Invalid (?=) <lookahead>")
|
||||
test("(?!))", "", "re2: Invalid (?!) <lookahead>")
|
||||
|
||||
test("(?!)", "re2: Invalid (?!) <lookahead>")
|
||||
test("\\0", "\\0", nil)
|
||||
|
||||
// An error anyway
|
||||
test("(?=", "re2: Invalid (?=) <lookahead>")
|
||||
test("\\1", "\\1", "re2: Invalid \\1 <backreference>")
|
||||
|
||||
test("\\1", "re2: Invalid \\1 <backreference>")
|
||||
|
||||
test("\\90", "re2: Invalid \\90 <backreference>")
|
||||
|
||||
test("\\9123456789", "re2: Invalid \\9123456789 <backreference>")
|
||||
|
||||
test("\\(?=)", "Unmatched ')'")
|
||||
|
||||
test(")", "Unmatched ')'")
|
||||
}
|
||||
|
||||
{
|
||||
// err
|
||||
test := func(input, expect string, expectErr interface{}) {
|
||||
output, err := TransformRegExp(input)
|
||||
Is(output, expect)
|
||||
Is(err, expectErr)
|
||||
test("\\9123456789", "\\9123456789", "re2: Invalid \\9123456789 <backreference>")
|
||||
}
|
||||
|
||||
test("(?!)", "(?!)", "re2: Invalid (?!) <lookahead>")
|
||||
|
||||
test(")", "", "Unmatched ')'")
|
||||
|
||||
test("(?!))", "", "re2: Invalid (?!) <lookahead>")
|
||||
|
||||
test("\\0", "\\0", nil)
|
||||
|
||||
test("\\1", "\\1", "re2: Invalid \\1 <backreference>")
|
||||
|
||||
test("\\9123456789", "\\9123456789", "re2: Invalid \\9123456789 <backreference>")
|
||||
}
|
||||
|
||||
{
|
||||
// err
|
||||
test := func(input string, expect string) {
|
||||
result, err := TransformRegExp(input)
|
||||
Is(err, nil)
|
||||
if Is(result, expect) {
|
||||
_, err := regexp.Compile(result)
|
||||
if !Is(err, nil) {
|
||||
t.Log(result)
|
||||
{
|
||||
// err
|
||||
test := func(input string, expect string) {
|
||||
result, err := TransformRegExp(input)
|
||||
is(err, nil)
|
||||
if is(result, expect) {
|
||||
_, err := regexp.Compile(result)
|
||||
if !is(err, nil) {
|
||||
t.Log(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test("", "")
|
||||
|
||||
test("abc", "abc")
|
||||
|
||||
test(`\abc`, `abc`)
|
||||
|
||||
test(`\a\b\c`, `a\bc`)
|
||||
|
||||
test(`\x`, `x`)
|
||||
|
||||
test(`\c`, `c`)
|
||||
|
||||
test(`\cA`, `\x01`)
|
||||
|
||||
test(`\cz`, `\x1a`)
|
||||
|
||||
test(`\ca`, `\x01`)
|
||||
|
||||
test(`\cj`, `\x0a`)
|
||||
|
||||
test(`\ck`, `\x0b`)
|
||||
|
||||
test(`\+`, `\+`)
|
||||
|
||||
test(`[\b]`, `[\x08]`)
|
||||
|
||||
test(`\u0z01\x\undefined`, `u0z01xundefined`)
|
||||
|
||||
test(`\\|'|\r|\n|\t|\u2028|\u2029`, `\\|'|\r|\n|\t|\x{2028}|\x{2029}`)
|
||||
|
||||
test("]", "]")
|
||||
|
||||
test("}", "}")
|
||||
|
||||
test("%", "%")
|
||||
|
||||
test("(%)", "(%)")
|
||||
|
||||
test("(?:[%\\s])", "(?:[%\\s])")
|
||||
|
||||
test("[[]", "[[]")
|
||||
|
||||
test("\\101", "\\x41")
|
||||
|
||||
test("\\51", "\\x29")
|
||||
|
||||
test("\\051", "\\x29")
|
||||
|
||||
test("\\175", "\\x7d")
|
||||
|
||||
test("\\04", "\\x04")
|
||||
|
||||
test(`<%([\s\S]+?)%>`, `<%([\s\S]+?)%>`)
|
||||
|
||||
test(`(.)^`, "(.)^")
|
||||
|
||||
test(`<%-([\s\S]+?)%>|<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$`, `<%-([\s\S]+?)%>|<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$`)
|
||||
|
||||
test(`\$`, `\$`)
|
||||
|
||||
test(`[G-b]`, `[G-b]`)
|
||||
|
||||
test(`[G-b\0]`, `[G-b\0]`)
|
||||
}
|
||||
|
||||
test("", "")
|
||||
|
||||
test("abc", "abc")
|
||||
|
||||
test(`\abc`, `abc`)
|
||||
|
||||
test(`\a\b\c`, `a\bc`)
|
||||
|
||||
test(`\x`, `x`)
|
||||
|
||||
test(`\c`, `c`)
|
||||
|
||||
test(`\cA`, `\x01`)
|
||||
|
||||
test(`\cz`, `\x1a`)
|
||||
|
||||
test(`\ca`, `\x01`)
|
||||
|
||||
test(`\cj`, `\x0a`)
|
||||
|
||||
test(`\ck`, `\x0b`)
|
||||
|
||||
test(`\+`, `\+`)
|
||||
|
||||
test(`[\b]`, `[\x08]`)
|
||||
|
||||
test(`\u0z01\x\undefined`, `u0z01xundefined`)
|
||||
|
||||
test(`\\|'|\r|\n|\t|\u2028|\u2029`, `\\|'|\r|\n|\t|\x{2028}|\x{2029}`)
|
||||
|
||||
test("]", "]")
|
||||
|
||||
test("}", "}")
|
||||
|
||||
test("%", "%")
|
||||
|
||||
test("(%)", "(%)")
|
||||
|
||||
test("(?:[%\\s])", "(?:[%\\s])")
|
||||
|
||||
test("[[]", "[[]")
|
||||
|
||||
test("\\101", "\\x41")
|
||||
|
||||
test("\\51", "\\x29")
|
||||
|
||||
test("\\051", "\\x29")
|
||||
|
||||
test("\\175", "\\x7d")
|
||||
|
||||
test("\\04", "\\x04")
|
||||
|
||||
test(`<%([\s\S]+?)%>`, `<%([\s\S]+?)%>`)
|
||||
|
||||
test(`(.)^`, "(.)^")
|
||||
|
||||
test(`<%-([\s\S]+?)%>|<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$`, `<%-([\s\S]+?)%>|<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$`)
|
||||
|
||||
test(`\$`, `\$`)
|
||||
|
||||
test(`[G-b]`, `[G-b]`)
|
||||
|
||||
test(`[G-b\0]`, `[G-b\0]`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTransformRegExp(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
pattern, err := TransformRegExp(`\s+abc\s+`)
|
||||
Is(err, nil)
|
||||
Is(pattern, `\s+abc\s+`)
|
||||
Is(regexp.MustCompile(pattern).MatchString("\t abc def"), true)
|
||||
tt(t, func() {
|
||||
pattern, err := TransformRegExp(`\s+abc\s+`)
|
||||
is(err, nil)
|
||||
is(pattern, `\s+abc\s+`)
|
||||
is(regexp.MustCompile(pattern).MatchString("\t abc def"), true)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPersistence(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
_, test := runTestWithOtto()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
function abc() { return 1; }
|
||||
abc.toString();
|
||||
`, "function abc() { return 1; }")
|
||||
|
||||
test(`
|
||||
test(`
|
||||
function def() { return 3.14159; }
|
||||
[ abc.toString(), def.toString() ];
|
||||
`, "function abc() { return 1; },function def() { return 3.14159; }")
|
||||
|
||||
test(`
|
||||
test(`
|
||||
eval("function ghi() { return 'ghi' }");
|
||||
[ abc.toString(), def.toString(), ghi.toString() ];
|
||||
`, "function abc() { return 1; },function def() { return 3.14159; },function ghi() { return 'ghi' }")
|
||||
|
||||
test(`
|
||||
test(`
|
||||
[ abc.toString(), def.toString(), ghi.toString() ];
|
||||
`, "function abc() { return 1; },function def() { return 3.14159; },function ghi() { return 'ghi' }")
|
||||
|
||||
test(`/*
|
||||
test(`/*
|
||||
|
||||
|
||||
|
||||
@@ -40,4 +38,5 @@ func TestPersistence(t *testing.T) {
|
||||
|
||||
|
||||
*/`, UndefinedValue())
|
||||
})
|
||||
}
|
||||
|
||||
579
reflect_test.go
579
reflect_test.go
@@ -1,7 +1,6 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"math"
|
||||
"reflect"
|
||||
"testing"
|
||||
@@ -43,370 +42,370 @@ func (t testStruct) FuncVarArgs(as ...string) int {
|
||||
}
|
||||
|
||||
func TestReflect(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
if false {
|
||||
return
|
||||
tt(t, func() {
|
||||
// Testing dbgf
|
||||
// These should panic
|
||||
toValue("Xyzzy").toReflectValue(reflect.Ptr)
|
||||
stringToReflectValue("Xyzzy", reflect.Ptr)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_reflectStruct(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
_, test := runTestWithOtto()
|
||||
// testStruct
|
||||
{
|
||||
abc := &testStruct{}
|
||||
vm.Set("abc", abc)
|
||||
|
||||
// testStruct
|
||||
{
|
||||
abc := &testStruct{}
|
||||
failSet("abc", abc)
|
||||
test(`
|
||||
abc.FuncPointerReciever();
|
||||
`, "abc")
|
||||
|
||||
test(`
|
||||
abc.FuncPointerReciever();
|
||||
`, "abc")
|
||||
test(`
|
||||
[ abc.Abc, abc.Ghi ];
|
||||
`, "false,")
|
||||
|
||||
test(`
|
||||
[ abc.Abc, abc.Ghi ];
|
||||
`, "false,")
|
||||
abc.Abc = true
|
||||
abc.Ghi = "Nothing happens."
|
||||
|
||||
abc.Abc = true
|
||||
abc.Ghi = "Nothing happens."
|
||||
test(`
|
||||
[ abc.Abc, abc.Ghi ];
|
||||
`, "true,Nothing happens.")
|
||||
|
||||
test(`
|
||||
[ abc.Abc, abc.Ghi ];
|
||||
`, "true,Nothing happens.")
|
||||
*abc = testStruct{}
|
||||
|
||||
*abc = testStruct{}
|
||||
test(`
|
||||
[ abc.Abc, abc.Ghi ];
|
||||
`, "false,")
|
||||
|
||||
test(`
|
||||
[ abc.Abc, abc.Ghi ];
|
||||
`, "false,")
|
||||
abc.Abc = true
|
||||
abc.Ghi = "Xyzzy"
|
||||
vm.Set("abc", abc)
|
||||
|
||||
abc.Abc = true
|
||||
abc.Ghi = "Xyzzy"
|
||||
failSet("abc", abc)
|
||||
test(`
|
||||
[ abc.Abc, abc.Ghi ];
|
||||
`, "true,Xyzzy")
|
||||
|
||||
test(`
|
||||
[ abc.Abc, abc.Ghi ];
|
||||
`, "true,Xyzzy")
|
||||
is(abc.Abc, true)
|
||||
test(`
|
||||
abc.Abc = false;
|
||||
abc.Def = 451;
|
||||
abc.Ghi = "Nothing happens.";
|
||||
abc.abc = "Something happens.";
|
||||
[ abc.Def, abc.abc ];
|
||||
`, "451,Something happens.")
|
||||
is(abc.Abc, false)
|
||||
is(abc.Def, 451)
|
||||
is(abc.Ghi, "Nothing happens.")
|
||||
|
||||
Is(abc.Abc, true)
|
||||
test(`
|
||||
abc.Abc = false;
|
||||
abc.Def = 451;
|
||||
abc.Ghi = "Nothing happens.";
|
||||
abc.abc = "Something happens.";
|
||||
[ abc.Def, abc.abc ];
|
||||
`, "451,Something happens.")
|
||||
Is(abc.Abc, false)
|
||||
Is(abc.Def, 451)
|
||||
Is(abc.Ghi, "Nothing happens.")
|
||||
test(`
|
||||
delete abc.Def;
|
||||
delete abc.abc;
|
||||
[ abc.Def, abc.abc ];
|
||||
`, "451,")
|
||||
is(abc.Def, 451)
|
||||
|
||||
test(`
|
||||
delete abc.Def;
|
||||
delete abc.abc;
|
||||
[ abc.Def, abc.abc ];
|
||||
`, "451,")
|
||||
Is(abc.Def, 451)
|
||||
test(`
|
||||
abc.FuncNoArgsNoRet();
|
||||
`, "undefined")
|
||||
test(`
|
||||
abc.FuncNoArgs();
|
||||
`, "abc")
|
||||
test(`
|
||||
abc.FuncOneArgs("abc");
|
||||
`, "abc")
|
||||
test(`
|
||||
abc.FuncMultArgs("abc", "def");
|
||||
`, "abcdef")
|
||||
test(`
|
||||
abc.FuncVarArgs("abc", "def", "ghi");
|
||||
`, 3)
|
||||
|
||||
test(`
|
||||
abc.FuncNoArgsNoRet();
|
||||
`, "undefined")
|
||||
test(`
|
||||
abc.FuncNoArgs();
|
||||
`, "abc")
|
||||
test(`
|
||||
abc.FuncOneArgs("abc");
|
||||
`, "abc")
|
||||
test(`
|
||||
abc.FuncMultArgs("abc", "def");
|
||||
`, "abcdef")
|
||||
test(`
|
||||
abc.FuncVarArgs("abc", "def", "ghi");
|
||||
`, "3")
|
||||
|
||||
test(`raise:
|
||||
abc.FuncNoArgsMultRet();
|
||||
`, "TypeError")
|
||||
}
|
||||
test(`raise:
|
||||
abc.FuncNoArgsMultRet();
|
||||
`, "TypeError")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_reflectMap(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
_, test := runTestWithOtto()
|
||||
// map[string]string
|
||||
{
|
||||
abc := map[string]string{
|
||||
"Xyzzy": "Nothing happens.",
|
||||
"def": "1",
|
||||
}
|
||||
vm.Set("abc", abc)
|
||||
|
||||
// map[string]string
|
||||
{
|
||||
abc := map[string]string{
|
||||
"Xyzzy": "Nothing happens.",
|
||||
"def": "1",
|
||||
test(`
|
||||
abc.xyz = "pqr";
|
||||
[ abc.Xyzzy, abc.def, abc.ghi ];
|
||||
`, "Nothing happens.,1,")
|
||||
|
||||
is(abc["xyz"], "pqr")
|
||||
}
|
||||
failSet("abc", abc)
|
||||
|
||||
test(`
|
||||
abc.xyz = "pqr";
|
||||
[ abc.Xyzzy, abc.def, abc.ghi ];
|
||||
`, "Nothing happens.,1,")
|
||||
// map[string]float64
|
||||
{
|
||||
abc := map[string]float64{
|
||||
"Xyzzy": math.Pi,
|
||||
"def": 1,
|
||||
}
|
||||
vm.Set("abc", abc)
|
||||
|
||||
Is(abc["xyz"], "pqr")
|
||||
}
|
||||
test(`
|
||||
abc.xyz = "pqr";
|
||||
abc.jkl = 10;
|
||||
[ abc.Xyzzy, abc.def, abc.ghi ];
|
||||
`, "3.141592653589793,1,")
|
||||
|
||||
// map[string]float64
|
||||
{
|
||||
abc := map[string]float64{
|
||||
"Xyzzy": math.Pi,
|
||||
"def": 1,
|
||||
is(abc["xyz"], math.NaN())
|
||||
is(abc["jkl"], float64(10))
|
||||
}
|
||||
failSet("abc", abc)
|
||||
|
||||
test(`
|
||||
abc.xyz = "pqr";
|
||||
abc.jkl = 10;
|
||||
[ abc.Xyzzy, abc.def, abc.ghi ];
|
||||
`, "3.141592653589793,1,")
|
||||
// map[string]int32
|
||||
{
|
||||
abc := map[string]int32{
|
||||
"Xyzzy": 3,
|
||||
"def": 1,
|
||||
}
|
||||
vm.Set("abc", abc)
|
||||
|
||||
Is(abc["xyz"], "NaN")
|
||||
Is(abc["jkl"], float64(10))
|
||||
}
|
||||
test(`
|
||||
abc.xyz = "pqr";
|
||||
abc.jkl = 10;
|
||||
[ abc.Xyzzy, abc.def, abc.ghi ];
|
||||
`, "3,1,")
|
||||
|
||||
// map[string]int32
|
||||
{
|
||||
abc := map[string]int32{
|
||||
"Xyzzy": 3,
|
||||
"def": 1,
|
||||
is(abc["xyz"], 0)
|
||||
is(abc["jkl"], int32(10))
|
||||
|
||||
test(`
|
||||
delete abc["Xyzzy"];
|
||||
`)
|
||||
|
||||
_, exists := abc["Xyzzy"]
|
||||
is(exists, false)
|
||||
is(abc["Xyzzy"], 0)
|
||||
}
|
||||
failSet("abc", abc)
|
||||
|
||||
test(`
|
||||
abc.xyz = "pqr";
|
||||
abc.jkl = 10;
|
||||
[ abc.Xyzzy, abc.def, abc.ghi ];
|
||||
`, "3,1,")
|
||||
// map[int32]string
|
||||
{
|
||||
abc := map[int32]string{
|
||||
0: "abc",
|
||||
1: "def",
|
||||
}
|
||||
vm.Set("abc", abc)
|
||||
|
||||
Is(abc["xyz"], 0)
|
||||
Is(abc["jkl"], int32(10))
|
||||
test(`
|
||||
abc[2] = "pqr";
|
||||
//abc.jkl = 10;
|
||||
abc[3] = 10;
|
||||
[ abc[0], abc[1], abc[2], abc[3] ]
|
||||
`, "abc,def,pqr,10")
|
||||
|
||||
test(`
|
||||
delete abc["Xyzzy"];
|
||||
`)
|
||||
is(abc[2], "pqr")
|
||||
is(abc[3], "10")
|
||||
|
||||
_, exists := abc["Xyzzy"]
|
||||
IsFalse(exists)
|
||||
Is(abc["Xyzzy"], 0)
|
||||
}
|
||||
test(`
|
||||
delete abc[2];
|
||||
`)
|
||||
|
||||
// map[int32]string
|
||||
{
|
||||
abc := map[int32]string{
|
||||
0: "abc",
|
||||
1: "def",
|
||||
_, exists := abc[2]
|
||||
is(exists, false)
|
||||
}
|
||||
failSet("abc", abc)
|
||||
|
||||
test(`
|
||||
abc[2] = "pqr";
|
||||
//abc.jkl = 10;
|
||||
abc[3] = 10;
|
||||
[ abc[0], abc[1], abc[2], abc[3] ]
|
||||
`, "abc,def,pqr,10")
|
||||
|
||||
Is(abc[2], "pqr")
|
||||
Is(abc[3], "10")
|
||||
|
||||
test(`
|
||||
delete abc[2];
|
||||
`)
|
||||
|
||||
_, exists := abc[2]
|
||||
IsFalse(exists)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func Test_reflectSlice(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
_, test := runTestWithOtto()
|
||||
// []bool
|
||||
{
|
||||
abc := []bool{
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
}
|
||||
vm.Set("abc", abc)
|
||||
|
||||
// []bool
|
||||
{
|
||||
abc := []bool{
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
test(`
|
||||
abc;
|
||||
`, "false,true,true,false")
|
||||
|
||||
test(`
|
||||
abc[0] = true;
|
||||
abc[abc.length-1] = true;
|
||||
delete abc[2];
|
||||
abc;
|
||||
`, "true,true,false,true")
|
||||
|
||||
is(abc, []bool{true, true, false, true})
|
||||
is(abc[len(abc)-1], true)
|
||||
}
|
||||
failSet("abc", abc)
|
||||
|
||||
test(`
|
||||
abc;
|
||||
`, "false,true,true,false")
|
||||
// []int32
|
||||
{
|
||||
abc := make([]int32, 4)
|
||||
vm.Set("abc", abc)
|
||||
|
||||
test(`
|
||||
abc[0] = true;
|
||||
abc[abc.length-1] = true;
|
||||
delete abc[2];
|
||||
abc;
|
||||
`, "true,true,false,true")
|
||||
test(`
|
||||
abc;
|
||||
`, "0,0,0,0")
|
||||
|
||||
Is(abc, []bool{true, true, false, true})
|
||||
Is(abc[len(abc)-1], true)
|
||||
}
|
||||
test(`
|
||||
abc[0] = 4.2;
|
||||
abc[1] = "42";
|
||||
abc[2] = 3.14;
|
||||
abc;
|
||||
`, "4,42,3,0")
|
||||
|
||||
// []int32
|
||||
{
|
||||
abc := make([]int32, 4)
|
||||
failSet("abc", abc)
|
||||
is(abc, []int32{4, 42, 3, 0})
|
||||
|
||||
test(`
|
||||
abc;
|
||||
`, "0,0,0,0")
|
||||
|
||||
test(`
|
||||
abc[0] = 4.2;
|
||||
abc[1] = "42";
|
||||
abc[2] = 3.14;
|
||||
abc;
|
||||
`, "4,42,3,0")
|
||||
|
||||
Is(abc, []int32{4, 42, 3, 0})
|
||||
|
||||
test(`
|
||||
delete abc[1];
|
||||
delete abc[2];
|
||||
`)
|
||||
Is(abc[1], 0)
|
||||
Is(abc[2], 0)
|
||||
}
|
||||
test(`
|
||||
delete abc[1];
|
||||
delete abc[2];
|
||||
`)
|
||||
is(abc[1], 0)
|
||||
is(abc[2], 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_reflectArray(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
_, test := runTestWithOtto()
|
||||
// []bool
|
||||
{
|
||||
abc := [4]bool{
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
}
|
||||
vm.Set("abc", abc)
|
||||
|
||||
// []bool
|
||||
{
|
||||
abc := [4]bool{
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
test(`
|
||||
abc;
|
||||
`, "false,true,true,false")
|
||||
// Unaddressable array
|
||||
|
||||
test(`
|
||||
abc[0] = true;
|
||||
abc[abc.length-1] = true;
|
||||
abc;
|
||||
`, "false,true,true,false")
|
||||
// Again, unaddressable array
|
||||
|
||||
is(abc, [4]bool{false, true, true, false})
|
||||
is(abc[len(abc)-1], false)
|
||||
// ...
|
||||
}
|
||||
failSet("abc", abc)
|
||||
|
||||
test(`
|
||||
abc;
|
||||
`, "false,true,true,false")
|
||||
// Unaddressable array
|
||||
// []int32
|
||||
{
|
||||
abc := make([]int32, 4)
|
||||
vm.Set("abc", abc)
|
||||
|
||||
test(`
|
||||
abc[0] = true;
|
||||
abc[abc.length-1] = true;
|
||||
abc;
|
||||
`, "false,true,true,false")
|
||||
// Again, unaddressable array
|
||||
test(`
|
||||
abc;
|
||||
`, "0,0,0,0")
|
||||
|
||||
Is(abc, [4]bool{false, true, true, false})
|
||||
Is(abc[len(abc)-1], false)
|
||||
// ...
|
||||
}
|
||||
test(`
|
||||
abc[0] = 4.2;
|
||||
abc[1] = "42";
|
||||
abc[2] = 3.14;
|
||||
abc;
|
||||
`, "4,42,3,0")
|
||||
|
||||
// []int32
|
||||
{
|
||||
abc := make([]int32, 4)
|
||||
failSet("abc", abc)
|
||||
|
||||
test(`
|
||||
abc;
|
||||
`, "0,0,0,0")
|
||||
|
||||
test(`
|
||||
abc[0] = 4.2;
|
||||
abc[1] = "42";
|
||||
abc[2] = 3.14;
|
||||
abc;
|
||||
`, "4,42,3,0")
|
||||
|
||||
Is(abc, []int32{4, 42, 3, 0})
|
||||
}
|
||||
|
||||
// []bool
|
||||
{
|
||||
abc := [4]bool{
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
is(abc, []int32{4, 42, 3, 0})
|
||||
}
|
||||
failSet("abc", &abc)
|
||||
|
||||
test(`
|
||||
abc;
|
||||
`, "false,true,true,false")
|
||||
// []bool
|
||||
{
|
||||
abc := [4]bool{
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
}
|
||||
vm.Set("abc", &abc)
|
||||
|
||||
test(`
|
||||
abc[0] = true;
|
||||
abc[abc.length-1] = true;
|
||||
delete abc[2];
|
||||
abc;
|
||||
`, "true,true,false,true")
|
||||
test(`
|
||||
abc;
|
||||
`, "false,true,true,false")
|
||||
|
||||
Is(abc, [4]bool{true, true, false, true})
|
||||
Is(abc[len(abc)-1], true)
|
||||
}
|
||||
test(`
|
||||
abc[0] = true;
|
||||
abc[abc.length-1] = true;
|
||||
delete abc[2];
|
||||
abc;
|
||||
`, "true,true,false,true")
|
||||
|
||||
is(abc, [4]bool{true, true, false, true})
|
||||
is(abc[len(abc)-1], true)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func Test_reflectArray_concat(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
_, test := runTestWithOtto()
|
||||
failSet("ghi", []string{"jkl", "mno"})
|
||||
failSet("pqr", []interface{}{"jkl", 42, 3.14159, true})
|
||||
test(`
|
||||
var def = {
|
||||
"abc": ["abc"],
|
||||
"xyz": ["xyz"]
|
||||
};
|
||||
xyz = pqr.concat(ghi, def.abc, def, def.xyz);
|
||||
[ xyz, xyz.length ];
|
||||
`, "jkl,42,3.14159,true,jkl,mno,abc,[object Object],xyz,9")
|
||||
vm.Set("ghi", []string{"jkl", "mno"})
|
||||
vm.Set("pqr", []interface{}{"jkl", 42, 3.14159, true})
|
||||
test(`
|
||||
var def = {
|
||||
"abc": ["abc"],
|
||||
"xyz": ["xyz"]
|
||||
};
|
||||
xyz = pqr.concat(ghi, def.abc, def, def.xyz);
|
||||
[ xyz, xyz.length ];
|
||||
`, "jkl,42,3.14159,true,jkl,mno,abc,[object Object],xyz,9")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_reflectMapInterface(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
_, test := runTestWithOtto()
|
||||
{
|
||||
abc := map[string]interface{}{
|
||||
"Xyzzy": "Nothing happens.",
|
||||
"def": "1",
|
||||
"jkl": "jkl",
|
||||
}
|
||||
vm.Set("abc", abc)
|
||||
vm.Set("mno", &testStruct{})
|
||||
|
||||
{
|
||||
abc := map[string]interface{}{
|
||||
"Xyzzy": "Nothing happens.",
|
||||
"def": "1",
|
||||
"jkl": "jkl",
|
||||
test(`
|
||||
abc.xyz = "pqr";
|
||||
abc.ghi = {};
|
||||
abc.jkl = 3.14159;
|
||||
abc.mno = mno;
|
||||
mno.Abc = true;
|
||||
mno.Ghi = "Something happens.";
|
||||
[ abc.Xyzzy, abc.def, abc.ghi, abc.mno ];
|
||||
`, "Nothing happens.,1,[object Object],[object Object]")
|
||||
|
||||
is(abc["xyz"], "pqr")
|
||||
is(abc["ghi"], "[object Object]")
|
||||
is(abc["jkl"], float64(3.14159))
|
||||
mno, valid := abc["mno"].(*testStruct)
|
||||
is(valid, true)
|
||||
is(mno.Abc, true)
|
||||
is(mno.Ghi, "Something happens.")
|
||||
}
|
||||
failSet("abc", abc)
|
||||
failSet("mno", &testStruct{})
|
||||
|
||||
test(`
|
||||
abc.xyz = "pqr";
|
||||
abc.ghi = {};
|
||||
abc.jkl = 3.14159;
|
||||
abc.mno = mno;
|
||||
mno.Abc = true;
|
||||
mno.Ghi = "Something happens.";
|
||||
[ abc.Xyzzy, abc.def, abc.ghi, abc.mno ];
|
||||
`, "Nothing happens.,1,[object Object],[object Object]")
|
||||
|
||||
Is(abc["xyz"], "pqr")
|
||||
Is(abc["ghi"], "[object Object]")
|
||||
Equal(abc["jkl"], float64(3.14159))
|
||||
mno, valid := abc["mno"].(*testStruct)
|
||||
Is(valid, true)
|
||||
Is(mno.Abc, true)
|
||||
Is(mno.Ghi, "Something happens.")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
394
regexp_test.go
394
regexp_test.go
@@ -1,275 +1,287 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegExp(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
[
|
||||
/abc/.toString(),
|
||||
/abc/gim.toString(),
|
||||
""+/abc/gi.toString(),
|
||||
new RegExp("1(\\d+)").toString(),
|
||||
];
|
||||
`, "/abc/,/abc/gim,/abc/gi,/1(\\d+)/")
|
||||
|
||||
test(`
|
||||
[
|
||||
/abc/.toString(),
|
||||
/abc/gim.toString(),
|
||||
""+/abc/gi.toString(),
|
||||
new RegExp("1(\\d+)").toString(),
|
||||
];
|
||||
`, "/abc/,/abc/gim,/abc/gi,/1(\\d+)/")
|
||||
test(`
|
||||
[
|
||||
new RegExp("abc").exec("123abc456"),
|
||||
null === new RegExp("xyzzy").exec("123abc456"),
|
||||
new RegExp("1(\\d+)").exec("123abc456"),
|
||||
new RegExp("xyzzy").test("123abc456"),
|
||||
new RegExp("1(\\d+)").test("123abc456"),
|
||||
new RegExp("abc").exec("123abc456"),
|
||||
];
|
||||
`, "abc,true,123,23,false,true,abc")
|
||||
|
||||
test(`
|
||||
[
|
||||
new RegExp("abc").exec("123abc456"),
|
||||
null === new RegExp("xyzzy").exec("123abc456"),
|
||||
new RegExp("1(\\d+)").exec("123abc456"),
|
||||
new RegExp("xyzzy").test("123abc456"),
|
||||
new RegExp("1(\\d+)").test("123abc456"),
|
||||
new RegExp("abc").exec("123abc456"),
|
||||
];
|
||||
`, "abc,true,123,23,false,true,abc")
|
||||
test(`new RegExp("abc").toString()`, "/abc/")
|
||||
test(`new RegExp("abc", "g").toString()`, "/abc/g")
|
||||
test(`new RegExp("abc", "mig").toString()`, "/abc/gim")
|
||||
|
||||
test(`new RegExp("abc").toString()`, "/abc/")
|
||||
test(`new RegExp("abc", "g").toString()`, "/abc/g")
|
||||
test(`new RegExp("abc", "mig").toString()`, "/abc/gim")
|
||||
result := test(`/(a)?/.exec('b')`, ",")
|
||||
is(result._object().get("0"), "")
|
||||
is(result._object().get("1"), "undefined")
|
||||
is(result._object().get("length"), 2)
|
||||
|
||||
result := test(`/(a)?/.exec('b')`, ",")
|
||||
Is(result._object().get("0"), "")
|
||||
Is(result._object().get("1"), "undefined")
|
||||
Is(result._object().get("length"), "2")
|
||||
result = test(`/(a)?(b)?/.exec('b')`, "b,,b")
|
||||
is(result._object().get("0"), "b")
|
||||
is(result._object().get("1"), "undefined")
|
||||
is(result._object().get("2"), "b")
|
||||
is(result._object().get("length"), 3)
|
||||
|
||||
result = test(`/(a)?(b)?/.exec('b')`, "b,,b")
|
||||
Is(result._object().get("0"), "b")
|
||||
Is(result._object().get("1"), "undefined")
|
||||
Is(result._object().get("2"), "b")
|
||||
Is(result._object().get("length"), "3")
|
||||
test(`/\u0041/.source`, "\\u0041")
|
||||
test(`/\a/.source`, "\\a")
|
||||
test(`/\;/.source`, "\\;")
|
||||
|
||||
test(`/\u0041/.source`, "\\u0041")
|
||||
test(`/\a/.source`, "\\a")
|
||||
test(`/\;/.source`, "\\;")
|
||||
test(`/a\a/.source`, "a\\a")
|
||||
test(`/,\;/.source`, ",\\;")
|
||||
test(`/ \ /.source`, " \\ ")
|
||||
|
||||
test(`/a\a/.source`, "a\\a")
|
||||
test(`/,\;/.source`, ",\\;")
|
||||
test(`/ \ /.source`, " \\ ")
|
||||
// Start sanity check...
|
||||
test("eval(\"/abc/\").source", "abc")
|
||||
test("eval(\"/\u0023/\").source", "#")
|
||||
test("eval(\"/\u0058/\").source", "X")
|
||||
test("eval(\"/\\\u0023/\").source == \"\\\u0023\"", true)
|
||||
test("'0x' + '0058'", "0x0058")
|
||||
test("'\\\\' + '0x' + '0058'", "\\0x0058")
|
||||
// ...stop sanity check
|
||||
|
||||
// Start sanity check...
|
||||
test("eval(\"/abc/\").source", "abc")
|
||||
test("eval(\"/\u0023/\").source", "#")
|
||||
test("eval(\"/\u0058/\").source", "X")
|
||||
test("eval(\"/\\\u0023/\").source == \"\\\u0023\"", "true")
|
||||
test("'0x' + '0058'", "0x0058")
|
||||
test("'\\\\' + '0x' + '0058'", "\\0x0058")
|
||||
// ...stop sanity check
|
||||
test(`abc = '\\' + String.fromCharCode('0x' + '0058'); eval('/' + abc + '/').source`, "\\X")
|
||||
test(`abc = '\\' + String.fromCharCode('0x0058'); eval('/' + abc + '/').source == "\\\u0058"`, true)
|
||||
test(`abc = '\\' + String.fromCharCode('0x0023'); eval('/' + abc + '/').source == "\\\u0023"`, true)
|
||||
test(`abc = '\\' + String.fromCharCode('0x0078'); eval('/' + abc + '/').source == "\\\u0078"`, true)
|
||||
|
||||
test(`abc = '\\' + String.fromCharCode('0x' + '0058'); eval('/' + abc + '/').source`, "\\X")
|
||||
test(`abc = '\\' + String.fromCharCode('0x0058'); eval('/' + abc + '/').source == "\\\u0058"`, "true")
|
||||
test(`abc = '\\' + String.fromCharCode('0x0023'); eval('/' + abc + '/').source == "\\\u0023"`, "true")
|
||||
test(`abc = '\\' + String.fromCharCode('0x0078'); eval('/' + abc + '/').source == "\\\u0078"`, "true")
|
||||
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(RegExp, "prototype");
|
||||
[ [ typeof RegExp.prototype ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "object,false,false,false")
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(RegExp, "prototype");
|
||||
[ [ typeof RegExp.prototype ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "object,false,false,false")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_global(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
var abc = /(?:ab|cd)\d?/g;
|
||||
var found = [];
|
||||
do {
|
||||
match = abc.exec("ab cd2 ab34 cd");
|
||||
if (match !== null) {
|
||||
found.push(match[0]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
found;
|
||||
`, "ab,cd2,ab3,cd")
|
||||
test(`
|
||||
var abc = /(?:ab|cd)\d?/g;
|
||||
var found = [];
|
||||
do {
|
||||
match = abc.exec("ab cd2 ab34 cd");
|
||||
if (match !== null) {
|
||||
found.push(match[0]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
found;
|
||||
`, "ab,cd2,ab3,cd")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_exec(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = /./g;
|
||||
def = '123456';
|
||||
ghi = 0;
|
||||
while (ghi < 100 && abc.exec(def) !== null) {
|
||||
ghi += 1;
|
||||
}
|
||||
[ ghi, def.length, ghi == def.length ];
|
||||
`, "6,6,true")
|
||||
test(`
|
||||
abc = /./g;
|
||||
def = '123456';
|
||||
ghi = 0;
|
||||
while (ghi < 100 && abc.exec(def) !== null) {
|
||||
ghi += 1;
|
||||
}
|
||||
[ ghi, def.length, ghi == def.length ];
|
||||
`, "6,6,true")
|
||||
|
||||
test(`
|
||||
abc = /[abc](\d)?/g;
|
||||
def = 'a0 b c1 d3';
|
||||
ghi = 0;
|
||||
lastIndex = 0;
|
||||
while (ghi < 100 && abc.exec(def) !== null) {
|
||||
lastIndex = abc.lastIndex;
|
||||
ghi += 1;
|
||||
test(`
|
||||
abc = /[abc](\d)?/g;
|
||||
def = 'a0 b c1 d3';
|
||||
ghi = 0;
|
||||
lastIndex = 0;
|
||||
while (ghi < 100 && abc.exec(def) !== null) {
|
||||
lastIndex = abc.lastIndex;
|
||||
ghi += 1;
|
||||
|
||||
}
|
||||
[ ghi, lastIndex ];
|
||||
`, "3,7")
|
||||
}
|
||||
[ ghi, lastIndex ];
|
||||
`, "3,7")
|
||||
|
||||
test(`
|
||||
var abc = /[abc](\d)?/.exec("a0 b c1 d3");
|
||||
[ abc.length, abc.input, abc.index, abc ];
|
||||
`, "2,a0 b c1 d3,0,a0,0")
|
||||
test(`
|
||||
var abc = /[abc](\d)?/.exec("a0 b c1 d3");
|
||||
[ abc.length, abc.input, abc.index, abc ];
|
||||
`, "2,a0 b c1 d3,0,a0,0")
|
||||
|
||||
test(`raise:
|
||||
var exec = RegExp.prototype.exec;
|
||||
exec("Xyzzy");
|
||||
`, "TypeError: Calling RegExp.exec on a non-RegExp object")
|
||||
test(`raise:
|
||||
var exec = RegExp.prototype.exec;
|
||||
exec("Xyzzy");
|
||||
`, "TypeError: Calling RegExp.exec on a non-RegExp object")
|
||||
|
||||
test(`
|
||||
var abc = /\w{3}\d?/.exec("CE\uFFFFL\uFFDDbox127");
|
||||
[ abc.input.length, abc.length, abc.input, abc.index, abc ];
|
||||
`, "11,1,CE\uFFFFL\uFFDDbox127,5,box1")
|
||||
test(`
|
||||
var abc = /\w{3}\d?/.exec("CE\uFFFFL\uFFDDbox127");
|
||||
[ abc.input.length, abc.length, abc.input, abc.index, abc ];
|
||||
`, "11,1,CE\uFFFFL\uFFDDbox127,5,box1")
|
||||
|
||||
test(`RegExp.prototype.exec.length`, "1")
|
||||
test(`RegExp.prototype.exec.prototype`, "undefined")
|
||||
test(`RegExp.prototype.exec.length`, 1)
|
||||
test(`RegExp.prototype.exec.prototype`, "undefined")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_test(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`RegExp.prototype.test.length`, "1")
|
||||
test(`RegExp.prototype.test.prototype`, "undefined")
|
||||
test(`RegExp.prototype.test.length`, 1)
|
||||
test(`RegExp.prototype.test.prototype`, "undefined")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_toString(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`RegExp.prototype.toString.length`, "0")
|
||||
test(`RegExp.prototype.toString.prototype`, "undefined")
|
||||
test(`RegExp.prototype.toString.length`, 0)
|
||||
test(`RegExp.prototype.toString.prototype`, "undefined")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_zaacbbbcac(t *testing.T) {
|
||||
Terst(t)
|
||||
return
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
if false {
|
||||
// FIXME? TODO /(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac")
|
||||
test(`
|
||||
var abc = /(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac");
|
||||
[ abc.length, abc.index, abc ];
|
||||
`, "6,0,zaacbbbcac,z,ac,a,,c")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExpCopying(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = /xyzzy/i;
|
||||
def = RegExp(abc);
|
||||
abc.indicator = 1;
|
||||
[ abc.indicator, def.indicator ];
|
||||
`, "1,1")
|
||||
test(`
|
||||
abc = /xyzzy/i;
|
||||
def = RegExp(abc);
|
||||
abc.indicator = 1;
|
||||
[ abc.indicator, def.indicator ];
|
||||
`, "1,1")
|
||||
|
||||
test(`raise:
|
||||
RegExp(new RegExp("\\d"), "1");
|
||||
`, "TypeError: Cannot supply flags when constructing one RegExp from another")
|
||||
test(`raise:
|
||||
RegExp(new RegExp("\\d"), "1");
|
||||
`, "TypeError: Cannot supply flags when constructing one RegExp from another")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_multiline(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
var abc = /s$/m.exec("pairs\nmakes\tdouble");
|
||||
[ abc.length, abc.index, abc ];
|
||||
`, "1,4,s")
|
||||
test(`
|
||||
var abc = /s$/m.exec("pairs\nmakes\tdouble");
|
||||
[ abc.length, abc.index, abc ];
|
||||
`, "1,4,s")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_source(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
[ /xyzzy/i.source, /./i.source ];
|
||||
`, "xyzzy,.")
|
||||
test(`
|
||||
[ /xyzzy/i.source, /./i.source ];
|
||||
`, "xyzzy,.")
|
||||
|
||||
test(`
|
||||
var abc = /./i;
|
||||
var def = new RegExp(abc);
|
||||
[ abc.source, def.source, abc.source === def.source ];
|
||||
`, ".,.,true")
|
||||
test(`
|
||||
var abc = /./i;
|
||||
var def = new RegExp(abc);
|
||||
[ abc.source, def.source, abc.source === def.source ];
|
||||
`, ".,.,true")
|
||||
|
||||
test(`
|
||||
var abc = /./i;
|
||||
var def = abc.hasOwnProperty("source");
|
||||
var ghi = abc.source;
|
||||
abc.source = "xyzzy";
|
||||
[ def, abc.source ];
|
||||
`, "true,.")
|
||||
test(`
|
||||
var abc = /./i;
|
||||
var def = abc.hasOwnProperty("source");
|
||||
var ghi = abc.source;
|
||||
abc.source = "xyzzy";
|
||||
[ def, abc.source ];
|
||||
`, "true,.")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_newRegExp(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
Math.toString();
|
||||
var abc = new RegExp(Math,eval("\"g\""));
|
||||
[ abc, abc.global ];
|
||||
`, "/[object Math]/g,true")
|
||||
test(`
|
||||
Math.toString();
|
||||
var abc = new RegExp(Math,eval("\"g\""));
|
||||
[ abc, abc.global ];
|
||||
`, "/[object Math]/g,true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_flags(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
var abc = /./i;
|
||||
var def = new RegExp(abc);
|
||||
[ abc.multiline == def.multiline, abc.global == def.global, abc.ignoreCase == def.ignoreCase ];
|
||||
`, "true,true,true")
|
||||
test(`
|
||||
var abc = /./i;
|
||||
var def = new RegExp(abc);
|
||||
[ abc.multiline == def.multiline, abc.global == def.global, abc.ignoreCase == def.ignoreCase ];
|
||||
`, "true,true,true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_controlCharacter(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
for code := 0x41; code < 0x5a; code++ {
|
||||
string_ := string(code - 64)
|
||||
test(fmt.Sprintf(`
|
||||
var code = 0x%x;
|
||||
var string = String.fromCharCode(code %% 32);
|
||||
var result = (new RegExp("\\c" + String.fromCharCode(code))).exec(string);
|
||||
[ code, string, result ];
|
||||
`, code), fmt.Sprintf("%d,%s,%s", code, string_, string_))
|
||||
}
|
||||
for code := 0x41; code < 0x5a; code++ {
|
||||
string_ := string(code - 64)
|
||||
test(fmt.Sprintf(`
|
||||
var code = 0x%x;
|
||||
var string = String.fromCharCode(code %% 32);
|
||||
var result = (new RegExp("\\c" + String.fromCharCode(code))).exec(string);
|
||||
[ code, string, result ];
|
||||
`, code), fmt.Sprintf("%d,%s,%s", code, string_, string_))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_notNotEmptyCharacterClass(t *testing.T) {
|
||||
Terst(t)
|
||||
test := runTest()
|
||||
test(`
|
||||
var abc = /[\s\S]a/m.exec("a\naba");
|
||||
[ abc.length, abc.input, abc ];
|
||||
`, "1,a\naba,\na")
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`
|
||||
var abc = /[\s\S]a/m.exec("a\naba");
|
||||
[ abc.length, abc.input, abc ];
|
||||
`, "1,a\naba,\na")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegExp_compile(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
var abc = /[\s\S]a/;
|
||||
abc.compile('^\w+');
|
||||
`, "undefined")
|
||||
test(`
|
||||
var abc = /[\s\S]a/;
|
||||
abc.compile('^\w+');
|
||||
`, "undefined")
|
||||
})
|
||||
}
|
||||
|
||||
1253
runtime_test.go
1253
runtime_test.go
File diff suppressed because it is too large
Load Diff
117
script_test.go
117
script_test.go
@@ -1,77 +1,76 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScript(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
return
|
||||
|
||||
return
|
||||
vm := New()
|
||||
|
||||
vm := New()
|
||||
script, err := vm.Compile("xyzzy", `var abc; if (!abc) abc = 0; abc += 2; abc;`)
|
||||
is(err, nil)
|
||||
|
||||
script, err := vm.Compile("xyzzy", `var abc; if (!abc) abc = 0; abc += 2; abc;`)
|
||||
Is(err, nil)
|
||||
|
||||
str := script.String()
|
||||
Is(str, "// xyzzy\nvar abc; if (!abc) abc = 0; abc += 2; abc;")
|
||||
|
||||
value, err := vm.Run(script)
|
||||
Is(err, nil)
|
||||
is(value, 2)
|
||||
|
||||
tmp, err := script.marshalBinary()
|
||||
Is(err, nil)
|
||||
Is(len(tmp), 1228)
|
||||
|
||||
{
|
||||
script := &Script{}
|
||||
err = script.unmarshalBinary(tmp)
|
||||
Is(err, nil)
|
||||
|
||||
Is(script.String(), str)
|
||||
|
||||
value, err = vm.Run(script)
|
||||
Is(err, nil)
|
||||
is(value, 4)
|
||||
|
||||
tmp, err = script.marshalBinary()
|
||||
Is(err, nil)
|
||||
Is(len(tmp), 1228)
|
||||
}
|
||||
|
||||
{
|
||||
script := &Script{}
|
||||
err = script.unmarshalBinary(tmp)
|
||||
Is(err, nil)
|
||||
|
||||
Is(script.String(), str)
|
||||
str := script.String()
|
||||
is(str, "// xyzzy\nvar abc; if (!abc) abc = 0; abc += 2; abc;")
|
||||
|
||||
value, err := vm.Run(script)
|
||||
Is(err, nil)
|
||||
is(value, 6)
|
||||
is(err, nil)
|
||||
is(value, 2)
|
||||
|
||||
tmp, err = script.marshalBinary()
|
||||
Is(err, nil)
|
||||
Is(len(tmp), 1228)
|
||||
}
|
||||
tmp, err := script.marshalBinary()
|
||||
is(err, nil)
|
||||
is(len(tmp), 1228)
|
||||
|
||||
{
|
||||
version := scriptVersion
|
||||
scriptVersion = "bogus"
|
||||
{
|
||||
script := &Script{}
|
||||
err = script.unmarshalBinary(tmp)
|
||||
is(err, nil)
|
||||
|
||||
script := &Script{}
|
||||
err = script.unmarshalBinary(tmp)
|
||||
Is(err, "version mismatch")
|
||||
is(script.String(), str)
|
||||
|
||||
Is(script.String(), "// \n")
|
||||
Is(script.version, "")
|
||||
Is(script.program == nil, true)
|
||||
Is(script.filename, "")
|
||||
Is(script.src, "")
|
||||
value, err = vm.Run(script)
|
||||
is(err, nil)
|
||||
is(value, 4)
|
||||
|
||||
scriptVersion = version
|
||||
}
|
||||
tmp, err = script.marshalBinary()
|
||||
is(err, nil)
|
||||
is(len(tmp), 1228)
|
||||
}
|
||||
|
||||
{
|
||||
script := &Script{}
|
||||
err = script.unmarshalBinary(tmp)
|
||||
is(err, nil)
|
||||
|
||||
is(script.String(), str)
|
||||
|
||||
value, err := vm.Run(script)
|
||||
is(err, nil)
|
||||
is(value, 6)
|
||||
|
||||
tmp, err = script.marshalBinary()
|
||||
is(err, nil)
|
||||
is(len(tmp), 1228)
|
||||
}
|
||||
|
||||
{
|
||||
version := scriptVersion
|
||||
scriptVersion = "bogus"
|
||||
|
||||
script := &Script{}
|
||||
err = script.unmarshalBinary(tmp)
|
||||
is(err, "version mismatch")
|
||||
|
||||
is(script.String(), "// \n")
|
||||
is(script.version, "")
|
||||
is(script.program == nil, true)
|
||||
is(script.filename, "")
|
||||
is(script.src, "")
|
||||
|
||||
scriptVersion = version
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
522
string_test.go
522
string_test.go
@@ -1,349 +1,365 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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")
|
||||
test(`"a\uFFFFbc".length`, "4")
|
||||
test(`String(+0)`, "0")
|
||||
test(`String(-0)`, "0")
|
||||
test(`""+-0`, "0")
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(String, "prototype");
|
||||
[ [ typeof String.prototype ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "object,false,false,false")
|
||||
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)
|
||||
test(`"a\uFFFFbc".length`, 4)
|
||||
test(`String(+0)`, "0")
|
||||
test(`String(-0)`, "0")
|
||||
test(`""+-0`, "0")
|
||||
test(`
|
||||
var abc = Object.getOwnPropertyDescriptor(String, "prototype");
|
||||
[ [ typeof String.prototype ],
|
||||
[ abc.writable, abc.enumerable, abc.configurable ] ];
|
||||
`, "object,false,false,false")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_charAt(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = "xyzzy".charAt(0)
|
||||
def = "xyzzy".charAt(11)
|
||||
`)
|
||||
test("abc", "x")
|
||||
test("def", "")
|
||||
test(`
|
||||
abc = "xyzzy".charAt(0)
|
||||
def = "xyzzy".charAt(11)
|
||||
`)
|
||||
test("abc", "x")
|
||||
test("def", "")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_charCodeAt(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`
|
||||
abc = "xyzzy".charCodeAt(0)
|
||||
def = "xyzzy".charCodeAt(11)
|
||||
`)
|
||||
test("abc", "120")
|
||||
test("def", "NaN")
|
||||
test(`
|
||||
abc = "xyzzy".charCodeAt(0)
|
||||
def = "xyzzy".charCodeAt(11)
|
||||
`)
|
||||
test("abc", 120)
|
||||
test("def", _NaN)
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_fromCharCode(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`String.fromCharCode()`, "")
|
||||
test(`String.fromCharCode(88, 121, 122, 122, 121)`, "Xyzzy")
|
||||
test(`String.fromCharCode("88", 121, 122, 122.05, 121)`, "Xyzzy")
|
||||
test(`String.fromCharCode("88", 121, 122, NaN, 121)`, "Xyz\x00y")
|
||||
test(`String.fromCharCode("0x21")`, "!")
|
||||
test(`String.fromCharCode(-1).charCodeAt(0)`, "65535")
|
||||
test(`String.fromCharCode(65535).charCodeAt(0)`, "65535")
|
||||
test(`String.fromCharCode(65534).charCodeAt(0)`, "65534")
|
||||
test(`String.fromCharCode(4294967295).charCodeAt(0)`, "65535")
|
||||
test(`String.fromCharCode(4294967294).charCodeAt(0)`, "65534")
|
||||
test(`String.fromCharCode(0x0024) === "$"`, "true")
|
||||
test(`String.fromCharCode()`, []uint16{})
|
||||
test(`String.fromCharCode(88, 121, 122, 122, 121)`, []uint16{88, 121, 122, 122, 121}) // FIXME terst, Double-check these...
|
||||
test(`String.fromCharCode("88", 121, 122, 122.05, 121)`, []uint16{88, 121, 122, 122, 121})
|
||||
test(`String.fromCharCode("88", 121, 122, NaN, 121)`, []uint16{88, 121, 122, 0, 121})
|
||||
test(`String.fromCharCode("0x21")`, []uint16{33})
|
||||
test(`String.fromCharCode(-1).charCodeAt(0)`, 65535)
|
||||
test(`String.fromCharCode(65535).charCodeAt(0)`, 65535)
|
||||
test(`String.fromCharCode(65534).charCodeAt(0)`, 65534)
|
||||
test(`String.fromCharCode(4294967295).charCodeAt(0)`, 65535)
|
||||
test(`String.fromCharCode(4294967294).charCodeAt(0)`, 65534)
|
||||
test(`String.fromCharCode(0x0024) === "$"`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_concat(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`"".concat()`, "")
|
||||
test(`"".concat("abc", "def")`, "abcdef")
|
||||
test(`"".concat("abc", undefined, "def")`, "abcundefineddef")
|
||||
test(`"".concat()`, "")
|
||||
test(`"".concat("abc", "def")`, "abcdef")
|
||||
test(`"".concat("abc", undefined, "def")`, "abcundefineddef")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_indexOf(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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")
|
||||
test(`"$$abcdabcd".indexOf("ab", function(){return -Infinity;}())`, "2")
|
||||
test(`"$$abcdabcd".indexOf("ab", function(){return NaN;}())`, "2")
|
||||
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)
|
||||
test(`"$$abcdabcd".indexOf("ab", function(){return -Infinity;}())`, 2)
|
||||
test(`"$$abcdabcd".indexOf("ab", function(){return NaN;}())`, 2)
|
||||
|
||||
test(`
|
||||
var abc = {toString:function(){return "\u0041B";}}
|
||||
var def = {valueOf:function(){return true;}}
|
||||
var ghi = "ABB\u0041BABAB";
|
||||
var jkl;
|
||||
with(ghi) {
|
||||
jkl = indexOf(abc, def);
|
||||
}
|
||||
[ jkl ];
|
||||
`, "3")
|
||||
test(`
|
||||
var abc = {toString:function(){return "\u0041B";}}
|
||||
var def = {valueOf:function(){return true;}}
|
||||
var ghi = "ABB\u0041BABAB";
|
||||
var jkl;
|
||||
with(ghi) {
|
||||
jkl = indexOf(abc, def);
|
||||
}
|
||||
jkl;
|
||||
`, 3)
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_lastIndexOf(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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")
|
||||
test(`"abc".lastIndexOf("abcabcabc", 2)`, "-1")
|
||||
test(`"abc".lastIndexOf("abc", 0)`, "0")
|
||||
test(`"abc".lastIndexOf("abc", 1)`, "0")
|
||||
test(`"abc".lastIndexOf("abc", 2)`, "0")
|
||||
test(`"abc".lastIndexOf("abc", 3)`, "0")
|
||||
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)
|
||||
test(`"abc".lastIndexOf("abcabcabc", 2)`, -1)
|
||||
test(`"abc".lastIndexOf("abc", 0)`, 0)
|
||||
test(`"abc".lastIndexOf("abc", 1)`, 0)
|
||||
test(`"abc".lastIndexOf("abc", 2)`, 0)
|
||||
test(`"abc".lastIndexOf("abc", 3)`, 0)
|
||||
|
||||
test(`
|
||||
abc = new Object(true);
|
||||
abc.lastIndexOf = String.prototype.lastIndexOf;
|
||||
abc.lastIndexOf(true, false);
|
||||
`, "0")
|
||||
test(`
|
||||
abc = new Object(true);
|
||||
abc.lastIndexOf = String.prototype.lastIndexOf;
|
||||
abc.lastIndexOf(true, false);
|
||||
`, 0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_match(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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")
|
||||
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)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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_")
|
||||
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_")
|
||||
|
||||
test(`"b".replace(/(a)?(b)?/, "_$1_")`, "__")
|
||||
test(`
|
||||
"b".replace(/(a)?(b)?/, function(a, b, c, d, e, f){
|
||||
return [a, b, c, d, e, f]
|
||||
})
|
||||
`, "b,,b,0,b,")
|
||||
test(`"b".replace(/(a)?(b)?/, "_$1_")`, "__")
|
||||
test(`
|
||||
"b".replace(/(a)?(b)?/, function(a, b, c, d, e, f){
|
||||
return [a, b, c, d, e, f]
|
||||
})
|
||||
`, "b,,b,0,b,")
|
||||
|
||||
test(`
|
||||
var abc = 'She sells seashells by the seashore.';
|
||||
var def = /sh/;
|
||||
[ abc.replace(def, "$'" + 'sch') ];
|
||||
`, "She sells seaells by the seashore.schells by the seashore.")
|
||||
test(`
|
||||
var abc = 'She sells seashells by the seashore.';
|
||||
var def = /sh/;
|
||||
[ abc.replace(def, "$'" + 'sch') ];
|
||||
`, "She sells seaells by the seashore.schells by the seashore.")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_search(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`"abc".search(/abc/)`, "0")
|
||||
test(`"abc".search(/def/)`, "-1")
|
||||
test(`"abc".search(/c$/)`, "2")
|
||||
test(`"abc".search(/$/)`, "3")
|
||||
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)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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("", 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(`"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(`"__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(`"ab".split(/a*/)`, ",b")
|
||||
|
||||
test(`_ = "A<B>bold</B>and<CODE>coded</CODE>".split(/<(\/)?([^<>]+)>/)`, "A,,B,bold,/,B,and,,CODE,coded,/,CODE,")
|
||||
test(`_.length`, "13")
|
||||
test(`_[1] === undefined`, "true")
|
||||
test(`_[12] === ""`, "true")
|
||||
test(`_ = "A<B>bold</B>and<CODE>coded</CODE>".split(/<(\/)?([^<>]+)>/)`, "A,,B,bold,/,B,and,,CODE,coded,/,CODE,")
|
||||
test(`_.length`, 13)
|
||||
test(`_[1] === undefined`, true)
|
||||
test(`_[12] === ""`, true)
|
||||
|
||||
test(`
|
||||
var abc = new String("one-1 two-2 three-3");
|
||||
var def = abc.split(new RegExp);
|
||||
test(`
|
||||
var abc = new String("one-1 two-2 three-3");
|
||||
var def = abc.split(new RegExp);
|
||||
|
||||
[ def.constructor === Array, abc.length, def.length, def.join('') ];
|
||||
`, "true,19,19,one-1 two-2 three-3")
|
||||
[ def.constructor === Array, abc.length, def.length, def.join('') ];
|
||||
`, "true,19,19,one-1 two-2 three-3")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_slice(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
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")
|
||||
test(`abc = "abc"; abc.slice(abc.length+1, 0)`, "")
|
||||
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")
|
||||
test(`abc = "abc"; abc.slice(abc.length+1, 0)`, "")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_substring(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`"abc".substring()`, "abc")
|
||||
test(`"abc".substring(0)`, "abc")
|
||||
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")
|
||||
test(`"abc".substring(1)`, "bc")
|
||||
test(`"abc".substring(Infinity, Infinity)`, "")
|
||||
test(`"abc".substring()`, "abc")
|
||||
test(`"abc".substring(0)`, "abc")
|
||||
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")
|
||||
test(`"abc".substring(1)`, "bc")
|
||||
test(`"abc".substring(Infinity, Infinity)`, "")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_toCase(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`"abc".toLowerCase()`, "abc")
|
||||
test(`"ABC".toLowerCase()`, "abc")
|
||||
test(`"abc".toLocaleLowerCase()`, "abc")
|
||||
test(`"ABC".toLocaleLowerCase()`, "abc")
|
||||
test(`"abc".toUpperCase()`, "ABC")
|
||||
test(`"ABC".toUpperCase()`, "ABC")
|
||||
test(`"abc".toLocaleUpperCase()`, "ABC")
|
||||
test(`"ABC".toLocaleUpperCase()`, "ABC")
|
||||
test(`"abc".toLowerCase()`, "abc")
|
||||
test(`"ABC".toLowerCase()`, "abc")
|
||||
test(`"abc".toLocaleLowerCase()`, "abc")
|
||||
test(`"ABC".toLocaleLowerCase()`, "abc")
|
||||
test(`"abc".toUpperCase()`, "ABC")
|
||||
test(`"ABC".toUpperCase()`, "ABC")
|
||||
test(`"abc".toLocaleUpperCase()`, "ABC")
|
||||
test(`"ABC".toLocaleUpperCase()`, "ABC")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_floatToString(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`String(-1234567890)`, "-1234567890")
|
||||
test(`-+String(-(-1234567890))`, "-1234567890")
|
||||
test(`String(-1e128)`, "-1e+128")
|
||||
test(`String(0.12345)`, "0.12345")
|
||||
test(`String(-0.00000012345)`, "-1.2345e-7")
|
||||
test(`String(0.0000012345)`, "0.0000012345")
|
||||
test(`String(1000000000000000000000)`, "1e+21")
|
||||
test(`String(1e21)`, "1e+21")
|
||||
test(`String(1E21)`, "1e+21")
|
||||
test(`String(-1000000000000000000000)`, "-1e+21")
|
||||
test(`String(-1e21)`, "-1e+21")
|
||||
test(`String(-1E21)`, "-1e+21")
|
||||
test(`String(0.0000001)`, "1e-7")
|
||||
test(`String(1e-7)`, "1e-7")
|
||||
test(`String(1E-7)`, "1e-7")
|
||||
test(`String(-0.0000001)`, "-1e-7")
|
||||
test(`String(-1e-7)`, "-1e-7")
|
||||
test(`String(-1E-7)`, "-1e-7")
|
||||
test(`String(-1234567890)`, "-1234567890")
|
||||
test(`-+String(-(-1234567890))`, -1234567890)
|
||||
test(`String(-1e128)`, "-1e+128")
|
||||
test(`String(0.12345)`, "0.12345")
|
||||
test(`String(-0.00000012345)`, "-1.2345e-7")
|
||||
test(`String(0.0000012345)`, "0.0000012345")
|
||||
test(`String(1000000000000000000000)`, "1e+21")
|
||||
test(`String(1e21)`, "1e+21")
|
||||
test(`String(1E21)`, "1e+21")
|
||||
test(`String(-1000000000000000000000)`, "-1e+21")
|
||||
test(`String(-1e21)`, "-1e+21")
|
||||
test(`String(-1E21)`, "-1e+21")
|
||||
test(`String(0.0000001)`, "1e-7")
|
||||
test(`String(1e-7)`, "1e-7")
|
||||
test(`String(1E-7)`, "1e-7")
|
||||
test(`String(-0.0000001)`, "-1e-7")
|
||||
test(`String(-1e-7)`, "-1e-7")
|
||||
test(`String(-1E-7)`, "-1e-7")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_indexing(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
// Actually a test of stringToArrayIndex, under the hood.
|
||||
test(`
|
||||
abc = new String("abc");
|
||||
index = Math.pow(2, 32);
|
||||
[ abc.length, abc[index], abc[index+1], abc[index+2], abc[index+3] ];
|
||||
`, "3,,,,")
|
||||
// Actually a test of stringToArrayIndex, under the hood.
|
||||
test(`
|
||||
abc = new String("abc");
|
||||
index = Math.pow(2, 32);
|
||||
[ abc.length, abc[index], abc[index+1], abc[index+2], abc[index+3] ];
|
||||
`, "3,,,,")
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_trim(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`' \n abc \t \n'.trim();`, "abc")
|
||||
test(`" abc\u000B".trim()`, "abc")
|
||||
test(`"abc ".trim()`, "abc")
|
||||
test(`
|
||||
var a = "\u180Eabc \u000B "
|
||||
var b = a.trim()
|
||||
a.length + b.length
|
||||
`, "10")
|
||||
test(`' \n abc \t \n'.trim();`, "abc")
|
||||
test(`" abc\u000B".trim()`, "abc")
|
||||
test(`"abc ".trim()`, "abc")
|
||||
test(`
|
||||
var a = "\u180Eabc \u000B "
|
||||
var b = a.trim()
|
||||
a.length + b.length
|
||||
`, 10)
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_trimLeft(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`" abc\u000B".trimLeft()`, "abc\u000B")
|
||||
test(`"abc ".trimLeft()`, "abc ")
|
||||
test(`
|
||||
var a = "\u180Eabc \u000B "
|
||||
var b = a.trimLeft()
|
||||
a.length + b.length
|
||||
`, "13")
|
||||
test(`" abc\u000B".trimLeft()`, "abc\u000B")
|
||||
test(`"abc ".trimLeft()`, "abc ")
|
||||
test(`
|
||||
var a = "\u180Eabc \u000B "
|
||||
var b = a.trimLeft()
|
||||
a.length + b.length
|
||||
`, 13)
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_trimRight(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
test(`" abc\u000B".trimRight()`, " abc")
|
||||
test(`" abc ".trimRight()`, " abc")
|
||||
test(`
|
||||
var a = "\u180Eabc \u000B "
|
||||
var b = a.trimRight()
|
||||
a.length + b.length
|
||||
`, "11")
|
||||
test(`" abc\u000B".trimRight()`, " abc")
|
||||
test(`" abc ".trimRight()`, " abc")
|
||||
test(`
|
||||
var a = "\u180Eabc \u000B "
|
||||
var b = a.trimRight()
|
||||
a.length + b.length
|
||||
`, 11)
|
||||
})
|
||||
}
|
||||
|
||||
func TestString_localeCompare(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test := runTest()
|
||||
|
||||
test(`'a'.localeCompare('c');`, "-1")
|
||||
test(`'c'.localeCompare('a');`, "1")
|
||||
test(`'a'.localeCompare('a');`, "0")
|
||||
test(`'a'.localeCompare('c');`, -1)
|
||||
test(`'c'.localeCompare('a');`, 1)
|
||||
test(`'a'.localeCompare('a');`, 0)
|
||||
})
|
||||
}
|
||||
|
||||
1558
terst/terst.go
1558
terst/terst.go
File diff suppressed because it is too large
Load Diff
128
testing_test.go
Normal file
128
testing_test.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
"./terst"
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func tt(t *testing.T, arguments ...func()) {
|
||||
halt := errors.New("A test was taking too long")
|
||||
timer := time.AfterFunc(2*time.Second, func() {
|
||||
panic(halt)
|
||||
})
|
||||
defer func() {
|
||||
timer.Stop()
|
||||
}()
|
||||
terst.Terst(t, arguments...)
|
||||
}
|
||||
|
||||
func is(arguments ...interface{}) bool {
|
||||
var got, expect interface{}
|
||||
|
||||
switch len(arguments) {
|
||||
case 0, 1:
|
||||
return terst.Is(arguments...)
|
||||
case 2:
|
||||
got, expect = arguments[0], arguments[1]
|
||||
default:
|
||||
got, expect = arguments[0], arguments[2]
|
||||
}
|
||||
|
||||
if value, ok := got.(Value); ok {
|
||||
if _, ok := expect.(Value); !ok {
|
||||
if value.value != nil {
|
||||
got = value.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(arguments) == 2 {
|
||||
arguments[0] = got
|
||||
arguments[1] = expect
|
||||
} else {
|
||||
arguments[0] = got
|
||||
arguments[2] = expect
|
||||
}
|
||||
|
||||
return terst.Is(arguments...)
|
||||
}
|
||||
|
||||
func test(arguments ...interface{}) (func(string, ...interface{}) Value, *_tester) {
|
||||
tester := newTester()
|
||||
if len(arguments) > 0 {
|
||||
tester.test(arguments[0].(string))
|
||||
}
|
||||
return tester.test, tester
|
||||
}
|
||||
|
||||
type _tester struct {
|
||||
vm *Otto
|
||||
}
|
||||
|
||||
func newTester() *_tester {
|
||||
return &_tester{
|
||||
vm: New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_tester) Get(name string) (Value, error) {
|
||||
return self.vm.Get(name)
|
||||
}
|
||||
|
||||
func (self *_tester) Set(name string, value interface{}) Value {
|
||||
err := self.vm.Set(name, value)
|
||||
is(err, nil)
|
||||
if err != nil {
|
||||
terst.Caller().T().FailNow()
|
||||
}
|
||||
return self.vm.getValue(name)
|
||||
}
|
||||
|
||||
func (self *_tester) Run(src interface{}) (Value, error) {
|
||||
return self.vm.Run(src)
|
||||
}
|
||||
|
||||
func (self *_tester) test(name string, expect ...interface{}) Value {
|
||||
vm := self.vm
|
||||
raise := false
|
||||
defer func() {
|
||||
if caught := recover(); caught != nil {
|
||||
if exception, ok := caught.(*_exception); ok {
|
||||
caught = exception.eject()
|
||||
}
|
||||
if raise {
|
||||
if len(expect) > 0 {
|
||||
is(caught, expect[0])
|
||||
}
|
||||
} else {
|
||||
dbg("Panic, caught:", caught)
|
||||
panic(caught)
|
||||
}
|
||||
}
|
||||
}()
|
||||
var value Value
|
||||
var err error
|
||||
if isIdentifier(name) {
|
||||
value = vm.getValue(name)
|
||||
} else {
|
||||
source := name
|
||||
index := strings.Index(source, "raise:")
|
||||
if index == 0 {
|
||||
raise = true
|
||||
source = source[6:]
|
||||
source = strings.TrimLeft(source, " ")
|
||||
}
|
||||
value, err = vm.runtime.cmpl_run(source)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
value = vm.runtime.GetValue(value)
|
||||
if len(expect) > 0 {
|
||||
is(value, expect[0])
|
||||
}
|
||||
return value
|
||||
}
|
||||
@@ -52,7 +52,6 @@ for my $file (@js) {
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -65,13 +64,13 @@ _END_
|
||||
$fh->print(<<_END_);
|
||||
// $name
|
||||
func Test_${underscore_name}_$count(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func(){
|
||||
test := underscoreTest()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
$test
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
_END_
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// first
|
||||
func Test_underscore_arrays_0(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("first", function() {
|
||||
equal(_.first([1,2,3]), 1, 'can pull out the first element of an array');
|
||||
equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
|
||||
@@ -27,16 +25,16 @@ func Test_underscore_arrays_0(t *testing.T) {
|
||||
|
||||
equal(_.first(null), undefined, 'handles nulls');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// rest
|
||||
func Test_underscore_arrays_1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("rest", function() {
|
||||
var numbers = [1, 2, 3, 4];
|
||||
equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()');
|
||||
@@ -49,16 +47,16 @@ func Test_underscore_arrays_1(t *testing.T) {
|
||||
result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4);
|
||||
equal(result.join(', '), '2, 3, 4', 'aliased as drop and works on arguments object');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// initial
|
||||
func Test_underscore_arrays_2(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("initial", function() {
|
||||
equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()');
|
||||
equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index');
|
||||
@@ -67,16 +65,16 @@ func Test_underscore_arrays_2(t *testing.T) {
|
||||
result = _.map([[1,2,3],[1,2,3]], _.initial);
|
||||
equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// last
|
||||
func Test_underscore_arrays_3(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("last", function() {
|
||||
equal(_.last([1,2,3]), 3, 'can pull out the last element of an array');
|
||||
equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last');
|
||||
@@ -89,31 +87,31 @@ func Test_underscore_arrays_3(t *testing.T) {
|
||||
|
||||
equal(_.last(null), undefined, 'handles nulls');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// compact
|
||||
func Test_underscore_arrays_4(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("compact", function() {
|
||||
equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values');
|
||||
var result = (function(){ return _.compact(arguments).length; })(0, 1, false, 2, false, 3);
|
||||
equal(result, 3, 'works on an arguments object');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// flatten
|
||||
func Test_underscore_arrays_5(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("flatten", function() {
|
||||
var list = [1, [2], [3, [[[4]]]]];
|
||||
deepEqual(_.flatten(list), [1,2,3,4], 'can flatten nested arrays');
|
||||
@@ -121,16 +119,16 @@ func Test_underscore_arrays_5(t *testing.T) {
|
||||
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
|
||||
deepEqual(result, [1,2,3,4], 'works on an arguments object');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// without
|
||||
func Test_underscore_arrays_6(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("without", function() {
|
||||
var list = [1, 2, 1, 0, 3, 1, 4];
|
||||
equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object');
|
||||
@@ -141,16 +139,16 @@ func Test_underscore_arrays_6(t *testing.T) {
|
||||
ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.');
|
||||
ok(_.without(list, list[0]).length == 1, 'ditto.');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// uniq
|
||||
func Test_underscore_arrays_7(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("uniq", function() {
|
||||
var list = [1, 2, 1, 3, 1, 4];
|
||||
equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array');
|
||||
@@ -171,16 +169,16 @@ func Test_underscore_arrays_7(t *testing.T) {
|
||||
var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4);
|
||||
equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// intersection
|
||||
func Test_underscore_arrays_8(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("intersection", function() {
|
||||
var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
|
||||
equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays');
|
||||
@@ -188,16 +186,16 @@ func Test_underscore_arrays_8(t *testing.T) {
|
||||
var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry');
|
||||
equal(result.join(''), 'moe', 'works on an arguments object');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// union
|
||||
func Test_underscore_arrays_9(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("union", function() {
|
||||
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]);
|
||||
equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays');
|
||||
@@ -205,16 +203,16 @@ func Test_underscore_arrays_9(t *testing.T) {
|
||||
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]);
|
||||
equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// difference
|
||||
func Test_underscore_arrays_10(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("difference", function() {
|
||||
var result = _.difference([1, 2, 3], [2, 30, 40]);
|
||||
equal(result.join(' '), '1 3', 'takes the difference of two arrays');
|
||||
@@ -222,31 +220,31 @@ func Test_underscore_arrays_10(t *testing.T) {
|
||||
var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]);
|
||||
equal(result.join(' '), '3 4', 'takes the difference of three arrays');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// zip
|
||||
func Test_underscore_arrays_11(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('zip', function() {
|
||||
var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
|
||||
var stooges = _.zip(names, ages, leaders);
|
||||
equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// object
|
||||
func Test_underscore_arrays_12(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('object', function() {
|
||||
var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]);
|
||||
var shouldBe = {moe: 30, larry: 40, curly: 50};
|
||||
@@ -261,16 +259,16 @@ func Test_underscore_arrays_12(t *testing.T) {
|
||||
|
||||
ok(_.isEqual(_.object(null), {}), 'handles nulls');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// indexOf
|
||||
func Test_underscore_arrays_13(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("indexOf", function() {
|
||||
var numbers = [1, 2, 3];
|
||||
numbers.indexOf = null;
|
||||
@@ -295,16 +293,16 @@ func Test_underscore_arrays_13(t *testing.T) {
|
||||
index = _.indexOf(numbers, 2, 5);
|
||||
equal(index, 7, 'supports the fromIndex argument');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// lastIndexOf
|
||||
func Test_underscore_arrays_14(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("lastIndexOf", function() {
|
||||
var numbers = [1, 0, 1];
|
||||
equal(_.lastIndexOf(numbers, 1), 2);
|
||||
@@ -321,16 +319,16 @@ func Test_underscore_arrays_14(t *testing.T) {
|
||||
var index = _.lastIndexOf(numbers, 2, 2);
|
||||
equal(index, 1, 'supports the fromIndex argument');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// range
|
||||
func Test_underscore_arrays_15(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("range", function() {
|
||||
equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array');
|
||||
equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
|
||||
@@ -341,5 +339,6 @@ func Test_underscore_arrays_15(t *testing.T) {
|
||||
equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
|
||||
equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// map/flatten/reduce
|
||||
func Test_underscore_chaining_0(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("map/flatten/reduce", function() {
|
||||
var lyrics = [
|
||||
"I'm a lumberjack and I'm okay",
|
||||
@@ -29,16 +27,16 @@ func Test_underscore_chaining_0(t *testing.T) {
|
||||
}, {}).value();
|
||||
ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// select/reject/sortBy
|
||||
func Test_underscore_chaining_1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("select/reject/sortBy", function() {
|
||||
var numbers = [1,2,3,4,5,6,7,8,9,10];
|
||||
numbers = _(numbers).chain().select(function(n) {
|
||||
@@ -50,16 +48,16 @@ func Test_underscore_chaining_1(t *testing.T) {
|
||||
}).value();
|
||||
equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// select/reject/sortBy in functional style
|
||||
func Test_underscore_chaining_2(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("select/reject/sortBy in functional style", function() {
|
||||
var numbers = [1,2,3,4,5,6,7,8,9,10];
|
||||
numbers = _.chain(numbers).select(function(n) {
|
||||
@@ -71,16 +69,16 @@ func Test_underscore_chaining_2(t *testing.T) {
|
||||
}).value();
|
||||
equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// reverse/concat/unshift/pop/map
|
||||
func Test_underscore_chaining_3(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("reverse/concat/unshift/pop/map", function() {
|
||||
var numbers = [1,2,3,4,5];
|
||||
numbers = _(numbers).chain()
|
||||
@@ -92,5 +90,6 @@ func Test_underscore_chaining_3(t *testing.T) {
|
||||
.value();
|
||||
equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// each
|
||||
func Test_underscore_collections_0(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("each", function() {
|
||||
_.each([1, 2, 3], function(num, i) {
|
||||
equal(num, i + 1, 'each iterators provide value and iteration count');
|
||||
@@ -29,8 +27,7 @@ func Test_underscore_collections_0(t *testing.T) {
|
||||
var obj = {one : 1, two : 2, three : 3};
|
||||
obj.constructor.prototype.four = 4;
|
||||
_.each(obj, function(value, key){ answers.push(key); });
|
||||
// TODO: Property ordering unreliable
|
||||
//equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.');
|
||||
equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.');
|
||||
delete obj.constructor.prototype.four;
|
||||
|
||||
var answer = null;
|
||||
@@ -41,16 +38,16 @@ func Test_underscore_collections_0(t *testing.T) {
|
||||
_.each(null, function(){ ++answers; });
|
||||
equal(answers, 0, 'handles a null properly');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// map
|
||||
func Test_underscore_collections_1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('map', function() {
|
||||
var doubled = _.map([1, 2, 3], function(num){ return num * 2; });
|
||||
equal(doubled.join(', '), '2, 4, 6', 'doubled numbers');
|
||||
@@ -64,30 +61,33 @@ func Test_underscore_collections_1(t *testing.T) {
|
||||
var doubled = _([1, 2, 3]).map(function(num){ return num * 2; });
|
||||
equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers');
|
||||
|
||||
//if (document.querySelectorAll) {
|
||||
// var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; });
|
||||
// deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.');
|
||||
//}
|
||||
// TEST: ReferenceError: document is not defined
|
||||
return;
|
||||
|
||||
//var ids = _.map($('#map-test').children(), function(n){ return n.id; });
|
||||
//deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.');
|
||||
if (document.querySelectorAll) {
|
||||
var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; });
|
||||
deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.');
|
||||
}
|
||||
|
||||
//var ids = _.map(document.images, function(n){ return n.id; });
|
||||
//ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections');
|
||||
var ids = _.map($('#map-test').children(), function(n){ return n.id; });
|
||||
deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.');
|
||||
|
||||
var ids = _.map(document.images, function(n){ return n.id; });
|
||||
ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections');
|
||||
|
||||
var ifnull = _.map(null, function(){});
|
||||
ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// reduce
|
||||
func Test_underscore_collections_2(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('reduce', function() {
|
||||
var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0);
|
||||
equal(sum, 6, 'can sum up an array');
|
||||
@@ -115,19 +115,18 @@ func Test_underscore_collections_2(t *testing.T) {
|
||||
|
||||
ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly');
|
||||
equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case');
|
||||
return
|
||||
raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// reduceRight
|
||||
func Test_underscore_collections_3(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('reduceRight', function() {
|
||||
var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, '');
|
||||
equal(list, 'bazbarfoo', 'can perform right folds');
|
||||
@@ -156,9 +155,6 @@ func Test_underscore_collections_3(t *testing.T) {
|
||||
|
||||
// Assert that the correct arguments are being passed.
|
||||
|
||||
// TODO: Property ordering unreliable
|
||||
return;
|
||||
|
||||
var args,
|
||||
memo = {},
|
||||
object = {a: 1, b: 2},
|
||||
@@ -190,45 +186,45 @@ func Test_underscore_collections_3(t *testing.T) {
|
||||
|
||||
deepEqual(args, expected);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// find
|
||||
func Test_underscore_collections_4(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('find', function() {
|
||||
var array = [1, 2, 3, 4];
|
||||
strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found <value>');
|
||||
strictEqual(_.find(array, function() { return false; }), void 0, 'should return <undefined> if <value> is not found');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// detect
|
||||
func Test_underscore_collections_5(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('detect', function() {
|
||||
var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; });
|
||||
equal(result, 2, 'found the first "2" and broke the loop');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// select
|
||||
func Test_underscore_collections_6(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('select', function() {
|
||||
var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
|
||||
equal(evens.join(', '), '2, 4, 6', 'selected each even number');
|
||||
@@ -236,16 +232,16 @@ func Test_underscore_collections_6(t *testing.T) {
|
||||
evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
|
||||
equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// reject
|
||||
func Test_underscore_collections_7(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('reject', function() {
|
||||
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
|
||||
equal(odds.join(', '), '1, 3, 5', 'rejected each even number');
|
||||
@@ -258,16 +254,16 @@ func Test_underscore_collections_7(t *testing.T) {
|
||||
}, context);
|
||||
equal(evens.join(', '), '2, 4, 6', 'rejected each odd number');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// all
|
||||
func Test_underscore_collections_8(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('all', function() {
|
||||
ok(_.all([], _.identity), 'the empty set');
|
||||
ok(_.all([true, true, true], _.identity), 'all true values');
|
||||
@@ -279,16 +275,16 @@ func Test_underscore_collections_8(t *testing.T) {
|
||||
ok(_.every([true, true, true], _.identity), 'aliased as "every"');
|
||||
ok(!_.all([undefined, undefined, undefined], _.identity), 'works with arrays of undefined');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// any
|
||||
func Test_underscore_collections_9(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('any', function() {
|
||||
var nativeSome = Array.prototype.some;
|
||||
Array.prototype.some = null;
|
||||
@@ -304,64 +300,64 @@ func Test_underscore_collections_9(t *testing.T) {
|
||||
ok(_.some([false, false, true]), 'aliased as "some"');
|
||||
Array.prototype.some = nativeSome;
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// include
|
||||
func Test_underscore_collections_10(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('include', function() {
|
||||
ok(_.include([1,2,3], 2), 'two is in the array');
|
||||
ok(!_.include([1,3,9], 2), 'two is not in the array');
|
||||
ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values');
|
||||
ok(_([1,2,3]).include(2), 'OO-style include');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// invoke
|
||||
func Test_underscore_collections_11(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('invoke', function() {
|
||||
var list = [[5, 1, 7], [3, 2, 1]];
|
||||
var result = _.invoke(list, 'sort');
|
||||
equal(result[0].join(', '), '1, 5, 7', 'first array sorted');
|
||||
equal(result[1].join(', '), '1, 2, 3', 'second array sorted');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// invoke w/ function reference
|
||||
func Test_underscore_collections_12(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('invoke w/ function reference', function() {
|
||||
var list = [[5, 1, 7], [3, 2, 1]];
|
||||
var result = _.invoke(list, Array.prototype.sort);
|
||||
equal(result[0].join(', '), '1, 5, 7', 'first array sorted');
|
||||
equal(result[1].join(', '), '1, 2, 3', 'second array sorted');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// invoke when strings have a call method
|
||||
func Test_underscore_collections_13(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('invoke when strings have a call method', function() {
|
||||
String.prototype.call = function() {
|
||||
return 42;
|
||||
@@ -375,30 +371,30 @@ func Test_underscore_collections_13(t *testing.T) {
|
||||
delete String.prototype.call;
|
||||
equal(s.call, undefined, "call function removed");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// pluck
|
||||
func Test_underscore_collections_14(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('pluck', function() {
|
||||
var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}];
|
||||
equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// where
|
||||
func Test_underscore_collections_15(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('where', function() {
|
||||
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
|
||||
var result = _.where(list, {a: 1});
|
||||
@@ -408,16 +404,16 @@ func Test_underscore_collections_15(t *testing.T) {
|
||||
equal(result.length, 2);
|
||||
equal(result[0].a, 1);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// findWhere
|
||||
func Test_underscore_collections_16(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('findWhere', function() {
|
||||
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
|
||||
var result = _.findWhere(list, {a: 1});
|
||||
@@ -425,16 +421,16 @@ func Test_underscore_collections_16(t *testing.T) {
|
||||
result = _.findWhere(list, {b: 4});
|
||||
deepEqual(result, {a: 1, b: 4});
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// max
|
||||
func Test_underscore_collections_17(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('max', function() {
|
||||
equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max');
|
||||
|
||||
@@ -445,18 +441,21 @@ func Test_underscore_collections_17(t *testing.T) {
|
||||
equal(-Infinity, _.max([]), 'Maximum value of an empty array');
|
||||
equal(_.max({'a': 'a'}), -Infinity, 'Maximum value of a non-numeric collection');
|
||||
|
||||
//equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array");
|
||||
// TEST: Takes too long
|
||||
return;
|
||||
|
||||
equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// min
|
||||
func Test_underscore_collections_18(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('min', function() {
|
||||
equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min');
|
||||
|
||||
@@ -471,18 +470,21 @@ func Test_underscore_collections_18(t *testing.T) {
|
||||
var then = new Date(0);
|
||||
equal(_.min([now, then]), then);
|
||||
|
||||
//equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array");
|
||||
// TEST: Takes too long
|
||||
return;
|
||||
|
||||
equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// sortBy
|
||||
func Test_underscore_collections_19(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('sortBy', function() {
|
||||
var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}];
|
||||
people = _.sortBy(people, function(person){ return person.age; });
|
||||
@@ -518,16 +520,16 @@ func Test_underscore_collections_19(t *testing.T) {
|
||||
|
||||
deepEqual(actual, collection, 'sortBy should be stable');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// groupBy
|
||||
func Test_underscore_collections_20(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('groupBy', function() {
|
||||
var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; });
|
||||
ok('0' in parity && '1' in parity, 'created a group for each value');
|
||||
@@ -556,16 +558,16 @@ func Test_underscore_collections_20(t *testing.T) {
|
||||
equal(grouped['1'].length, 2);
|
||||
equal(grouped['3'].length, 1);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// countBy
|
||||
func Test_underscore_collections_21(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('countBy', function() {
|
||||
var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; });
|
||||
equal(parity['true'], 2);
|
||||
@@ -594,16 +596,16 @@ func Test_underscore_collections_21(t *testing.T) {
|
||||
equal(grouped['1'], 2);
|
||||
equal(grouped['3'], 1);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// sortedIndex
|
||||
func Test_underscore_collections_22(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('sortedIndex', function() {
|
||||
var numbers = [10, 20, 30, 40, 50], num = 35;
|
||||
var indexForNum = _.sortedIndex(numbers, num);
|
||||
@@ -621,32 +623,32 @@ func Test_underscore_collections_22(t *testing.T) {
|
||||
iterator = function(obj){ return this[obj]; };
|
||||
strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// shuffle
|
||||
func Test_underscore_collections_23(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('shuffle', function() {
|
||||
var numbers = _.range(10);
|
||||
var shuffled = _.shuffle(numbers).sort();
|
||||
notStrictEqual(numbers, shuffled, 'original object is unmodified');
|
||||
equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// toArray
|
||||
func Test_underscore_collections_24(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('toArray', function() {
|
||||
ok(!_.isArray(arguments), 'arguments object is not an array');
|
||||
ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array');
|
||||
@@ -654,12 +656,12 @@ func Test_underscore_collections_24(t *testing.T) {
|
||||
ok(_.toArray(a) !== a, 'array is cloned');
|
||||
equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements');
|
||||
|
||||
// TODO: Property ordering unreliable
|
||||
return;
|
||||
|
||||
var numbers = _.toArray({one : 1, two : 2, three : 3});
|
||||
equal(numbers.join(', '), '1, 2, 3', 'object flattened into array');
|
||||
|
||||
// TEST: ReferenceError: document is not defined
|
||||
return;
|
||||
|
||||
// test in IE < 9
|
||||
try {
|
||||
var actual = _.toArray(document.childNodes);
|
||||
@@ -667,16 +669,16 @@ func Test_underscore_collections_24(t *testing.T) {
|
||||
|
||||
ok(_.isArray(actual), 'should not throw converting a node list');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// size
|
||||
func Test_underscore_collections_25(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('size', function() {
|
||||
equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object');
|
||||
equal(_.size([1, 2, 3]), 3, 'can compute the size of an array');
|
||||
@@ -691,5 +693,6 @@ func Test_underscore_collections_25(t *testing.T) {
|
||||
|
||||
equal(_.size(null), 0, 'handles nulls');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// bind
|
||||
func Test_underscore_functions_0(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("bind", function() {
|
||||
var context = {name : 'moe'};
|
||||
var func = function(arg) { return "name: " + (this.name || arg); };
|
||||
@@ -46,16 +44,16 @@ func Test_underscore_functions_0(t *testing.T) {
|
||||
var Boundf = _.bind(F, {hello: "moe curly"});
|
||||
equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// partial
|
||||
func Test_underscore_functions_1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("partial", function() {
|
||||
var obj = {name: 'moe'};
|
||||
var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); };
|
||||
@@ -63,16 +61,16 @@ func Test_underscore_functions_1(t *testing.T) {
|
||||
obj.func = _.partial(func, 'a', 'b');
|
||||
equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// bindAll
|
||||
func Test_underscore_functions_2(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("bindAll", function() {
|
||||
var curly = {name : 'curly'}, moe = {
|
||||
name : 'moe',
|
||||
@@ -91,24 +89,20 @@ func Test_underscore_functions_2(t *testing.T) {
|
||||
getName : function() { return 'name: ' + this.name; },
|
||||
sayHi : function() { return 'hi: ' + this.name; }
|
||||
};
|
||||
|
||||
// FIXME: This functionality is being changed in the underscore master right now
|
||||
//raises(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named');
|
||||
|
||||
_.bindAll(moe, 'sayHi');
|
||||
_.bindAll(moe);
|
||||
curly.sayHi = moe.sayHi;
|
||||
equal(curly.sayHi(), 'hi: moe');
|
||||
equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// memoize
|
||||
func Test_underscore_functions_3(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("memoize", function() {
|
||||
var fib = function(n) {
|
||||
return n < 2 ? n : fib(n - 1) + fib(n - 2);
|
||||
@@ -124,16 +118,16 @@ func Test_underscore_functions_3(t *testing.T) {
|
||||
equal(o('toString'), 'toString', 'checks hasOwnProperty');
|
||||
equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// once
|
||||
func Test_underscore_functions_4(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("once", function() {
|
||||
var num = 0;
|
||||
var increment = _.once(function(){ num++; });
|
||||
@@ -141,16 +135,16 @@ func Test_underscore_functions_4(t *testing.T) {
|
||||
increment();
|
||||
equal(num, 1);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// wrap
|
||||
func Test_underscore_functions_5(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("wrap", function() {
|
||||
var greet = function(name){ return "hi: " + name; };
|
||||
var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); });
|
||||
@@ -166,16 +160,16 @@ func Test_underscore_functions_5(t *testing.T) {
|
||||
var ret = wrapped(['whats', 'your'], 'vector', 'victor');
|
||||
deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// compose
|
||||
func Test_underscore_functions_6(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("compose", function() {
|
||||
var greet = function(name){ return "hi: " + name; };
|
||||
var exclaim = function(sentence){ return sentence + '!'; };
|
||||
@@ -185,16 +179,16 @@ func Test_underscore_functions_6(t *testing.T) {
|
||||
composed = _.compose(greet, exclaim);
|
||||
equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// after
|
||||
func Test_underscore_functions_7(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("after", function() {
|
||||
var testAfter = function(afterAmount, timesCalled) {
|
||||
var afterCalled = 0;
|
||||
@@ -209,5 +203,6 @@ func Test_underscore_functions_7(t *testing.T) {
|
||||
equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times");
|
||||
equal(testAfter(0, 0), 1, "after(0) should fire immediately");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// keys
|
||||
func Test_underscore_objects_0(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("keys", function() {
|
||||
equal(_.keys({one : 1, two : 2}).sort().join(', '), 'one, two', 'can extract the keys from an object');
|
||||
equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object');
|
||||
// the test above is not safe because it relies on for-in enumeration order
|
||||
var a = []; a[1] = 0;
|
||||
equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95');
|
||||
@@ -23,65 +21,62 @@ func Test_underscore_objects_0(t *testing.T) {
|
||||
raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives');
|
||||
raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// values
|
||||
func Test_underscore_objects_1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("values", function() {
|
||||
equal(_.values({one: 1, two: 2}).sort().join(', '), '1, 2', 'can extract the values from an object');
|
||||
equal(_.values({one: 1, two: 2, length: 3}).sort().join(', '), '1, 2, 3', '... even when one of them is "length"');
|
||||
equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object');
|
||||
equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// pairs
|
||||
func Test_underscore_objects_2(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("pairs", function() {
|
||||
// TODO: Property ordering unreliable
|
||||
return;
|
||||
deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs');
|
||||
deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// invert
|
||||
func Test_underscore_objects_3(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("invert", function() {
|
||||
var obj = {first: 'Moe', second: 'Larry', third: 'Curly'};
|
||||
// TODO: Property ordering unreliable
|
||||
//equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object');
|
||||
equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object');
|
||||
ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started');
|
||||
|
||||
var obj = {length: 3};
|
||||
ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"')
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// functions
|
||||
func Test_underscore_objects_4(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("functions", function() {
|
||||
var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce};
|
||||
ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object');
|
||||
@@ -90,16 +85,16 @@ func Test_underscore_objects_4(t *testing.T) {
|
||||
Animal.prototype.run = function(){};
|
||||
equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// extend
|
||||
func Test_underscore_objects_5(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("extend", function() {
|
||||
var result;
|
||||
equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another');
|
||||
@@ -110,8 +105,7 @@ func Test_underscore_objects_5(t *testing.T) {
|
||||
result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'});
|
||||
ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps');
|
||||
result = _.extend({}, {a: void 0, b: null});
|
||||
// TODO: Property ordering unreliable
|
||||
//equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values');
|
||||
equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values');
|
||||
|
||||
try {
|
||||
result = {};
|
||||
@@ -120,16 +114,16 @@ func Test_underscore_objects_5(t *testing.T) {
|
||||
|
||||
equal(result.a, 1, 'should not error on <null> or <undefined> sources');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// pick
|
||||
func Test_underscore_objects_6(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("pick", function() {
|
||||
var result;
|
||||
result = _.pick({a:1, b:2, c:3}, 'a', 'c');
|
||||
@@ -143,16 +137,16 @@ func Test_underscore_objects_6(t *testing.T) {
|
||||
Obj.prototype = {a: 1, b: 2, c: 3};
|
||||
ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// omit
|
||||
func Test_underscore_objects_7(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("omit", function() {
|
||||
var result;
|
||||
result = _.omit({a:1, b:2, c:3}, 'b');
|
||||
@@ -166,16 +160,16 @@ func Test_underscore_objects_7(t *testing.T) {
|
||||
Obj.prototype = {a: 1, b: 2, c: 3};
|
||||
ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// defaults
|
||||
func Test_underscore_objects_8(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("defaults", function() {
|
||||
var result;
|
||||
var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"};
|
||||
@@ -197,16 +191,16 @@ func Test_underscore_objects_8(t *testing.T) {
|
||||
|
||||
equal(options.a, 1, 'should not error on <null> or <undefined> sources');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// clone
|
||||
func Test_underscore_objects_9(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("clone", function() {
|
||||
var moe = {name : 'moe', lucky : [13, 27, 34]};
|
||||
var clone = _.clone(moe);
|
||||
@@ -222,16 +216,16 @@ func Test_underscore_objects_9(t *testing.T) {
|
||||
equal(_.clone(1), 1, 'non objects should not be changed by clone');
|
||||
equal(_.clone(null), null, 'non objects should not be changed by clone');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isEqual
|
||||
func Test_underscore_objects_10(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isEqual", function() {
|
||||
function First() {
|
||||
this.value = 1;
|
||||
@@ -460,19 +454,22 @@ func Test_underscore_objects_10(t *testing.T) {
|
||||
b = _({x: 1, y: 2}).chain();
|
||||
equal(_.isEqual(a.isEqual(b), _(true)), true, '<isEqual> can be chained');
|
||||
|
||||
//// Objects from another frame.
|
||||
//ok(_.isEqual({}, iObject));
|
||||
// TEST: ???
|
||||
return;
|
||||
|
||||
// Objects from another frame.
|
||||
ok(_.isEqual({}, iObject));
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isEmpty
|
||||
func Test_underscore_objects_11(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isEmpty", function() {
|
||||
ok(!_([1]).isEmpty(), '[1] is not empty');
|
||||
ok(_.isEmpty([]), '[] is empty');
|
||||
@@ -488,16 +485,34 @@ func Test_underscore_objects_11(t *testing.T) {
|
||||
delete obj.one;
|
||||
ok(_.isEmpty(obj), 'deleting all the keys from an object empties it');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isElement
|
||||
func Test_underscore_objects_12(t *testing.T) {
|
||||
// TEST: ReferenceError: $ is not defined
|
||||
return
|
||||
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test(`
|
||||
test("isElement", function() {
|
||||
ok(!_.isElement('div'), 'strings are not dom elements');
|
||||
ok(_.isElement($('html')[0]), 'the html tag is a DOM element');
|
||||
ok(_.isElement(iElement), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isArguments
|
||||
func Test_underscore_objects_13(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isArguments", function() {
|
||||
var args = (function(){ return arguments; })(1, 2, 3);
|
||||
ok(!_.isArguments('string'), 'a string is not an arguments object');
|
||||
@@ -505,25 +520,30 @@ func Test_underscore_objects_13(t *testing.T) {
|
||||
ok(_.isArguments(args), 'but the arguments object is an arguments object');
|
||||
ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array');
|
||||
ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.');
|
||||
//ok(_.isArguments(iArguments), 'even from another frame');
|
||||
|
||||
// TEST: ReferenceError: iArguments is not defined
|
||||
return;
|
||||
ok(_.isArguments(iArguments), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isObject
|
||||
func Test_underscore_objects_14(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isObject", function() {
|
||||
ok(_.isObject(arguments), 'the arguments object is object');
|
||||
ok(_.isObject([1, 2, 3]), 'and arrays');
|
||||
//ok(_.isObject($('html')[0]), 'and DOM element');
|
||||
//ok(_.isObject(iElement), 'even from another frame');
|
||||
// TEST: ReferenceError: $ is not defined
|
||||
return;
|
||||
ok(_.isObject($('html')[0]), 'and DOM element');
|
||||
ok(_.isObject(iElement), 'even from another frame');
|
||||
ok(_.isObject(function () {}), 'and functions');
|
||||
//ok(_.isObject(iFunction), 'even from another frame');
|
||||
ok(_.isObject(iFunction), 'even from another frame');
|
||||
ok(!_.isObject(null), 'but not null');
|
||||
ok(!_.isObject(undefined), 'and not undefined');
|
||||
ok(!_.isObject('string'), 'and not string');
|
||||
@@ -531,46 +551,53 @@ func Test_underscore_objects_14(t *testing.T) {
|
||||
ok(!_.isObject(true), 'and not boolean');
|
||||
ok(_.isObject(new String('string')), 'but new String()');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isArray
|
||||
func Test_underscore_objects_15(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isArray", function() {
|
||||
ok(!_.isArray(arguments), 'the arguments object is not an array');
|
||||
ok(_.isArray([1, 2, 3]), 'but arrays are');
|
||||
//ok(_.isArray(iArray), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isArray(iArray), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isString
|
||||
func Test_underscore_objects_16(t *testing.T) {
|
||||
Terst(t)
|
||||
// TEST: ReferenceError: document is not defined
|
||||
return
|
||||
|
||||
test := underscoreTest()
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isString", function() {
|
||||
//ok(!_.isString(document.body), 'the document body is not a string');
|
||||
ok(!_.isString(document.body), 'the document body is not a string');
|
||||
ok(_.isString([1, 2, 3].join(', ')), 'but strings are');
|
||||
//ok(_.isString(iString), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isString(iString), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isNumber
|
||||
func Test_underscore_objects_17(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isNumber", function() {
|
||||
ok(!_.isNumber('string'), 'a string is not a number');
|
||||
ok(!_.isNumber(arguments), 'the arguments object is not a number');
|
||||
@@ -578,19 +605,21 @@ func Test_underscore_objects_17(t *testing.T) {
|
||||
ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are');
|
||||
ok(_.isNumber(NaN), 'NaN *is* a number');
|
||||
ok(_.isNumber(Infinity), 'Infinity is a number');
|
||||
//ok(_.isNumber(iNumber), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isNumber(iNumber), 'even from another frame');
|
||||
ok(!_.isNumber('1'), 'numeric strings are not numbers');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isBoolean
|
||||
func Test_underscore_objects_18(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isBoolean", function() {
|
||||
ok(!_.isBoolean(2), 'a number is not a boolean');
|
||||
ok(!_.isBoolean("string"), 'a string is not a boolean');
|
||||
@@ -602,65 +631,73 @@ func Test_underscore_objects_18(t *testing.T) {
|
||||
ok(!_.isBoolean(null), 'null is not a boolean');
|
||||
ok(_.isBoolean(true), 'but true is');
|
||||
ok(_.isBoolean(false), 'and so is false');
|
||||
//ok(_.isBoolean(iBoolean), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isBoolean(iBoolean), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isFunction
|
||||
func Test_underscore_objects_19(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isFunction", function() {
|
||||
ok(!_.isFunction([1, 2, 3]), 'arrays are not functions');
|
||||
ok(!_.isFunction('moe'), 'strings are not functions');
|
||||
ok(_.isFunction(_.isFunction), 'but functions are');
|
||||
//ok(_.isFunction(iFunction), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isFunction(iFunction), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isDate
|
||||
func Test_underscore_objects_20(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isDate", function() {
|
||||
ok(!_.isDate(100), 'numbers are not dates');
|
||||
ok(!_.isDate({}), 'objects are not dates');
|
||||
ok(_.isDate(new Date()), 'but dates are');
|
||||
//ok(_.isDate(iDate), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isDate(iDate), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isRegExp
|
||||
func Test_underscore_objects_21(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isRegExp", function() {
|
||||
ok(!_.isRegExp(_.identity), 'functions are not RegExps');
|
||||
ok(_.isRegExp(/identity/), 'but RegExps are');
|
||||
//ok(_.isRegExp(iRegExp), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isRegExp(iRegExp), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isFinite
|
||||
func Test_underscore_objects_22(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isFinite", function() {
|
||||
ok(!_.isFinite(undefined), 'undefined is not Finite');
|
||||
ok(!_.isFinite(null), 'null is not Finite');
|
||||
@@ -676,50 +713,54 @@ func Test_underscore_objects_22(t *testing.T) {
|
||||
ok(_.isFinite(123), 'Ints are Finite');
|
||||
ok(_.isFinite(-12.44), 'Floats are Finite');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isNaN
|
||||
func Test_underscore_objects_23(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isNaN", function() {
|
||||
ok(!_.isNaN(undefined), 'undefined is not NaN');
|
||||
ok(!_.isNaN(null), 'null is not NaN');
|
||||
ok(!_.isNaN(0), '0 is not NaN');
|
||||
ok(_.isNaN(NaN), 'but NaN is');
|
||||
//ok(_.isNaN(iNaN), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isNaN(iNaN), 'even from another frame');
|
||||
ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isNull
|
||||
func Test_underscore_objects_24(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isNull", function() {
|
||||
ok(!_.isNull(undefined), 'undefined is not null');
|
||||
ok(!_.isNull(NaN), 'NaN is not null');
|
||||
ok(_.isNull(null), 'but null is');
|
||||
//ok(_.isNull(iNull), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isNull(iNull), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// isUndefined
|
||||
func Test_underscore_objects_25(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("isUndefined", function() {
|
||||
ok(!_.isUndefined(1), 'numbers are defined');
|
||||
ok(!_.isUndefined(null), 'null is defined');
|
||||
@@ -727,18 +768,20 @@ func Test_underscore_objects_25(t *testing.T) {
|
||||
ok(!_.isUndefined(NaN), 'NaN is defined');
|
||||
ok(_.isUndefined(), 'nothing is undefined');
|
||||
ok(_.isUndefined(undefined), 'undefined is undefined');
|
||||
//ok(_.isUndefined(iUndefined), 'even from another frame');
|
||||
// TEST: ???
|
||||
return;
|
||||
ok(_.isUndefined(iUndefined), 'even from another frame');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// tap
|
||||
func Test_underscore_objects_26(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("tap", function() {
|
||||
var intercepted = null;
|
||||
var interceptor = function(obj) { intercepted = obj; };
|
||||
@@ -753,16 +796,16 @@ func Test_underscore_objects_26(t *testing.T) {
|
||||
value();
|
||||
ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// has
|
||||
func Test_underscore_objects_27(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("has", function () {
|
||||
var obj = {foo: "bar", func: function () {} };
|
||||
ok (_.has(obj, "foo"), "has() checks that the object has a property.");
|
||||
@@ -774,5 +817,6 @@ func Test_underscore_objects_27(t *testing.T) {
|
||||
child.prototype = obj;
|
||||
ok (_.has(child, "foo") == false, "has() does not check the prototype chain for a property.")
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,156 +1,164 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"github.com/robertkrimen/otto/underscore"
|
||||
"./terst"
|
||||
"testing"
|
||||
|
||||
"github.com/robertkrimen/otto/underscore"
|
||||
)
|
||||
|
||||
func init() {
|
||||
underscore.Disable()
|
||||
}
|
||||
|
||||
var (
|
||||
_underscoreTest = struct {
|
||||
Otto *Otto
|
||||
test func(string, ...interface{}) Value
|
||||
}{}
|
||||
)
|
||||
// A persistent handle for the underscore tester
|
||||
// We do not run underscore tests in parallel, so it is okay to stash globally
|
||||
// (Maybe use sync.Pool in the future...)
|
||||
var tester_ *_tester
|
||||
|
||||
func underscoreTest() func(string, ...interface{}) Value {
|
||||
cache := &_underscoreTest
|
||||
if cache.Otto == nil {
|
||||
Otto, test := runTestWithOtto()
|
||||
cache.Otto, cache.test = Otto, test
|
||||
_, err := Otto.Run(underscore.Source())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
Otto.Set("assert", func(call FunctionCall) Value {
|
||||
if !toBoolean(call.Argument(0)) {
|
||||
message := "Assertion failed"
|
||||
if len(call.ArgumentList) > 1 {
|
||||
message = toString(call.ArgumentList[1])
|
||||
}
|
||||
Fail(message)
|
||||
return FalseValue()
|
||||
}
|
||||
return TrueValue()
|
||||
})
|
||||
|
||||
Otto.Run(`
|
||||
|
||||
var templateSettings;
|
||||
|
||||
function _setup() {
|
||||
templateSettings = _.clone(_.templateSettings);
|
||||
}
|
||||
|
||||
function _teardown() {
|
||||
_.templateSettings = templateSettings;
|
||||
}
|
||||
|
||||
function module() {
|
||||
/* Nothing happens. */
|
||||
}
|
||||
|
||||
function equals(a, b, emit) {
|
||||
assert(a == b, emit + ", <" + a + "> != <" + b + ">");
|
||||
}
|
||||
var equal = equals;
|
||||
|
||||
function notStrictEqual(a, b, emit) {
|
||||
assert(a !== b, emit);
|
||||
}
|
||||
|
||||
function strictEqual(a, b, emit) {
|
||||
assert(a === b, emit);
|
||||
}
|
||||
|
||||
function ok(a, emit) {
|
||||
assert(a, emit);
|
||||
}
|
||||
|
||||
function raises(fn, want, emit) {
|
||||
var have, _ok = false;
|
||||
if (typeof want === "string") {
|
||||
emit = want;
|
||||
want = null;
|
||||
}
|
||||
|
||||
try {
|
||||
fn();
|
||||
} catch(tmp) {
|
||||
have = tmp;
|
||||
}
|
||||
|
||||
if (have) {
|
||||
if (!want) {
|
||||
_ok = true;
|
||||
}
|
||||
else if (want instanceof RegExp) {
|
||||
_ok = want.test(have);
|
||||
}
|
||||
else if (have instanceof want) {
|
||||
_ok = true
|
||||
}
|
||||
else if (want.call({}, have) === true) {
|
||||
_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
ok(_ok, emit);
|
||||
}
|
||||
|
||||
function test(name){
|
||||
_setup()
|
||||
try {
|
||||
templateSettings = _.clone(_.templateSettings);
|
||||
if (arguments.length == 3) {
|
||||
count = 0
|
||||
for (count = 0; count < arguments[1]; count++) {
|
||||
arguments[2]()
|
||||
}
|
||||
} else {
|
||||
// For now.
|
||||
arguments[1]()
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_teardown()
|
||||
}
|
||||
}
|
||||
|
||||
function deepEqual(a, b, emit) {
|
||||
// Also, for now.
|
||||
assert(_.isEqual(a, b), emit)
|
||||
}
|
||||
`)
|
||||
// A tester for underscore: test_ => test(underscore) :)
|
||||
func test_(arguments ...interface{}) (func(string, ...interface{}) Value, *_tester) {
|
||||
tester := tester_
|
||||
if tester == nil {
|
||||
tester = newTester()
|
||||
tester.underscore() // Load underscore and testing shim, etc.
|
||||
tester_ = tester
|
||||
}
|
||||
return cache.test
|
||||
|
||||
return tester.test, tester
|
||||
}
|
||||
|
||||
func (self *_tester) underscore() {
|
||||
vm := self.vm
|
||||
_, err := vm.Run(underscore.Source())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
vm.Set("assert", func(call FunctionCall) Value {
|
||||
if !toBoolean(call.Argument(0)) {
|
||||
message := "Assertion failed"
|
||||
if len(call.ArgumentList) > 1 {
|
||||
message = toString(call.ArgumentList[1])
|
||||
}
|
||||
t := terst.Caller().T()
|
||||
is(message, nil)
|
||||
t.Fail()
|
||||
return FalseValue()
|
||||
}
|
||||
return TrueValue()
|
||||
})
|
||||
|
||||
vm.Run(`
|
||||
var templateSettings;
|
||||
|
||||
function _setup() {
|
||||
templateSettings = _.clone(_.templateSettings);
|
||||
}
|
||||
|
||||
function _teardown() {
|
||||
_.templateSettings = templateSettings;
|
||||
}
|
||||
|
||||
function module() {
|
||||
/* Nothing happens. */
|
||||
}
|
||||
|
||||
function equals(a, b, emit) {
|
||||
assert(a == b, emit + ", <" + a + "> != <" + b + ">");
|
||||
}
|
||||
var equal = equals;
|
||||
|
||||
function notStrictEqual(a, b, emit) {
|
||||
assert(a !== b, emit);
|
||||
}
|
||||
|
||||
function strictEqual(a, b, emit) {
|
||||
assert(a === b, emit);
|
||||
}
|
||||
|
||||
function ok(a, emit) {
|
||||
assert(a, emit);
|
||||
}
|
||||
|
||||
function raises(fn, want, emit) {
|
||||
var have, _ok = false;
|
||||
if (typeof want === "string") {
|
||||
emit = want;
|
||||
want = null;
|
||||
}
|
||||
|
||||
try {
|
||||
fn();
|
||||
} catch(tmp) {
|
||||
have = tmp;
|
||||
}
|
||||
|
||||
if (have) {
|
||||
if (!want) {
|
||||
_ok = true;
|
||||
}
|
||||
else if (want instanceof RegExp) {
|
||||
_ok = want.test(have);
|
||||
}
|
||||
else if (have instanceof want) {
|
||||
_ok = true
|
||||
}
|
||||
else if (want.call({}, have) === true) {
|
||||
_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
ok(_ok, emit);
|
||||
}
|
||||
|
||||
function test(name){
|
||||
_setup()
|
||||
try {
|
||||
templateSettings = _.clone(_.templateSettings);
|
||||
if (arguments.length == 3) {
|
||||
count = 0
|
||||
for (count = 0; count < arguments[1]; count++) {
|
||||
arguments[2]()
|
||||
}
|
||||
} else {
|
||||
// For now.
|
||||
arguments[1]()
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_teardown()
|
||||
}
|
||||
}
|
||||
|
||||
function deepEqual(a, b, emit) {
|
||||
// Also, for now.
|
||||
assert(_.isEqual(a, b), emit)
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
func Test_underscore(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
test(`
|
||||
_.map([1, 2, 3], function(value){
|
||||
return value + 1
|
||||
})
|
||||
`, "2,3,4")
|
||||
|
||||
test(`
|
||||
_.map([1, 2, 3], function(value){
|
||||
return value + 1
|
||||
})
|
||||
`, "2,3,4")
|
||||
test(`
|
||||
abc = _.find([1, 2, 3, -1], function(value) { return value == -1 })
|
||||
`, -1)
|
||||
|
||||
test(`
|
||||
abc = _.find([1, 2, 3, -1], function(value) { return value == -1 })
|
||||
`, "-1")
|
||||
|
||||
test(`_.isEqual(1, 1)`, "true")
|
||||
test(`_.isEqual([], [])`, "true")
|
||||
test(`_.isEqual(['b', 'd'], ['b', 'd'])`, "true")
|
||||
test(`_.isEqual(['b', 'd', 'c'], ['b', 'd', 'e'])`, "false")
|
||||
test(`_.isFunction(function(){})`, "true")
|
||||
test(`_.template('<p>\u2028<%= "\\u2028\\u2029" %>\u2029</p>')()`, "<p>\u2028\u2028\u2029\u2029</p>")
|
||||
test(`_.isEqual(1, 1)`, true)
|
||||
test(`_.isEqual([], [])`, true)
|
||||
test(`_.isEqual(['b', 'd'], ['b', 'd'])`, true)
|
||||
test(`_.isEqual(['b', 'd', 'c'], ['b', 'd', 'e'])`, false)
|
||||
test(`_.isFunction(function(){})`, true)
|
||||
test(`_.template('<p>\u2028<%= "\\u2028\\u2029" %>\u2029</p>')()`, "<p>\u2028\u2028\u2029\u2029</p>")
|
||||
})
|
||||
}
|
||||
|
||||
// TODO Test: typeof An argument reference
|
||||
|
||||
@@ -1,46 +1,44 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// #750 - Return _ instance.
|
||||
func Test_underscore_utility_0(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("#750 - Return _ instance.", 2, function() {
|
||||
var instance = _([]);
|
||||
ok(_(instance) === instance);
|
||||
ok(new _(instance) === instance);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// identity
|
||||
func Test_underscore_utility_1(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("identity", function() {
|
||||
var moe = {name : 'moe'};
|
||||
equal(_.identity(moe), moe, 'moe is the same as his identity');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// random
|
||||
func Test_underscore_utility_2(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("random", function() {
|
||||
var array = _.range(1000);
|
||||
var min = Math.pow(2, 31);
|
||||
@@ -54,31 +52,31 @@ func Test_underscore_utility_2(t *testing.T) {
|
||||
return _.random(Number.MAX_VALUE) > 0;
|
||||
}), "should produce a random number when passed <Number.MAX_VALUE>");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// uniqueId
|
||||
func Test_underscore_utility_3(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("uniqueId", function() {
|
||||
var ids = [], i = 0;
|
||||
while(i++ < 100) ids.push(_.uniqueId());
|
||||
equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// times
|
||||
func Test_underscore_utility_4(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("times", function() {
|
||||
var vals = [];
|
||||
_.times(3, function (i) { vals.push(i); });
|
||||
@@ -90,16 +88,16 @@ func Test_underscore_utility_4(t *testing.T) {
|
||||
// collects return values
|
||||
ok(_.isEqual([0, 1, 2], _.times(3, function(i) { return i; })), "collects return values");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// mixin
|
||||
func Test_underscore_utility_5(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("mixin", function() {
|
||||
_.mixin({
|
||||
myReverse: function(string) {
|
||||
@@ -109,31 +107,31 @@ func Test_underscore_utility_5(t *testing.T) {
|
||||
equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _');
|
||||
equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// _.escape
|
||||
func Test_underscore_utility_6(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("_.escape", function() {
|
||||
equal(_.escape("Curly & Moe"), "Curly & Moe");
|
||||
equal(_.escape("Curly & Moe"), "Curly &amp; Moe");
|
||||
equal(_.escape(null), '');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// _.unescape
|
||||
func Test_underscore_utility_7(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("_.unescape", function() {
|
||||
var string = "Curly & Moe";
|
||||
equal(_.unescape("Curly & Moe"), string);
|
||||
@@ -141,16 +139,16 @@ func Test_underscore_utility_7(t *testing.T) {
|
||||
equal(_.unescape(null), '');
|
||||
equal(_.unescape(_.escape(string)), string);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// template
|
||||
func Test_underscore_utility_8(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test("template", function() {
|
||||
var basicTemplate = _.template("<%= thing %> is gettin' on my noives!");
|
||||
var result = basicTemplate({thing : 'This'});
|
||||
@@ -169,8 +167,7 @@ func Test_underscore_utility_8(t *testing.T) {
|
||||
for (var key in people) { \
|
||||
%><li><%= people[key] %></li><% } %></ul>");
|
||||
result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
|
||||
// TODO: Property ordering unreliable
|
||||
//equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
||||
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
||||
|
||||
var escapedCharsInJavascriptTemplate = _.template("<ul><% _.each(numbers.split('\\n'), function(item) { %><li><%= item %></li><% }) %></ul>");
|
||||
result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"});
|
||||
@@ -185,8 +182,7 @@ func Test_underscore_utility_8(t *testing.T) {
|
||||
3: "p3-thumbnail.gif"
|
||||
}
|
||||
});
|
||||
// TODO: Property ordering unreliable
|
||||
//equal(result, "3 p3-thumbnail.gif <div class=\"thumbnail\" rel=\"p1-thumbnail.gif\"></div><div class=\"thumbnail\" rel=\"p2-thumbnail.gif\"></div><div class=\"thumbnail\" rel=\"p3-thumbnail.gif\"></div>");
|
||||
equal(result, "3 p3-thumbnail.gif <div class=\"thumbnail\" rel=\"p1-thumbnail.gif\"></div><div class=\"thumbnail\" rel=\"p2-thumbnail.gif\"></div><div class=\"thumbnail\" rel=\"p3-thumbnail.gif\"></div>");
|
||||
|
||||
var noInterpolateTemplate = _.template("<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>");
|
||||
result = noInterpolateTemplate();
|
||||
@@ -213,20 +209,22 @@ func Test_underscore_utility_8(t *testing.T) {
|
||||
};
|
||||
equal(stooge.template(), "I'm Moe");
|
||||
|
||||
//if (!$.browser.msie) {
|
||||
// var fromHTML = _.template($('#template').html());
|
||||
// equal(fromHTML({data : 12345}).replace(/\s/g, ''), '<li>24690</li>');
|
||||
//}
|
||||
// TEST: ReferenceError: $ is not defined
|
||||
if (false) {
|
||||
if (!$.browser.msie) {
|
||||
var fromHTML = _.template($('#template').html());
|
||||
equal(fromHTML({data : 12345}).replace(/\s/g, ''), '<li>24690</li>');
|
||||
}
|
||||
}
|
||||
|
||||
_.templateSettings = {
|
||||
evaluate : /\{\{([\s\S]+?)\}\}/g,
|
||||
interpolate : /\{\{=([\s\S]+?)\}\}/g
|
||||
};
|
||||
|
||||
// TODO: Property ordering unreliable
|
||||
//var custom = _.template("<ul>{{ for (var key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>");
|
||||
//result = custom({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
|
||||
//equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
||||
var custom = _.template("<ul>{{ for (var key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>");
|
||||
result = custom({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
|
||||
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
||||
|
||||
var customQuote = _.template("It's its, not it's");
|
||||
equal(customQuote({}), "It's its, not it's");
|
||||
@@ -239,10 +237,9 @@ func Test_underscore_utility_8(t *testing.T) {
|
||||
interpolate : /<\?=([\s\S]+?)\?>/g
|
||||
};
|
||||
|
||||
// TODO: Property ordering unreliable
|
||||
//var customWithSpecialChars = _.template("<ul><? for (var key in people) { ?><li><?= people[key] ?></li><? } ?></ul>");
|
||||
//result = customWithSpecialChars({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
|
||||
//equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
||||
var customWithSpecialChars = _.template("<ul><? for (var key in people) { ?><li><?= people[key] ?></li><? } ?></ul>");
|
||||
result = customWithSpecialChars({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
|
||||
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
||||
|
||||
var customWithSpecialCharsQuote = _.template("It's its, not it's");
|
||||
equal(customWithSpecialCharsQuote({}), "It's its, not it's");
|
||||
@@ -260,16 +257,16 @@ func Test_underscore_utility_8(t *testing.T) {
|
||||
var templateWithNull = _.template("a null undefined {{planet}}");
|
||||
equal(templateWithNull({planet : "world"}), "a null undefined world", "can handle missing escape and evaluate settings");
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// _.template provides the generated function source, when a SyntaxError occurs
|
||||
func Test_underscore_utility_9(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('_.template provides the generated function source, when a SyntaxError occurs', function() {
|
||||
try {
|
||||
_.template('<b><%= if x %></b>');
|
||||
@@ -278,49 +275,48 @@ func Test_underscore_utility_9(t *testing.T) {
|
||||
}
|
||||
ok(/__p/.test(source));
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// _.template handles \\u2028 & \\u2029
|
||||
func Test_underscore_utility_10(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('_.template handles \\u2028 & \\u2029', function() {
|
||||
var tmpl = _.template('<p>\u2028<%= "\\u2028\\u2029" %>\u2029</p>');
|
||||
strictEqual(tmpl(), '<p>\u2028\u2028\u2029\u2029</p>');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// result calls functions and returns primitives
|
||||
func Test_underscore_utility_11(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('result calls functions and returns primitives', function() {
|
||||
var obj = {w: '', x: 'x', y: function(){ return this.x; }};
|
||||
strictEqual(_.result(obj, 'w'), '');
|
||||
strictEqual(_.result(obj, 'x'), 'x');
|
||||
strictEqual(_.result(obj, 'y'), 'x');
|
||||
strictEqual(_.result(obj, 'z'), undefined);
|
||||
// FIXME: This functionality is being changed in the underscore master right now
|
||||
//strictEqual(_.result(null, 'x'), undefined);
|
||||
strictEqual(_.result(null, 'x'), null);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// _.templateSettings.variable
|
||||
func Test_underscore_utility_12(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('_.templateSettings.variable', function() {
|
||||
var s = '<%=data.x%>';
|
||||
var data = {x: 'x'};
|
||||
@@ -328,31 +324,31 @@ func Test_underscore_utility_12(t *testing.T) {
|
||||
_.templateSettings.variable = 'data';
|
||||
strictEqual(_.template(s)(data), 'x');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// #547 - _.templateSettings is unchanged by custom settings.
|
||||
func Test_underscore_utility_13(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('#547 - _.templateSettings is unchanged by custom settings.', function() {
|
||||
ok(!_.templateSettings.variable);
|
||||
_.template('', {}, {variable: 'x'});
|
||||
ok(!_.templateSettings.variable);
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// #556 - undefined template variables.
|
||||
func Test_underscore_utility_14(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('#556 - undefined template variables.', function() {
|
||||
var template = _.template('<%=x%>');
|
||||
strictEqual(template({x: null}), '');
|
||||
@@ -370,16 +366,16 @@ func Test_underscore_utility_14(t *testing.T) {
|
||||
strictEqual(templateWithPropertyEscaped({x: {} }), '');
|
||||
strictEqual(templateWithPropertyEscaped({x: {} }), '');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// interpolate evaluates code only once.
|
||||
func Test_underscore_utility_15(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('interpolate evaluates code only once.', 2, function() {
|
||||
var count = 0;
|
||||
var template = _.template('<%= f() %>');
|
||||
@@ -389,34 +385,35 @@ func Test_underscore_utility_15(t *testing.T) {
|
||||
var templateEscaped = _.template('<%- f() %>');
|
||||
templateEscaped({f: function(){ ok(!(countEscaped++)); }});
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// #746 - _.template settings are not modified.
|
||||
func Test_underscore_utility_16(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('#746 - _.template settings are not modified.', 1, function() {
|
||||
var settings = {};
|
||||
_.template('', null, settings);
|
||||
deepEqual(settings, {});
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
// #779 - delimeters are applied to unescaped text.
|
||||
func Test_underscore_utility_17(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, _ := test_()
|
||||
|
||||
test := underscoreTest()
|
||||
|
||||
test(`
|
||||
test(`
|
||||
test('#779 - delimeters are applied to unescaped text.', 1, function() {
|
||||
var template = _.template('<<\nx\n>>', null, {evaluate: /<<(.*?)>>/g});
|
||||
strictEqual(template(), '<<\nx\n>>');
|
||||
});
|
||||
`)
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
427
value_test.go
427
value_test.go
@@ -1,280 +1,281 @@
|
||||
package otto
|
||||
|
||||
import (
|
||||
. "./terst"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValue(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
value := UndefinedValue()
|
||||
is(value.IsUndefined(), true)
|
||||
is(value, UndefinedValue())
|
||||
is(value, "undefined")
|
||||
|
||||
value := UndefinedValue()
|
||||
Is(value.IsUndefined(), true)
|
||||
Is(value, UndefinedValue())
|
||||
Is(value, "undefined")
|
||||
|
||||
Is(toValue(false), "false")
|
||||
Is(toValue(1), "1")
|
||||
Equal(toValue(1).toFloat(), float64(1))
|
||||
is(toValue(false), false)
|
||||
is(toValue(1), 1)
|
||||
is(toValue(1).toFloat(), float64(1))
|
||||
})
|
||||
}
|
||||
|
||||
func TestObject(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
Is(Value{}.isEmpty(), true)
|
||||
//Is(newObject().Value(), "[object]")
|
||||
//Is(newBooleanObject(false).Value(), "false")
|
||||
//Is(newFunctionObject(nil).Value(), "[function]")
|
||||
//Is(newNumberObject(1).Value(), "1")
|
||||
//Is(newStringObject("Hello, World.").Value(), "Hello, World.")
|
||||
tt(t, func() {
|
||||
is(Value{}.isEmpty(), true)
|
||||
//is(newObject().Value(), "[object]")
|
||||
//is(newBooleanObject(false).Value(), "false")
|
||||
//is(newFunctionObject(nil).Value(), "[function]")
|
||||
//is(newNumberObject(1).Value(), "1")
|
||||
//is(newStringObject("Hello, World.").Value(), "Hello, World.")
|
||||
})
|
||||
}
|
||||
|
||||
type intAlias int
|
||||
|
||||
func TestToValue(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
_, tester := test()
|
||||
vm := tester.vm
|
||||
|
||||
otto, _ := runTestWithOtto()
|
||||
value, _ := vm.ToValue(nil)
|
||||
is(value, "undefined")
|
||||
|
||||
value, _ := otto.ToValue(nil)
|
||||
Is(value, "undefined")
|
||||
value, _ = vm.ToValue((*byte)(nil))
|
||||
is(value, "undefined")
|
||||
|
||||
value, _ = otto.ToValue((*byte)(nil))
|
||||
Is(value, "undefined")
|
||||
value, _ = vm.ToValue(intAlias(5))
|
||||
is(value, 5)
|
||||
|
||||
value, _ = otto.ToValue(intAlias(5))
|
||||
Is(value, "5")
|
||||
{
|
||||
tmp := new(int)
|
||||
|
||||
{
|
||||
tmp := new(int)
|
||||
value, _ = vm.ToValue(&tmp)
|
||||
is(value, 0)
|
||||
|
||||
value, _ = otto.ToValue(&tmp)
|
||||
Is(value, "0")
|
||||
*tmp = 1
|
||||
|
||||
*tmp = 1
|
||||
value, _ = vm.ToValue(&tmp)
|
||||
is(value, 1)
|
||||
|
||||
value, _ = otto.ToValue(&tmp)
|
||||
Is(value, "1")
|
||||
tmp = nil
|
||||
|
||||
tmp = nil
|
||||
value, _ = vm.ToValue(&tmp)
|
||||
is(value, "undefined")
|
||||
}
|
||||
|
||||
value, _ = otto.ToValue(&tmp)
|
||||
Is(value, "undefined")
|
||||
}
|
||||
{
|
||||
tmp0 := new(int)
|
||||
tmp1 := &tmp0
|
||||
tmp2 := &tmp1
|
||||
|
||||
{
|
||||
tmp0 := new(int)
|
||||
tmp1 := &tmp0
|
||||
tmp2 := &tmp1
|
||||
value, _ = vm.ToValue(&tmp2)
|
||||
is(value, 0)
|
||||
|
||||
value, _ = otto.ToValue(&tmp2)
|
||||
Is(value, "0")
|
||||
*tmp0 = 1
|
||||
|
||||
*tmp0 = 1
|
||||
value, _ = vm.ToValue(&tmp2)
|
||||
is(value, 1)
|
||||
|
||||
value, _ = otto.ToValue(&tmp2)
|
||||
Is(value, "1")
|
||||
tmp0 = nil
|
||||
|
||||
tmp0 = nil
|
||||
|
||||
value, _ = otto.ToValue(&tmp2)
|
||||
Is(value, "undefined")
|
||||
}
|
||||
value, _ = vm.ToValue(&tmp2)
|
||||
is(value, "undefined")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestToBoolean(t *testing.T) {
|
||||
Terst(t)
|
||||
is := func(left interface{}, right bool) {
|
||||
Is(toValue(left).toBoolean(), right)
|
||||
}
|
||||
is("", false)
|
||||
is("xyzzy", true)
|
||||
is(1, true)
|
||||
is(0, false)
|
||||
//is(toValue(newObject()), true)
|
||||
is(UndefinedValue(), false)
|
||||
is(NullValue(), false)
|
||||
tt(t, func() {
|
||||
is := func(left interface{}, right bool) {
|
||||
is(toValue(left).toBoolean(), right)
|
||||
}
|
||||
|
||||
is("", false)
|
||||
is("xyzzy", true)
|
||||
is(1, true)
|
||||
is(0, false)
|
||||
//is(toValue(newObject()), true)
|
||||
is(UndefinedValue(), false)
|
||||
is(NullValue(), false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestToFloat(t *testing.T) {
|
||||
Terst(t)
|
||||
is := func(left interface{}, right float64) {
|
||||
if math.IsNaN(right) {
|
||||
Is(toValue(left).toFloat(), "NaN")
|
||||
} else {
|
||||
Is(toValue(left).toFloat(), right)
|
||||
tt(t, func() {
|
||||
{
|
||||
is := func(left interface{}, right float64) {
|
||||
is(toValue(left).toFloat(), right)
|
||||
}
|
||||
is("", 0)
|
||||
is("xyzzy", math.NaN())
|
||||
is("2", 2)
|
||||
is(1, 1)
|
||||
is(0, 0)
|
||||
is(NullValue(), 0)
|
||||
//is(newObjectValue(), math.NaN())
|
||||
}
|
||||
}
|
||||
is("", 0)
|
||||
is("xyzzy", math.NaN())
|
||||
is("2", 2)
|
||||
is(1, 1)
|
||||
is(0, 0)
|
||||
//is(newObjectValue(), math.NaN())
|
||||
IsTrue(math.IsNaN(UndefinedValue().toFloat()))
|
||||
is(NullValue(), 0)
|
||||
}
|
||||
|
||||
func TestToObject(t *testing.T) {
|
||||
Terst(t)
|
||||
is(math.IsNaN(UndefinedValue().toFloat()), true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestToString(t *testing.T) {
|
||||
Terst(t)
|
||||
Is("undefined", UndefinedValue().toString())
|
||||
Is("null", NullValue().toString())
|
||||
Is("true", toValue(true).toString())
|
||||
Is("false", toValue(false).toString())
|
||||
tt(t, func() {
|
||||
is("undefined", UndefinedValue().toString())
|
||||
is("null", NullValue().toString())
|
||||
is("true", toValue(true).toString())
|
||||
is("false", toValue(false).toString())
|
||||
|
||||
Is(UndefinedValue(), "undefined")
|
||||
Is(NullValue(), "null")
|
||||
Is(toValue(true), "true")
|
||||
Is(toValue(false), "false")
|
||||
is(UndefinedValue(), "undefined")
|
||||
is(NullValue(), "null")
|
||||
is(toValue(true), true)
|
||||
is(toValue(false), false)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_toInt32(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
test := []interface{}{
|
||||
0, int32(0),
|
||||
1, int32(1),
|
||||
-2147483649.0, int32(2147483647),
|
||||
-4294967297.0, int32(-1),
|
||||
-4294967296.0, int32(0),
|
||||
-4294967295.0, int32(1),
|
||||
math.Inf(+1), int32(0),
|
||||
math.Inf(-1), int32(0),
|
||||
}
|
||||
for index := 0; index < len(test)/2; index++ {
|
||||
Like(
|
||||
toInt32(toValue(test[index*2])),
|
||||
test[index*2+1].(int32),
|
||||
)
|
||||
}
|
||||
tt(t, func() {
|
||||
test := []interface{}{
|
||||
0, int32(0),
|
||||
1, int32(1),
|
||||
-2147483649.0, int32(2147483647),
|
||||
-4294967297.0, int32(-1),
|
||||
-4294967296.0, int32(0),
|
||||
-4294967295.0, int32(1),
|
||||
math.Inf(+1), int32(0),
|
||||
math.Inf(-1), int32(0),
|
||||
}
|
||||
for index := 0; index < len(test)/2; index++ {
|
||||
// FIXME terst, Make strict again?
|
||||
is(
|
||||
toInt32(toValue(test[index*2])),
|
||||
test[index*2+1].(int32),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_toUint32(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
test := []interface{}{
|
||||
0, uint32(0),
|
||||
1, uint32(1),
|
||||
-2147483649.0, uint32(2147483647),
|
||||
-4294967297.0, uint32(4294967295),
|
||||
-4294967296.0, uint32(0),
|
||||
-4294967295.0, uint32(1),
|
||||
math.Inf(+1), uint32(0),
|
||||
math.Inf(-1), uint32(0),
|
||||
}
|
||||
for index := 0; index < len(test)/2; index++ {
|
||||
Like(
|
||||
toUint32(toValue(test[index*2])),
|
||||
test[index*2+1].(uint32),
|
||||
)
|
||||
}
|
||||
tt(t, func() {
|
||||
test := []interface{}{
|
||||
0, uint32(0),
|
||||
1, uint32(1),
|
||||
-2147483649.0, uint32(2147483647),
|
||||
-4294967297.0, uint32(4294967295),
|
||||
-4294967296.0, uint32(0),
|
||||
-4294967295.0, uint32(1),
|
||||
math.Inf(+1), uint32(0),
|
||||
math.Inf(-1), uint32(0),
|
||||
}
|
||||
for index := 0; index < len(test)/2; index++ {
|
||||
// FIXME terst, Make strict again?
|
||||
is(
|
||||
toUint32(toValue(test[index*2])),
|
||||
test[index*2+1].(uint32),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_toUint16(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
test := []interface{}{
|
||||
0, uint16(0),
|
||||
1, uint16(1),
|
||||
-2147483649.0, uint16(65535),
|
||||
-4294967297.0, uint16(65535),
|
||||
-4294967296.0, uint16(0),
|
||||
-4294967295.0, uint16(1),
|
||||
math.Inf(+1), uint16(0),
|
||||
math.Inf(-1), uint16(0),
|
||||
}
|
||||
for index := 0; index < len(test)/2; index++ {
|
||||
Like(
|
||||
toUint16(toValue(test[index*2])),
|
||||
test[index*2+1].(uint16),
|
||||
)
|
||||
}
|
||||
tt(t, func() {
|
||||
test := []interface{}{
|
||||
0, uint16(0),
|
||||
1, uint16(1),
|
||||
-2147483649.0, uint16(65535),
|
||||
-4294967297.0, uint16(65535),
|
||||
-4294967296.0, uint16(0),
|
||||
-4294967295.0, uint16(1),
|
||||
math.Inf(+1), uint16(0),
|
||||
math.Inf(-1), uint16(0),
|
||||
}
|
||||
for index := 0; index < len(test)/2; index++ {
|
||||
// FIXME terst, Make strict again?
|
||||
is(
|
||||
toUint16(toValue(test[index*2])),
|
||||
test[index*2+1].(uint16),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_sameValue(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
IsFalse(sameValue(positiveZeroValue(), negativeZeroValue()))
|
||||
IsTrue(sameValue(positiveZeroValue(), toValue(0)))
|
||||
IsTrue(sameValue(NaNValue(), NaNValue()))
|
||||
IsFalse(sameValue(NaNValue(), toValue("Nothing happens.")))
|
||||
tt(t, func() {
|
||||
is(sameValue(positiveZeroValue(), negativeZeroValue()), false)
|
||||
is(sameValue(positiveZeroValue(), toValue(0)), true)
|
||||
is(sameValue(NaNValue(), NaNValue()), true)
|
||||
is(sameValue(NaNValue(), toValue("Nothing happens.")), false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestExport(t *testing.T) {
|
||||
Terst(t)
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
test := runTest()
|
||||
is(test(`null;`).export(), nil)
|
||||
is(test(`undefined;`).export(), nil)
|
||||
is(test(`true;`).export(), true)
|
||||
is(test(`false;`).export(), false)
|
||||
is(test(`0;`).export(), 0)
|
||||
is(test(`3.1459`).export(), 3.1459)
|
||||
is(test(`"Nothing happens";`).export(), "Nothing happens")
|
||||
is(test(`String.fromCharCode(97,98,99,100,101,102)`).export(), "abcdef")
|
||||
{
|
||||
value := test(`({ abc: 1, def: true, ghi: undefined });`).export().(map[string]interface{})
|
||||
is(value["abc"], 1)
|
||||
is(value["def"], true)
|
||||
_, exists := value["ghi"]
|
||||
is(exists, false)
|
||||
}
|
||||
{
|
||||
value := test(`[ "abc", 1, "def", true, undefined, null ];`).export().([]interface{})
|
||||
is(value[0], "abc")
|
||||
is(value[1], 1)
|
||||
is(value[2], "def")
|
||||
is(value[3], true)
|
||||
is(value[4], nil)
|
||||
is(value[5], nil)
|
||||
is(value[5], interface{}(nil))
|
||||
}
|
||||
|
||||
Is(test(`null;`).export(), nil)
|
||||
Is(test(`undefined;`).export(), nil)
|
||||
Is(test(`true;`).export(), true)
|
||||
Is(test(`false;`).export(), false)
|
||||
Is(test(`0;`).export(), 0)
|
||||
Is(test(`3.1459`).export(), 3.1459)
|
||||
Is(test(`"Nothing happens";`).export(), "Nothing happens")
|
||||
Is(test(`String.fromCharCode(97,98,99,100,101,102)`).export(), "abcdef")
|
||||
{
|
||||
value := test(`({ abc: 1, def: true, ghi: undefined });`).export().(map[string]interface{})
|
||||
Is(value["abc"], 1)
|
||||
Is(value["def"], true)
|
||||
_, exists := value["ghi"]
|
||||
Is(exists, false)
|
||||
}
|
||||
{
|
||||
value := test(`[ "abc", 1, "def", true, undefined, null ];`).export().([]interface{})
|
||||
Is(value[0], "abc")
|
||||
Is(value[1], 1)
|
||||
Is(value[2], "def")
|
||||
Is(value[3], true)
|
||||
Is(value[4], nil)
|
||||
Is(value[5], nil)
|
||||
Is(value[5], interface{}(nil))
|
||||
}
|
||||
|
||||
roundtrip := []interface{}{
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
3.1459,
|
||||
[]interface{}{true, false, 0, 3.1459, "abc"},
|
||||
map[string]interface{}{
|
||||
"Boolean": true,
|
||||
"Number": 3.1459,
|
||||
"String": "abc",
|
||||
"Array": []interface{}{false, 0, "", nil},
|
||||
"Object": map[string]interface{}{
|
||||
"Boolean": false,
|
||||
"Number": 0,
|
||||
"String": "def",
|
||||
roundtrip := []interface{}{
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
3.1459,
|
||||
[]interface{}{true, false, 0, 3.1459, "abc"},
|
||||
map[string]interface{}{
|
||||
"Boolean": true,
|
||||
"Number": 3.1459,
|
||||
"String": "abc",
|
||||
"Array": []interface{}{false, 0, "", nil},
|
||||
"Object": map[string]interface{}{
|
||||
"Boolean": false,
|
||||
"Number": 0,
|
||||
"String": "def",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
for _, value := range roundtrip {
|
||||
input, err := json.Marshal(value)
|
||||
Is(err, nil)
|
||||
for _, value := range roundtrip {
|
||||
input, err := json.Marshal(value)
|
||||
is(err, nil)
|
||||
|
||||
output, err := json.Marshal(test("(" + string(input) + ");").export())
|
||||
Is(err, nil)
|
||||
output, err := json.Marshal(test("(" + string(input) + ");").export())
|
||||
is(err, nil)
|
||||
|
||||
Is(string(input), string(output))
|
||||
}
|
||||
is(string(input), string(output))
|
||||
}
|
||||
|
||||
{
|
||||
abc := struct {
|
||||
def int
|
||||
ghi interface{}
|
||||
xyz float32
|
||||
}{}
|
||||
abc.def = 3
|
||||
abc.xyz = 3.1459
|
||||
failSet("abc", abc)
|
||||
Is(test(`abc;`).export(), abc)
|
||||
}
|
||||
{
|
||||
abc := struct {
|
||||
def int
|
||||
ghi interface{}
|
||||
xyz float32
|
||||
}{}
|
||||
abc.def = 3
|
||||
abc.xyz = 3.1459
|
||||
vm.Set("abc", abc)
|
||||
is(test(`abc;`).export(), abc)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user