1
2
3
4
5 package json
6
7 import (
8 "bytes"
9 "math"
10 "reflect"
11 "testing"
12 "unicode"
13 )
14
15 type Optionals struct {
16 Sr string `json:"sr"`
17 So string `json:"so,omitempty"`
18 Sw string `json:"-"`
19
20 Ir int `json:"omitempty"`
21 Io int `json:"io,omitempty"`
22
23 Slr []string `json:"slr,random"`
24 Slo []string `json:"slo,omitempty"`
25
26 Mr map[string]interface{} `json:"mr"`
27 Mo map[string]interface{} `json:",omitempty"`
28
29 Fr float64 `json:"fr"`
30 Fo float64 `json:"fo,omitempty"`
31
32 Br bool `json:"br"`
33 Bo bool `json:"bo,omitempty"`
34
35 Ur uint `json:"ur"`
36 Uo uint `json:"uo,omitempty"`
37
38 Str struct{} `json:"str"`
39 Sto struct{} `json:"sto,omitempty"`
40 }
41
42 var optionalsExpected = `{
43 "sr": "",
44 "omitempty": 0,
45 "slr": null,
46 "mr": {},
47 "fr": 0,
48 "br": false,
49 "ur": 0,
50 "str": {},
51 "sto": {}
52 }`
53
54 func TestOmitEmpty(t *testing.T) {
55 var o Optionals
56 o.Sw = "something"
57 o.Mr = map[string]interface{}{}
58 o.Mo = map[string]interface{}{}
59
60 got, err := MarshalIndent(&o, "", " ")
61 if err != nil {
62 t.Fatal(err)
63 }
64 if got := string(got); got != optionalsExpected {
65 t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected)
66 }
67 }
68
69 type StringTag struct {
70 BoolStr bool `json:",string"`
71 IntStr int64 `json:",string"`
72 StrStr string `json:",string"`
73 }
74
75 var stringTagExpected = `{
76 "BoolStr": "true",
77 "IntStr": "42",
78 "StrStr": "\"xzbit\""
79 }`
80
81 func TestStringTag(t *testing.T) {
82 var s StringTag
83 s.BoolStr = true
84 s.IntStr = 42
85 s.StrStr = "xzbit"
86 got, err := MarshalIndent(&s, "", " ")
87 if err != nil {
88 t.Fatal(err)
89 }
90 if got := string(got); got != stringTagExpected {
91 t.Fatalf(" got: %s\nwant: %s\n", got, stringTagExpected)
92 }
93
94
95 var s2 StringTag
96 err = NewDecoder(bytes.NewReader(got)).Decode(&s2)
97 if err != nil {
98 t.Fatalf("Decode: %v", err)
99 }
100 if !reflect.DeepEqual(s, s2) {
101 t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
102 }
103 }
104
105
106 type renamedByte byte
107 type renamedByteSlice []byte
108 type renamedRenamedByteSlice []renamedByte
109
110 func TestEncodeRenamedByteSlice(t *testing.T) {
111 s := renamedByteSlice("abc")
112 result, err := Marshal(s)
113 if err != nil {
114 t.Fatal(err)
115 }
116 expect := `"YWJj"`
117 if string(result) != expect {
118 t.Errorf(" got %s want %s", result, expect)
119 }
120 r := renamedRenamedByteSlice("abc")
121 result, err = Marshal(r)
122 if err != nil {
123 t.Fatal(err)
124 }
125 if string(result) != expect {
126 t.Errorf(" got %s want %s", result, expect)
127 }
128 }
129
130 var unsupportedValues = []interface{}{
131 math.NaN(),
132 math.Inf(-1),
133 math.Inf(1),
134 }
135
136 func TestUnsupportedValues(t *testing.T) {
137 for _, v := range unsupportedValues {
138 if _, err := Marshal(v); err != nil {
139 if _, ok := err.(*UnsupportedValueError); !ok {
140 t.Errorf("for %v, got %T want UnsupportedValueError", v, err)
141 }
142 } else {
143 t.Errorf("for %v, expected error", v)
144 }
145 }
146 }
147
148
149 type Ref int
150
151 func (*Ref) MarshalJSON() ([]byte, error) {
152 return []byte(`"ref"`), nil
153 }
154
155 func (r *Ref) UnmarshalJSON([]byte) error {
156 *r = 12
157 return nil
158 }
159
160
161 type Val int
162
163 func (Val) MarshalJSON() ([]byte, error) {
164 return []byte(`"val"`), nil
165 }
166
167
168 type RefText int
169
170 func (*RefText) MarshalText() ([]byte, error) {
171 return []byte(`"ref"`), nil
172 }
173
174 func (r *RefText) UnmarshalText([]byte) error {
175 *r = 13
176 return nil
177 }
178
179
180 type ValText int
181
182 func (ValText) MarshalText() ([]byte, error) {
183 return []byte(`"val"`), nil
184 }
185
186 func TestRefValMarshal(t *testing.T) {
187 var s = struct {
188 R0 Ref
189 R1 *Ref
190 R2 RefText
191 R3 *RefText
192 V0 Val
193 V1 *Val
194 V2 ValText
195 V3 *ValText
196 }{
197 R0: 12,
198 R1: new(Ref),
199 R2: 14,
200 R3: new(RefText),
201 V0: 13,
202 V1: new(Val),
203 V2: 15,
204 V3: new(ValText),
205 }
206 const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
207 b, err := Marshal(&s)
208 if err != nil {
209 t.Fatalf("Marshal: %v", err)
210 }
211 if got := string(b); got != want {
212 t.Errorf("got %q, want %q", got, want)
213 }
214 }
215
216
217 type C int
218
219 func (C) MarshalJSON() ([]byte, error) {
220 return []byte(`"<&>"`), nil
221 }
222
223
224 type CText int
225
226 func (CText) MarshalText() ([]byte, error) {
227 return []byte(`"<&>"`), nil
228 }
229
230 func TestMarshalerEscaping(t *testing.T) {
231 var c C
232 want := `"\u003c\u0026\u003e"`
233 b, err := Marshal(c)
234 if err != nil {
235 t.Fatalf("Marshal(c): %v", err)
236 }
237 if got := string(b); got != want {
238 t.Errorf("Marshal(c) = %#q, want %#q", got, want)
239 }
240
241 var ct CText
242 want = `"\"\u003c\u0026\u003e\""`
243 b, err = Marshal(ct)
244 if err != nil {
245 t.Fatalf("Marshal(ct): %v", err)
246 }
247 if got := string(b); got != want {
248 t.Errorf("Marshal(ct) = %#q, want %#q", got, want)
249 }
250 }
251
252 type IntType int
253
254 type MyStruct struct {
255 IntType
256 }
257
258 func TestAnonymousNonstruct(t *testing.T) {
259 var i IntType = 11
260 a := MyStruct{i}
261 const want = `{"IntType":11}`
262
263 b, err := Marshal(a)
264 if err != nil {
265 t.Fatalf("Marshal: %v", err)
266 }
267 if got := string(b); got != want {
268 t.Errorf("got %q, want %q", got, want)
269 }
270 }
271
272 type BugA struct {
273 S string
274 }
275
276 type BugB struct {
277 BugA
278 S string
279 }
280
281 type BugC struct {
282 S string
283 }
284
285
286 type BugX struct {
287 A int
288 BugA
289 BugB
290 }
291
292
293 func TestEmbeddedBug(t *testing.T) {
294 v := BugB{
295 BugA{"A"},
296 "B",
297 }
298 b, err := Marshal(v)
299 if err != nil {
300 t.Fatal("Marshal:", err)
301 }
302 want := `{"S":"B"}`
303 got := string(b)
304 if got != want {
305 t.Fatalf("Marshal: got %s want %s", got, want)
306 }
307
308 x := BugX{
309 A: 23,
310 }
311 b, err = Marshal(x)
312 if err != nil {
313 t.Fatal("Marshal:", err)
314 }
315 want = `{"A":23}`
316 got = string(b)
317 if got != want {
318 t.Fatalf("Marshal: got %s want %s", got, want)
319 }
320 }
321
322 type BugD struct {
323 XXX string `json:"S"`
324 }
325
326
327 type BugY struct {
328 BugA
329 BugD
330 }
331
332
333 func TestTaggedFieldDominates(t *testing.T) {
334 v := BugY{
335 BugA{"BugA"},
336 BugD{"BugD"},
337 }
338 b, err := Marshal(v)
339 if err != nil {
340 t.Fatal("Marshal:", err)
341 }
342 want := `{"S":"BugD"}`
343 got := string(b)
344 if got != want {
345 t.Fatalf("Marshal: got %s want %s", got, want)
346 }
347 }
348
349
350 type BugZ struct {
351 BugA
352 BugC
353 BugY
354 }
355
356 func TestDuplicatedFieldDisappears(t *testing.T) {
357 v := BugZ{
358 BugA{"BugA"},
359 BugC{"BugC"},
360 BugY{
361 BugA{"nested BugA"},
362 BugD{"nested BugD"},
363 },
364 }
365 b, err := Marshal(v)
366 if err != nil {
367 t.Fatal("Marshal:", err)
368 }
369 want := `{}`
370 got := string(b)
371 if got != want {
372 t.Fatalf("Marshal: got %s want %s", got, want)
373 }
374 }
375
376 func TestStringBytes(t *testing.T) {
377
378 es := &encodeState{}
379 var r []rune
380 for i := '\u0000'; i <= unicode.MaxRune; i++ {
381 r = append(r, i)
382 }
383 s := string(r) + "\xff\xff\xffhello"
384 es.string(s)
385
386 esBytes := &encodeState{}
387 esBytes.stringBytes([]byte(s))
388
389 enc := es.Buffer.String()
390 encBytes := esBytes.Buffer.String()
391 if enc != encBytes {
392 i := 0
393 for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] {
394 i++
395 }
396 enc = enc[i:]
397 encBytes = encBytes[i:]
398 i = 0
399 for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] {
400 i++
401 }
402 enc = enc[:len(enc)-i]
403 encBytes = encBytes[:len(encBytes)-i]
404
405 if len(enc) > 20 {
406 enc = enc[:20] + "..."
407 }
408 if len(encBytes) > 20 {
409 encBytes = encBytes[:20] + "..."
410 }
411
412 t.Errorf("encodings differ at %#q vs %#q", enc, encBytes)
413 }
414 }
415
416 func TestIssue6458(t *testing.T) {
417 type Foo struct {
418 M RawMessage
419 }
420 x := Foo{RawMessage(`"foo"`)}
421
422 b, err := Marshal(&x)
423 if err != nil {
424 t.Fatal(err)
425 }
426 if want := `{"M":"foo"}`; string(b) != want {
427 t.Errorf("Marshal(&x) = %#q; want %#q", b, want)
428 }
429
430 b, err = Marshal(x)
431 if err != nil {
432 t.Fatal(err)
433 }
434
435 if want := `{"M":"ImZvbyI="}`; string(b) != want {
436 t.Errorf("Marshal(x) = %#q; want %#q", b, want)
437 }
438 }
439
440 func TestIssue10281(t *testing.T) {
441 type Foo struct {
442 N Number
443 }
444 x := Foo{Number(`invalid`)}
445
446 b, err := Marshal(&x)
447 if err == nil {
448 t.Errorf("Marshal(&x) = %#q; want error", b)
449 }
450 }
451
452 func TestHTMLEscape(t *testing.T) {
453 var b, want bytes.Buffer
454 m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
455 want.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`))
456 HTMLEscape(&b, []byte(m))
457 if !bytes.Equal(b.Bytes(), want.Bytes()) {
458 t.Errorf("HTMLEscape(&b, []byte(m)) = %s; want %s", b.Bytes(), want.Bytes())
459 }
460 }
461
462
463 func TestEncodePointerString(t *testing.T) {
464 type stringPointer struct {
465 N *int64 `json:"n,string"`
466 }
467 var n int64 = 42
468 b, err := Marshal(stringPointer{N: &n})
469 if err != nil {
470 t.Fatalf("Marshal: %v", err)
471 }
472 if got, want := string(b), `{"n":"42"}`; got != want {
473 t.Errorf("Marshal = %s, want %s", got, want)
474 }
475 var back stringPointer
476 err = Unmarshal(b, &back)
477 if err != nil {
478 t.Fatalf("Unmarshal: %v", err)
479 }
480 if back.N == nil {
481 t.Fatalf("Unmarshalled nil N field")
482 }
483 if *back.N != 42 {
484 t.Fatalf("*N = %d; want 42", *back.N)
485 }
486 }
487
488 var encodeStringTests = []struct {
489 in string
490 out string
491 }{
492 {"\x00", `"\u0000"`},
493 {"\x01", `"\u0001"`},
494 {"\x02", `"\u0002"`},
495 {"\x03", `"\u0003"`},
496 {"\x04", `"\u0004"`},
497 {"\x05", `"\u0005"`},
498 {"\x06", `"\u0006"`},
499 {"\x07", `"\u0007"`},
500 {"\x08", `"\u0008"`},
501 {"\x09", `"\t"`},
502 {"\x0a", `"\n"`},
503 {"\x0b", `"\u000b"`},
504 {"\x0c", `"\u000c"`},
505 {"\x0d", `"\r"`},
506 {"\x0e", `"\u000e"`},
507 {"\x0f", `"\u000f"`},
508 {"\x10", `"\u0010"`},
509 {"\x11", `"\u0011"`},
510 {"\x12", `"\u0012"`},
511 {"\x13", `"\u0013"`},
512 {"\x14", `"\u0014"`},
513 {"\x15", `"\u0015"`},
514 {"\x16", `"\u0016"`},
515 {"\x17", `"\u0017"`},
516 {"\x18", `"\u0018"`},
517 {"\x19", `"\u0019"`},
518 {"\x1a", `"\u001a"`},
519 {"\x1b", `"\u001b"`},
520 {"\x1c", `"\u001c"`},
521 {"\x1d", `"\u001d"`},
522 {"\x1e", `"\u001e"`},
523 {"\x1f", `"\u001f"`},
524 }
525
526 func TestEncodeString(t *testing.T) {
527 for _, tt := range encodeStringTests {
528 b, err := Marshal(tt.in)
529 if err != nil {
530 t.Errorf("Marshal(%q): %v", tt.in, err)
531 continue
532 }
533 out := string(b)
534 if out != tt.out {
535 t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out)
536 }
537 }
538 }
539
View as plain text