From 673e6c84d1d50ac3923a80110513d828a60af170 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 21 May 2020 09:52:24 +0300 Subject: [PATCH] vm/tests: preserve order when decoding Map item. When using Go's `map` for decoding, order can change from time to time, while we may want to check it too. Use custom decoder for saving items in order. --- pkg/vm/json_test.go | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/pkg/vm/json_test.go b/pkg/vm/json_test.go index 4069025cf..229cfdd92 100644 --- a/pkg/vm/json_test.go +++ b/pkg/vm/json_test.go @@ -250,16 +250,7 @@ func (v *vmUTStackItem) toStackItem() StackItem { case typeString: panic("not implemented") case typeMap: - items := v.Value.(map[string]vmUTStackItem) - result := NewMapItem() - for k, v := range items { - item := jsonStringToInteger(k) - if item == nil { - panic(fmt.Sprintf("can't unmarshal StackItem %s", k)) - } - result.Add(item, v.toStackItem()) - } - return result + return v.Value.(*MapItem) case typeInterop: panic("not implemented") case typeByteString: @@ -426,11 +417,37 @@ func (v *vmUTStackItem) UnmarshalJSON(data []byte) error { case typeInterop, typeNull: v.Value = nil case typeMap: - var m map[string]vmUTStackItem - if err := json.Unmarshal(si.Value, &m); err != nil { - return err + // we want to have the same order as in test file, so a custom decoder is used + d := json.NewDecoder(bytes.NewReader(si.Value)) + if tok, err := d.Token(); err != nil || tok != json.Delim('{') { + return fmt.Errorf("invalid map start") } - v.Value = m + + result := NewMapItem() + for { + tok, err := d.Token() + if err != nil { + return err + } else if tok == json.Delim('}') { + break + } + key, ok := tok.(string) + if !ok { + return fmt.Errorf("string expected in map key") + } + + var it vmUTStackItem + if err := d.Decode(&it); err != nil { + return fmt.Errorf("can't decode map value: %v", err) + } + + item := jsonStringToInteger(key) + if item == nil { + return fmt.Errorf("can't unmarshal StackItem %s", key) + } + result.Add(item, it.toStackItem()) + } + v.Value = result case typeString: panic("not implemented") default: