From 3901e7e552f25fd4eb3caceb3c928d48515ba59b Mon Sep 17 00:00:00 2001 From: Morgan Date: Wed, 26 Jun 2024 15:43:00 +0200 Subject: [PATCH] fix(tm2/std)!: use snake_case JSON fields for MemFile and MemPackage (#2019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR changes the MemFile and MemPackage to use `snake_case` fields for their JSON key names. This matches what all other objects in transactions do. A new test ensures that no transaction objects within the VM keeper have uppercase runes within their exported json fields. **BREAKING CHANGE:** old `m_addpkg` and `m_run` transactions will stop working. Clients will need to update accordingly, and this change needs to be synced like #1939. cc/ @zivkovicmilos @gnolang/berty @gnolang/onbloc --------- Co-authored-by: Miloš Živković --- gno.land/pkg/sdk/vm/errors.go | 2 +- gno.land/pkg/sdk/vm/package_test.go | 49 +++++++++++++++++++++++++++++ tm2/pkg/std/memfile.go | 10 +++--- 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 gno.land/pkg/sdk/vm/package_test.go diff --git a/gno.land/pkg/sdk/vm/errors.go b/gno.land/pkg/sdk/vm/errors.go index 132d98b7ecd..0020e989eb6 100644 --- a/gno.land/pkg/sdk/vm/errors.go +++ b/gno.land/pkg/sdk/vm/errors.go @@ -20,7 +20,7 @@ type ( InvalidExprError struct{ abciError } TypeCheckError struct { abciError - Errors []string + Errors []string `json:"errors"` } ) diff --git a/gno.land/pkg/sdk/vm/package_test.go b/gno.land/pkg/sdk/vm/package_test.go new file mode 100644 index 00000000000..f19cc55aa20 --- /dev/null +++ b/gno.land/pkg/sdk/vm/package_test.go @@ -0,0 +1,49 @@ +package vm + +import ( + "reflect" + "strings" + "testing" + "unicode" + + "github.com/stretchr/testify/assert" +) + +func TestJSONSnakeCase(t *testing.T) { + t.Parallel() + for _, typ := range Package.Types { + assertJSONSnakeCase(t, typ.Type) + } +} + +func assertJSONSnakeCase(t *testing.T, typ reflect.Type) { + t.Helper() + + switch typ.Kind() { + case reflect.Array, reflect.Slice, reflect.Pointer: + assertJSONSnakeCase(t, typ.Elem()) + case reflect.Map: + assertJSONSnakeCase(t, typ.Key()) + assertJSONSnakeCase(t, typ.Elem()) + case reflect.Struct: + for i := 0; i < typ.NumField(); i++ { + fld := typ.Field(i) + if !fld.IsExported() { + continue + } + jt := fld.Tag.Get("json") + if jt == "" { + if fld.Anonymous { + assertJSONSnakeCase(t, fld.Type) + continue + } + t.Errorf("field %s.%s does not have a json tag but is exported", typ.Name(), fld.Name) + continue + } + has := strings.ContainsFunc(jt, unicode.IsUpper) + assert.False(t, has, + "field %s.%s contains uppercase symbols in json tag", typ.Name(), fld.Name) + assertJSONSnakeCase(t, fld.Type) + } + } +} diff --git a/tm2/pkg/std/memfile.go b/tm2/pkg/std/memfile.go index ce73995a22a..01bc18c1487 100644 --- a/tm2/pkg/std/memfile.go +++ b/tm2/pkg/std/memfile.go @@ -8,8 +8,8 @@ import ( ) type MemFile struct { - Name string - Body string + Name string `json:"name" yaml:"name"` + Body string `json:"body" yaml:"body"` } // MemPackage represents the information and files of a package which will be @@ -19,9 +19,9 @@ type MemFile struct { // NOTE: in the future, a MemPackage may represent // updates/additional-files for an existing package. type MemPackage struct { - Name string // package name as declared by `package` - Path string // import path - Files []*MemFile + Name string `json:"name" yaml:"name"` // package name as declared by `package` + Path string `json:"path" yaml:"path"` // import path + Files []*MemFile `json:"files" yaml:"files"` } func (mempkg *MemPackage) GetFile(name string) *MemFile {