diff --git a/pkg/util/orderedmap/example_test.go b/pkg/util/orderedmap/example_test.go index 67b92800c..5cae7fefa 100644 --- a/pkg/util/orderedmap/example_test.go +++ b/pkg/util/orderedmap/example_test.go @@ -1,29 +1,30 @@ package orderedmap import ( + "bytes" "encoding/json" "reflect" "testing" ) -type KeyValue struct { +type keyValue struct { Key string Value int } -type KeyValues []KeyValue +type keyValues []keyValue -func (xs *KeyValues) UnmarshalJSON(b []byte) error { +func (xs *keyValues) UnmarshalJSON(b []byte) error { return UnmarshalJSON(b, xs) } -func (xs KeyValues) MarshalJSON() ([]byte, error) { +func (xs keyValues) MarshalJSON() ([]byte, error) { return MarshalJSON(xs) } func TestExample(t *testing.T) { in := []byte(`{"a":1,"b":2}`) - out := KeyValues{ + out := keyValues{ { Key: "a", Value: 1, @@ -34,14 +35,14 @@ func TestExample(t *testing.T) { }, } - var m KeyValues + var m keyValues err := json.Unmarshal(in, &m) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(m, out) { - t.Errorf("got m %#v", m) + t.Error(m) } b, err := json.Marshal(&m) @@ -49,7 +50,7 @@ func TestExample(t *testing.T) { t.Fatal(err) } - if !reflect.DeepEqual(b, in) { - t.Errorf("got b %s", string(b)) + if !bytes.Equal(b, in) { + t.Error(string(b)) } } diff --git a/pkg/util/orderedmap/orderedmap.go b/pkg/util/orderedmap/orderedmap.go index f70c7eb06..59740e165 100644 --- a/pkg/util/orderedmap/orderedmap.go +++ b/pkg/util/orderedmap/orderedmap.go @@ -21,6 +21,7 @@ func UnmarshalJSON(b []byte, i interface{}) error { return fmt.Errorf("unexpected token %v", tok) } + indexes := map[string]int{} for { tok, err = d.Token() if err != nil { @@ -41,7 +42,12 @@ func UnmarshalJSON(b []byte, i interface{}) error { return err } - xs = reflect.Append(xs, kv) + if i, found := indexes[k]; found { + xs.Index(i).Set(kv) + } else { + indexes[k] = xs.Len() + xs = reflect.Append(xs, kv) + } } reflect.ValueOf(i).Elem().Set(xs) diff --git a/pkg/util/orderedmap/orderedmap_test.go b/pkg/util/orderedmap/orderedmap_test.go new file mode 100644 index 000000000..b2ea3a8dd --- /dev/null +++ b/pkg/util/orderedmap/orderedmap_test.go @@ -0,0 +1,31 @@ +package orderedmap + +import ( + "encoding/json" + "reflect" + "testing" +) + +func TestUnmarshalDuplicateField(t *testing.T) { + in := []byte(`{"a":1,"b":0,"b":2}`) + out := keyValues{ + { + Key: "a", + Value: 1, + }, + { + Key: "b", + Value: 2, + }, + } + + var m keyValues + err := json.Unmarshal(in, &m) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(m, out) { + t.Error(m) + } +}