1 package misc_tests
2
3 import (
4 "bytes"
5 "reflect"
6 "testing"
7
8 "github.com/json-iterator/go"
9 "github.com/stretchr/testify/require"
10 "strings"
11 "time"
12 )
13
14 func Test_empty_object(t *testing.T) {
15 should := require.New(t)
16 iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{}`)
17 field := iter.ReadObject()
18 should.Equal("", field)
19 iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{}`)
20 iter.ReadObjectCB(func(iter *jsoniter.Iterator, field string) bool {
21 should.FailNow("should not call")
22 return true
23 })
24 }
25
26 func Test_one_field(t *testing.T) {
27 should := require.New(t)
28 iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{"a": "stream"}`)
29 field := iter.ReadObject()
30 should.Equal("a", field)
31 value := iter.ReadString()
32 should.Equal("stream", value)
33 field = iter.ReadObject()
34 should.Equal("", field)
35 iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{"a": "stream"}`)
36 should.True(iter.ReadObjectCB(func(iter *jsoniter.Iterator, field string) bool {
37 should.Equal("a", field)
38 iter.Skip()
39 return true
40 }))
41
42 }
43
44 func Test_two_field(t *testing.T) {
45 should := require.New(t)
46 iter := jsoniter.ParseString(jsoniter.ConfigDefault, `{ "a": "stream" , "c": "d" }`)
47 field := iter.ReadObject()
48 should.Equal("a", field)
49 value := iter.ReadString()
50 should.Equal("stream", value)
51 field = iter.ReadObject()
52 should.Equal("c", field)
53 value = iter.ReadString()
54 should.Equal("d", value)
55 field = iter.ReadObject()
56 should.Equal("", field)
57 iter = jsoniter.ParseString(jsoniter.ConfigDefault, `{"field1": "1", "field2": 2}`)
58 for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
59 switch field {
60 case "field1":
61 iter.ReadString()
62 case "field2":
63 iter.ReadInt64()
64 default:
65 iter.ReportError("bind object", "unexpected field")
66 }
67 }
68 }
69
70 func Test_write_object(t *testing.T) {
71 should := require.New(t)
72 buf := &bytes.Buffer{}
73 stream := jsoniter.NewStream(jsoniter.Config{IndentionStep: 2}.Froze(), buf, 4096)
74 stream.WriteObjectStart()
75 stream.WriteObjectField("hello")
76 stream.WriteInt(1)
77 stream.WriteMore()
78 stream.WriteObjectField("world")
79 stream.WriteInt(2)
80 stream.WriteObjectEnd()
81 stream.Flush()
82 should.Nil(stream.Error)
83 should.Equal("{\n \"hello\": 1,\n \"world\": 2\n}", buf.String())
84 }
85
86 func Test_reader_and_load_more(t *testing.T) {
87 should := require.New(t)
88 type TestObject struct {
89 CreatedAt time.Time
90 }
91 reader := strings.NewReader(`
92 {
93 "agency": null,
94 "candidateId": 0,
95 "candidate": "Blah Blah",
96 "bookingId": 0,
97 "shiftId": 1,
98 "shiftTypeId": 0,
99 "shift": "Standard",
100 "bonus": 0,
101 "bonusNI": 0,
102 "days": [],
103 "totalHours": 27,
104 "expenses": [],
105 "weekEndingDateSystem": "2016-10-09",
106 "weekEndingDateClient": "2016-10-09",
107 "submittedAt": null,
108 "submittedById": null,
109 "approvedAt": "2016-10-10T18:38:04Z",
110 "approvedById": 0,
111 "authorisedAt": "2016-10-10T18:38:04Z",
112 "authorisedById": 0,
113 "invoicedAt": "2016-10-10T20:00:00Z",
114 "revokedAt": null,
115 "revokedById": null,
116 "revokeReason": null,
117 "rejectedAt": null,
118 "rejectedById": null,
119 "rejectReasonCode": null,
120 "rejectReason": null,
121 "createdAt": "2016-10-03T00:00:00Z",
122 "updatedAt": "2016-11-09T10:26:13Z",
123 "updatedById": null,
124 "overrides": [],
125 "bookingApproverId": null,
126 "bookingApprover": null,
127 "status": "approved"
128 }
129 `)
130 decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(reader)
131 obj := TestObject{}
132 should.Nil(decoder.Decode(&obj))
133 }
134
135 func Test_unmarshal_into_existing_value(t *testing.T) {
136 should := require.New(t)
137 type TestObject struct {
138 Field1 int
139 Field2 interface{}
140 }
141 var obj TestObject
142 m := map[string]interface{}{}
143 obj.Field2 = &m
144 cfg := jsoniter.Config{UseNumber: true}.Froze()
145 err := cfg.Unmarshal([]byte(`{"Field1":1,"Field2":{"k":"v"}}`), &obj)
146 should.NoError(err)
147 should.Equal(map[string]interface{}{
148 "k": "v",
149 }, m)
150 }
151
152
153 func Test_unmarshal_anonymous_struct_invalid(t *testing.T) {
154 should := require.New(t)
155 t0 := struct {
156 Field1 string
157 }{}
158
159 cfg := jsoniter.ConfigCompatibleWithStandardLibrary
160 err := cfg.UnmarshalFromString(`{"Field1":`, &t0)
161 should.NotNil(err)
162 should.NotContains(err.Error(), reflect.TypeOf(t0).String())
163
164 cfgCaseSensitive := jsoniter.Config{
165 CaseSensitive: true,
166 }.Froze()
167
168 type TestObject1 struct {
169 Field1 struct {
170 InnerField1 string
171 }
172 }
173 t1 := TestObject1{}
174 err = cfgCaseSensitive.UnmarshalFromString(`{"Field1":{"InnerField1"`, &t1)
175 should.NotNil(err)
176 should.NotContains(err.Error(), reflect.TypeOf(t1.Field1).String())
177 should.Contains(err.Error(), reflect.TypeOf(t1).String())
178
179 type TestObject2 struct {
180 Field1 int
181 Field2 struct {
182 InnerField1 string
183 InnerField2 string
184 }
185 }
186 t2 := TestObject2{}
187 err = cfgCaseSensitive.UnmarshalFromString(`{"Field2":{"InnerField2"`, &t2)
188 should.NotNil(err)
189 should.NotContains(err.Error(), reflect.TypeOf(t2.Field2).String())
190 should.Contains(err.Error(), reflect.TypeOf(t2).String())
191
192 type TestObject3 struct {
193 Field1 int
194 Field2 int
195 Field3 struct {
196 InnerField1 string
197 InnerField2 string
198 InnerField3 string
199 }
200 }
201 t3 := TestObject3{}
202 err = cfgCaseSensitive.UnmarshalFromString(`{"Field3":{"InnerField3"`, &t3)
203 should.NotNil(err)
204 should.NotContains(err.Error(), reflect.TypeOf(t3.Field3).String())
205 should.Contains(err.Error(), reflect.TypeOf(t3).String())
206
207 type TestObject4 struct {
208 Field1 int
209 Field2 int
210 Field3 int
211 Field4 struct {
212 InnerField1 string
213 InnerField2 string
214 InnerField3 string
215 InnerField4 string
216 }
217 }
218 t4 := TestObject4{}
219 err = cfgCaseSensitive.UnmarshalFromString(`{"Field4":{"InnerField4"`, &t4)
220 should.NotNil(err)
221 should.NotContains(err.Error(), reflect.TypeOf(t4.Field4).String())
222 should.Contains(err.Error(), reflect.TypeOf(t4).String())
223
224 type TestObject5 struct {
225 Field1 int
226 Field2 int
227 Field3 int
228 Field4 int
229 Field5 struct {
230 InnerField1 string
231 InnerField2 string
232 InnerField3 string
233 InnerField4 string
234 InnerField5 string
235 }
236 }
237 t5 := TestObject5{}
238 err = cfgCaseSensitive.UnmarshalFromString(`{"Field5":{"InnerField5"`, &t5)
239 should.NotNil(err)
240 should.NotContains(err.Error(), reflect.TypeOf(t5.Field5).String())
241 should.Contains(err.Error(), reflect.TypeOf(t5).String())
242
243 type TestObject6 struct {
244 Field1 int
245 Field2 int
246 Field3 int
247 Field4 int
248 Field5 int
249 Field6 struct {
250 InnerField1 string
251 InnerField2 string
252 InnerField3 string
253 InnerField4 string
254 InnerField5 string
255 InnerField6 string
256 }
257 }
258 t6 := TestObject6{}
259 err = cfgCaseSensitive.UnmarshalFromString(`{"Field6":{"InnerField6"`, &t6)
260 should.NotNil(err)
261 should.NotContains(err.Error(), reflect.TypeOf(t6.Field6).String())
262 should.Contains(err.Error(), reflect.TypeOf(t6).String())
263
264 type TestObject7 struct {
265 Field1 int
266 Field2 int
267 Field3 int
268 Field4 int
269 Field5 int
270 Field6 int
271 Field7 struct {
272 InnerField1 string
273 InnerField2 string
274 InnerField3 string
275 InnerField4 string
276 InnerField5 string
277 InnerField6 string
278 InnerField7 string
279 }
280 }
281 t7 := TestObject7{}
282 err = cfgCaseSensitive.UnmarshalFromString(`{"Field7":{"InnerField7"`, &t7)
283 should.NotNil(err)
284 should.NotContains(err.Error(), reflect.TypeOf(t7.Field7).String())
285 should.Contains(err.Error(), reflect.TypeOf(t7).String())
286
287 type TestObject8 struct {
288 Field1 int
289 Field2 int
290 Field3 int
291 Field4 int
292 Field5 int
293 Field6 int
294 Field7 int
295 Field8 struct {
296 InnerField1 string
297 InnerField2 string
298 InnerField3 string
299 InnerField4 string
300 InnerField5 string
301 InnerField6 string
302 InnerField7 string
303 InnerField8 string
304 }
305 }
306 t8 := TestObject8{}
307 err = cfgCaseSensitive.UnmarshalFromString(`{"Field8":{"InnerField8"`, &t8)
308 should.NotNil(err)
309 should.NotContains(err.Error(), reflect.TypeOf(t8.Field8).String())
310 should.Contains(err.Error(), reflect.TypeOf(t8).String())
311
312 type TestObject9 struct {
313 Field1 int
314 Field2 int
315 Field3 int
316 Field4 int
317 Field5 int
318 Field6 int
319 Field7 int
320 Field8 int
321 Field9 struct {
322 InnerField1 string
323 InnerField2 string
324 InnerField3 string
325 InnerField4 string
326 InnerField5 string
327 InnerField6 string
328 InnerField7 string
329 InnerField8 string
330 InnerField9 string
331 }
332 }
333 t9 := TestObject9{}
334 err = cfgCaseSensitive.UnmarshalFromString(`{"Field9":{"InnerField9"`, &t9)
335 should.NotNil(err)
336 should.NotContains(err.Error(), reflect.TypeOf(t9.Field9).String())
337 should.Contains(err.Error(), reflect.TypeOf(t9).String())
338
339 type TestObject10 struct {
340 Field1 int
341 Field2 int
342 Field3 int
343 Field4 int
344 Field5 int
345 Field6 int
346 Field7 int
347 Field8 int
348 Field9 int
349 Field10 struct {
350 InnerField1 string
351 InnerField2 string
352 InnerField3 string
353 InnerField4 string
354 InnerField5 string
355 InnerField6 string
356 InnerField7 string
357 InnerField8 string
358 InnerField9 string
359 InnerField10 string
360 }
361 }
362 t10 := TestObject10{}
363 err = cfgCaseSensitive.UnmarshalFromString(`{"Field10":{"InnerField10"`, &t10)
364 should.NotNil(err)
365 should.NotContains(err.Error(), reflect.TypeOf(t10.Field10).String())
366 should.Contains(err.Error(), reflect.TypeOf(t10).String())
367
368 err = cfg.UnmarshalFromString(`{"Field10":{"InnerField10"`, &t10)
369 should.NotNil(err)
370 should.NotContains(err.Error(), reflect.TypeOf(t10.Field10).String())
371 should.Contains(err.Error(), reflect.TypeOf(t10).String())
372 }
373
View as plain text