manifest: move Event into a file of its own

This commit is contained in:
Roman Khimov 2021-02-08 17:09:17 +03:00
parent e9ea89b4e3
commit f78e3fb290
4 changed files with 97 additions and 80 deletions

View file

@ -0,0 +1,54 @@
package manifest
import (
"errors"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
// Event is a description of a single event.
type Event struct {
Name string `json:"name"`
Parameters []Parameter `json:"parameters"`
}
// ToStackItem converts Event to stackitem.Item.
func (e *Event) ToStackItem() stackitem.Item {
params := make([]stackitem.Item, len(e.Parameters))
for i := range e.Parameters {
params[i] = e.Parameters[i].ToStackItem()
}
return stackitem.NewStruct([]stackitem.Item{
stackitem.Make(e.Name),
stackitem.Make(params),
})
}
// FromStackItem converts stackitem.Item to Event.
func (e *Event) FromStackItem(item stackitem.Item) error {
var err error
if item.Type() != stackitem.StructT {
return errors.New("invalid Event stackitem type")
}
event := item.Value().([]stackitem.Item)
if len(event) != 2 {
return errors.New("invalid Event stackitem length")
}
e.Name, err = stackitem.ToString(event[0])
if err != nil {
return err
}
if event[1].Type() != stackitem.ArrayT {
return errors.New("invalid Params stackitem type")
}
params := event[1].Value().([]stackitem.Item)
e.Parameters = make([]Parameter, len(params))
for i := range params {
p := new(Parameter)
if err := p.FromStackItem(params[i]); err != nil {
return err
}
e.Parameters[i] = *p
}
return nil
}

View file

@ -0,0 +1,43 @@
package manifest
import (
"math/big"
"testing"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/require"
)
func TestEvent_ToStackItemFromStackItem(t *testing.T) {
m := &Event{
Name: "mur",
Parameters: []Parameter{{Name: "p1", Type: smartcontract.BoolType}},
}
expected := stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray([]byte(m.Name)),
stackitem.NewArray([]stackitem.Item{
stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray([]byte(m.Parameters[0].Name)),
stackitem.NewBigInteger(big.NewInt(int64(m.Parameters[0].Type))),
}),
}),
})
CheckToFromStackItem(t, m, expected)
}
func TestEvent_FromStackItemErrors(t *testing.T) {
errCases := map[string]stackitem.Item{
"not a struct": stackitem.NewArray([]stackitem.Item{}),
"invalid length": stackitem.NewStruct([]stackitem.Item{}),
"invalid name type": stackitem.NewStruct([]stackitem.Item{stackitem.NewInterop(nil), stackitem.Null{}}),
"invalid parameters type": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray([]byte{}), stackitem.Null{}}),
"invalid parameter": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray([]byte{}), stackitem.NewArray([]stackitem.Item{stackitem.NewStruct([]stackitem.Item{})})}),
}
for name, errCase := range errCases {
t.Run(name, func(t *testing.T) {
p := new(Event)
require.Error(t, p.FromStackItem(errCase))
})
}
}

View file

@ -13,12 +13,6 @@ type Parameter struct {
Type smartcontract.ParamType `json:"type"` Type smartcontract.ParamType `json:"type"`
} }
// Event is a description of a single event.
type Event struct {
Name string `json:"name"`
Parameters []Parameter `json:"parameters"`
}
// Method represents method's metadata. // Method represents method's metadata.
type Method struct { type Method struct {
Name string `json:"name"` Name string `json:"name"`
@ -130,44 +124,3 @@ func (p *Parameter) FromStackItem(item stackitem.Item) error {
} }
return nil return nil
} }
// ToStackItem converts Event to stackitem.Item.
func (e *Event) ToStackItem() stackitem.Item {
params := make([]stackitem.Item, len(e.Parameters))
for i := range e.Parameters {
params[i] = e.Parameters[i].ToStackItem()
}
return stackitem.NewStruct([]stackitem.Item{
stackitem.Make(e.Name),
stackitem.Make(params),
})
}
// FromStackItem converts stackitem.Item to Event.
func (e *Event) FromStackItem(item stackitem.Item) error {
var err error
if item.Type() != stackitem.StructT {
return errors.New("invalid Event stackitem type")
}
event := item.Value().([]stackitem.Item)
if len(event) != 2 {
return errors.New("invalid Event stackitem length")
}
e.Name, err = stackitem.ToString(event[0])
if err != nil {
return err
}
if event[1].Type() != stackitem.ArrayT {
return errors.New("invalid Params stackitem type")
}
params := event[1].Value().([]stackitem.Item)
e.Parameters = make([]Parameter, len(params))
for i := range params {
p := new(Parameter)
if err := p.FromStackItem(params[i]); err != nil {
return err
}
e.Parameters[i] = *p
}
return nil
}

View file

@ -80,39 +80,6 @@ func TestParameter_FromStackItemErrors(t *testing.T) {
} }
} }
func TestEvent_ToStackItemFromStackItem(t *testing.T) {
m := &Event{
Name: "mur",
Parameters: []Parameter{{Name: "p1", Type: smartcontract.BoolType}},
}
expected := stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray([]byte(m.Name)),
stackitem.NewArray([]stackitem.Item{
stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray([]byte(m.Parameters[0].Name)),
stackitem.NewBigInteger(big.NewInt(int64(m.Parameters[0].Type))),
}),
}),
})
CheckToFromStackItem(t, m, expected)
}
func TestEvent_FromStackItemErrors(t *testing.T) {
errCases := map[string]stackitem.Item{
"not a struct": stackitem.NewArray([]stackitem.Item{}),
"invalid length": stackitem.NewStruct([]stackitem.Item{}),
"invalid name type": stackitem.NewStruct([]stackitem.Item{stackitem.NewInterop(nil), stackitem.Null{}}),
"invalid parameters type": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray([]byte{}), stackitem.Null{}}),
"invalid parameter": stackitem.NewStruct([]stackitem.Item{stackitem.NewByteArray([]byte{}), stackitem.NewArray([]stackitem.Item{stackitem.NewStruct([]stackitem.Item{})})}),
}
for name, errCase := range errCases {
t.Run(name, func(t *testing.T) {
p := new(Event)
require.Error(t, p.FromStackItem(errCase))
})
}
}
func TestGroup_ToStackItemFromStackItem(t *testing.T) { func TestGroup_ToStackItemFromStackItem(t *testing.T) {
pk, _ := keys.NewPrivateKey() pk, _ := keys.NewPrivateKey()
g := &Group{ g := &Group{