• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package json_test
6
7import (
8	"fmt"
9	"math"
10	"strings"
11	"testing"
12	"unicode/utf8"
13
14	"github.com/google/go-cmp/cmp"
15
16	"google.golang.org/protobuf/internal/encoding/json"
17)
18
19type R struct {
20	// E is expected error substring from calling Decoder.Read if set.
21	E string
22	// V is one of the checker implementations that validates the token value.
23	V checker
24	// P is expected Token.Pos() if set > 0.
25	P int
26	// RS is expected result from Token.RawString() if not empty.
27	RS string
28}
29
30// checker defines API for Token validation.
31type checker interface {
32	// check checks and expects for token API call to return and compare
33	// against implementation-stored value. Returns empty string if success,
34	// else returns error message describing the error.
35	check(json.Token) string
36}
37
38// checkers that checks the token kind only.
39var (
40	EOF         = kindOnly{json.EOF}
41	Null        = kindOnly{json.Null}
42	ObjectOpen  = kindOnly{json.ObjectOpen}
43	ObjectClose = kindOnly{json.ObjectClose}
44	ArrayOpen   = kindOnly{json.ArrayOpen}
45	ArrayClose  = kindOnly{json.ArrayClose}
46)
47
48type kindOnly struct {
49	want json.Kind
50}
51
52func (x kindOnly) check(tok json.Token) string {
53	if got := tok.Kind(); got != x.want {
54		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, x.want)
55	}
56	return ""
57}
58
59type Name struct {
60	val string
61}
62
63func (x Name) check(tok json.Token) string {
64	if got := tok.Kind(); got != json.Name {
65		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Name)
66	}
67
68	if got := tok.Name(); got != x.val {
69		return fmt.Sprintf("Token.Name(): got %v, want %v", got, x.val)
70	}
71	return ""
72}
73
74type Bool struct {
75	val bool
76}
77
78func (x Bool) check(tok json.Token) string {
79	if got := tok.Kind(); got != json.Bool {
80		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Bool)
81	}
82
83	if got := tok.Bool(); got != x.val {
84		return fmt.Sprintf("Token.Bool(): got %v, want %v", got, x.val)
85	}
86	return ""
87}
88
89type Str struct {
90	val string
91}
92
93func (x Str) check(tok json.Token) string {
94	if got := tok.Kind(); got != json.String {
95		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.String)
96	}
97
98	if got := tok.ParsedString(); got != x.val {
99		return fmt.Sprintf("Token.ParsedString(): got %v, want %v", got, x.val)
100	}
101	return ""
102}
103
104type F64 struct {
105	val float64
106}
107
108func (x F64) check(tok json.Token) string {
109	if got := tok.Kind(); got != json.Number {
110		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
111	}
112
113	got, ok := tok.Float(64)
114	if !ok {
115		return fmt.Sprintf("Token.Float(64): returned not ok")
116	}
117	if got != x.val {
118		return fmt.Sprintf("Token.Float(64): got %v, want %v", got, x.val)
119	}
120	return ""
121}
122
123type F32 struct {
124	val float32
125}
126
127func (x F32) check(tok json.Token) string {
128	if got := tok.Kind(); got != json.Number {
129		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
130	}
131
132	got, ok := tok.Float(32)
133	if !ok {
134		return fmt.Sprintf("Token.Float(32): returned not ok")
135	}
136	if float32(got) != x.val {
137		return fmt.Sprintf("Token.Float(32): got %v, want %v", got, x.val)
138	}
139	return ""
140}
141
142// NotF64 is a checker to validate a Number token where Token.Float(64) returns not ok.
143var NotF64 = xf64{}
144
145type xf64 struct{}
146
147func (x xf64) check(tok json.Token) string {
148	if got := tok.Kind(); got != json.Number {
149		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
150	}
151
152	_, ok := tok.Float(64)
153	if ok {
154		return fmt.Sprintf("Token.Float(64): returned ok")
155	}
156	return ""
157}
158
159// NotF32 is a checker to validate a Number token where Token.Float(32) returns not ok.
160var NotF32 = xf32{}
161
162type xf32 struct{}
163
164func (x xf32) check(tok json.Token) string {
165	if got := tok.Kind(); got != json.Number {
166		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
167	}
168
169	_, ok := tok.Float(32)
170	if ok {
171		return fmt.Sprintf("Token.Float(32): returned ok")
172	}
173	return ""
174}
175
176type I64 struct {
177	val int64
178}
179
180func (x I64) check(tok json.Token) string {
181	if got := tok.Kind(); got != json.Number {
182		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
183	}
184
185	got, ok := tok.Int(64)
186	if !ok {
187		return fmt.Sprintf("Token.Int(64): returned not ok")
188	}
189	if got != x.val {
190		return fmt.Sprintf("Token.Int(64): got %v, want %v", got, x.val)
191	}
192	return ""
193}
194
195type I32 struct {
196	val int32
197}
198
199func (x I32) check(tok json.Token) string {
200	if got := tok.Kind(); got != json.Number {
201		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
202	}
203
204	got, ok := tok.Int(32)
205	if !ok {
206		return fmt.Sprintf("Token.Int(32): returned not ok")
207	}
208	if int32(got) != x.val {
209		return fmt.Sprintf("Token.Int(32): got %v, want %v", got, x.val)
210	}
211	return ""
212}
213
214// NotI64 is a checker to validate a Number token where Token.Int(64) returns not ok.
215var NotI64 = xi64{}
216
217type xi64 struct{}
218
219func (x xi64) check(tok json.Token) string {
220	if got := tok.Kind(); got != json.Number {
221		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
222	}
223
224	_, ok := tok.Int(64)
225	if ok {
226		return fmt.Sprintf("Token.Int(64): returned ok")
227	}
228	return ""
229}
230
231// NotI32 is a checker to validate a Number token where Token.Int(32) returns not ok.
232var NotI32 = xi32{}
233
234type xi32 struct{}
235
236func (x xi32) check(tok json.Token) string {
237	if got := tok.Kind(); got != json.Number {
238		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
239	}
240
241	_, ok := tok.Int(32)
242	if ok {
243		return fmt.Sprintf("Token.Int(32): returned ok")
244	}
245	return ""
246}
247
248type Ui64 struct {
249	val uint64
250}
251
252func (x Ui64) check(tok json.Token) string {
253	if got := tok.Kind(); got != json.Number {
254		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
255	}
256
257	got, ok := tok.Uint(64)
258	if !ok {
259		return fmt.Sprintf("Token.Uint(64): returned not ok")
260	}
261	if got != x.val {
262		return fmt.Sprintf("Token.Uint(64): got %v, want %v", got, x.val)
263	}
264	return ""
265}
266
267type Ui32 struct {
268	val uint32
269}
270
271func (x Ui32) check(tok json.Token) string {
272	if got := tok.Kind(); got != json.Number {
273		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
274	}
275
276	got, ok := tok.Uint(32)
277	if !ok {
278		return fmt.Sprintf("Token.Uint(32): returned not ok")
279	}
280	if uint32(got) != x.val {
281		return fmt.Sprintf("Token.Uint(32): got %v, want %v", got, x.val)
282	}
283	return ""
284}
285
286// NotUi64 is a checker to validate a Number token where Token.Uint(64) returns not ok.
287var NotUi64 = xui64{}
288
289type xui64 struct{}
290
291func (x xui64) check(tok json.Token) string {
292	if got := tok.Kind(); got != json.Number {
293		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
294	}
295
296	_, ok := tok.Uint(64)
297	if ok {
298		return fmt.Sprintf("Token.Uint(64): returned ok")
299	}
300	return ""
301}
302
303// NotI32 is a checker to validate a Number token where Token.Uint(32) returns not ok.
304var NotUi32 = xui32{}
305
306type xui32 struct{}
307
308func (x xui32) check(tok json.Token) string {
309	if got := tok.Kind(); got != json.Number {
310		return fmt.Sprintf("Token.Kind(): got %v, want %v", got, json.Number)
311	}
312
313	_, ok := tok.Uint(32)
314	if ok {
315		return fmt.Sprintf("Token.Uint(32): returned ok")
316	}
317	return ""
318}
319
320var errEOF = json.ErrUnexpectedEOF.Error()
321
322func TestDecoder(t *testing.T) {
323	const space = " \n\r\t"
324
325	tests := []struct {
326		in string
327		// want is a list of expected values returned from calling
328		// Decoder.Read. An item makes the test code invoke
329		// Decoder.Read and compare against R.E for error returned or use R.V to
330		// validate the returned Token object.
331		want []R
332	}{
333		{
334			in:   ``,
335			want: []R{{V: EOF}},
336		},
337		{
338			in:   space,
339			want: []R{{V: EOF}},
340		},
341		{
342			// Calling Read after EOF will keep returning EOF for
343			// succeeding Read calls.
344			in: space,
345			want: []R{
346				{V: EOF},
347				{V: EOF},
348				{V: EOF},
349			},
350		},
351
352		// JSON literals.
353		{
354			in: space + `null` + space,
355			want: []R{
356				{V: Null, P: len(space), RS: `null`},
357				{V: EOF},
358			},
359		},
360		{
361			in: space + `true` + space,
362			want: []R{
363				{V: Bool{true}},
364				{V: EOF},
365			},
366		},
367		{
368			in: space + `false` + space,
369			want: []R{
370				{V: Bool{false}},
371				{V: EOF},
372			},
373		},
374		{
375			// Error returned will produce the same error again.
376			in: space + `foo` + space,
377			want: []R{
378				{E: `invalid value foo`},
379				{E: `invalid value foo`},
380			},
381		},
382
383		// JSON strings.
384		{
385			in: space + `""` + space,
386			want: []R{
387				{V: Str{}},
388				{V: EOF},
389			},
390		},
391		{
392			in: space + `"hello"` + space,
393			want: []R{
394				{V: Str{"hello"}, RS: `"hello"`},
395				{V: EOF},
396			},
397		},
398		{
399			in:   `"hello`,
400			want: []R{{E: errEOF}},
401		},
402		{
403			in:   "\"\x00\"",
404			want: []R{{E: `invalid character '\x00' in string`}},
405		},
406		{
407			in: "\"\u0031\u0032\"",
408			want: []R{
409				{V: Str{"12"}, RS: "\"\u0031\u0032\""},
410				{V: EOF},
411			},
412		},
413		{
414			// Invalid UTF-8 error is returned in ReadString instead of Read.
415			in:   "\"\xff\"",
416			want: []R{{E: `syntax error (line 1:1): invalid UTF-8 in string`}},
417		},
418		{
419			in: `"` + string(utf8.RuneError) + `"`,
420			want: []R{
421				{V: Str{string(utf8.RuneError)}},
422				{V: EOF},
423			},
424		},
425		{
426			in: `"\uFFFD"`,
427			want: []R{
428				{V: Str{string(utf8.RuneError)}},
429				{V: EOF},
430			},
431		},
432		{
433			in:   `"\x"`,
434			want: []R{{E: `invalid escape code "\\x" in string`}},
435		},
436		{
437			in:   `"\uXXXX"`,
438			want: []R{{E: `invalid escape code "\\uXXXX" in string`}},
439		},
440		{
441			in:   `"\uDEAD"`, // unmatched surrogate pair
442			want: []R{{E: errEOF}},
443		},
444		{
445			in:   `"\uDEAD\uBEEF"`, // invalid surrogate half
446			want: []R{{E: `invalid escape code "\\uBEEF" in string`}},
447		},
448		{
449			in: `"\uD800\udead"`, // valid surrogate pair
450			want: []R{
451				{V: Str{`��`}},
452				{V: EOF},
453			},
454		},
455		{
456			in: `"\u0000\"\\\/\b\f\n\r\t"`,
457			want: []R{
458				{V: Str{"\u0000\"\\/\b\f\n\r\t"}},
459				{V: EOF},
460			},
461		},
462
463		// Invalid JSON numbers.
464		{
465			in:   `-`,
466			want: []R{{E: `invalid value -`}},
467		},
468		{
469			in:   `+0`,
470			want: []R{{E: `invalid value +0`}},
471		},
472		{
473			in:   `-+`,
474			want: []R{{E: `invalid value -+`}},
475		},
476		{
477			in:   `0.`,
478			want: []R{{E: `invalid value 0.`}},
479		},
480		{
481			in:   `.1`,
482			want: []R{{E: `invalid value .1`}},
483		},
484		{
485			in:   `1.0.1`,
486			want: []R{{E: `invalid value 1.0.1`}},
487		},
488		{
489			in:   `1..1`,
490			want: []R{{E: `invalid value 1..1`}},
491		},
492		{
493			in:   `-1-2`,
494			want: []R{{E: `invalid value -1-2`}},
495		},
496		{
497			in:   `01`,
498			want: []R{{E: `invalid value 01`}},
499		},
500		{
501			in:   `1e`,
502			want: []R{{E: `invalid value 1e`}},
503		},
504		{
505			in:   `1e1.2`,
506			want: []R{{E: `invalid value 1e1.2`}},
507		},
508		{
509			in:   `1Ee`,
510			want: []R{{E: `invalid value 1Ee`}},
511		},
512		{
513			in:   `1.e1`,
514			want: []R{{E: `invalid value 1.e1`}},
515		},
516		{
517			in:   `1.e+`,
518			want: []R{{E: `invalid value 1.e+`}},
519		},
520		{
521			in:   `1e+-2`,
522			want: []R{{E: `invalid value 1e+-2`}},
523		},
524		{
525			in:   `1e--2`,
526			want: []R{{E: `invalid value 1e--2`}},
527		},
528		{
529			in:   `1.0true`,
530			want: []R{{E: `invalid value 1.0true`}},
531		},
532
533		// JSON numbers as floating point.
534		{
535			in: space + `0.0` + space,
536			want: []R{
537				{V: F32{0}, P: len(space), RS: `0.0`},
538				{V: EOF},
539			},
540		},
541		{
542			in: space + `0` + space,
543			want: []R{
544				{V: F32{0}},
545				{V: EOF},
546			},
547		},
548		{
549			in: space + `-0` + space,
550			want: []R{
551				{V: F32{float32(math.Copysign(0, -1))}},
552				{V: EOF},
553			},
554		},
555		{
556			in: `-0`,
557			want: []R{
558				{V: F64{math.Copysign(0, -1)}},
559				{V: EOF},
560			},
561		},
562		{
563			in: `-0.0`,
564			want: []R{
565				{V: F32{float32(math.Copysign(0, -1))}},
566				{V: EOF},
567			},
568		},
569		{
570			in: `-0.0`,
571			want: []R{
572				{V: F64{math.Copysign(0, -1)}},
573				{V: EOF},
574			},
575		},
576		{
577			in: `-1.02`,
578			want: []R{
579				{V: F32{-1.02}},
580				{V: EOF},
581			},
582		},
583		{
584			in: `1.020000`,
585			want: []R{
586				{V: F32{1.02}},
587				{V: EOF},
588			},
589		},
590		{
591			in: `-1.0e0`,
592			want: []R{
593				{V: F32{-1}},
594				{V: EOF},
595			},
596		},
597		{
598			in: `1.0e-000`,
599			want: []R{
600				{V: F32{1}},
601				{V: EOF},
602			},
603		},
604		{
605			in: `1e+00`,
606			want: []R{
607				{V: F32{1}},
608				{V: EOF},
609			},
610		},
611		{
612			in: `1.02e3`,
613			want: []R{
614				{V: F32{1.02e3}},
615				{V: EOF},
616			},
617		},
618		{
619			in: `-1.02E03`,
620			want: []R{
621				{V: F32{-1.02e3}},
622				{V: EOF},
623			},
624		},
625		{
626			in: `1.0200e+3`,
627			want: []R{
628				{V: F32{1.02e3}},
629				{V: EOF},
630			},
631		},
632		{
633			in: `-1.0200E+03`,
634			want: []R{
635				{V: F32{-1.02e3}},
636				{V: EOF},
637			},
638		},
639		{
640			in: `1.0200e-3`,
641			want: []R{
642				{V: F32{1.02e-3}},
643				{V: EOF},
644			},
645		},
646		{
647			in: `-1.0200E-03`,
648			want: []R{
649				{V: F32{-1.02e-3}},
650				{V: EOF},
651			},
652		},
653		{
654			// Exceeds max float32 limit, but should be ok for float64.
655			in: `3.4e39`,
656			want: []R{
657				{V: F64{3.4e39}},
658				{V: EOF},
659			},
660		},
661
662		{
663			// Exceeds max float32 limit.
664			in: `3.4e39`,
665			want: []R{
666				{V: NotF32},
667				{V: EOF},
668			},
669		},
670		{
671			// Less than negative max float32 limit.
672			in: `-3.4e39`,
673			want: []R{
674				{V: NotF32},
675				{V: EOF},
676			},
677		},
678		{
679			// Exceeds max float64 limit.
680			in: `1.79e+309`,
681			want: []R{
682				{V: NotF64},
683				{V: EOF},
684			},
685		},
686		{
687			// Less than negative max float64 limit.
688			in: `-1.79e+309`,
689			want: []R{
690				{V: NotF64},
691				{V: EOF},
692			},
693		},
694
695		// JSON numbers as signed integers.
696		{
697			in: space + `0` + space,
698			want: []R{
699				{V: I32{0}},
700				{V: EOF},
701			},
702		},
703		{
704			in: space + `-0` + space,
705			want: []R{
706				{V: I32{0}},
707				{V: EOF},
708			},
709		},
710		{
711			// Fractional part equals 0 is ok.
712			in: `1.00000`,
713			want: []R{
714				{V: I32{1}},
715				{V: EOF},
716			},
717		},
718		{
719			// Fractional part not equals 0 returns error.
720			in: `1.0000000001`,
721			want: []R{
722				{V: NotI32},
723				{V: EOF},
724			},
725		},
726		{
727			in: `0e0`,
728			want: []R{
729				{V: I32{0}},
730				{V: EOF},
731			},
732		},
733		{
734			in: `0.0E0`,
735			want: []R{
736				{V: I32{0}},
737				{V: EOF},
738			},
739		},
740		{
741			in: `0.0E10`,
742			want: []R{
743				{V: I32{0}},
744				{V: EOF},
745			},
746		},
747		{
748			in: `-1`,
749			want: []R{
750				{V: I32{-1}},
751				{V: EOF},
752			},
753		},
754		{
755			in: `1.0e+0`,
756			want: []R{
757				{V: I32{1}},
758				{V: EOF},
759			},
760		},
761		{
762			in: `-1E-0`,
763			want: []R{
764				{V: I32{-1}},
765				{V: EOF},
766			},
767		},
768		{
769			in: `1E1`,
770			want: []R{
771				{V: I32{10}},
772				{V: EOF},
773			},
774		},
775		{
776			in: `-100.00e-02`,
777			want: []R{
778				{V: I32{-1}},
779				{V: EOF},
780			},
781		},
782		{
783			in: `0.1200E+02`,
784			want: []R{
785				{V: I64{12}},
786				{V: EOF},
787			},
788		},
789		{
790			in: `0.012e2`,
791			want: []R{
792				{V: NotI32},
793				{V: EOF},
794			},
795		},
796		{
797			in: `12e-2`,
798			want: []R{
799				{V: NotI32},
800				{V: EOF},
801			},
802		},
803		{
804			// Exceeds math.MaxInt32.
805			in: `2147483648`,
806			want: []R{
807				{V: NotI32},
808				{V: EOF},
809			},
810		},
811		{
812			// Exceeds math.MinInt32.
813			in: `-2147483649`,
814			want: []R{
815				{V: NotI32},
816				{V: EOF},
817			},
818		},
819		{
820			// Exceeds math.MaxInt32, but ok for int64.
821			in: `2147483648`,
822			want: []R{
823				{V: I64{2147483648}},
824				{V: EOF},
825			},
826		},
827		{
828			// Exceeds math.MinInt32, but ok for int64.
829			in: `-2147483649`,
830			want: []R{
831				{V: I64{-2147483649}},
832				{V: EOF},
833			},
834		},
835		{
836			// Exceeds math.MaxInt64.
837			in: `9223372036854775808`,
838			want: []R{
839				{V: NotI64},
840				{V: EOF},
841			},
842		},
843		{
844			// Exceeds math.MinInt64.
845			in: `-9223372036854775809`,
846			want: []R{
847				{V: NotI64},
848				{V: EOF},
849			},
850		},
851
852		// JSON numbers as unsigned integers.
853		{
854			in: space + `0` + space,
855			want: []R{
856				{V: Ui32{0}},
857				{V: EOF},
858			},
859		},
860		{
861			in: space + `-0` + space,
862			want: []R{
863				{V: Ui32{0}},
864				{V: EOF},
865			},
866		},
867		{
868			in: `-1`,
869			want: []R{
870				{V: NotUi32},
871				{V: EOF},
872			},
873		},
874		{
875			// Exceeds math.MaxUint32.
876			in: `4294967296`,
877			want: []R{
878				{V: NotUi32},
879				{V: EOF},
880			},
881		},
882		{
883			// Exceeds math.MaxUint64.
884			in: `18446744073709551616`,
885			want: []R{
886				{V: NotUi64},
887				{V: EOF},
888			},
889		},
890
891		// JSON sequence of values.
892		{
893			in: `true null`,
894			want: []R{
895				{V: Bool{true}},
896				{E: `(line 1:6): unexpected token null`},
897			},
898		},
899		{
900			in: "null false",
901			want: []R{
902				{V: Null},
903				{E: `unexpected token false`},
904			},
905		},
906		{
907			in: `true,false`,
908			want: []R{
909				{V: Bool{true}},
910				{E: `unexpected token ,`},
911			},
912		},
913		{
914			in: `47"hello"`,
915			want: []R{
916				{V: I32{47}},
917				{E: `unexpected token "hello"`},
918			},
919		},
920		{
921			in: `47 "hello"`,
922			want: []R{
923				{V: I32{47}},
924				{E: `unexpected token "hello"`},
925			},
926		},
927		{
928			in: `true 42`,
929			want: []R{
930				{V: Bool{true}},
931				{E: `unexpected token 42`},
932			},
933		},
934
935		// JSON arrays.
936		{
937			in: space + `[]` + space,
938			want: []R{
939				{V: ArrayOpen},
940				{V: ArrayClose},
941				{V: EOF},
942			},
943		},
944		{
945			in: space + `[` + space + `]` + space,
946			want: []R{
947				{V: ArrayOpen, P: len(space), RS: `[`},
948				{V: ArrayClose},
949				{V: EOF},
950			},
951		},
952		{
953			in: space + `[` + space,
954			want: []R{
955				{V: ArrayOpen},
956				{E: errEOF},
957			},
958		},
959		{
960			in:   space + `]` + space,
961			want: []R{{E: `unexpected token ]`}},
962		},
963		{
964			in: `[null,true,false,  1e1, "hello"   ]`,
965			want: []R{
966				{V: ArrayOpen},
967				{V: Null},
968				{V: Bool{true}},
969				{V: Bool{false}},
970				{V: I32{10}},
971				{V: Str{"hello"}},
972				{V: ArrayClose},
973				{V: EOF},
974			},
975		},
976		{
977			in: `[` + space + `true` + space + `,` + space + `"hello"` + space + `]`,
978			want: []R{
979				{V: ArrayOpen},
980				{V: Bool{true}},
981				{V: Str{"hello"}},
982				{V: ArrayClose},
983				{V: EOF},
984			},
985		},
986		{
987			in: `[` + space + `true` + space + `,` + space + `]`,
988			want: []R{
989				{V: ArrayOpen},
990				{V: Bool{true}},
991				{E: `unexpected token ]`},
992			},
993		},
994		{
995			in: `[` + space + `false` + space + `]`,
996			want: []R{
997				{V: ArrayOpen},
998				{V: Bool{false}},
999				{V: ArrayClose},
1000				{V: EOF},
1001			},
1002		},
1003		{
1004			in: `[` + space + `1` + space + `0` + space + `]`,
1005			want: []R{
1006				{V: ArrayOpen},
1007				{V: I64{1}},
1008				{E: `unexpected token 0`},
1009			},
1010		},
1011		{
1012			in: `[null`,
1013			want: []R{
1014				{V: ArrayOpen},
1015				{V: Null},
1016				{E: errEOF},
1017			},
1018		},
1019		{
1020			in: `[foo]`,
1021			want: []R{
1022				{V: ArrayOpen},
1023				{E: `invalid value foo`},
1024			},
1025		},
1026		{
1027			in: `[{}, "hello", [true, false], null]`,
1028			want: []R{
1029				{V: ArrayOpen},
1030				{V: ObjectOpen},
1031				{V: ObjectClose},
1032				{V: Str{"hello"}},
1033				{V: ArrayOpen},
1034				{V: Bool{true}},
1035				{V: Bool{false}},
1036				{V: ArrayClose},
1037				{V: Null},
1038				{V: ArrayClose},
1039				{V: EOF},
1040			},
1041		},
1042		{
1043			in: `[{ ]`,
1044			want: []R{
1045				{V: ArrayOpen},
1046				{V: ObjectOpen},
1047				{E: `unexpected token ]`},
1048			},
1049		},
1050		{
1051			in: `[[ ]`,
1052			want: []R{
1053				{V: ArrayOpen},
1054				{V: ArrayOpen},
1055				{V: ArrayClose},
1056				{E: errEOF},
1057			},
1058		},
1059		{
1060			in: `[,]`,
1061			want: []R{
1062				{V: ArrayOpen},
1063				{E: `unexpected token ,`},
1064			},
1065		},
1066		{
1067			in: `[true "hello"]`,
1068			want: []R{
1069				{V: ArrayOpen},
1070				{V: Bool{true}},
1071				{E: `unexpected token "hello"`},
1072			},
1073		},
1074		{
1075			in: `[] null`,
1076			want: []R{
1077				{V: ArrayOpen},
1078				{V: ArrayClose},
1079				{E: `unexpected token null`},
1080			},
1081		},
1082		{
1083			in: `true []`,
1084			want: []R{
1085				{V: Bool{true}},
1086				{E: `unexpected token [`},
1087			},
1088		},
1089
1090		// JSON objects.
1091		{
1092			in: space + `{}` + space,
1093			want: []R{
1094				{V: ObjectOpen},
1095				{V: ObjectClose},
1096				{V: EOF},
1097			},
1098		},
1099		{
1100			in: space + `{` + space + `}` + space,
1101			want: []R{
1102				{V: ObjectOpen},
1103				{V: ObjectClose},
1104				{V: EOF},
1105			},
1106		},
1107		{
1108			in: space + `{` + space,
1109			want: []R{
1110				{V: ObjectOpen},
1111				{E: errEOF},
1112			},
1113		},
1114		{
1115			in:   space + `}` + space,
1116			want: []R{{E: `unexpected token }`}},
1117		},
1118		{
1119			in: `{` + space + `null` + space + `}`,
1120			want: []R{
1121				{V: ObjectOpen},
1122				{E: `unexpected token null`},
1123			},
1124		},
1125		{
1126			in: `{[]}`,
1127			want: []R{
1128				{V: ObjectOpen},
1129				{E: `(line 1:2): unexpected token [`},
1130			},
1131		},
1132		{
1133			in: `{,}`,
1134			want: []R{
1135				{V: ObjectOpen},
1136				{E: `unexpected token ,`},
1137			},
1138		},
1139		{
1140			in: `{"345678"}`,
1141			want: []R{
1142				{V: ObjectOpen},
1143				{E: `(line 1:10): unexpected character }, missing ":" after field name`},
1144			},
1145		},
1146		{
1147			in: `{` + space + `"hello"` + space + `:` + space + `"world"` + space + `}`,
1148			want: []R{
1149				{V: ObjectOpen},
1150				{V: Name{"hello"}, P: len(space) + 1, RS: `"hello"`},
1151				{V: Str{"world"}, RS: `"world"`},
1152				{V: ObjectClose},
1153				{V: EOF},
1154			},
1155		},
1156		{
1157			in: `{"hello" "world"}`,
1158			want: []R{
1159				{V: ObjectOpen},
1160				{E: `(line 1:10): unexpected character ", missing ":" after field name`},
1161			},
1162		},
1163		{
1164			in: `{"hello":`,
1165			want: []R{
1166				{V: ObjectOpen},
1167				{V: Name{"hello"}},
1168				{E: errEOF},
1169			},
1170		},
1171		{
1172			in: `{"hello":"world"`,
1173			want: []R{
1174				{V: ObjectOpen},
1175				{V: Name{"hello"}},
1176				{V: Str{"world"}},
1177				{E: errEOF},
1178			},
1179		},
1180		{
1181			in: `{"hello":"world",`,
1182			want: []R{
1183				{V: ObjectOpen},
1184				{V: Name{"hello"}},
1185				{V: Str{"world"}},
1186				{E: errEOF},
1187			},
1188		},
1189		{
1190			in: `{""`,
1191			want: []R{
1192				{V: ObjectOpen},
1193				{E: errEOF},
1194			},
1195		},
1196		{
1197			in: `{"34":"89",}`,
1198			want: []R{
1199				{V: ObjectOpen},
1200				{V: Name{"34"}, RS: `"34"`},
1201				{V: Str{"89"}},
1202				{E: `syntax error (line 1:12): unexpected token }`},
1203			},
1204		},
1205		{
1206			in: `{
1207			  "number": 123e2,
1208			  "bool"  : false,
1209			  "object": {"string": "world"},
1210			  "null"  : null,
1211			  "array" : [1.01, "hello", true],
1212			  "string": "hello"
1213			}`,
1214			want: []R{
1215				{V: ObjectOpen},
1216
1217				{V: Name{"number"}},
1218				{V: I32{12300}},
1219
1220				{V: Name{"bool"}},
1221				{V: Bool{false}},
1222
1223				{V: Name{"object"}},
1224				{V: ObjectOpen},
1225				{V: Name{"string"}},
1226				{V: Str{"world"}},
1227				{V: ObjectClose},
1228
1229				{V: Name{"null"}},
1230				{V: Null},
1231
1232				{V: Name{"array"}},
1233				{V: ArrayOpen},
1234				{V: F32{1.01}},
1235				{V: Str{"hello"}},
1236				{V: Bool{true}},
1237				{V: ArrayClose},
1238
1239				{V: Name{"string"}},
1240				{V: Str{"hello"}},
1241
1242				{V: ObjectClose},
1243				{V: EOF},
1244			},
1245		},
1246		{
1247			in: `[
1248			  {"object": {"number": 47}},
1249			  ["list"],
1250			  null
1251			]`,
1252			want: []R{
1253				{V: ArrayOpen},
1254
1255				{V: ObjectOpen},
1256				{V: Name{"object"}},
1257				{V: ObjectOpen},
1258				{V: Name{"number"}},
1259				{V: I32{47}},
1260				{V: ObjectClose},
1261				{V: ObjectClose},
1262
1263				{V: ArrayOpen},
1264				{V: Str{"list"}},
1265				{V: ArrayClose},
1266
1267				{V: Null},
1268
1269				{V: ArrayClose},
1270				{V: EOF},
1271			},
1272		},
1273
1274		// Tests for line and column info.
1275		{
1276			in: `12345678 x`,
1277			want: []R{
1278				{V: I64{12345678}},
1279				{E: `syntax error (line 1:10): invalid value x`},
1280			},
1281		},
1282		{
1283			in: "\ntrue\n   x",
1284			want: []R{
1285				{V: Bool{true}},
1286				{E: `syntax error (line 3:4): invalid value x`},
1287			},
1288		},
1289		{
1290			in: `"��"x`,
1291			want: []R{
1292				{V: Str{"��"}},
1293				{E: `syntax error (line 1:4): invalid value x`},
1294			},
1295		},
1296		{
1297			in: "\n\n[\"������\"x",
1298			want: []R{
1299				{V: ArrayOpen},
1300				{V: Str{"������"}},
1301				{E: `syntax error (line 3:7): invalid value x`},
1302			},
1303		},
1304		{
1305			// Multi-rune emojis.
1306			in: `["��������"x`,
1307			want: []R{
1308				{V: ArrayOpen},
1309				{V: Str{"��������"}},
1310				{E: `syntax error (line 1:8): invalid value x`},
1311			},
1312		},
1313	}
1314
1315	for _, tc := range tests {
1316		tc := tc
1317		t.Run("", func(t *testing.T) {
1318			dec := json.NewDecoder([]byte(tc.in))
1319			for i, want := range tc.want {
1320				peekTok, peekErr := dec.Peek()
1321				tok, err := dec.Read()
1322				if err != nil {
1323					if want.E == "" {
1324						errorf(t, tc.in, "want#%d: Read() got unexpected error: %v", i, err)
1325					} else if !strings.Contains(err.Error(), want.E) {
1326						errorf(t, tc.in, "want#%d: Read() got %q, want %q", i, err, want.E)
1327					}
1328					return
1329				}
1330				if want.E != "" {
1331					errorf(t, tc.in, "want#%d: Read() got nil error, want %q", i, want.E)
1332					return
1333				}
1334				checkToken(t, tok, i, want, tc.in)
1335				if !cmp.Equal(tok, peekTok, cmp.Comparer(json.TokenEquals)) {
1336					errorf(t, tc.in, "want#%d: Peek() %+v != Read() token %+v", i, peekTok, tok)
1337				}
1338				if err != peekErr {
1339					errorf(t, tc.in, "want#%d: Peek() error %v != Read() error %v", i, err, peekErr)
1340				}
1341			}
1342		})
1343	}
1344}
1345
1346func checkToken(t *testing.T, tok json.Token, idx int, r R, in string) {
1347	// Validate Token.Pos() if R.P is set.
1348	if r.P > 0 {
1349		got := tok.Pos()
1350		if got != r.P {
1351			errorf(t, in, "want#%d: Token.Pos() got %v want %v", idx, got, r.P)
1352		}
1353	}
1354	// Validate Token.RawString if R.RS is set.
1355	if len(r.RS) > 0 {
1356		got := tok.RawString()
1357		if got != r.RS {
1358			errorf(t, in, "want#%d: Token.RawString() got %v want %v", idx, got, r.P)
1359		}
1360	}
1361
1362	// Skip checking for Token details if r.V is not set.
1363	if r.V == nil {
1364		return
1365	}
1366
1367	if err := r.V.check(tok); err != "" {
1368		errorf(t, in, "want#%d: %s", idx, err)
1369	}
1370	return
1371}
1372
1373func errorf(t *testing.T, in string, fmtStr string, args ...interface{}) {
1374	t.Helper()
1375	vargs := []interface{}{in}
1376	for _, arg := range args {
1377		vargs = append(vargs, arg)
1378	}
1379	t.Errorf("input:\n%s\n~end~\n"+fmtStr, vargs...)
1380}
1381
1382func TestClone(t *testing.T) {
1383	input := `{"outer":{"str":"hello", "number": 123}}`
1384	dec := json.NewDecoder([]byte(input))
1385
1386	// Clone at the start should produce the same reads as the original.
1387	clone := dec.Clone()
1388	compareDecoders(t, dec, clone)
1389
1390	// Advance to inner object, clone and compare again.
1391	dec.Read() // Read ObjectOpen.
1392	dec.Read() // Read Name.
1393	clone = dec.Clone()
1394	compareDecoders(t, dec, clone)
1395}
1396
1397func compareDecoders(t *testing.T, d1 *json.Decoder, d2 *json.Decoder) {
1398	for {
1399		tok1, err1 := d1.Read()
1400		tok2, err2 := d2.Read()
1401		if tok1.Kind() != tok2.Kind() {
1402			t.Errorf("cloned decoder: got Kind %v, want %v", tok2.Kind(), tok1.Kind())
1403		}
1404		if tok1.RawString() != tok2.RawString() {
1405			t.Errorf("cloned decoder: got RawString %v, want %v", tok2.RawString(), tok1.RawString())
1406		}
1407		if err1 != err2 {
1408			t.Errorf("cloned decoder: got error %v, want %v", err2, err1)
1409		}
1410		if tok1.Kind() == json.EOF {
1411			break
1412		}
1413	}
1414}
1415