From b4a2da8a3083ef2074071e3022ac5d0a6a6f8edb Mon Sep 17 00:00:00 2001 From: Mike Bazuin Date: Fri, 18 Jan 2019 22:19:36 +0100 Subject: [PATCH 1/3] runtime/vm_builtin_test.go: Added builtin bytes convert test --- runtime/vm_builtin_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runtime/vm_builtin_test.go b/runtime/vm_builtin_test.go index c6a8abe..71746bb 100644 --- a/runtime/vm_builtin_test.go +++ b/runtime/vm_builtin_test.go @@ -74,6 +74,16 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = bool({})`, false) // empty maps: false expect(t, `out = bool(undefined)`, false) // undefined: false + expect(t, `out = bytes(1)`, []byte{0}) + expect(t, `out = bytes(1.8)`, undefined()) + expect(t, `out = bytes("-522")`, []byte{'-', '5', '2', '2'}) + expect(t, `out = bytes(true)`, undefined()) + expect(t, `out = bytes(false)`, undefined()) + expect(t, `out = bytes('8')`, undefined()) + expect(t, `out = bytes([1])`, undefined()) + expect(t, `out = bytes({a: 1})`, undefined()) + expect(t, `out = bytes(undefined)`, undefined()) + expect(t, `out = is_error(error(1))`, true) expect(t, `out = is_error(1)`, false) From a747c98fb5a484de560b5ed2a1152b9438f55702 Mon Sep 17 00:00:00 2001 From: Mike Bazuin Date: Fri, 18 Jan 2019 18:55:18 +0100 Subject: [PATCH 2/3] Builtin converts now take default values objects/builtin_convert.go: Added defaults to all builtin convert functions except bool as this one returns false for undefined, instead of undefined. runtime/vm_builtin_test.go: Added tests for checking default value behaviour for builtin convert funcs --- objects/builtin_convert.go | 54 ++++++++++++++++++++++++++++++++++---- runtime/vm_builtin_test.go | 20 ++++++++++++++ 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/objects/builtin_convert.go b/objects/builtin_convert.go index 922efc0..460a921 100644 --- a/objects/builtin_convert.go +++ b/objects/builtin_convert.go @@ -1,7 +1,8 @@ package objects func builtinString(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -14,11 +15,18 @@ func builtinString(args ...Object) (Object, error) { return &String{Value: v}, nil } + if argsLen == 2 { + if _, ok := args[1].(*String); ok { + return args[1], nil + } + } + return UndefinedValue, nil } func builtinInt(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -31,11 +39,18 @@ func builtinInt(args ...Object) (Object, error) { return &Int{Value: v}, nil } + if argsLen == 2 { + if _, ok := args[1].(*Int); ok { + return args[1], nil + } + } + return UndefinedValue, nil } func builtinFloat(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -48,6 +63,15 @@ func builtinFloat(args ...Object) (Object, error) { return &Float{Value: v}, nil } + if argsLen == 2 { + if _, ok := args[1].(*Float); ok { + return args[1], nil + } else if _, ok := args[1].(*Int); ok { + v, _ := ToFloat64(args[1]) + return &Float{Value: v}, nil + } + } + return UndefinedValue, nil } @@ -69,7 +93,8 @@ func builtinBool(args ...Object) (Object, error) { } func builtinChar(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -82,11 +107,18 @@ func builtinChar(args ...Object) (Object, error) { return &Char{Value: v}, nil } + if argsLen == 2 { + if _, ok := args[1].(*Char); ok { + return args[1], nil + } + } + return UndefinedValue, nil } func builtinBytes(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -100,5 +132,17 @@ func builtinBytes(args ...Object) (Object, error) { return &Bytes{Value: v}, nil } + if argsLen == 2 { + // bytes(N) => create a new bytes with given size N + if n, ok := args[1].(*Int); ok { + return &Bytes{Value: make([]byte, int(n.Value))}, nil + } + + v, ok = ToByteSlice(args[1]) + if ok { + return &Bytes{Value: v}, nil + } + } + return UndefinedValue, nil } diff --git a/runtime/vm_builtin_test.go b/runtime/vm_builtin_test.go index 71746bb..705834d 100644 --- a/runtime/vm_builtin_test.go +++ b/runtime/vm_builtin_test.go @@ -27,6 +27,10 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = int([1])`, undefined()) expect(t, `out = int({a: 1})`, undefined()) expect(t, `out = int(undefined)`, undefined()) + expect(t, `out = int("-522", 1)`, -522) + expect(t, `out = int(undefined, 1)`, 1) + expect(t, `out = int(undefined, 1.8)`, undefined()) + expect(t, `out = int(undefined, undefined)`, undefined()) expect(t, `out = string(1)`, "1") expect(t, `out = string(1.8)`, "1.8") @@ -37,6 +41,8 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = string([1,8.1,true,3])`, "[1, 8.1, true, 3]") expect(t, `out = string({b: "foo"})`, `{b: "foo"}`) expect(t, `out = string(undefined)`, undefined()) // not "undefined" + expect(t, `out = string(1, "-522")`, "1") + expect(t, `out = string(undefined, "-522")`, "-522") // not "undefined" expect(t, `out = float(1)`, 1.0) expect(t, `out = float(1.8)`, 1.8) @@ -47,6 +53,11 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = float([1,8.1,true,3])`, undefined()) expect(t, `out = float({a: 1, b: "foo"})`, undefined()) expect(t, `out = float(undefined)`, undefined()) + expect(t, `out = float("-52.2", 1.8)`, -52.2) + expect(t, `out = float(undefined, 1)`, 1.0) + expect(t, `out = float(undefined, 1.8)`, 1.8) + expect(t, `out = float(undefined, "-52.2")`, undefined()) + expect(t, `out = float(undefined, undefined)`, undefined()) expect(t, `out = char(56)`, '8') expect(t, `out = char(1.8)`, undefined()) @@ -57,6 +68,10 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = char([1,8.1,true,3])`, undefined()) expect(t, `out = char({a: 1, b: "foo"})`, undefined()) expect(t, `out = char(undefined)`, undefined()) + expect(t, `out = char(56, 'a')`, '8') + expect(t, `out = char(undefined, '8')`, '8') + expect(t, `out = char(undefined, 56)`, undefined()) + expect(t, `out = char(undefined, "-52.2")`, undefined()) expect(t, `out = bool(1)`, true) // non-zero integer: true expect(t, `out = bool(0)`, false) // zero: true @@ -83,6 +98,11 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = bytes([1])`, undefined()) expect(t, `out = bytes({a: 1})`, undefined()) expect(t, `out = bytes(undefined)`, undefined()) + expect(t, `out = bytes("-522", ['8'])`, []byte{'-', '5', '2', '2'}) + expect(t, `out = bytes(undefined, "-522")`, []byte{'-', '5', '2', '2'}) + expect(t, `out = bytes(undefined, 1)`, []byte{0}) + expect(t, `out = bytes(undefined, 1.8)`, undefined()) + expect(t, `out = bytes(undefined, undefined)`, undefined()) expect(t, `out = is_error(error(1))`, true) expect(t, `out = is_error(1)`, false) From fae85000cf8de6d5f827212b25c9e9d34c405f54 Mon Sep 17 00:00:00 2001 From: Mike Bazuin Date: Fri, 18 Jan 2019 23:12:16 +0100 Subject: [PATCH 3/3] Convert returns second argument Object as it self in case of failure of conversion of first argument objects/builtin_convert.go - Changed type check of in case of args[0] failure to always return args[1] if set runtime/vm_builtin_test.go: - Changed tests according to changes in objects/builtin_convert.go --- objects/builtin_convert.go | 29 +++++------------------------ runtime/vm_builtin_test.go | 20 ++++++++++++-------- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/objects/builtin_convert.go b/objects/builtin_convert.go index 460a921..2dfb7e2 100644 --- a/objects/builtin_convert.go +++ b/objects/builtin_convert.go @@ -16,9 +16,7 @@ func builtinString(args ...Object) (Object, error) { } if argsLen == 2 { - if _, ok := args[1].(*String); ok { - return args[1], nil - } + return args[1], nil } return UndefinedValue, nil @@ -40,9 +38,7 @@ func builtinInt(args ...Object) (Object, error) { } if argsLen == 2 { - if _, ok := args[1].(*Int); ok { - return args[1], nil - } + return args[1] } return UndefinedValue, nil @@ -64,12 +60,7 @@ func builtinFloat(args ...Object) (Object, error) { } if argsLen == 2 { - if _, ok := args[1].(*Float); ok { - return args[1], nil - } else if _, ok := args[1].(*Int); ok { - v, _ := ToFloat64(args[1]) - return &Float{Value: v}, nil - } + return args[1] } return UndefinedValue, nil @@ -108,9 +99,7 @@ func builtinChar(args ...Object) (Object, error) { } if argsLen == 2 { - if _, ok := args[1].(*Char); ok { - return args[1], nil - } + return args[1] } return UndefinedValue, nil @@ -133,15 +122,7 @@ func builtinBytes(args ...Object) (Object, error) { } if argsLen == 2 { - // bytes(N) => create a new bytes with given size N - if n, ok := args[1].(*Int); ok { - return &Bytes{Value: make([]byte, int(n.Value))}, nil - } - - v, ok = ToByteSlice(args[1]) - if ok { - return &Bytes{Value: v}, nil - } + return args[1] } return UndefinedValue, nil diff --git a/runtime/vm_builtin_test.go b/runtime/vm_builtin_test.go index 705834d..587269e 100644 --- a/runtime/vm_builtin_test.go +++ b/runtime/vm_builtin_test.go @@ -29,7 +29,8 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = int(undefined)`, undefined()) expect(t, `out = int("-522", 1)`, -522) expect(t, `out = int(undefined, 1)`, 1) - expect(t, `out = int(undefined, 1.8)`, undefined()) + expect(t, `out = int(undefined, 1.8)`, 1.8) + expect(t, `out = int(undefined, string(1))`, "1") expect(t, `out = int(undefined, undefined)`, undefined()) expect(t, `out = string(1)`, "1") @@ -54,9 +55,10 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = float({a: 1, b: "foo"})`, undefined()) expect(t, `out = float(undefined)`, undefined()) expect(t, `out = float("-52.2", 1.8)`, -52.2) - expect(t, `out = float(undefined, 1)`, 1.0) + expect(t, `out = float(undefined, 1)`, 1) expect(t, `out = float(undefined, 1.8)`, 1.8) - expect(t, `out = float(undefined, "-52.2")`, undefined()) + expect(t, `out = float(undefined, "-52.2")`, "-52.2") + expect(t, `out = float(undefined, char(56))`, '8') expect(t, `out = float(undefined, undefined)`, undefined()) expect(t, `out = char(56)`, '8') @@ -70,8 +72,9 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = char(undefined)`, undefined()) expect(t, `out = char(56, 'a')`, '8') expect(t, `out = char(undefined, '8')`, '8') - expect(t, `out = char(undefined, 56)`, undefined()) - expect(t, `out = char(undefined, "-52.2")`, undefined()) + expect(t, `out = char(undefined, 56)`, 56) + expect(t, `out = char(undefined, "-52.2")`, "-52.2") + expect(t, `out = char(undefined, undefined)`, undefined()) expect(t, `out = bool(1)`, true) // non-zero integer: true expect(t, `out = bool(0)`, false) // zero: true @@ -99,9 +102,10 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = bytes({a: 1})`, undefined()) expect(t, `out = bytes(undefined)`, undefined()) expect(t, `out = bytes("-522", ['8'])`, []byte{'-', '5', '2', '2'}) - expect(t, `out = bytes(undefined, "-522")`, []byte{'-', '5', '2', '2'}) - expect(t, `out = bytes(undefined, 1)`, []byte{0}) - expect(t, `out = bytes(undefined, 1.8)`, undefined()) + expect(t, `out = bytes(undefined, "-522")`, "-522") + expect(t, `out = bytes(undefined, 1)`, 1) + expect(t, `out = bytes(undefined, 1.8)`, 1.8) + expect(t, `out = bytes(undefined, int("-522"))`, -522) expect(t, `out = bytes(undefined, undefined)`, undefined()) expect(t, `out = is_error(error(1))`, true)