123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736 |
- package tengo_test
- import (
- "testing"
- "github.com/d5/tengo/v2"
- "github.com/d5/tengo/v2/require"
- "github.com/d5/tengo/v2/token"
- )
- func TestObject_TypeName(t *testing.T) {
- var o tengo.Object = &tengo.Int{}
- require.Equal(t, "int", o.TypeName())
- o = &tengo.Float{}
- require.Equal(t, "float", o.TypeName())
- o = &tengo.Char{}
- require.Equal(t, "char", o.TypeName())
- o = &tengo.String{}
- require.Equal(t, "string", o.TypeName())
- o = &tengo.Bool{}
- require.Equal(t, "bool", o.TypeName())
- o = &tengo.Array{}
- require.Equal(t, "array", o.TypeName())
- o = &tengo.Map{}
- require.Equal(t, "map", o.TypeName())
- o = &tengo.ArrayIterator{}
- require.Equal(t, "array-iterator", o.TypeName())
- o = &tengo.StringIterator{}
- require.Equal(t, "string-iterator", o.TypeName())
- o = &tengo.MapIterator{}
- require.Equal(t, "map-iterator", o.TypeName())
- o = &tengo.BuiltinFunction{Name: "fn"}
- require.Equal(t, "builtin-function:fn", o.TypeName())
- o = &tengo.UserFunction{Name: "fn"}
- require.Equal(t, "user-function:fn", o.TypeName())
- o = &tengo.CompiledFunction{}
- require.Equal(t, "compiled-function", o.TypeName())
- o = &tengo.Undefined{}
- require.Equal(t, "undefined", o.TypeName())
- o = &tengo.Error{}
- require.Equal(t, "error", o.TypeName())
- o = &tengo.Bytes{}
- require.Equal(t, "bytes", o.TypeName())
- }
- func TestObject_IsFalsy(t *testing.T) {
- var o tengo.Object = &tengo.Int{Value: 0}
- require.True(t, o.IsFalsy())
- o = &tengo.Int{Value: 1}
- require.False(t, o.IsFalsy())
- o = &tengo.Float{Value: 0}
- require.False(t, o.IsFalsy())
- o = &tengo.Float{Value: 1}
- require.False(t, o.IsFalsy())
- o = &tengo.Char{Value: ' '}
- require.False(t, o.IsFalsy())
- o = &tengo.Char{Value: 'T'}
- require.False(t, o.IsFalsy())
- o = &tengo.String{Value: ""}
- require.True(t, o.IsFalsy())
- o = &tengo.String{Value: " "}
- require.False(t, o.IsFalsy())
- o = &tengo.Array{Value: nil}
- require.True(t, o.IsFalsy())
- o = &tengo.Array{Value: []tengo.Object{nil}} // nil is not valid but still count as 1 element
- require.False(t, o.IsFalsy())
- o = &tengo.Map{Value: nil}
- require.True(t, o.IsFalsy())
- o = &tengo.Map{Value: map[string]tengo.Object{"a": nil}} // nil is not valid but still count as 1 element
- require.False(t, o.IsFalsy())
- o = &tengo.StringIterator{}
- require.True(t, o.IsFalsy())
- o = &tengo.ArrayIterator{}
- require.True(t, o.IsFalsy())
- o = &tengo.MapIterator{}
- require.True(t, o.IsFalsy())
- o = &tengo.BuiltinFunction{}
- require.False(t, o.IsFalsy())
- o = &tengo.CompiledFunction{}
- require.False(t, o.IsFalsy())
- o = &tengo.Undefined{}
- require.True(t, o.IsFalsy())
- o = &tengo.Error{}
- require.True(t, o.IsFalsy())
- o = &tengo.Bytes{}
- require.True(t, o.IsFalsy())
- o = &tengo.Bytes{Value: []byte{1, 2}}
- require.False(t, o.IsFalsy())
- }
- func TestObject_String(t *testing.T) {
- var o tengo.Object = &tengo.Int{Value: 0}
- require.Equal(t, "0", o.String())
- o = &tengo.Int{Value: 1}
- require.Equal(t, "1", o.String())
- o = &tengo.Float{Value: 0}
- require.Equal(t, "0", o.String())
- o = &tengo.Float{Value: 1}
- require.Equal(t, "1", o.String())
- o = &tengo.Char{Value: ' '}
- require.Equal(t, " ", o.String())
- o = &tengo.Char{Value: 'T'}
- require.Equal(t, "T", o.String())
- o = &tengo.String{Value: ""}
- require.Equal(t, `""`, o.String())
- o = &tengo.String{Value: " "}
- require.Equal(t, `" "`, o.String())
- o = &tengo.Array{Value: nil}
- require.Equal(t, "[]", o.String())
- o = &tengo.Map{Value: nil}
- require.Equal(t, "{}", o.String())
- o = &tengo.Error{Value: nil}
- require.Equal(t, "error", o.String())
- o = &tengo.Error{Value: &tengo.String{Value: "error 1"}}
- require.Equal(t, `error: "error 1"`, o.String())
- o = &tengo.StringIterator{}
- require.Equal(t, "<string-iterator>", o.String())
- o = &tengo.ArrayIterator{}
- require.Equal(t, "<array-iterator>", o.String())
- o = &tengo.MapIterator{}
- require.Equal(t, "<map-iterator>", o.String())
- o = &tengo.Undefined{}
- require.Equal(t, "<undefined>", o.String())
- o = &tengo.Bytes{}
- require.Equal(t, "", o.String())
- o = &tengo.Bytes{Value: []byte("foo")}
- require.Equal(t, "foo", o.String())
- }
- func TestObject_BinaryOp(t *testing.T) {
- var o tengo.Object = &tengo.Char{}
- _, err := o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.Bool{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.Map{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.ArrayIterator{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.StringIterator{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.MapIterator{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.BuiltinFunction{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.CompiledFunction{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.Undefined{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- o = &tengo.Error{}
- _, err = o.BinaryOp(token.Add, tengo.UndefinedValue)
- require.Error(t, err)
- }
- func TestArray_BinaryOp(t *testing.T) {
- testBinaryOp(t, &tengo.Array{Value: nil}, token.Add,
- &tengo.Array{Value: nil}, &tengo.Array{Value: nil})
- testBinaryOp(t, &tengo.Array{Value: nil}, token.Add,
- &tengo.Array{Value: []tengo.Object{}}, &tengo.Array{Value: nil})
- testBinaryOp(t, &tengo.Array{Value: []tengo.Object{}}, token.Add,
- &tengo.Array{Value: nil}, &tengo.Array{Value: []tengo.Object{}})
- testBinaryOp(t, &tengo.Array{Value: []tengo.Object{}}, token.Add,
- &tengo.Array{Value: []tengo.Object{}},
- &tengo.Array{Value: []tengo.Object{}})
- testBinaryOp(t, &tengo.Array{Value: nil}, token.Add,
- &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 1},
- }}, &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 1},
- }})
- testBinaryOp(t, &tengo.Array{Value: nil}, token.Add,
- &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 1},
- &tengo.Int{Value: 2},
- &tengo.Int{Value: 3},
- }}, &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 1},
- &tengo.Int{Value: 2},
- &tengo.Int{Value: 3},
- }})
- testBinaryOp(t, &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 1},
- &tengo.Int{Value: 2},
- &tengo.Int{Value: 3},
- }}, token.Add, &tengo.Array{Value: nil},
- &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 1},
- &tengo.Int{Value: 2},
- &tengo.Int{Value: 3},
- }})
- testBinaryOp(t, &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 1},
- &tengo.Int{Value: 2},
- &tengo.Int{Value: 3},
- }}, token.Add, &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 4},
- &tengo.Int{Value: 5},
- &tengo.Int{Value: 6},
- }}, &tengo.Array{Value: []tengo.Object{
- &tengo.Int{Value: 1},
- &tengo.Int{Value: 2},
- &tengo.Int{Value: 3},
- &tengo.Int{Value: 4},
- &tengo.Int{Value: 5},
- &tengo.Int{Value: 6},
- }})
- }
- func TestError_Equals(t *testing.T) {
- err1 := &tengo.Error{Value: &tengo.String{Value: "some error"}}
- err2 := err1
- require.True(t, err1.Equals(err2))
- require.True(t, err2.Equals(err1))
- err2 = &tengo.Error{Value: &tengo.String{Value: "some error"}}
- require.False(t, err1.Equals(err2))
- require.False(t, err2.Equals(err1))
- }
- func TestFloat_BinaryOp(t *testing.T) {
- // float + float
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := float64(-2); r <= 2.1; r += 0.4 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Add,
- &tengo.Float{Value: r}, &tengo.Float{Value: l + r})
- }
- }
- // float - float
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := float64(-2); r <= 2.1; r += 0.4 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Sub,
- &tengo.Float{Value: r}, &tengo.Float{Value: l - r})
- }
- }
- // float * float
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := float64(-2); r <= 2.1; r += 0.4 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Mul,
- &tengo.Float{Value: r}, &tengo.Float{Value: l * r})
- }
- }
- // float / float
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := float64(-2); r <= 2.1; r += 0.4 {
- if r != 0 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Quo,
- &tengo.Float{Value: r}, &tengo.Float{Value: l / r})
- }
- }
- }
- // float < float
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := float64(-2); r <= 2.1; r += 0.4 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Less,
- &tengo.Float{Value: r}, boolValue(l < r))
- }
- }
- // float > float
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := float64(-2); r <= 2.1; r += 0.4 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Greater,
- &tengo.Float{Value: r}, boolValue(l > r))
- }
- }
- // float <= float
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := float64(-2); r <= 2.1; r += 0.4 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.LessEq,
- &tengo.Float{Value: r}, boolValue(l <= r))
- }
- }
- // float >= float
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := float64(-2); r <= 2.1; r += 0.4 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.GreaterEq,
- &tengo.Float{Value: r}, boolValue(l >= r))
- }
- }
- // float + int
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Add,
- &tengo.Int{Value: r}, &tengo.Float{Value: l + float64(r)})
- }
- }
- // float - int
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Sub,
- &tengo.Int{Value: r}, &tengo.Float{Value: l - float64(r)})
- }
- }
- // float * int
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Mul,
- &tengo.Int{Value: r}, &tengo.Float{Value: l * float64(r)})
- }
- }
- // float / int
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := int64(-2); r <= 2; r++ {
- if r != 0 {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Quo,
- &tengo.Int{Value: r},
- &tengo.Float{Value: l / float64(r)})
- }
- }
- }
- // float < int
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Less,
- &tengo.Int{Value: r}, boolValue(l < float64(r)))
- }
- }
- // float > int
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Float{Value: l}, token.Greater,
- &tengo.Int{Value: r}, boolValue(l > float64(r)))
- }
- }
- // float <= int
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Float{Value: l}, token.LessEq,
- &tengo.Int{Value: r}, boolValue(l <= float64(r)))
- }
- }
- // float >= int
- for l := float64(-2); l <= 2.1; l += 0.4 {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Float{Value: l}, token.GreaterEq,
- &tengo.Int{Value: r}, boolValue(l >= float64(r)))
- }
- }
- }
- func TestInt_BinaryOp(t *testing.T) {
- // int + int
- for l := int64(-2); l <= 2; l++ {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Add,
- &tengo.Int{Value: r}, &tengo.Int{Value: l + r})
- }
- }
- // int - int
- for l := int64(-2); l <= 2; l++ {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Sub,
- &tengo.Int{Value: r}, &tengo.Int{Value: l - r})
- }
- }
- // int * int
- for l := int64(-2); l <= 2; l++ {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Mul,
- &tengo.Int{Value: r}, &tengo.Int{Value: l * r})
- }
- }
- // int / int
- for l := int64(-2); l <= 2; l++ {
- for r := int64(-2); r <= 2; r++ {
- if r != 0 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Quo,
- &tengo.Int{Value: r}, &tengo.Int{Value: l / r})
- }
- }
- }
- // int % int
- for l := int64(-4); l <= 4; l++ {
- for r := -int64(-4); r <= 4; r++ {
- if r == 0 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Rem,
- &tengo.Int{Value: r}, &tengo.Int{Value: l % r})
- }
- }
- }
- // int & int
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.And, &tengo.Int{Value: 0},
- &tengo.Int{Value: int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.And, &tengo.Int{Value: 0},
- &tengo.Int{Value: int64(1) & int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.And, &tengo.Int{Value: 1},
- &tengo.Int{Value: int64(0) & int64(1)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.And, &tengo.Int{Value: 1},
- &tengo.Int{Value: int64(1)})
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.And, &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(0) & int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.And, &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(1) & int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: int64(0xffffffff)}, token.And,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: 1984}, token.And,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(1984) & int64(0xffffffff)})
- testBinaryOp(t, &tengo.Int{Value: -1984}, token.And,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(-1984) & int64(0xffffffff)})
- // int | int
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.Or, &tengo.Int{Value: 0},
- &tengo.Int{Value: int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.Or, &tengo.Int{Value: 0},
- &tengo.Int{Value: int64(1) | int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.Or, &tengo.Int{Value: 1},
- &tengo.Int{Value: int64(0) | int64(1)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.Or, &tengo.Int{Value: 1},
- &tengo.Int{Value: int64(1)})
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.Or, &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(0) | int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.Or, &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(1) | int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: int64(0xffffffff)}, token.Or,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: 1984}, token.Or,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(1984) | int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: -1984}, token.Or,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(-1984) | int64(0xffffffff)})
- // int ^ int
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.Xor, &tengo.Int{Value: 0},
- &tengo.Int{Value: int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.Xor, &tengo.Int{Value: 0},
- &tengo.Int{Value: int64(1) ^ int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.Xor, &tengo.Int{Value: 1},
- &tengo.Int{Value: int64(0) ^ int64(1)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.Xor, &tengo.Int{Value: 1},
- &tengo.Int{Value: int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.Xor, &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(0) ^ int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.Xor, &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(1) ^ int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: int64(0xffffffff)}, token.Xor,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 1984}, token.Xor,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(1984) ^ int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: -1984}, token.Xor,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(-1984) ^ int64(0xffffffff)})
- // int &^ int
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.AndNot, &tengo.Int{Value: 0},
- &tengo.Int{Value: int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.AndNot, &tengo.Int{Value: 0},
- &tengo.Int{Value: int64(1) &^ int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.AndNot,
- &tengo.Int{Value: 1}, &tengo.Int{Value: int64(0) &^ int64(1)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.AndNot, &tengo.Int{Value: 1},
- &tengo.Int{Value: int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.AndNot,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(0) &^ int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.AndNot,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(1) &^ int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: int64(0xffffffff)}, token.AndNot,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(0)})
- testBinaryOp(t,
- &tengo.Int{Value: 1984}, token.AndNot,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(1984) &^ int64(0xffffffff)})
- testBinaryOp(t,
- &tengo.Int{Value: -1984}, token.AndNot,
- &tengo.Int{Value: int64(0xffffffff)},
- &tengo.Int{Value: int64(-1984) &^ int64(0xffffffff)})
- // int << int
- for s := int64(0); s < 64; s++ {
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.Shl, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(0) << uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.Shl, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(1) << uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: 2}, token.Shl, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(2) << uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: -1}, token.Shl, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(-1) << uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: -2}, token.Shl, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(-2) << uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: int64(0xffffffff)}, token.Shl,
- &tengo.Int{Value: s},
- &tengo.Int{Value: int64(0xffffffff) << uint(s)})
- }
- // int >> int
- for s := int64(0); s < 64; s++ {
- testBinaryOp(t,
- &tengo.Int{Value: 0}, token.Shr, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(0) >> uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: 1}, token.Shr, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(1) >> uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: 2}, token.Shr, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(2) >> uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: -1}, token.Shr, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(-1) >> uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: -2}, token.Shr, &tengo.Int{Value: s},
- &tengo.Int{Value: int64(-2) >> uint(s)})
- testBinaryOp(t,
- &tengo.Int{Value: int64(0xffffffff)}, token.Shr,
- &tengo.Int{Value: s},
- &tengo.Int{Value: int64(0xffffffff) >> uint(s)})
- }
- // int < int
- for l := int64(-2); l <= 2; l++ {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Less,
- &tengo.Int{Value: r}, boolValue(l < r))
- }
- }
- // int > int
- for l := int64(-2); l <= 2; l++ {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Greater,
- &tengo.Int{Value: r}, boolValue(l > r))
- }
- }
- // int <= int
- for l := int64(-2); l <= 2; l++ {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Int{Value: l}, token.LessEq,
- &tengo.Int{Value: r}, boolValue(l <= r))
- }
- }
- // int >= int
- for l := int64(-2); l <= 2; l++ {
- for r := int64(-2); r <= 2; r++ {
- testBinaryOp(t, &tengo.Int{Value: l}, token.GreaterEq,
- &tengo.Int{Value: r}, boolValue(l >= r))
- }
- }
- // int + float
- for l := int64(-2); l <= 2; l++ {
- for r := float64(-2); r <= 2.1; r += 0.5 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Add,
- &tengo.Float{Value: r},
- &tengo.Float{Value: float64(l) + r})
- }
- }
- // int - float
- for l := int64(-2); l <= 2; l++ {
- for r := float64(-2); r <= 2.1; r += 0.5 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Sub,
- &tengo.Float{Value: r},
- &tengo.Float{Value: float64(l) - r})
- }
- }
- // int * float
- for l := int64(-2); l <= 2; l++ {
- for r := float64(-2); r <= 2.1; r += 0.5 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Mul,
- &tengo.Float{Value: r},
- &tengo.Float{Value: float64(l) * r})
- }
- }
- // int / float
- for l := int64(-2); l <= 2; l++ {
- for r := float64(-2); r <= 2.1; r += 0.5 {
- if r != 0 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Quo,
- &tengo.Float{Value: r},
- &tengo.Float{Value: float64(l) / r})
- }
- }
- }
- // int < float
- for l := int64(-2); l <= 2; l++ {
- for r := float64(-2); r <= 2.1; r += 0.5 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Less,
- &tengo.Float{Value: r}, boolValue(float64(l) < r))
- }
- }
- // int > float
- for l := int64(-2); l <= 2; l++ {
- for r := float64(-2); r <= 2.1; r += 0.5 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.Greater,
- &tengo.Float{Value: r}, boolValue(float64(l) > r))
- }
- }
- // int <= float
- for l := int64(-2); l <= 2; l++ {
- for r := float64(-2); r <= 2.1; r += 0.5 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.LessEq,
- &tengo.Float{Value: r}, boolValue(float64(l) <= r))
- }
- }
- // int >= float
- for l := int64(-2); l <= 2; l++ {
- for r := float64(-2); r <= 2.1; r += 0.5 {
- testBinaryOp(t, &tengo.Int{Value: l}, token.GreaterEq,
- &tengo.Float{Value: r}, boolValue(float64(l) >= r))
- }
- }
- }
- func TestMap_Index(t *testing.T) {
- m := &tengo.Map{Value: make(map[string]tengo.Object)}
- k := &tengo.Int{Value: 1}
- v := &tengo.String{Value: "abcdef"}
- err := m.IndexSet(k, v)
- require.NoError(t, err)
- res, err := m.IndexGet(k)
- require.NoError(t, err)
- require.Equal(t, v, res)
- }
- func TestString_BinaryOp(t *testing.T) {
- lstr := "abcde"
- rstr := "01234"
- for l := 0; l < len(lstr); l++ {
- for r := 0; r < len(rstr); r++ {
- ls := lstr[l:]
- rs := rstr[r:]
- testBinaryOp(t, &tengo.String{Value: ls}, token.Add,
- &tengo.String{Value: rs},
- &tengo.String{Value: ls + rs})
- rc := []rune(rstr)[r]
- testBinaryOp(t, &tengo.String{Value: ls}, token.Add,
- &tengo.Char{Value: rc},
- &tengo.String{Value: ls + string(rc)})
- }
- }
- }
- func testBinaryOp(
- t *testing.T,
- lhs tengo.Object,
- op token.Token,
- rhs tengo.Object,
- expected tengo.Object,
- ) {
- t.Helper()
- actual, err := lhs.BinaryOp(op, rhs)
- require.NoError(t, err)
- require.Equal(t, expected, actual)
- }
- func boolValue(b bool) tengo.Object {
- if b {
- return tengo.TrueValue
- }
- return tengo.FalseValue
- }
|