neoneo-go/pkg/vm/emit_test.go
Roman Khimov 8d4dd2d2e1 vm: move opcodes into their own package
This allows easier reuse of opcodes and in some cases allows to eliminate
dependencies on the whole vm package, like in compiler that only needs opcodes
and doesn't care about VM for any other purpose.

And yes, they're opcodes because an instruction is a whole thing with
operands, that's what context.Next() returns.
2019-12-03 18:22:14 +03:00

65 lines
1.6 KiB
Go

package vm
import (
"bytes"
"encoding/binary"
"testing"
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
"github.com/stretchr/testify/assert"
)
func TestEmitInt(t *testing.T) {
buf := new(bytes.Buffer)
EmitInt(buf, 10)
assert.Equal(t, opcode.Opcode(buf.Bytes()[0]), opcode.PUSH10)
buf.Reset()
EmitInt(buf, 100)
assert.Equal(t, buf.Bytes()[0], uint8(1))
assert.Equal(t, buf.Bytes()[1], uint8(100))
buf.Reset()
EmitInt(buf, 1000)
assert.Equal(t, buf.Bytes()[0], uint8(2))
assert.Equal(t, buf.Bytes()[1:3], []byte{0xe8, 0x03})
}
func TestEmitBool(t *testing.T) {
buf := new(bytes.Buffer)
EmitBool(buf, true)
EmitBool(buf, false)
assert.Equal(t, opcode.Opcode(buf.Bytes()[0]), opcode.PUSH1)
assert.Equal(t, opcode.Opcode(buf.Bytes()[1]), opcode.PUSH0)
}
func TestEmitString(t *testing.T) {
buf := new(bytes.Buffer)
str := "City Of Zion"
EmitString(buf, str)
assert.Equal(t, buf.Len(), len(str)+1)
assert.Equal(t, buf.Bytes()[1:], []byte(str))
}
func TestEmitSyscall(t *testing.T) {
syscalls := []string{
"Neo.Runtime.Log",
"Neo.Runtime.Notify",
"Neo.Runtime.Whatever",
}
buf := new(bytes.Buffer)
for _, syscall := range syscalls {
EmitSyscall(buf, syscall)
assert.Equal(t, opcode.Opcode(buf.Bytes()[0]), opcode.SYSCALL)
assert.Equal(t, buf.Bytes()[1], uint8(len(syscall)))
assert.Equal(t, buf.Bytes()[2:], []byte(syscall))
buf.Reset()
}
}
func TestEmitCall(t *testing.T) {
buf := new(bytes.Buffer)
EmitCall(buf, opcode.JMP, 100)
assert.Equal(t, opcode.Opcode(buf.Bytes()[0]), opcode.JMP)
label := binary.LittleEndian.Uint16(buf.Bytes()[1:3])
assert.Equal(t, label, uint16(100))
}