1
16
17 package issue_test
18
19 import (
20 `encoding/json`
21 `testing`
22
23 `github.com/bytedance/sonic`
24 `github.com/stretchr/testify/assert`
25 `github.com/stretchr/testify/require`
26 )
27
28 type Foo struct {
29 Name string
30 }
31
32 func (f *Foo) UnmarshalJSON(data []byte) error {
33 println("UnmarshalJSON called!!!")
34 f.Name = "Unmarshaler"
35 return nil
36 }
37
38 type MyPtr *Foo
39
40 func TestIssue379(t *testing.T) {
41 tests := []struct{
42 data string
43 newf func() interface{}
44 equal func(exp, act interface{}) bool
45 } {
46 {
47 data: `{"Name":"MyPtr"}`,
48 newf: func() interface{} { return &Foo{} },
49 },
50 {
51 data: `{"Name":"MyPtr"}`,
52 newf: func() interface{} { ptr := &Foo{}; return &ptr },
53 },
54 {
55 data: `{"Name":"MyPtr"}`,
56 newf: func() interface{} { return MyPtr(&Foo{}) },
57 },
58 {
59 data: `{"Name":"MyPtr"}`,
60 newf: func() interface{} { ptr := MyPtr(&Foo{}); return &ptr },
61 },
62 {
63 data: `null`,
64 newf: func() interface{} { return MyPtr(&Foo{}) },
65 },
66 {
67 data: `null`,
68 newf: func() interface{} { ptr := MyPtr(&Foo{}); return &ptr },
69 equal: func(exp, act interface{}) bool {
70 isExpNil := exp == nil || *(exp.(*MyPtr)) == nil
71 isActNil := act == nil || *(act.(*MyPtr)) == nil
72 return isActNil == isExpNil
73 },
74 },
75 {
76 data: `null`,
77 newf: func() interface{} { return &Foo{} },
78 },
79 {
80 data: `null`,
81 newf: func() interface{} { ptr := &Foo{}; return &ptr },
82 equal: func(exp, act interface{}) bool {
83 isExpNil := exp == nil || *(exp.(**Foo)) == nil
84 isActNil := act == nil || *(act.(**Foo)) == nil
85 return isActNil == isExpNil
86 },
87 },
88 {
89 data: `{"map":{"Name":"MyPtr"}}`,
90 newf: func() interface{} { return new(map[string]MyPtr) },
91 },
92 {
93 data: `{"map":{"Name":"MyPtr"}}`,
94 newf: func() interface{} { return new(map[string]*Foo) },
95 },
96 {
97 data: `{"map":{"Name":"MyPtr"}}`,
98 newf: func() interface{} { return new(map[string]*MyPtr) },
99 },
100 {
101 data: `[{"Name":"MyPtr"}]`,
102 newf: func() interface{} { return new([]MyPtr) },
103 },
104 {
105 data: `[{"Name":"MyPtr"}]`,
106 newf: func() interface{} { return new([]*MyPtr) },
107 },
108 {
109 data: `[{"Name":"MyPtr"}]`,
110 newf: func() interface{} { return new([]*Foo) },
111 },
112 }
113
114 for i, tt := range tests {
115 println(i)
116 jv, sv := tt.newf(), tt.newf()
117 jerr := json.Unmarshal([]byte(tt.data), jv)
118 serr := sonic.Unmarshal([]byte(tt.data), sv)
119 require.Equal(t, jv, sv)
120 require.Equal(t, jerr, serr)
121
122 jv, sv = tt.newf(), tt.newf()
123 jerr = json.Unmarshal([]byte(tt.data), &jv)
124 serr = sonic.Unmarshal([]byte(tt.data), &sv)
125 if !assert.ObjectsAreEqual(jv, sv) {
126 if tt.equal == nil || !tt.equal(jv, sv) {
127 t.Fatal()
128 }
129 }
130 require.Equal(t, jerr, serr)
131 }
132 }
133
View as plain text