json-stream 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/spec/parser_spec.rb DELETED
@@ -1,913 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'json/stream'
4
- require 'minitest/autorun'
5
-
6
- describe JSON::Stream::Parser do
7
- subject { JSON::Stream::Parser.new }
8
-
9
- describe 'parsing a document' do
10
- it 'rejects documents containing bad start character' do
11
- expected = [:error]
12
- assert_equal expected, events('a')
13
- end
14
-
15
- it 'rejects documents starting with period' do
16
- expected = [:error]
17
- assert_equal expected, events('.')
18
- end
19
-
20
- it 'parses a null value document' do
21
- expected = [:start_document, [:value, nil], :end_document]
22
- assert_equal expected, events('null')
23
- end
24
-
25
- it 'parses a false value document' do
26
- expected = [:start_document, [:value, false], :end_document]
27
- assert_equal expected, events('false')
28
- end
29
-
30
- it 'parses a true value document' do
31
- expected = [:start_document, [:value, true], :end_document]
32
- assert_equal expected, events('true')
33
- end
34
-
35
- it 'parses a string document' do
36
- expected = [:start_document, [:value, "test"], :end_document]
37
- assert_equal expected, events('"test"')
38
- end
39
-
40
- it 'parses a single digit integer value document' do
41
- expected = [:start_document, [:value, 2], :end_document]
42
- events = events('2', subject)
43
- assert events.empty?
44
- subject.finish
45
- assert_equal expected, events
46
- end
47
-
48
- it 'parses a multiple digit integer value document' do
49
- expected = [:start_document, [:value, 12], :end_document]
50
- events = events('12', subject)
51
- assert events.empty?
52
- subject.finish
53
- assert_equal expected, events
54
- end
55
-
56
- it 'parses a zero literal document' do
57
- expected = [:start_document, [:value, 0], :end_document]
58
- events = events('0', subject)
59
- assert events.empty?
60
- subject.finish
61
- assert_equal expected, events
62
- end
63
-
64
- it 'parses a negative integer document' do
65
- expected = [:start_document, [:value, -1], :end_document]
66
- events = events('-1', subject)
67
- assert events.empty?
68
- subject.finish
69
- assert_equal expected, events
70
- end
71
-
72
- it 'parses an exponent literal document' do
73
- expected = [:start_document, [:value, 200.0], :end_document]
74
- events = events('2e2', subject)
75
- assert events.empty?
76
- subject.finish
77
- assert_equal expected, events
78
- end
79
-
80
- it 'parses a float value document' do
81
- expected = [:start_document, [:value, 12.1], :end_document]
82
- events = events('12.1', subject)
83
- assert events.empty?
84
- subject.finish
85
- assert_equal expected, events
86
- end
87
-
88
- it 'parses a value document with leading whitespace' do
89
- expected = [:start_document, [:value, false], :end_document]
90
- assert_equal expected, events(' false ')
91
- end
92
-
93
- it 'parses array documents' do
94
- expected = [:start_document, :start_array, :end_array, :end_document]
95
- assert_equal expected, events('[]')
96
- assert_equal expected, events('[ ]')
97
- assert_equal expected, events(' [] ')
98
- assert_equal expected, events(' [ ] ')
99
- end
100
-
101
- it 'parses object documents' do
102
- expected = [:start_document, :start_object, :end_object, :end_document]
103
- assert_equal expected, events('{}')
104
- assert_equal expected, events('{ }')
105
- assert_equal expected, events(' {} ')
106
- assert_equal expected, events(' { } ')
107
- end
108
-
109
- it 'rejects documents with trailing characters' do
110
- expected = [:start_document, :start_object, :end_object, :end_document, :error]
111
- assert_equal expected, events('{}a')
112
- assert_equal expected, events('{ } 12')
113
- assert_equal expected, events(' {} false')
114
- assert_equal expected, events(' { }, {}')
115
- end
116
-
117
- it 'ignores whitespace around tokens, preserves it within strings' do
118
- json = %Q{
119
- { " key 1 " : \t [
120
- 1, 2, " my string ",\r
121
- false, true, null ]
122
- }
123
- }
124
- expected = [
125
- :start_document,
126
- :start_object,
127
- [:key, " key 1 "],
128
- :start_array,
129
- [:value, 1],
130
- [:value, 2],
131
- [:value, " my string "],
132
- [:value, false],
133
- [:value, true],
134
- [:value, nil],
135
- :end_array,
136
- :end_object,
137
- :end_document
138
- ]
139
- assert_equal expected, events(json)
140
- end
141
-
142
- it 'rejects form feed whitespace' do
143
- json = "[1,\f 2]"
144
- expected = [:start_document, :start_array, [:value, 1], :error]
145
- assert_equal expected, events(json)
146
- end
147
-
148
- it 'rejects vertical tab whitespace' do
149
- json = "[1,\v 2]"
150
- expected = [:start_document, :start_array, [:value, 1], :error]
151
- assert_equal expected, events(json)
152
- end
153
-
154
- it 'rejects partial keyword tokens' do
155
- expected = [:start_document, :start_array, :error]
156
- assert_equal expected, events('[tru]')
157
- assert_equal expected, events('[fal]')
158
- assert_equal expected, events('[nul,true]')
159
- assert_equal expected, events('[fals1]')
160
- end
161
-
162
- it 'rejects scrambled keyword tokens' do
163
- expected = [:start_document, :start_array, :error]
164
- assert_equal expected, events('[ture]')
165
- assert_equal expected, events('[fales]')
166
- assert_equal expected, events('[nlul]')
167
- end
168
-
169
- it 'parses single keyword tokens' do
170
- expected = [:start_document, :start_array, [:value, true], :end_array, :end_document]
171
- assert_equal expected, events('[true]')
172
- end
173
-
174
- it 'parses keywords in series' do
175
- expected = [:start_document, :start_array, [:value, true], [:value, nil], :end_array, :end_document]
176
- assert_equal expected, events('[true, null]')
177
- end
178
- end
179
-
180
- describe 'finishing the parse' do
181
- it 'rejects finish with no json data provided' do
182
- -> { subject.finish }.must_raise JSON::Stream::ParserError
183
- end
184
-
185
- it 'rejects partial null keyword' do
186
- subject << 'nul'
187
- -> { subject.finish }.must_raise JSON::Stream::ParserError
188
- end
189
-
190
- it 'rejects partial true keyword' do
191
- subject << 'tru'
192
- -> { subject.finish }.must_raise JSON::Stream::ParserError
193
- end
194
-
195
- it 'rejects partial false keyword' do
196
- subject << 'fals'
197
- -> { subject.finish }.must_raise JSON::Stream::ParserError
198
- end
199
-
200
- it 'rejects partial float literal' do
201
- subject << '42.'
202
- -> { subject.finish }.must_raise JSON::Stream::ParserError
203
- end
204
-
205
- it 'rejects partial exponent' do
206
- subject << '42e'
207
- -> { subject.finish }.must_raise JSON::Stream::ParserError
208
- end
209
-
210
- it 'rejects malformed exponent' do
211
- subject << '42e+'
212
- -> { subject.finish }.must_raise JSON::Stream::ParserError
213
- end
214
-
215
- it 'rejects partial negative number' do
216
- subject << '-'
217
- -> { subject.finish }.must_raise JSON::Stream::ParserError
218
- end
219
-
220
- it 'rejects partial string literal' do
221
- subject << '"test'
222
- -> { subject.finish }.must_raise JSON::Stream::ParserError
223
- end
224
-
225
- it 'rejects partial object ending in literal value' do
226
- subject << '{"test": 42'
227
- -> { subject.finish }.must_raise JSON::Stream::ParserError
228
- end
229
-
230
- it 'rejects partial array ending in literal value' do
231
- subject << '[42'
232
- -> { subject.finish }.must_raise JSON::Stream::ParserError
233
- end
234
-
235
- it 'does nothing on subsequent finish' do
236
- begin
237
- subject << 'false'
238
- subject.finish
239
- subject.finish
240
- rescue
241
- fail 'raised unexpected error'
242
- end
243
- end
244
- end
245
-
246
- describe 'parsing number tokens' do
247
- it 'rejects invalid negative numbers' do
248
- expected = [:start_document, :start_array, :error]
249
- assert_equal expected, events('[-]')
250
-
251
- expected = [:start_document, :start_array, [:value, 1], :error]
252
- assert_equal expected, events('[1-0]')
253
- end
254
-
255
- it 'parses integer zero' do
256
- expected = [:start_document, :start_array, [:value, 0], :end_array, :end_document]
257
- assert_equal expected, events('[0]')
258
- assert_equal expected, events('[-0]')
259
- end
260
-
261
- it 'parses float zero' do
262
- expected = [:start_document, :start_array, [:value, 0.0], :end_array, :end_document]
263
- assert_equal expected, events('[0.0]')
264
- assert_equal expected, events('[-0.0]')
265
- end
266
-
267
- it 'rejects multi zero' do
268
- expected = [:start_document, :start_array, [:value, 0], :error]
269
- assert_equal expected, events('[00]')
270
- assert_equal expected, events('[-00]')
271
- end
272
-
273
- it 'rejects integers that start with zero' do
274
- expected = [:start_document, :start_array, [:value, 0], :error]
275
- assert_equal expected, events('[01]')
276
- assert_equal expected, events('[-01]')
277
- end
278
-
279
- it 'parses integer tokens' do
280
- expected = [:start_document, :start_array, [:value, 1], :end_array, :end_document]
281
- assert_equal expected, events('[1]')
282
-
283
- expected = [:start_document, :start_array, [:value, -1], :end_array, :end_document]
284
- assert_equal expected, events('[-1]')
285
-
286
- expected = [:start_document, :start_array, [:value, 123], :end_array, :end_document]
287
- assert_equal expected, events('[123]')
288
-
289
- expected = [:start_document, :start_array, [:value, -123], :end_array, :end_document]
290
- assert_equal expected, events('[-123]')
291
- end
292
-
293
- it 'parses float tokens' do
294
- expected = [:start_document, :start_array, [:value, 1.0], :end_array, :end_document]
295
- assert_equal expected, events('[1.0]')
296
- assert_equal expected, events('[1.00]')
297
- end
298
-
299
- it 'parses negative floats' do
300
- expected = [:start_document, :start_array, [:value, -1.0], :end_array, :end_document]
301
- assert_equal expected, events('[-1.0]')
302
- assert_equal expected, events('[-1.00]')
303
- end
304
-
305
- it 'parses multi-digit floats' do
306
- expected = [:start_document, :start_array, [:value, 123.012], :end_array, :end_document]
307
- assert_equal expected, events('[123.012]')
308
- assert_equal expected, events('[123.0120]')
309
- end
310
-
311
- it 'parses negative multi-digit floats' do
312
- expected = [:start_document, :start_array, [:value, -123.012], :end_array, :end_document]
313
- assert_equal expected, events('[-123.012]')
314
- assert_equal expected, events('[-123.0120]')
315
- end
316
-
317
- it 'rejects floats missing leading zero' do
318
- expected = [:start_document, :start_array, :error]
319
- assert_equal expected, events('[.1]')
320
- assert_equal expected, events('[-.1]')
321
- assert_equal expected, events('[.01]')
322
- assert_equal expected, events('[-.01]')
323
- end
324
-
325
- it 'rejects float missing fraction' do
326
- expected = [:start_document, :start_array, :error]
327
- assert_equal expected, events('[.]')
328
- assert_equal expected, events('[..]')
329
- assert_equal expected, events('[0.]')
330
- assert_equal expected, events('[12.]')
331
- end
332
-
333
- it 'parses zero with implicit positive exponent as float' do
334
- expected = [:start_document, :start_array, [:value, 0.0], :end_array, :end_document]
335
- events = events('[0e2]')
336
- assert_equal expected, events
337
- assert_kind_of Float, events[2][1]
338
- end
339
-
340
- it 'parses zero with explicit positive exponent as float' do
341
- expected = [:start_document, :start_array, [:value, 0.0], :end_array, :end_document]
342
- events = events('[0e+2]')
343
- assert_equal expected, events
344
- assert_kind_of Float, events[2][1]
345
- end
346
-
347
- it 'parses zero with negative exponent as float' do
348
- expected = [:start_document, :start_array, [:value, 0.0], :end_array, :end_document]
349
- events = events('[0e-2]')
350
- assert_equal expected, events
351
- assert_kind_of Float, events[2][1]
352
- end
353
-
354
- it 'parses positive exponent integers as floats' do
355
- expected = [:start_document, :start_array, [:value, 212.0], :end_array, :end_document]
356
-
357
- events = events('[2.12e2]')
358
- assert_equal expected, events('[2.12e2]')
359
- assert_kind_of Float, events[2][1]
360
-
361
- assert_equal expected, events('[2.12e02]')
362
- assert_equal expected, events('[2.12e+2]')
363
- assert_equal expected, events('[2.12e+02]')
364
- end
365
-
366
- it 'parses positive exponent floats' do
367
- expected = [:start_document, :start_array, [:value, 21.2], :end_array, :end_document]
368
- assert_equal expected, events('[2.12e1]')
369
- assert_equal expected, events('[2.12e01]')
370
- assert_equal expected, events('[2.12e+1]')
371
- assert_equal expected, events('[2.12e+01]')
372
- end
373
-
374
- it 'parses negative exponent' do
375
- expected = [:start_document, :start_array, [:value, 0.0212], :end_array, :end_document]
376
- assert_equal expected, events('[2.12e-2]')
377
- assert_equal expected, events('[2.12e-02]')
378
- assert_equal expected, events('[2.12e-2]')
379
- assert_equal expected, events('[2.12e-02]')
380
- end
381
-
382
- it 'parses zero exponent floats' do
383
- expected = [:start_document, :start_array, [:value, 2.12], :end_array, :end_document]
384
- assert_equal expected, events('[2.12e0]')
385
- assert_equal expected, events('[2.12e00]')
386
- assert_equal expected, events('[2.12e-0]')
387
- assert_equal expected, events('[2.12e-00]')
388
- end
389
-
390
- it 'parses zero exponent integers' do
391
- expected = [:start_document, :start_array, [:value, 2.0], :end_array, :end_document]
392
- assert_equal expected, events('[2e0]')
393
- assert_equal expected, events('[2e00]')
394
- assert_equal expected, events('[2e-0]')
395
- assert_equal expected, events('[2e-00]')
396
- end
397
-
398
- it 'rejects missing exponent' do
399
- expected = [:start_document, :start_array, :error]
400
- assert_equal expected, events('[e]')
401
- assert_equal expected, events('[1e]')
402
- assert_equal expected, events('[1e-]')
403
- assert_equal expected, events('[1e--]')
404
- assert_equal expected, events('[1e+]')
405
- assert_equal expected, events('[1e++]')
406
- assert_equal expected, events('[0.e]')
407
- assert_equal expected, events('[10.e]')
408
- end
409
-
410
- it 'rejects float with trailing character' do
411
- expected = [:start_document, :start_array, [:value, 0.0], :error]
412
- assert_equal expected, events('[0.0q]')
413
- end
414
-
415
- it 'rejects integer with trailing character' do
416
- expected = [:start_document, :start_array, [:value, 1], :error]
417
- assert_equal expected, events('[1q]')
418
- end
419
- end
420
-
421
- describe 'parsing string tokens' do
422
- describe 'parsing two-character escapes' do
423
- it 'rejects invalid escape characters' do
424
- expected = [:start_document, :start_array, :error]
425
- assert_equal expected, events('["\\a"]')
426
- end
427
-
428
- it 'parses quotation mark' do
429
- expected = [:start_document, :start_array, [:value, "\""], :end_array, :end_document]
430
- assert_equal expected, events('["\""]')
431
- end
432
-
433
- it 'parses reverse solidus' do
434
- expected = [:start_document, :start_array, [:value, "\\"], :end_array, :end_document]
435
- assert_equal expected, events('["\\\"]')
436
- end
437
-
438
- it 'parses solidus' do
439
- expected = [:start_document, :start_array, [:value, "/"], :end_array, :end_document]
440
- assert_equal expected, events('["\/"]')
441
- end
442
-
443
- it 'parses backspace' do
444
- expected = [:start_document, :start_array, [:value, "\b"], :end_array, :end_document]
445
- assert_equal expected, events('["\b"]')
446
- end
447
-
448
- it 'parses form feed' do
449
- expected = [:start_document, :start_array, [:value, "\f"], :end_array, :end_document]
450
- assert_equal expected, events('["\f"]')
451
- end
452
-
453
- it 'parses line feed' do
454
- expected = [:start_document, :start_array, [:value, "\n"], :end_array, :end_document]
455
- assert_equal expected, events('["\n"]')
456
- end
457
-
458
- it 'parses carriage return' do
459
- expected = [:start_document, :start_array, [:value, "\r"], :end_array, :end_document]
460
- assert_equal expected, events('["\r"]')
461
- end
462
-
463
- it 'parses tab' do
464
- expected = [:start_document, :start_array, [:value, "\t"], :end_array, :end_document]
465
- assert_equal expected, events('["\t"]')
466
- end
467
-
468
- it 'parses a series of escapes with whitespace' do
469
- expected = [:start_document, :start_array, [:value, "\" \\ / \b \f \n \r \t"], :end_array, :end_document]
470
- assert_equal expected, events('["\" \\\ \/ \b \f \n \r \t"]')
471
- end
472
-
473
- it 'parses a series of escapes without whitespace' do
474
- expected = [:start_document, :start_array, [:value, "\"\\/\b\f\n\r\t"], :end_array, :end_document]
475
- assert_equal expected, events('["\"\\\\/\b\f\n\r\t"]')
476
- end
477
-
478
- it 'parses a series of escapes with duplicate characters between them' do
479
- expected = [:start_document, :start_array, [:value, "\"t\\b/f\bn\f/\nn\rr\t"], :end_array, :end_document]
480
- assert_equal expected, events('["\"t\\\b\/f\bn\f/\nn\rr\t"]')
481
- end
482
- end
483
-
484
- describe 'parsing control characters' do
485
- it 'rejects control character in array' do
486
- expected = [:start_document, :start_array, :error]
487
- assert_equal expected, events("[\" \u0000 \"]")
488
- end
489
-
490
- it 'rejects control character in object' do
491
- expected = [:start_document, :start_object, :error]
492
- assert_equal expected, events("{\" \u0000 \":12}")
493
- end
494
-
495
- it 'parses escaped control character' do
496
- expected = [:start_document, :start_array, [:value, "\u0000"], :end_array, :end_document]
497
- assert_equal expected, events('["\\u0000"]')
498
- end
499
-
500
- it 'parses escaped control character in object key' do
501
- expected = [:start_document, :start_object, [:key, "\u0000"], [:value, 12], :end_object, :end_document]
502
- assert_equal expected, events('{"\\u0000": 12}')
503
- end
504
-
505
- it 'parses non-control character' do
506
- # del ascii 127 is allowed unescaped in json
507
- expected = [:start_document, :start_array, [:value, " \u007F "], :end_array, :end_document]
508
- assert_equal expected, events("[\" \u007f \"]")
509
- end
510
- end
511
-
512
- describe 'parsing unicode escape sequences' do
513
- it 'parses escaped ascii character' do
514
- a = "\x61"
515
- escaped = '\u0061'
516
- expected = [:start_document, :start_array, [:value, a], :end_array, :end_document]
517
- assert_equal expected, events('["' + escaped + '"]')
518
- end
519
-
520
- it 'parses un-escaped raw unicode' do
521
- # U+1F602 face with tears of joy
522
- face = "\xf0\x9f\x98\x82"
523
- expected = [:start_document, :start_array, [:value, face], :end_array, :end_document]
524
- assert_equal expected, events('["' + face + '"]')
525
- end
526
-
527
- it 'parses escaped unicode surrogate pairs' do
528
- # U+1F602 face with tears of joy
529
- face = "\xf0\x9f\x98\x82"
530
- escaped = '\uD83D\uDE02'
531
- expected = [:start_document, :start_array, [:value, face], :end_array, :end_document]
532
- assert_equal expected, events('["' + escaped + '"]')
533
- end
534
-
535
- it 'rejects partial unicode escapes' do
536
- expected = [:start_document, :start_array, :error]
537
- assert_equal expected, events('[" \\u "]')
538
- assert_equal expected, events('[" \\u2 "]')
539
- assert_equal expected, events('[" \\u26 "]')
540
- assert_equal expected, events('[" \\u260 "]')
541
- end
542
-
543
- it 'parses unicode escapes' do
544
- # U+2603 snowman
545
- snowman = "\xe2\x98\x83"
546
- escaped = '\u2603'
547
-
548
- expected = [:start_document, :start_array, [:value, snowman], :end_array, :end_document]
549
- assert_equal expected, events('["' + escaped + '"]')
550
-
551
- expected = [:start_document, :start_array, [:value, 'snow' + snowman + ' man'], :end_array, :end_document]
552
- assert_equal expected, events('["snow' + escaped + ' man"]')
553
-
554
- expected = [:start_document, :start_array, [:value, 'snow' + snowman + '3 man'], :end_array, :end_document]
555
- assert_equal expected, events('["snow' + escaped + '3 man"]')
556
-
557
- expected = [:start_document, :start_object, [:key, 'snow' + snowman + '3 man'], [:value, 1], :end_object, :end_document]
558
- assert_equal expected, events('{"snow\\u26033 man": 1}')
559
- end
560
- end
561
-
562
- describe 'parsing unicode escapes with surrogate pairs' do
563
- it 'rejects missing second pair' do
564
- expected = [:start_document, :start_array, :error]
565
- assert_equal expected, events('["\uD834"]')
566
- end
567
-
568
- it 'rejects missing first pair' do
569
- expected = [:start_document, :start_array, :error]
570
- assert_equal expected, events('["\uDD1E"]')
571
- end
572
-
573
- it 'rejects double first pair' do
574
- expected = [:start_document, :start_array, :error]
575
- assert_equal expected, events('["\uD834\uD834"]')
576
- end
577
-
578
- it 'rejects double second pair' do
579
- expected = [:start_document, :start_array, :error]
580
- assert_equal expected, events('["\uDD1E\uDD1E"]')
581
- end
582
-
583
- it 'rejects reversed pair' do
584
- expected = [:start_document, :start_array, :error]
585
- assert_equal expected, events('["\uDD1E\uD834"]')
586
- end
587
-
588
- it 'parses correct pairs in object keys and values' do
589
- # U+1D11E G-Clef
590
- clef = "\xf0\x9d\x84\x9e"
591
- expected = [
592
- :start_document,
593
- :start_object,
594
- [:key, clef],
595
- [:value, "g\u{1D11E}clef"],
596
- :end_object,
597
- :end_document
598
- ]
599
- assert_equal expected, events(%q{ {"\uD834\uDD1E": "g\uD834\uDD1Eclef"} })
600
- end
601
- end
602
- end
603
-
604
- describe 'parsing arrays' do
605
- it 'rejects trailing comma' do
606
- expected = [:start_document, :start_array, [:value, 12], :error]
607
- assert_equal expected, events('[12, ]')
608
- end
609
-
610
- it 'parses nested empty array' do
611
- expected = [:start_document, :start_array, :start_array, :end_array, :end_array, :end_document]
612
- assert_equal expected, events('[[]]')
613
- end
614
-
615
- it 'parses nested array with value' do
616
- expected = [:start_document, :start_array, :start_array, [:value, 2.1], :end_array, :end_array, :end_document]
617
- assert_equal expected, events('[[ 2.10 ]]')
618
- end
619
-
620
- it 'rejects malformed arrays' do
621
- expected = [:start_document, :start_array, :error]
622
- assert_equal expected, events('[}')
623
- assert_equal expected, events('[,]')
624
- assert_equal expected, events('[, 12]')
625
- end
626
-
627
- it 'rejects malformed nested arrays' do
628
- expected = [:start_document, :start_array, :start_array, :error]
629
- assert_equal(expected, events('[[}]'))
630
- assert_equal expected, events('[[}]')
631
- assert_equal expected, events('[[,]]')
632
- end
633
-
634
- it 'rejects malformed array value lists' do
635
- expected = [:start_document, :start_array, [:value, "test"], :error]
636
- assert_equal expected, events('["test"}')
637
- assert_equal expected, events('["test",]')
638
- assert_equal expected, events('["test" "test"]')
639
- assert_equal expected, events('["test" 12]')
640
- end
641
-
642
- it 'parses array with value' do
643
- expected = [:start_document, :start_array, [:value, "test"], :end_array, :end_document]
644
- assert_equal expected, events('["test"]')
645
- end
646
-
647
- it 'parses array with value list' do
648
- expected = [
649
- :start_document,
650
- :start_array,
651
- [:value, 1],
652
- [:value, 2],
653
- [:value, nil],
654
- [:value, 12.1],
655
- [:value, "test"],
656
- :end_array,
657
- :end_document
658
- ]
659
- assert_equal expected, events('[1,2, null, 12.1,"test"]')
660
- end
661
- end
662
-
663
- describe 'parsing objects' do
664
- it 'rejects malformed objects' do
665
- expected = [:start_document, :start_object, :error]
666
- assert_equal expected, events('{]')
667
- assert_equal expected, events('{:}')
668
- end
669
-
670
- it 'parses single key object' do
671
- expected = [:start_document, :start_object, [:key, "key 1"], [:value, 12], :end_object, :end_document]
672
- assert_equal expected, events('{"key 1" : 12}')
673
- end
674
-
675
- it 'parses object key value list' do
676
- expected = [
677
- :start_document,
678
- :start_object,
679
- [:key, "key 1"], [:value, 12],
680
- [:key, "key 2"], [:value, "two"],
681
- :end_object,
682
- :end_document
683
- ]
684
- assert_equal expected, events('{"key 1" : 12, "key 2":"two"}')
685
- end
686
-
687
- it 'rejects object key with no value' do
688
- expected = [
689
- :start_document,
690
- :start_object,
691
- [:key, "key"],
692
- :start_array,
693
- [:value, nil],
694
- [:value, false],
695
- [:value, true],
696
- :end_array,
697
- [:key, "key 2"],
698
- :error
699
- ]
700
- assert_equal expected, events('{"key": [ null , false , true ] ,"key 2"}')
701
- end
702
-
703
- it 'rejects object with trailing comma' do
704
- expected = [:start_document, :start_object, [:key, "key 1"], [:value, 12], :error]
705
- assert_equal expected, events('{"key 1" : 12,}')
706
- end
707
- end
708
-
709
- describe 'parsing unicode bytes' do
710
- it 'parses single byte utf-8' do
711
- expected = [:start_document, :start_array, [:value, "test"], :end_array, :end_document]
712
- assert_equal expected, events('["test"]')
713
- end
714
-
715
- it 'parses full two byte utf-8' do
716
- expected = [
717
- :start_document,
718
- :start_array,
719
- [:value, "résumé"],
720
- [:value, "éé"],
721
- :end_array,
722
- :end_document
723
- ]
724
- assert_equal expected, events("[\"résumé\", \"é\xC3\xA9\"]")
725
- end
726
-
727
- # Parser should throw an error when only one byte of a two byte character
728
- # is available. The \xC3 byte is the first byte of the é character.
729
- it 'rejects a partial two byte utf-8 string' do
730
- expected = [:start_document, :start_array, :error]
731
- assert_equal expected, events("[\"\xC3\"]")
732
- end
733
-
734
- it 'parses valid two byte utf-8 string' do
735
- expected = [:start_document, :start_array, [:value, 'é'], :end_array, :end_document]
736
- assert_equal expected, events("[\"\xC3\xA9\"]")
737
- end
738
-
739
- it 'parses full three byte utf-8 string' do
740
- expected = [
741
- :start_document,
742
- :start_array,
743
- [:value, "snow\u2603man"],
744
- [:value, "\u2603\u2603"],
745
- :end_array,
746
- :end_document
747
- ]
748
- assert_equal expected, events("[\"snow\u2603man\", \"\u2603\u2603\"]")
749
- end
750
-
751
- it 'rejects one byte of three byte utf-8 string' do
752
- expected = [:start_document, :start_array, :error]
753
- assert_equal expected, events("[\"\xE2\"]")
754
- end
755
-
756
- it 'rejects two bytes of three byte utf-8 string' do
757
- expected = [:start_document, :start_array, :error]
758
- assert_equal expected, events("[\"\xE2\x98\"]")
759
- end
760
-
761
- it 'parses full three byte utf-8 string' do
762
- expected = [:start_document, :start_array, [:value, "\u2603"], :end_array, :end_document]
763
- assert_equal expected, events("[\"\xE2\x98\x83\"]")
764
- end
765
-
766
- it 'parses full four byte utf-8 string' do
767
- expected = [
768
- :start_document,
769
- :start_array,
770
- [:value, "\u{10102} check mark"],
771
- :end_array,
772
- :end_document
773
- ]
774
- assert_equal expected, events("[\"\u{10102} check mark\"]")
775
- end
776
-
777
- it 'rejects one byte of four byte utf-8 string' do
778
- expected = [:start_document, :start_array, :error]
779
- assert_equal expected, events("[\"\xF0\"]")
780
- end
781
-
782
- it 'rejects two bytes of four byte utf-8 string' do
783
- expected = [:start_document, :start_array, :error]
784
- assert_equal expected, events("[\"\xF0\x90\"]")
785
- end
786
-
787
- it 'rejects three bytes of four byte utf-8 string' do
788
- expected = [:start_document, :start_array, :error]
789
- assert_equal expected, events("[\"\xF0\x90\x84\"]")
790
- end
791
-
792
- it 'parses full four byte utf-8 string' do
793
- expected = [:start_document, :start_array, [:value, "\u{10102}"], :end_array, :end_document]
794
- assert_equal expected, events("[\"\xF0\x90\x84\x82\"]")
795
- end
796
- end
797
-
798
- describe 'parsing json text from the module' do
799
- it 'parses an array document' do
800
- result = JSON::Stream::Parser.parse('[1,2,3]')
801
- assert_equal [1, 2, 3], result
802
- end
803
-
804
- it 'parses a true keyword literal document' do
805
- result = JSON::Stream::Parser.parse('true')
806
- assert_equal true, result
807
- end
808
-
809
- it 'parses a false keyword literal document' do
810
- result = JSON::Stream::Parser.parse('false')
811
- assert_equal false, result
812
- end
813
-
814
- it 'parses a null keyword literal document' do
815
- result = JSON::Stream::Parser.parse('null')
816
- assert_equal nil, result
817
- end
818
-
819
- it 'parses a string literal document' do
820
- result = JSON::Stream::Parser.parse('"hello"')
821
- assert_equal 'hello', result
822
- end
823
-
824
- it 'parses an integer literal document' do
825
- result = JSON::Stream::Parser.parse('42')
826
- assert_equal 42, result
827
- end
828
-
829
- it 'parses a float literal document' do
830
- result = JSON::Stream::Parser.parse('42.12')
831
- assert_equal 42.12, result
832
- end
833
-
834
- it 'rejects a partial float literal document' do
835
- assert_raises(JSON::Stream::ParserError) do
836
- JSON::Stream::Parser.parse('42.')
837
- end
838
- end
839
-
840
- it 'rejects a partial document' do
841
- assert_raises(JSON::Stream::ParserError) do
842
- JSON::Stream::Parser.parse('{')
843
- end
844
- end
845
-
846
- it 'rejects an empty document' do
847
- assert_raises(JSON::Stream::ParserError) do
848
- JSON::Stream::Parser.parse('')
849
- end
850
- end
851
- end
852
-
853
- it 'registers observers in initializer block' do
854
- events = []
855
- parser = JSON::Stream::Parser.new do
856
- start_document { events << :start_document }
857
- end_document { events << :end_document }
858
- start_object { events << :start_object }
859
- end_object { events << :end_object }
860
- key {|k| events << [:key, k] }
861
- value {|v| events << [:value, v] }
862
- end
863
- parser << '{"key":12}'
864
- expected = [:start_document, :start_object, [:key, "key"], [:value, 12], :end_object, :end_document]
865
- assert_equal expected, events
866
- end
867
-
868
- private
869
-
870
- # Run a worst case, one byte at a time, parse against the JSON string and
871
- # return a list of events generated by the parser. A special :error event is
872
- # included if the parser threw an exception.
873
- #
874
- # json - The String to parse.
875
- # parser - The optional Parser instance to use.
876
- #
877
- # Returns an Events instance.
878
- def events(json, parser = nil)
879
- parser ||= JSON::Stream::Parser.new
880
- collector = Events.new(parser)
881
- begin
882
- json.each_byte {|byte| parser << [byte].pack('C') }
883
- rescue JSON::Stream::ParserError
884
- collector.error
885
- end
886
- collector.events
887
- end
888
-
889
- # Dynamically map methods in this class to parser callback methods
890
- # so we can collect parser events for inspection by test cases.
891
- class Events
892
- METHODS = %w[start_document end_document start_object end_object start_array end_array key value]
893
-
894
- attr_reader :events
895
-
896
- def initialize(parser)
897
- @events = []
898
- METHODS.each do |name|
899
- parser.send(name, &method(name))
900
- end
901
- end
902
-
903
- METHODS.each do |name|
904
- define_method(name) do |*args|
905
- @events << (args.empty? ? name.to_sym : [name.to_sym, *args])
906
- end
907
- end
908
-
909
- def error
910
- @events << :error
911
- end
912
- end
913
- end