package otto import ( "encoding/json" "math" "reflect" "testing" ) func TestValue(t *testing.T) { tt(t, func() { value := UndefinedValue() is(value.IsUndefined(), true) is(value, UndefinedValue()) is(value, "undefined") is(toValue(false), false) is(toValue(1), 1) is(toValue(1).float64(), float64(1)) }) } func TestObject(t *testing.T) { tt(t, func() { is(emptyValue.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) { tt(t, func() { _, tester := test() vm := tester.vm value, _ := vm.ToValue(nil) is(value, "undefined") value, _ = vm.ToValue((*byte)(nil)) is(value, "undefined") value, _ = vm.ToValue(intAlias(5)) is(value, 5) { tmp := new(int) value, _ = vm.ToValue(&tmp) is(value, 0) *tmp = 1 value, _ = vm.ToValue(&tmp) is(value, 1) tmp = nil value, _ = vm.ToValue(&tmp) is(value, "undefined") } { tmp0 := new(int) tmp1 := &tmp0 tmp2 := &tmp1 value, _ = vm.ToValue(&tmp2) is(value, 0) *tmp0 = 1 value, _ = vm.ToValue(&tmp2) is(value, 1) tmp0 = nil value, _ = vm.ToValue(&tmp2) is(value, "undefined") } }) } func TestToBoolean(t *testing.T) { tt(t, func() { is := func(left interface{}, right bool) { is(toValue(left).bool(), right) } is("", false) is("xyzzy", true) is(1, true) is(0, false) //is(toValue(newObject()), true) is(UndefinedValue(), false) is(NullValue(), false) is([]uint16{}, false) is([]uint16{0x68, 0x65, 0x6c, 0x6c, 0x6f}, true) }) } func TestToFloat(t *testing.T) { tt(t, func() { { is := func(left interface{}, right float64) { is(toValue(left).float64(), right) } is("", 0) is("xyzzy", math.NaN()) is("2", 2) is(1, 1) is(0, 0) is(NullValue(), 0) //is(newObjectValue(), math.NaN()) } is(math.IsNaN(UndefinedValue().float64()), true) }) } func TestToString(t *testing.T) { tt(t, func() { is("undefined", UndefinedValue().string()) is("null", NullValue().string()) is("true", toValue(true).string()) is("false", toValue(false).string()) is(UndefinedValue(), "undefined") is(NullValue(), "null") is(toValue(true), true) is(toValue(false), false) }) } func Test_toInt32(t *testing.T) { 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) { 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) { 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) { 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) { tt(t, func() { test, vm := test() 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)) } { value := test(`[ undefined, null ];`).export().([]interface{}) is(value[0], nil) is(value[1], nil) is(value[1], 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", }, }, } for _, value := range roundtrip { input, err := json.Marshal(value) is(err, nil) output, err := json.Marshal(test("(" + string(input) + ");").export()) is(err, nil) is(string(input), string(output)) } { abc := struct { def int ghi interface{} xyz float32 }{} abc.def = 3 abc.xyz = 3.1459 vm.Set("abc", abc) is(test(`abc;`).export(), abc) } }) } func Test_toReflectValue(t *testing.T) { tt(t, func() { value := toValue(0.0) tmp, err := value.toReflectValue(reflect.Float32) is(tmp.Float(), 0.0) is(err, nil) }) }