forked from TrueCloudLab/neoneo-go
vm: add tests for missing bit and numeric operations
Added tests for: - bit operatoins: AND, OR, XOR - numeric operations: BOOLOR, MIN, MAX, WITHIN, NEGATE
This commit is contained in:
parent
b2c767e356
commit
495c1b0565
1 changed files with 299 additions and 0 deletions
|
@ -3032,6 +3032,305 @@ func TestHASH256(t *testing.T) {
|
|||
assert.Equal(t, res, hex.EncodeToString(vm.estack.Pop().Bytes()))
|
||||
}
|
||||
|
||||
var opcodesTestCases = map[opcode.Opcode][]struct {
|
||||
name string
|
||||
args []interface{}
|
||||
expected interface{}
|
||||
actual func(vm *VM) interface{}
|
||||
}{
|
||||
opcode.AND: {
|
||||
{
|
||||
name: "1_1",
|
||||
args: []interface{}{1, 1},
|
||||
expected: int64(1),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1_0",
|
||||
args: []interface{}{1, 0},
|
||||
expected: int64(0),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0_1",
|
||||
args: []interface{}{0, 1},
|
||||
expected: int64(0),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0_0",
|
||||
args: []interface{}{0, 0},
|
||||
expected: int64(0),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "random_values",
|
||||
args: []interface{}{
|
||||
[]byte{1, 0, 1, 0, 1, 0, 1, 1},
|
||||
[]byte{1, 1, 0, 0, 0, 0, 0, 1},
|
||||
},
|
||||
expected: []byte{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bytes()
|
||||
},
|
||||
},
|
||||
},
|
||||
opcode.OR: {
|
||||
{
|
||||
name: "1_1",
|
||||
args: []interface{}{1, 1},
|
||||
expected: int64(1),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0_0",
|
||||
args: []interface{}{0, 0},
|
||||
expected: int64(0),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0_1",
|
||||
args: []interface{}{0, 1},
|
||||
expected: int64(1),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1_0",
|
||||
args: []interface{}{1, 0},
|
||||
expected: int64(1),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "random_values",
|
||||
args: []interface{}{
|
||||
[]byte{1, 0, 1, 0, 1, 0, 1, 1},
|
||||
[]byte{1, 1, 0, 0, 0, 0, 0, 1},
|
||||
},
|
||||
expected: []byte{1, 1, 1, 0, 1, 0, 1, 1},
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bytes()
|
||||
},
|
||||
},
|
||||
},
|
||||
opcode.XOR: {
|
||||
{
|
||||
name: "1_1",
|
||||
args: []interface{}{1, 1},
|
||||
expected: int64(0),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0_0",
|
||||
args: []interface{}{0, 0},
|
||||
expected: int64(0),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0_1",
|
||||
args: []interface{}{0, 1},
|
||||
expected: int64(1),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1_0",
|
||||
args: []interface{}{1, 0},
|
||||
expected: int64(1),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "random_values",
|
||||
args: []interface{}{
|
||||
[]byte{1, 0, 1, 0, 1, 0, 1, 1},
|
||||
[]byte{1, 1, 0, 0, 0, 0, 0, 1},
|
||||
},
|
||||
expected: []byte{0, 1, 1, 0, 1, 0, 1},
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bytes()
|
||||
},
|
||||
},
|
||||
},
|
||||
opcode.BOOLOR: {
|
||||
{
|
||||
name: "1_1",
|
||||
args: []interface{}{true, true},
|
||||
expected: true,
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bool()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0_0",
|
||||
args: []interface{}{false, false},
|
||||
expected: false,
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bool()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0_1",
|
||||
args: []interface{}{false, true},
|
||||
expected: true,
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bool()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1_0",
|
||||
args: []interface{}{true, false},
|
||||
expected: true,
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bool()
|
||||
},
|
||||
},
|
||||
},
|
||||
opcode.MIN: {
|
||||
{
|
||||
name: "3_5",
|
||||
args: []interface{}{3, 5},
|
||||
expected: int64(3),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "5_3",
|
||||
args: []interface{}{5, 3},
|
||||
expected: int64(3),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "3_3",
|
||||
args: []interface{}{3, 3},
|
||||
expected: int64(3),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
},
|
||||
opcode.MAX: {
|
||||
{
|
||||
name: "3_5",
|
||||
args: []interface{}{3, 5},
|
||||
expected: int64(5),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "5_3",
|
||||
args: []interface{}{5, 3},
|
||||
expected: int64(5),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "3_3",
|
||||
args: []interface{}{3, 3},
|
||||
expected: int64(3),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
},
|
||||
opcode.WITHIN: {
|
||||
{
|
||||
name: "within",
|
||||
args: []interface{}{4, 3, 5},
|
||||
expected: true,
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bool()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "less",
|
||||
args: []interface{}{2, 3, 5},
|
||||
expected: false,
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bool()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "more",
|
||||
args: []interface{}{6, 3, 5},
|
||||
expected: false,
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().Bool()
|
||||
},
|
||||
},
|
||||
},
|
||||
opcode.NEGATE: {
|
||||
{
|
||||
name: "3",
|
||||
args: []interface{}{3},
|
||||
expected: int64(-3),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "-3",
|
||||
args: []interface{}{-3},
|
||||
expected: int64(3),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "0",
|
||||
args: []interface{}{0},
|
||||
expected: int64(0),
|
||||
actual: func(vm *VM) interface{} {
|
||||
return vm.estack.Pop().BigInt().Int64()
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestBitAndNumericOpcodes(t *testing.T) {
|
||||
for code, opcodeTestCases := range opcodesTestCases {
|
||||
t.Run(code.String(), func(t *testing.T) {
|
||||
for _, testCase := range opcodeTestCases {
|
||||
prog := makeProgram(code)
|
||||
vm := load(prog)
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
for _, arg := range testCase.args {
|
||||
vm.estack.PushVal(arg)
|
||||
}
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, testCase.expected, testCase.actual(vm))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func makeProgram(opcodes ...opcode.Opcode) []byte {
|
||||
prog := make([]byte, len(opcodes)+1) // RET
|
||||
for i := 0; i < len(opcodes); i++ {
|
||||
|
|
Loading…
Reference in a new issue