1 // Copyright 2010 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.
15 var validTests
= []struct {
23 {`{"foo":"bar"}`, true},
24 {`{"foo":"bar","bar":{"baz":["qux"]}}`, true},
27 func TestValid(t
*testing
.T
) {
28 for _
, tt
:= range validTests
{
29 if ok
:= Valid([]byte(tt
.data
)); ok
!= tt
.ok
{
30 t
.Errorf("Valid(%#q) = %v, want %v", tt
.data
, ok
, tt
.ok
)
35 // Tests of simple examples.
42 var examples
= []example
{
46 {`{"":2}`, "{\n\t\"\": 2\n}"},
48 {`[1,2,3]`, "[\n\t1,\n\t2,\n\t3\n]"},
49 {`{"x":1}`, "{\n\t\"x\": 1\n}"},
53 var ex1
= `[true,false,null,"x",1,1.5,0,-5e+2]`
66 func TestCompact(t
*testing
.T
) {
68 for _
, tt
:= range examples
{
70 if err
:= Compact(&buf
, []byte(tt
.compact
)); err
!= nil {
71 t
.Errorf("Compact(%#q): %v", tt
.compact
, err
)
72 } else if s
:= buf
.String(); s
!= tt
.compact
{
73 t
.Errorf("Compact(%#q) = %#q, want original", tt
.compact
, s
)
77 if err
:= Compact(&buf
, []byte(tt
.indent
)); err
!= nil {
78 t
.Errorf("Compact(%#q): %v", tt
.indent
, err
)
80 } else if s
:= buf
.String(); s
!= tt
.compact
{
81 t
.Errorf("Compact(%#q) = %#q, want %#q", tt
.indent
, s
, tt
.compact
)
86 func TestCompactSeparators(t
*testing
.T
) {
87 // U+2028 and U+2029 should be escaped inside strings.
88 // They should not appear outside strings.
92 {"{\"\u2028\": 1}", `{"\u2028":1}`},
93 {"{\"\u2029\" :2}", `{"\u2029":2}`},
95 for _
, tt
:= range tests
{
97 if err
:= Compact(&buf
, []byte(tt
.in
)); err
!= nil {
98 t
.Errorf("Compact(%q): %v", tt
.in
, err
)
99 } else if s
:= buf
.String(); s
!= tt
.compact
{
100 t
.Errorf("Compact(%q) = %q, want %q", tt
.in
, s
, tt
.compact
)
105 func TestIndent(t
*testing
.T
) {
107 for _
, tt
:= range examples
{
109 if err
:= Indent(&buf
, []byte(tt
.indent
), "", "\t"); err
!= nil {
110 t
.Errorf("Indent(%#q): %v", tt
.indent
, err
)
111 } else if s
:= buf
.String(); s
!= tt
.indent
{
112 t
.Errorf("Indent(%#q) = %#q, want original", tt
.indent
, s
)
116 if err
:= Indent(&buf
, []byte(tt
.compact
), "", "\t"); err
!= nil {
117 t
.Errorf("Indent(%#q): %v", tt
.compact
, err
)
119 } else if s
:= buf
.String(); s
!= tt
.indent
{
120 t
.Errorf("Indent(%#q) = %#q, want %#q", tt
.compact
, s
, tt
.indent
)
125 // Tests of a large random structure.
127 func TestCompactBig(t
*testing
.T
) {
130 if err
:= Compact(&buf
, jsonBig
); err
!= nil {
131 t
.Fatalf("Compact: %v", err
)
134 if !bytes
.Equal(b
, jsonBig
) {
135 t
.Error("Compact(jsonBig) != jsonBig")
141 func TestIndentBig(t
*testing
.T
) {
145 if err
:= Indent(&buf
, jsonBig
, "", "\t"); err
!= nil {
146 t
.Fatalf("Indent1: %v", err
)
149 if len(b
) == len(jsonBig
) {
150 // jsonBig is compact (no unnecessary spaces);
151 // indenting should make it bigger
152 t
.Fatalf("Indent(jsonBig) did not get bigger")
155 // should be idempotent
156 var buf1 bytes
.Buffer
157 if err
:= Indent(&buf1
, b
, "", "\t"); err
!= nil {
158 t
.Fatalf("Indent2: %v", err
)
161 if !bytes
.Equal(b1
, b
) {
162 t
.Error("Indent(Indent(jsonBig)) != Indent(jsonBig)")
167 // should get back to original
169 if err
:= Compact(&buf1
, b
); err
!= nil {
170 t
.Fatalf("Compact: %v", err
)
173 if !bytes
.Equal(b1
, jsonBig
) {
174 t
.Error("Compact(Indent(jsonBig)) != jsonBig")
180 type indentErrorTest
struct {
185 var indentErrorTests
= []indentErrorTest
{
186 {`{"X": "foo", "Y"}`, &SyntaxError
{"invalid character '}' after object key", 17}},
187 {`{"X": "foo" "Y": "bar"}`, &SyntaxError
{"invalid character '\"' after object key:value pair", 13}},
190 func TestIndentErrors(t
*testing
.T
) {
191 for i
, tt
:= range indentErrorTests
{
192 slice
:= make([]uint8, 0)
193 buf
:= bytes
.NewBuffer(slice
)
194 if err
:= Indent(buf
, []uint8(tt
.in
), "", ""); err
!= nil {
195 if !reflect
.DeepEqual(err
, tt
.err
) {
196 t
.Errorf("#%d: Indent: %#v", i
, err
)
203 func diff(t
*testing
.T
, a
, b
[]byte) {
205 if i
>= len(a
) || i
>= len(b
) || a
[i
] != b
[i
] {
210 t
.Errorf("diverge at %d: «%s» vs «%s»", i
, trim(a
[j
:]), trim(b
[j
:]))
216 func trim(b
[]byte) []byte {
223 // Generate a random JSON object.
232 b
, err
:= Marshal(genValue(n
))
239 func genValue(n
int) interface{} {
241 switch rand
.Intn(2) {
248 switch rand
.Intn(3) {
250 return rand
.Intn(2) == 0
252 return rand
.NormFloat64()
259 func genString(stddev
float64) string {
260 n
:= int(math
.Abs(rand
.NormFloat64()*stddev
+ stddev
/2))
263 f
:= math
.Abs(rand
.NormFloat64()*64 + 32)
272 func genArray(n
int) []interface{} {
273 f
:= int(math
.Abs(rand
.NormFloat64()) * math
.Min(10, float64(n
/2)))
280 x
:= make([]interface{}, f
)
282 x
[i
] = genValue(((i
+1)*n
)/f
- (i
*n
)/f
)
287 func genMap(n
int) map[string]interface{} {
288 f
:= int(math
.Abs(rand
.NormFloat64()) * math
.Min(10, float64(n
/2)))
295 x
:= make(map[string]interface{})
296 for i
:= 0; i
< f
; i
++ {
297 x
[genString(10)] = genValue(((i
+1)*n
)/f
- (i
*n
)/f
)