github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/misc_tests/jsoniter_object_test.go (about) 1 package misc_tests 2 3 import ( 4 "bytes" 5 "context" 6 "reflect" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/bingoohuang/gg/pkg/jsoni" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func Test_empty_object(t *testing.T) { 16 should := require.New(t) 17 iter := jsoni.ParseString(jsoni.ConfigDefault, `{}`) 18 field := iter.ReadObject() 19 should.Equal("", field) 20 iter = jsoni.ParseString(jsoni.ConfigDefault, `{}`) 21 iter.ReadObjectCB(func(iter *jsoni.Iterator, field string) bool { 22 should.FailNow("should not call") 23 return true 24 }) 25 } 26 27 func Test_one_field(t *testing.T) { 28 should := require.New(t) 29 iter := jsoni.ParseString(jsoni.ConfigDefault, `{"a": "stream"}`) 30 field := iter.ReadObject() 31 should.Equal("a", field) 32 value := iter.ReadString() 33 should.Equal("stream", value) 34 field = iter.ReadObject() 35 should.Equal("", field) 36 iter = jsoni.ParseString(jsoni.ConfigDefault, `{"a": "stream"}`) 37 should.True(iter.ReadObjectCB(func(iter *jsoni.Iterator, field string) bool { 38 should.Equal("a", field) 39 iter.Skip() 40 return true 41 })) 42 } 43 44 func Test_two_field(t *testing.T) { 45 should := require.New(t) 46 iter := jsoni.ParseString(jsoni.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 = jsoni.ParseString(jsoni.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 := jsoni.NewStream(jsoni.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 := jsoni.ConfigCompatibleWithStandardLibrary.NewDecoder(reader) 131 obj := TestObject{} 132 should.Nil(decoder.Decode(context.Background(), &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 := jsoni.Config{UseNumber: true}.Froze() 145 err := cfg.Unmarshal(context.Background(), []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 // for issue421 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 := jsoni.ConfigCompatibleWithStandardLibrary 160 err := cfg.UnmarshalFromString(context.Background(), `{"Field1":`, &t0) 161 should.NotNil(err) 162 should.NotContains(err.Error(), reflect.TypeOf(t0).String()) 163 164 cfgCaseSensitive := jsoni.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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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(context.Background(), `{"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 }