package compiler_test import ( "errors" "fmt" "math/big" "testing" "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/stretchr/testify/require" ) func TestPanic(t *testing.T) { t.Run("no panic", func(t *testing.T) { src := getPanicSource(false, `"execution fault"`) eval(t, src, big.NewInt(7)) }) t.Run("panic with message", func(t *testing.T) { var logs []string src := getPanicSource(true, `"execution fault"`) v := vmAndCompile(t, src) v.SyscallHandler = getLogHandler(&logs) require.Error(t, v.Run()) require.True(t, v.HasFailed()) require.Equal(t, 1, len(logs)) require.Equal(t, "execution fault", logs[0]) }) t.Run("panic with nil", func(t *testing.T) { var logs []string src := getPanicSource(true, `nil`) v := vmAndCompile(t, src) v.SyscallHandler = getLogHandler(&logs) require.Error(t, v.Run()) require.True(t, v.HasFailed()) require.Equal(t, 0, len(logs)) }) } func getPanicSource(need bool, message string) string { return fmt.Sprintf(` package main func Main() int { needPanic := %#v if needPanic { panic(%s) return 5 } return 7 } `, need, message) } func getLogHandler(logs *[]string) vm.SyscallHandler { logID := emit.InteropNameToID([]byte("System.Runtime.Log")) return func(v *vm.VM, id uint32) error { if id != logID { return errors.New("syscall not found") } msg := string(v.Estack().Pop().Bytes()) *logs = append(*logs, msg) return nil } }