ensure orderedmap handles repeated fields in json objects

This commit is contained in:
Jim Minter 2019-11-30 09:07:26 -06:00
Родитель b8134eaaad
Коммит 08c3db82b0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 0730CBDA10D1A2D3
3 изменённых файлов: 48 добавлений и 10 удалений

Просмотреть файл

@ -1,29 +1,30 @@
package orderedmap package orderedmap
import ( import (
"bytes"
"encoding/json" "encoding/json"
"reflect" "reflect"
"testing" "testing"
) )
type KeyValue struct { type keyValue struct {
Key string Key string
Value int 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) return UnmarshalJSON(b, xs)
} }
func (xs KeyValues) MarshalJSON() ([]byte, error) { func (xs keyValues) MarshalJSON() ([]byte, error) {
return MarshalJSON(xs) return MarshalJSON(xs)
} }
func TestExample(t *testing.T) { func TestExample(t *testing.T) {
in := []byte(`{"a":1,"b":2}`) in := []byte(`{"a":1,"b":2}`)
out := KeyValues{ out := keyValues{
{ {
Key: "a", Key: "a",
Value: 1, Value: 1,
@ -34,14 +35,14 @@ func TestExample(t *testing.T) {
}, },
} }
var m KeyValues var m keyValues
err := json.Unmarshal(in, &m) err := json.Unmarshal(in, &m)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !reflect.DeepEqual(m, out) { if !reflect.DeepEqual(m, out) {
t.Errorf("got m %#v", m) t.Error(m)
} }
b, err := json.Marshal(&m) b, err := json.Marshal(&m)
@ -49,7 +50,7 @@ func TestExample(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if !reflect.DeepEqual(b, in) { if !bytes.Equal(b, in) {
t.Errorf("got b %s", string(b)) t.Error(string(b))
} }
} }

Просмотреть файл

@ -21,6 +21,7 @@ func UnmarshalJSON(b []byte, i interface{}) error {
return fmt.Errorf("unexpected token %v", tok) return fmt.Errorf("unexpected token %v", tok)
} }
indexes := map[string]int{}
for { for {
tok, err = d.Token() tok, err = d.Token()
if err != nil { if err != nil {
@ -41,7 +42,12 @@ func UnmarshalJSON(b []byte, i interface{}) error {
return err 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) reflect.ValueOf(i).Elem().Set(xs)

Просмотреть файл

@ -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)
}
}