You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
2.9 KiB
147 lines
2.9 KiB
package json |
|
|
|
import ( |
|
"encoding/json" |
|
"reflect" |
|
"strings" |
|
"testing" |
|
|
|
testData "github.com/go-kratos/kratos/v2/internal/testdata/encoding" |
|
) |
|
|
|
type testEmbed struct { |
|
Level1a int `json:"a"` |
|
Level1b int `json:"b"` |
|
Level1c int `json:"c"` |
|
} |
|
|
|
type testMessage struct { |
|
Field1 string `json:"a"` |
|
Field2 string `json:"b"` |
|
Field3 string `json:"c"` |
|
Embed *testEmbed `json:"embed,omitempty"` |
|
} |
|
|
|
type mock struct { |
|
value int |
|
} |
|
|
|
const ( |
|
Unknown = iota |
|
Gopher |
|
Zebra |
|
) |
|
|
|
func (a *mock) UnmarshalJSON(b []byte) error { |
|
var s string |
|
if err := json.Unmarshal(b, &s); err != nil { |
|
return err |
|
} |
|
switch strings.ToLower(s) { |
|
default: |
|
a.value = Unknown |
|
case "gopher": |
|
a.value = Gopher |
|
case "zebra": |
|
a.value = Zebra |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func (a *mock) MarshalJSON() ([]byte, error) { |
|
var s string |
|
switch a.value { |
|
default: |
|
s = "unknown" |
|
case Gopher: |
|
s = "gopher" |
|
case Zebra: |
|
s = "zebra" |
|
} |
|
|
|
return json.Marshal(s) |
|
} |
|
|
|
func TestJSON_Marshal(t *testing.T) { |
|
tests := []struct { |
|
input interface{} |
|
expect string |
|
}{ |
|
{ |
|
input: &testMessage{}, |
|
expect: `{"a":"","b":"","c":""}`, |
|
}, |
|
{ |
|
input: &testMessage{Field1: "a", Field2: "b", Field3: "c"}, |
|
expect: `{"a":"a","b":"b","c":"c"}`, |
|
}, |
|
{ |
|
input: &testData.TestModel{Id: 1, Name: "go-kratos", Hobby: []string{"1", "2"}}, |
|
expect: `{"id":"1","name":"go-kratos","hobby":["1","2"],"attrs":{}}`, |
|
}, |
|
{ |
|
input: &mock{value: Gopher}, |
|
expect: `"gopher"`, |
|
}, |
|
} |
|
for _, v := range tests { |
|
data, err := (codec{}).Marshal(v.input) |
|
if err != nil { |
|
t.Errorf("marshal(%#v): %s", v.input, err) |
|
} |
|
if got, want := string(data), v.expect; strings.ReplaceAll(got, " ", "") != want { |
|
if strings.Contains(want, "\n") { |
|
t.Errorf("marshal(%#v):\nHAVE:\n%s\nWANT:\n%s", v.input, got, want) |
|
} else { |
|
t.Errorf("marshal(%#v):\nhave %#q\nwant %#q", v.input, got, want) |
|
} |
|
} |
|
} |
|
} |
|
|
|
func TestJSON_Unmarshal(t *testing.T) { |
|
p := testMessage{} |
|
p2 := testData.TestModel{} |
|
p3 := &testData.TestModel{} |
|
p4 := &mock{} |
|
tests := []struct { |
|
input string |
|
expect interface{} |
|
}{ |
|
{ |
|
input: `{"a":"","b":"","c":""}`, |
|
expect: &testMessage{}, |
|
}, |
|
{ |
|
input: `{"a":"a","b":"b","c":"c"}`, |
|
expect: &p, |
|
}, |
|
{ |
|
input: `{"id":"1","name":"go-kratos","hobby":["1","2"],"attrs":{}}`, |
|
expect: &p2, |
|
}, |
|
{ |
|
input: `{"id":1,"name":"go-kratos","hobby":["1","2"]}`, |
|
expect: &p3, |
|
}, |
|
{ |
|
input: `"zebra"`, |
|
expect: p4, |
|
}, |
|
} |
|
for _, v := range tests { |
|
want := []byte(v.input) |
|
err := (codec{}).Unmarshal(want, v.expect) |
|
if err != nil { |
|
t.Errorf("marshal(%#v): %s", v.input, err) |
|
} |
|
got, err := codec{}.Marshal(v.expect) |
|
if err != nil { |
|
t.Errorf("marshal(%#v): %s", v.input, err) |
|
} |
|
if !reflect.DeepEqual(strings.ReplaceAll(string(got), " ", ""), strings.ReplaceAll(string(want), " ", "")) { |
|
t.Errorf("marshal(%#v):\nhave %#q\nwant %#q", v.input, got, want) |
|
} |
|
} |
|
}
|
|
|