github.com/songzhibin97/gkit@v1.2.13/tools/pretty/pretty_test.go (about) 1 package pretty 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "math/rand" 8 "reflect" 9 "strings" 10 "testing" 11 "time" 12 ) 13 14 func j(js interface{}) string { 15 var v interface{} 16 if err := json.Unmarshal([]byte(fmt.Sprintf("%s", js)), &v); err != nil { 17 fmt.Printf(">>%s<<\n", js) 18 panic(err) 19 } 20 data, err := json.Marshal(v) 21 if err != nil { 22 panic(err) 23 } 24 return string(data) 25 } 26 27 var example1 = []byte(` 28 { 29 "name": { 30 "last": "Sanders", 31 "first": "Janet" 32 }, 33 "children": [ 34 "Andy", "Carol", "Mike" 35 ], 36 "values": [ 37 10.10, true, false, null, "hello", {} 38 ], 39 "values2": {}, 40 "values3": [], 41 "deep": {"deep":{"deep":[1,2,3,4,5]}} 42 } 43 `) 44 45 var example2 = `[ 0, 10, 10.10, true, false, null, "hello \" "]` 46 47 func assertEqual(t *testing.T, a, b interface{}) { 48 t.Helper() 49 if !reflect.DeepEqual(a, b) { 50 t.Fatalf("Not equal\n\t'%v'\n\t'%v'", a, b) 51 } 52 } 53 54 func TestPretty(t *testing.T) { 55 pretty := Pretty(Ugly(Pretty([]byte(example1)))) 56 assertEqual(t, j(pretty), j(pretty)) 57 assertEqual(t, j(example1), j(pretty)) 58 pretty = Pretty(Ugly(Pretty([]byte(example2)))) 59 assertEqual(t, j(pretty), j(pretty)) 60 assertEqual(t, j(example2), j(pretty)) 61 pretty = Pretty([]byte(" ")) 62 assertEqual(t, "", string(pretty)) 63 opts := *DefaultOptions 64 opts.SortKeys = true 65 pretty = BestOptions(Ugly(Pretty([]byte(example2))), &opts) 66 assertEqual(t, j(pretty), j(pretty)) 67 assertEqual(t, j(example2), j(pretty)) 68 } 69 70 func TestUgly(t *testing.T) { 71 ugly := Ugly([]byte(example1)) 72 var buf bytes.Buffer 73 err := json.Compact(&buf, []byte(example1)) 74 assertEqual(t, nil, err) 75 assertEqual(t, buf.Bytes(), ugly) 76 ugly = UglyInPlace(ugly) 77 assertEqual(t, nil, err) 78 assertEqual(t, buf.Bytes(), ugly) 79 } 80 81 func TestRandom(t *testing.T) { 82 rand.Seed(time.Now().UnixNano()) 83 for i := 0; i < 100000; i++ { 84 b := make([]byte, 1024) 85 rand.Read(b) 86 Pretty(b) 87 Ugly(b) 88 } 89 } 90 91 func TestBig(t *testing.T) { 92 js := `[ 93 { 94 "_id": "58d19e070f4898817162964a", 95 "index": "<ReferenceError: indexkk is not defined>", 96 "guid": "65d46c3e-9d3a-4bfe-bab2-252f36a53c6b", 97 "isActive": false, 98 "balance": "$1,064.00", 99 "picture": "http://placehold.it/32x32", 100 "age": 37, 101 "eyeColor": "brown", 102 "name": "Chan Orr", 103 "gender": "male", 104 "company": "SURETECH", 105 "email": "chanorr@suretech.com", 106 "phone": "+1 (808) 496-3754", 107 "address": "792 Bushwick Place, Glenbrook, Vermont, 9893", 108 "about": "Amet consequat eu enim laboris cillum ad laboris in quis laboris reprehenderit. Eu deserunt occaecat dolore eu veniam non dolore et magna ex incididunt. Ea dolor laboris ex officia culpa laborum amet adipisicing laboris tempor magna elit mollit ad. Tempor ex aliqua mollit enim laboris sunt fugiat. Sint sunt ex est non dolore consectetur culpa ullamco id dolor nulla labore. Sunt duis fugiat cupidatat sunt deserunt qui aute elit consequat sint cupidatat. Consequat ullamco aliqua nulla velit tempor aute.\r\n", 109 "registered": "2014-08-04T04:09:10 +07:00", 110 "latitude": 80.707807, 111 "longitude": 18.857548, 112 "tags": [ 113 "consectetur", 114 "est", 115 "cupidatat", 116 "nisi", 117 "incididunt", 118 "aliqua", 119 "ullamco" 120 ], 121 "friends": [ 122 { 123 "id": 0, 124 "name": "Little Edwards" 125 }, 126 { 127 "id": 1, 128 "name": "Gay Johns" 129 }, 130 { 131 "id": 2, 132 "name": "Hoover Noble" 133 } 134 ], 135 "greeting": "Hello, Chan Orr! You have 3 unread messages.", 136 "favoriteFruit": "banana" 137 }, 138 { 139 "_id": "58d19e07c2119248f8fa11ff", 140 "index": "<ReferenceError: indexkk is not defined>", 141 "guid": "b362f0a0-d1ed-4b94-9d6b-213712620a20", 142 "isActive": false, 143 "balance": "$1,321.26", 144 "picture": "http://placehold.it/32x32", 145 "age": 28, 146 "eyeColor": "blue", 147 "name": "Molly Hyde", 148 "gender": "female", 149 "company": "QUALITEX", 150 "email": "mollyhyde@qualitex.com", 151 "phone": "+1 (849) 455-2934", 152 "address": "440 Visitation Place, Bridgetown, Palau, 5053", 153 "about": "Ipsum reprehenderit nulla est nostrud ad incididunt officia in commodo id esse id. Ullamco ullamco commodo mollit ut id cupidatat veniam nostrud minim duis qui sit. Occaecat esse nostrud velit qui non dolor proident. Ipsum ipsum anim non mollit minim voluptate amet irure in. Sunt commodo occaecat aute ullamco sunt fugiat laboris culpa Lorem anim. Aliquip tempor excepteur labore aute deserunt consectetur incididunt aute eu est ullamco consectetur excepteur. Sunt sint consequat cupidatat nisi exercitation minim enim occaecat esse ex amet ex non.\r\n", 154 "registered": "2014-09-12T08:51:11 +07:00", 155 "latitude": 15.867177, 156 "longitude": 165.862595, 157 "tags": [ 158 "enim", 159 "sint", 160 "elit", 161 "laborum", 162 "elit", 163 "cupidatat", 164 "ipsum" 165 ], 166 "friends": [ 167 { 168 "id": 0, 169 "name": "Watching Hurley" 170 }, 171 { 172 "id": 1, 173 "name": "Rhoda Spencer" 174 }, 175 { 176 "id": 2, 177 "name": "Tommie Gallegos" 178 } 179 ], 180 "greeting": "Hello, Molly Hyde! You have 10 unread messages.", 181 "favoriteFruit": "banana" 182 }, 183 { 184 "_id": "58d19e07fc27eedd9159d710", 185 "index": "<ReferenceError: indexkk is not defined>", 186 "guid": "1d343fd3-44f7-4246-a5e6-a9297afb3146", 187 "isActive": false, 188 "balance": "$1,459.65", 189 "picture": "http://placehold.it/32x32", 190 "age": 26, 191 "eyeColor": "brown", 192 "name": "Jaime Kennedy", 193 "gender": "female", 194 "company": "RECRITUBE", 195 "email": "jaimekennedy@recritube.com", 196 "phone": "+1 (983) 483-3522", 197 "address": "997 Vanderveer Street, Alamo, Marshall Islands, 4767", 198 "about": "Qui consequat veniam ex enim excepteur aliqua dolor duis Lorem deserunt. Lorem occaecat laboris quis nisi Lorem aute exercitation consectetur officia velit aliqua aliquip commodo. Tempor irure ad ipsum aliquip. Incididunt mollit aute cillum non magna duis officia anim laboris deserunt voluptate.\r\n", 199 "registered": "2015-08-31T06:51:25 +07:00", 200 "latitude": -7.486839, 201 "longitude": 57.659287, 202 "tags": [ 203 "veniam", 204 "aliqua", 205 "aute", 206 "amet", 207 "laborum", 208 "quis", 209 "sint" 210 ], 211 "friends": [ 212 { 213 "id": 0, 214 "name": "Brown Christensen" 215 }, 216 { 217 "id": 1, 218 "name": "Robyn Whitehead" 219 }, 220 { 221 "id": 2, 222 "name": "Dolly Weaver" 223 } 224 ], 225 "greeting": "Hello, Jaime Kennedy! You have 3 unread messages.", 226 "favoriteFruit": "banana" 227 }, 228 { 229 "_id": "58d19e0783c362da4b71240d", 230 "index": "<ReferenceError: indexkk is not defined>", 231 "guid": "dbe60229-60d2-4879-82f3-d9aca0baaf6f", 232 "isActive": false, 233 "balance": "$3,221.63", 234 "picture": "http://placehold.it/32x32", 235 "age": 32, 236 "eyeColor": "green", 237 "name": "Cherie Vinson", 238 "gender": "female", 239 "company": "SLAX", 240 "email": "cherievinson@slax.com", 241 "phone": "+1 (905) 474-3132", 242 "address": "563 Macdougal Street, Navarre, New York, 8733", 243 "about": "Ad laborum et magna quis veniam duis magna consectetur mollit in minim non officia aliquip. Ullamco dolor qui consectetur adipisicing. Incididunt ad ad incididunt duis velit laboris. Reprehenderit ullamco magna quis exercitation excepteur nisi labore pariatur laborum consequat eu laboris amet velit. Et dolore aliqua proident sunt dolore incididunt dolore fugiat ipsum tempor occaecat.\r\n", 244 "registered": "2015-03-19T08:48:47 +07:00", 245 "latitude": -56.480034, 246 "longitude": -59.894094, 247 "tags": [ 248 "irure", 249 "commodo", 250 "quis", 251 "cillum", 252 "quis", 253 "nulla", 254 "irure" 255 ], 256 "friends": [ 257 { 258 "id": 0, 259 "name": "Danielle Mullins" 260 }, 261 { 262 "id": 1, 263 "name": "Maxine Peters" 264 }, 265 { 266 "id": 2, 267 "name": "Francine James" 268 } 269 ], 270 "greeting": "Hello, Cherie Vinson! You have 1 unread messages.", 271 "favoriteFruit": "apple" 272 }, 273 { 274 "_id": "58d19e07b8f1ea8e3451870d", 275 "index": "<ReferenceError: indexkk is not defined>", 276 "guid": "91fd9527-770c-4006-a0ed-64ca0d819199", 277 "isActive": true, 278 "balance": "$2,387.38", 279 "picture": "http://placehold.it/32x32", 280 "age": 37, 281 "eyeColor": "blue", 282 "name": "Glenna Hanson", 283 "gender": "female", 284 "company": "ACUMENTOR", 285 "email": "glennahanson@acumentor.com", 286 "phone": "+1 (965) 564-3926", 287 "address": "323 Seigel Street, Rosedale, Florida, 2700", 288 "about": "Commodo id ex velit nulla incididunt occaecat aliquip ullamco consequat est. Esse officia adipisicing magna et et incididunt sit deserunt ex mollit id. Laborum proident sit sit duis proident cillum irure aliquip et commodo.\r\n", 289 "registered": "2014-06-29T02:48:04 +07:00", 290 "latitude": -6.141759, 291 "longitude": 155.991532, 292 "tags": [ 293 "amet", 294 "pariatur", 295 "culpa", 296 "eu", 297 "commodo", 298 "magna", 299 "excepteur" 300 ], 301 "friends": [ 302 { 303 "id": 0, 304 "name": "Blanchard Blackburn" 305 }, 306 { 307 "id": 1, 308 "name": "Ayers Guy" 309 }, 310 { 311 "id": 2, 312 "name": "Powers Salinas" 313 } 314 ], 315 "greeting": "Hello, Glenna Hanson! You have 4 unread messages.", 316 "favoriteFruit": "strawberry" 317 }, 318 { 319 "_id": "58d19e07f1ad063dac8b72dc", 320 "index": "<ReferenceError: indexkk is not defined>", 321 "guid": "9b8c6cef-cfcd-4e6d-85e4-fe2e6920ec31", 322 "isActive": true, 323 "balance": "$1,828.58", 324 "picture": "http://placehold.it/32x32", 325 "age": 29, 326 "eyeColor": "green", 327 "name": "Hays Shields", 328 "gender": "male", 329 "company": "ISOLOGICA", 330 "email": "haysshields@isologica.com", 331 "phone": "+1 (882) 469-3201", 332 "address": "574 Columbus Place, Singer, Georgia, 8716", 333 "about": "Consectetur et adipisicing ad quis incididunt qui labore et ex elit esse. Ad elit officia ullamco dolor reprehenderit. Sunt nisi ullamco mollit incididunt consectetur nostrud anim adipisicing ullamco aliqua eiusmod ad. Et excepteur voluptate adipisicing velit id quis duis Lorem id deserunt esse irure Lorem. Est irure sint Lorem aliqua adipisicing velit irure Lorem. Ex in culpa laborum nostrud esse eu laboris velit. Anim excepteur ex ipsum amet nostrud cillum.\r\n", 334 "registered": "2014-02-10T07:17:14 +07:00", 335 "latitude": -66.354543, 336 "longitude": 138.400461, 337 "tags": [ 338 "mollit", 339 "labore", 340 "id", 341 "labore", 342 "dolor", 343 "in", 344 "elit" 345 ], 346 "friends": [ 347 { 348 "id": 0, 349 "name": "Mendoza Craig" 350 }, 351 { 352 "id": 1, 353 "name": "Rowena Carey" 354 }, 355 { 356 "id": 2, 357 "name": "Barry Francis" 358 } 359 ], 360 "greeting": "Hello, Hays Shields! You have 10 unread messages.", 361 "favoriteFruit": "strawberry" 362 } 363 ]` 364 365 opts := *DefaultOptions 366 opts.SortKeys = true 367 jsonb := BestOptions(Ugly([]byte(js)), &opts) 368 assertEqual(t, j(jsonb), j(js)) 369 } 370 371 func TestColor(t *testing.T) { 372 res := Color(Pretty([]byte(` 373 {"hello":"world","what":123, 374 "arr":["1","2",1,2,true,false,null], 375 "obj":{"key1":null,"ar`+"\x1B[36m"+`Cyanr2":[1,2,3,"123","456"]}} 376 `)), nil) 377 if string(res) != `{ 378 [94m"hello"[0m: [92m"world"[0m, 379 [94m"what"[0m: [93m123[0m, 380 [94m"arr"[0m: [[92m"1"[0m, [92m"2"[0m, [93m1[0m, [93m2[0m, [96mtrue[0m, [96mfalse[0m, [91mnull[0m], 381 [94m"obj"[0m: { 382 [94m"key1"[0m: [91mnull[0m, 383 [94m"ar\u001b[36mCyanr2"[0m: [[93m1[0m, [93m2[0m, [93m3[0m, [92m"123"[0m, [92m"456"[0m] 384 } 385 } 386 ` { 387 t.Fatal("invalid output") 388 } 389 } 390 391 func BenchmarkPretty(t *testing.B) { 392 t.ReportAllocs() 393 t.ResetTimer() 394 for i := 0; i < t.N; i++ { 395 Pretty(example1) 396 } 397 } 398 399 func BenchmarkPrettySortKeys(t *testing.B) { 400 opts := *DefaultOptions 401 opts.SortKeys = true 402 t.ReportAllocs() 403 t.ResetTimer() 404 for i := 0; i < t.N; i++ { 405 BestOptions(example1, &opts) 406 } 407 } 408 409 func BenchmarkUgly(t *testing.B) { 410 t.ReportAllocs() 411 t.ResetTimer() 412 for i := 0; i < t.N; i++ { 413 Ugly(example1) 414 } 415 } 416 417 func BenchmarkUglyInPlace(t *testing.B) { 418 example2 := []byte(string(example1)) 419 t.ReportAllocs() 420 t.ResetTimer() 421 for i := 0; i < t.N; i++ { 422 UglyInPlace(example2) 423 } 424 } 425 426 func BenchmarkJSONIndent(t *testing.B) { 427 var dst bytes.Buffer 428 t.ReportAllocs() 429 t.ResetTimer() 430 for i := 0; i < t.N; i++ { 431 _ = json.Indent(&dst, example1, "", " ") 432 } 433 } 434 435 func BenchmarkJSONCompact(t *testing.B) { 436 var dst bytes.Buffer 437 t.ReportAllocs() 438 t.ResetTimer() 439 for i := 0; i < t.N; i++ { 440 _ = json.Compact(&dst, example1) 441 } 442 } 443 444 func TestPrettyNoSpaceAfterNewline(t *testing.T) { 445 json := `[{"foo":1,"bar":2},{"foo":3,"bar":4}]` 446 json = string(Pretty([]byte(json))) 447 if strings.Index(json, " \n") != -1 { 448 t.Fatal("found a space followed by a newline, which should not be allowed") 449 } 450 } 451 452 func TestPrettyStableSort(t *testing.T) { 453 json := `{"c":3,"b":3,"a":3,"c":2,"b":2,"a":2,"c":1,"b":1,"a":1}` 454 opts := *DefaultOptions 455 opts.SortKeys = true 456 json = string(Ugly(BestOptions([]byte(json), &opts))) 457 if json != `{"a":3,"a":2,"a":1,"b":3,"b":2,"b":1,"c":3,"c":2,"c":1}` { 458 t.Fatal("out of order") 459 } 460 } 461 462 func TestPrettyColor(t *testing.T) { 463 js := `"abc\u0020def\nghi"` 464 ret := string(Color([]byte(js), nil)) 465 exp := "" + 466 TerminalStyle.String[0] + `"abc` + TerminalStyle.String[1] + 467 TerminalStyle.Escape[0] + `\u0020` + TerminalStyle.Escape[1] + 468 TerminalStyle.String[0] + `def` + TerminalStyle.String[1] + 469 TerminalStyle.Escape[0] + `\n` + TerminalStyle.Escape[1] + 470 TerminalStyle.String[0] + `ghi"` + TerminalStyle.String[1] 471 if ret != exp { 472 t.Fatalf("expected '%s', got '%s'", exp, ret) 473 } 474 } 475 476 func TestSpec(t *testing.T) { 477 js := ` 478 { // hello 479 "c": 3,"b":3, // jello 480 /* SOME 481 LIKE 482 IT 483 HAUT */ 484 "d": [ 1, /* 2 */ 3, 4, ], 485 }` 486 expect := ` 487 { 488 "c": 3,"b":3, 489 490 491 492 493 "d": [ 1, 3, 4 ] 494 }` 495 out := string(Spec([]byte(js))) 496 if out != expect { 497 t.Fatalf("expected '%s', got '%s'", expect, out) 498 } 499 out = string(SpecInPlace([]byte(js))) 500 if out != expect { 501 t.Fatalf("expected '%s', got '%s'", expect, out) 502 } 503 }