neoneo-go/pkg/smartcontract/manifest/standard/comply_test.go
Evgeniy Stratonikov d89f055697 smartcontract: add checks for parameter names
It can be annoying to use parameter names as specified by standard,
so a separate `CheckABI` is supported.
2021-02-19 17:06:07 +03:00

179 lines
5.4 KiB
Go

package standard
import (
"errors"
"testing"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/stretchr/testify/require"
)
func fooMethodBarEvent() *manifest.Manifest {
return &manifest.Manifest{
ABI: manifest.ABI{
Methods: []manifest.Method{
{
Name: "foo",
Parameters: []manifest.Parameter{
{Type: smartcontract.ByteArrayType},
{Type: smartcontract.PublicKeyType},
},
ReturnType: smartcontract.IntegerType,
Safe: true,
},
},
Events: []manifest.Event{
{
Name: "bar",
Parameters: []manifest.Parameter{
{Type: smartcontract.StringType},
},
},
},
},
}
}
func TestComplyMissingMethod(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.GetMethod("foo", -1).Name = "notafoo"
err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
require.True(t, errors.Is(err, ErrMethodMissing))
}
func TestComplyInvalidReturnType(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.GetMethod("foo", -1).ReturnType = smartcontract.VoidType
err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
require.True(t, errors.Is(err, ErrInvalidReturnType))
}
func TestComplyMethodParameterCount(t *testing.T) {
t.Run("Method", func(t *testing.T) {
m := fooMethodBarEvent()
f := m.ABI.GetMethod("foo", -1)
f.Parameters = append(f.Parameters, manifest.Parameter{Type: smartcontract.BoolType})
err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
require.True(t, errors.Is(err, ErrMethodMissing))
})
t.Run("Event", func(t *testing.T) {
m := fooMethodBarEvent()
ev := m.ABI.GetEvent("bar")
ev.Parameters = append(ev.Parameters[:0])
err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
require.True(t, errors.Is(err, ErrInvalidParameterCount))
})
}
func TestComplyParameterType(t *testing.T) {
t.Run("Method", func(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.GetMethod("foo", -1).Parameters[0].Type = smartcontract.InteropInterfaceType
err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
require.True(t, errors.Is(err, ErrInvalidParameterType))
})
t.Run("Event", func(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.GetEvent("bar").Parameters[0].Type = smartcontract.InteropInterfaceType
err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
require.True(t, errors.Is(err, ErrInvalidParameterType))
})
}
func TestComplyParameterName(t *testing.T) {
t.Run("Method", func(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.GetMethod("foo", -1).Parameters[0].Name = "hehe"
s := &Standard{Manifest: *fooMethodBarEvent()}
err := Comply(m, s)
require.True(t, errors.Is(err, ErrInvalidParameterName))
require.NoError(t, ComplyABI(m, s))
})
t.Run("Event", func(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.GetEvent("bar").Parameters[0].Name = "hehe"
s := &Standard{Manifest: *fooMethodBarEvent()}
err := Comply(m, s)
require.True(t, errors.Is(err, ErrInvalidParameterName))
require.NoError(t, ComplyABI(m, s))
})
}
func TestMissingEvent(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.GetEvent("bar").Name = "notabar"
err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
require.True(t, errors.Is(err, ErrEventMissing))
}
func TestSafeFlag(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.GetMethod("foo", -1).Safe = false
err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
require.True(t, errors.Is(err, ErrSafeMethodMismatch))
}
func TestComplyValid(t *testing.T) {
m := fooMethodBarEvent()
m.ABI.Methods = append(m.ABI.Methods, manifest.Method{
Name: "newmethod",
Offset: 123,
ReturnType: smartcontract.ByteArrayType,
})
m.ABI.Events = append(m.ABI.Events, manifest.Event{
Name: "otherevent",
Parameters: []manifest.Parameter{{
Name: "names do not matter",
Type: smartcontract.IntegerType,
}},
})
require.NoError(t, Comply(m, &Standard{Manifest: *fooMethodBarEvent()}))
}
func TestCheck(t *testing.T) {
m := manifest.NewManifest("Test")
require.Error(t, Check(m, manifest.NEP17StandardName))
m.ABI.Methods = append(m.ABI.Methods, decimalTokenBase.ABI.Methods...)
m.ABI.Methods = append(m.ABI.Methods, nep17.ABI.Methods...)
m.ABI.Events = append(m.ABI.Events, nep17.ABI.Events...)
require.NoError(t, Check(m, manifest.NEP17StandardName))
require.NoError(t, CheckABI(m, manifest.NEP17StandardName))
}
func TestOptional(t *testing.T) {
var m Standard
m.Optional = []manifest.Method{{
Name: "optMet",
Parameters: []manifest.Parameter{{Type: smartcontract.ByteArrayType}},
ReturnType: smartcontract.IntegerType,
}}
t.Run("wrong parameter count, do not check", func(t *testing.T) {
var actual manifest.Manifest
actual.ABI.Methods = []manifest.Method{{
Name: "optMet",
ReturnType: smartcontract.IntegerType,
}}
require.NoError(t, Comply(&actual, &m))
})
t.Run("good parameter count, bad return", func(t *testing.T) {
var actual manifest.Manifest
actual.ABI.Methods = []manifest.Method{{
Name: "optMet",
Parameters: []manifest.Parameter{{Type: smartcontract.ArrayType}},
ReturnType: smartcontract.IntegerType,
}}
require.Error(t, Comply(&actual, &m))
})
t.Run("good parameter count, good return", func(t *testing.T) {
var actual manifest.Manifest
actual.ABI.Methods = []manifest.Method{{
Name: "optMet",
Parameters: []manifest.Parameter{{Type: smartcontract.ByteArrayType}},
ReturnType: smartcontract.IntegerType,
}}
require.NoError(t, Comply(&actual, &m))
})
}