vm: add tests to stack_item.go

closes #199
This commit is contained in:
Anna Shaleva 2020-03-31 17:18:13 +03:00
parent e41853d0a4
commit a8fa9c9244

View file

@ -1,12 +1,385 @@
package vm
import (
"math/big"
"testing"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/stretchr/testify/assert"
)
var makeStackItemTestCases = []struct {
input interface{}
result StackItem
}{
{
input: int64(3),
result: &BigIntegerItem{value: big.NewInt(3)},
},
{
input: int16(3),
result: &BigIntegerItem{value: big.NewInt(3)},
},
{
input: 3,
result: &BigIntegerItem{value: big.NewInt(3)},
},
{
input: uint8(3),
result: &BigIntegerItem{value: big.NewInt(3)},
},
{
input: uint16(3),
result: &BigIntegerItem{value: big.NewInt(3)},
},
{
input: uint32(3),
result: &BigIntegerItem{value: big.NewInt(3)},
},
{
input: uint64(3),
result: &BigIntegerItem{value: big.NewInt(3)},
},
{
input: big.NewInt(3),
result: &BigIntegerItem{value: big.NewInt(3)},
},
{
input: []byte{1, 2, 3, 4},
result: &ByteArrayItem{value: []byte{1, 2, 3, 4}},
},
{
input: []byte{},
result: &ByteArrayItem{value: []byte{}},
},
{
input: "bla",
result: &ByteArrayItem{value: []byte("bla")},
},
{
input: "",
result: &ByteArrayItem{value: []byte{}},
},
{
input: true,
result: &BoolItem{value: true},
},
{
input: false,
result: &BoolItem{value: false},
},
{
input: []StackItem{&BigIntegerItem{value: big.NewInt(3)}, &ByteArrayItem{value: []byte{1, 2, 3}}},
result: &ArrayItem{value: []StackItem{&BigIntegerItem{value: big.NewInt(3)}, &ByteArrayItem{value: []byte{1, 2, 3}}}},
},
{
input: []int{1, 2, 3},
result: &ArrayItem{value: []StackItem{&BigIntegerItem{value: big.NewInt(1)}, &BigIntegerItem{value: big.NewInt(2)}, &BigIntegerItem{value: big.NewInt(3)}}},
},
}
var makeStackItemErrorCases = []struct {
input interface{}
}{
{
input: nil,
},
}
func TestMakeStackItem(t *testing.T) {
for _, testCase := range makeStackItemTestCases {
assert.Equal(t, testCase.result, makeStackItem(testCase.input))
}
for _, errorCase := range makeStackItemErrorCases {
assert.Panics(t, func() { makeStackItem(errorCase.input) })
}
}
var stringerTestCases = []struct {
input StackItem
result string
}{
{
input: NewStructItem([]StackItem{}),
result: "Struct",
},
{
input: NewBigIntegerItem(3),
result: "BigInteger",
},
{
input: NewBoolItem(true),
result: "Boolean",
},
{
input: NewByteArrayItem([]byte{}),
result: "ByteArray",
},
{
input: NewArrayItem([]StackItem{}),
result: "Array",
},
{
input: NewMapItem(),
result: "Map",
},
{
input: NewInteropItem(nil),
result: "InteropItem",
},
}
func TestStringer(t *testing.T) {
for _, testCase := range stringerTestCases {
assert.Equal(t, testCase.result, testCase.input.String())
}
}
var equalsTestCases = map[string][]struct {
item1 StackItem
item2 StackItem
result bool
}{
"struct": {
{
item1: NewStructItem(nil),
item2: nil,
result: false,
},
{
item1: NewStructItem(nil),
item2: NewBigIntegerItem(1),
result: false,
},
{
item1: NewStructItem(nil),
item2: NewStructItem([]StackItem{NewBigIntegerItem(1)}),
result: false,
},
{
item1: NewStructItem([]StackItem{NewBigIntegerItem(1)}),
item2: NewStructItem([]StackItem{NewBigIntegerItem(2)}),
result: false,
},
{
item1: NewStructItem([]StackItem{NewBigIntegerItem(1)}),
item2: NewStructItem([]StackItem{NewBigIntegerItem(1)}),
result: true,
},
},
"bigint": {
{
item1: NewBigIntegerItem(2),
item2: nil,
result: false,
},
{
item1: NewBigIntegerItem(2),
item2: NewBigIntegerItem(2),
result: true,
},
{
item1: NewBigIntegerItem(2),
item2: NewBoolItem(false),
result: false,
},
{
item1: NewBigIntegerItem(0),
item2: NewBoolItem(false),
result: false,
},
{
item1: NewBigIntegerItem(2),
item2: makeStackItem(int32(2)),
result: true,
},
},
"bool": {
{
item1: NewBoolItem(true),
item2: nil,
result: false,
},
{
item1: NewBoolItem(true),
item2: NewBoolItem(true),
result: true,
},
{
item1: NewBoolItem(true),
item2: NewBigIntegerItem(1),
result: true,
},
{
item1: NewBoolItem(true),
item2: NewBoolItem(false),
result: false,
},
{
item1: NewBoolItem(true),
item2: makeStackItem(true),
result: true,
},
},
"bytearray": {
{
item1: NewByteArrayItem(nil),
item2: nil,
result: false,
},
{
item1: NewByteArrayItem([]byte{1, 2, 3}),
item2: NewByteArrayItem([]byte{1, 2, 3}),
result: true,
},
{
item1: NewByteArrayItem([]byte{1}),
item2: NewBigIntegerItem(1),
result: true,
},
{
item1: NewByteArrayItem([]byte{1, 2, 3}),
item2: NewByteArrayItem([]byte{1, 2, 4}),
result: false,
},
{
item1: NewByteArrayItem([]byte{1, 2, 3}),
item2: makeStackItem([]byte{1, 2, 3}),
result: true,
},
},
"array": {
{
item1: NewArrayItem(nil),
item2: nil,
result: false,
},
{
item1: NewArrayItem([]StackItem{&BigIntegerItem{big.NewInt(1)}, &BigIntegerItem{big.NewInt(2)}, &BigIntegerItem{big.NewInt(3)}}),
item2: NewArrayItem([]StackItem{&BigIntegerItem{big.NewInt(1)}, &BigIntegerItem{big.NewInt(2)}, &BigIntegerItem{big.NewInt(3)}}),
result: false,
},
{
item1: NewArrayItem([]StackItem{&BigIntegerItem{big.NewInt(1)}}),
item2: NewBigIntegerItem(1),
result: false,
},
{
item1: NewArrayItem([]StackItem{&BigIntegerItem{big.NewInt(1)}, &BigIntegerItem{big.NewInt(2)}, &BigIntegerItem{big.NewInt(3)}}),
item2: NewArrayItem([]StackItem{&BigIntegerItem{big.NewInt(1)}, &BigIntegerItem{big.NewInt(2)}, &BigIntegerItem{big.NewInt(4)}}),
result: false,
},
},
"map": {
{
item1: NewMapItem(),
item2: nil,
result: false,
},
{
item1: NewMapItem(),
item2: NewMapItem(),
result: false,
},
{
item1: &MapItem{value: map[interface{}]StackItem{"first": NewBigIntegerItem(1), true: NewByteArrayItem([]byte{2})}},
item2: &MapItem{value: map[interface{}]StackItem{"first": NewBigIntegerItem(1), true: NewByteArrayItem([]byte{2})}},
result: false,
},
{
item1: &MapItem{value: map[interface{}]StackItem{"first": NewBigIntegerItem(1), true: NewByteArrayItem([]byte{2})}},
item2: &MapItem{value: map[interface{}]StackItem{"first": NewBigIntegerItem(1), true: NewByteArrayItem([]byte{3})}},
result: false,
},
},
"interop": {
{
item1: NewInteropItem(nil),
item2: nil,
result: false,
},
{
item1: NewInteropItem(nil),
item2: NewInteropItem(nil),
result: true,
},
{
item1: NewInteropItem(2),
item2: NewInteropItem(3),
result: false,
},
{
item1: NewInteropItem(3),
item2: NewInteropItem(3),
result: true,
},
},
}
func TestEquals(t *testing.T) {
for name, testBatch := range equalsTestCases {
for _, testCase := range testBatch {
t.Run(name, func(t *testing.T) {
assert.Equal(t, testCase.result, testCase.item1.Equals(testCase.item2))
// Reference equals
assert.Equal(t, true, testCase.item1.Equals(testCase.item1))
})
}
}
}
var marshalJSONTestCases = []struct {
input StackItem
result []byte
}{
{
input: NewBigIntegerItem(2),
result: []byte(`2`),
},
{
input: NewBoolItem(true),
result: []byte(`true`),
},
{
input: NewByteArrayItem([]byte{1, 2, 3}),
result: []byte(`"010203"`),
},
{
input: &ArrayItem{value: []StackItem{&BigIntegerItem{value: big.NewInt(3)}, &ByteArrayItem{value: []byte{1, 2, 3}}}},
result: []byte(`[3,"010203"]`),
},
{
input: &InteropItem{value: 3},
result: []byte(`3`),
},
}
func TestMarshalJSON(t *testing.T) {
var (
actual []byte
err error
)
for _, testCase := range marshalJSONTestCases {
switch testCase.input.(type) {
case *BigIntegerItem:
actual, err = testCase.input.(*BigIntegerItem).MarshalJSON()
case *BoolItem:
actual, err = testCase.input.(*BoolItem).MarshalJSON()
case *ByteArrayItem:
actual, err = testCase.input.(*ByteArrayItem).MarshalJSON()
case *ArrayItem:
actual, err = testCase.input.(*ArrayItem).MarshalJSON()
case *InteropItem:
actual, err = testCase.input.(*InteropItem).MarshalJSON()
default:
continue
}
assert.NoError(t, err)
assert.Equal(t, testCase.result, actual)
}
}
var toContractParameterTestCases = []struct {
input StackItem
result smartcontract.Parameter