json-stream 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,87 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'json/stream'
4
+ require 'test/unit'
5
+
6
+ class BufferTest < Test::Unit::TestCase
7
+ def setup
8
+ @buf = JSON::Stream::Buffer.new
9
+ end
10
+
11
+ def test_single_byte_chars
12
+ assert_equal("", @buf << "")
13
+ assert_equal("abc", @buf << "abc")
14
+ assert_equal("\u0000abc", @buf << "\u0000abc")
15
+ end
16
+
17
+ # The é character can be a single codepoint \u00e9 or two codepoints
18
+ # \u0065\u0301. The first is encoded in 2 bytes, the second in 3 bytes.
19
+ # The json and yajl-ruby gems and CouchDB do not normalize unicode text
20
+ # so neither will we. Although, a good way to normalize is by calling
21
+ # ActiveSupport::Multibyte::Chars.new("é").normalize(:c).
22
+ def test_combined_chars
23
+ assert_equal("\u0065\u0301", @buf << "\u0065\u0301")
24
+ assert_equal(3, (@buf << "\u0065\u0301").bytesize)
25
+ assert_equal(2, (@buf << "\u0065\u0301").size)
26
+
27
+ assert_equal("\u00e9", @buf << "\u00e9")
28
+ assert_equal(2, (@buf << "\u00e9").bytesize)
29
+ assert_equal(1, (@buf << "\u00e9").size)
30
+ end
31
+
32
+ def test_valid_two_byte_chars
33
+ assert_equal("abcé", @buf << "abcé")
34
+ assert_equal("a", @buf << "a\xC3")
35
+ assert_equal("é", @buf << "\xA9")
36
+ assert_equal("", @buf << "\xC3")
37
+ assert_equal("é", @buf << "\xA9")
38
+ assert_equal("é", @buf << "\xC3\xA9")
39
+ end
40
+
41
+ def test_valid_three_byte_chars
42
+ assert_equal("abcé\u2603", @buf << "abcé\u2603")
43
+ assert_equal("a", @buf << "a\xE2")
44
+ assert_equal("", @buf << "\x98")
45
+ assert_equal("\u2603", @buf << "\x83")
46
+ end
47
+
48
+ def test_valid_four_byte_chars
49
+ assert_equal("abcé\u2603\u{10102}é", @buf << "abcé\u2603\u{10102}é")
50
+ assert_equal("a", @buf << "a\xF0")
51
+ assert_equal("", @buf << "\x90")
52
+ assert_equal("", @buf << "\x84")
53
+ assert_equal("\u{10102}", @buf << "\x82")
54
+ end
55
+
56
+ def test_invalid_two_byte_start_chars
57
+ assert_raise(JSON::Stream::ParserError) { @buf << "\xC3\xC3" }
58
+ end
59
+
60
+ def test_invalid_three_byte_start_chars
61
+ assert_raise(JSON::Stream::ParserError) { @buf << "\xE2\xE2" }
62
+ end
63
+
64
+ def test_invalid_four_byte_start_chars
65
+ assert_raise(JSON::Stream::ParserError) { @buf << "\xF0\xF0" }
66
+ end
67
+
68
+ def test_two_byte_start_with_single_byte_continuation_char
69
+ assert_raise(JSON::Stream::ParserError) { @buf << "\xC3\u0000" }
70
+ end
71
+
72
+ def test_three_byte_start_with_single_byte_continuation_char
73
+ assert_raise(JSON::Stream::ParserError) { @buf << "\xE2\u0010" }
74
+ end
75
+
76
+ def test_four_byte_start_with_single_byte_continuation_char
77
+ assert_raise(JSON::Stream::ParserError) { @buf << "\xF0a" }
78
+ end
79
+
80
+ def test_invalid_continuation_char
81
+ assert_raise(JSON::Stream::ParserError) { @buf << "\xA9" }
82
+ end
83
+
84
+ def test_overlong_form
85
+ assert_raise(JSON::Stream::ParserError) { @buf << "\xC0\x80" }
86
+ end
87
+ end
@@ -0,0 +1,123 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'json/stream'
4
+ require 'test/unit'
5
+
6
+ class BuilderTest < Test::Unit::TestCase
7
+ def setup
8
+ @b = JSON::Stream::Builder.new(JSON::Stream::Parser.new)
9
+ end
10
+
11
+ def test_empty_array
12
+ assert_nil(@b.result)
13
+ @b.start_document
14
+ @b.start_array
15
+ @b.end_array
16
+ assert_nil(@b.result)
17
+ @b.end_document
18
+ assert_equal([], @b.result)
19
+ end
20
+
21
+ def test_number_array
22
+ @b.start_document
23
+ @b.start_array
24
+ @b.value(1)
25
+ @b.value(2)
26
+ @b.value(3)
27
+ @b.end_array
28
+ @b.end_document
29
+ assert_equal([1,2,3], @b.result)
30
+ end
31
+
32
+ def test_nested_empty_arrays
33
+ @b.start_document
34
+ @b.start_array
35
+ @b.start_array
36
+ @b.end_array
37
+ @b.end_array
38
+ @b.end_document
39
+ assert_equal([[]], @b.result)
40
+ end
41
+
42
+ def test_nested_arrays
43
+ @b.start_document
44
+ @b.start_array
45
+ @b.value(1)
46
+ @b.start_array
47
+ @b.value(2)
48
+ @b.end_array
49
+ @b.value(3)
50
+ @b.end_array
51
+ @b.end_document
52
+ assert_equal([1,[2],3], @b.result)
53
+ end
54
+
55
+ def test_empty_object
56
+ @b.start_document
57
+ @b.start_object
58
+ @b.end_object
59
+ @b.end_document
60
+ assert_equal({}, @b.result)
61
+ end
62
+
63
+ def test_object
64
+ @b.start_document
65
+ @b.start_object
66
+ @b.key("k1")
67
+ @b.value(1)
68
+ @b.key("k2")
69
+ @b.value(nil)
70
+ @b.key("k3")
71
+ @b.value(true)
72
+ @b.key("k4")
73
+ @b.value(false)
74
+ @b.key("k5")
75
+ @b.value("string value")
76
+ @b.end_object
77
+ @b.end_document
78
+ expected = {"k1" => 1, "k2" => nil, "k3" => true,
79
+ "k4" => false, "k5" => "string value"}
80
+ assert_equal(expected, @b.result)
81
+ end
82
+
83
+ def test_nested_object
84
+ @b.start_document
85
+ @b.start_object
86
+ @b.key("k1")
87
+ @b.value(1)
88
+
89
+ @b.key("k2")
90
+ @b.start_object
91
+ @b.end_object
92
+
93
+ @b.key("k3")
94
+ @b.start_object
95
+ @b.key("sub1")
96
+ @b.start_array
97
+ @b.value(12)
98
+ @b.end_array
99
+ @b.end_object
100
+
101
+ @b.key("k4")
102
+ @b.start_array
103
+ @b.value(1)
104
+ @b.start_object
105
+ @b.key("sub2")
106
+ @b.start_array
107
+ @b.value(nil)
108
+ @b.end_array
109
+ @b.end_object
110
+ @b.end_array
111
+
112
+ @b.key("k5")
113
+ @b.value("string value")
114
+ @b.end_object
115
+ @b.end_document
116
+ expected = {"k1"=>1,
117
+ "k2"=>{},
118
+ "k3"=>{"sub1"=>[12]},
119
+ "k4"=>[1, {"sub2"=>[nil]}],
120
+ "k5"=>"string value"}
121
+ assert_equal(expected, @b.result)
122
+ end
123
+ end
@@ -0,0 +1,451 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'json/stream'
4
+ require 'test/unit'
5
+
6
+ class ParserTest < Test::Unit::TestCase
7
+
8
+ # JSON documents must start with an array or object container
9
+ # and there must not be any extra data following that container.
10
+ def test_document
11
+ expected = [:error]
12
+ ['a', 'null', 'false', 'true', '12', ' false '].each do |json|
13
+ assert_equal(expected, events(json))
14
+ end
15
+
16
+ expected = [:start_document, :start_array, :end_array, :end_document]
17
+ ['[]', '[ ]', ' [] ', ' [ ] '].each do |json|
18
+ assert_equal(expected, events(json))
19
+ end
20
+
21
+ expected = [:start_document, :start_object, :end_object, :end_document]
22
+ ['{}', '{ }', ' {} ', ' { } '].each do |json|
23
+ assert_equal(expected, events(json))
24
+ end
25
+
26
+ expected = [:start_document, :start_object, :end_object, :end_document, :error]
27
+ ['{}a', '{ } 12', ' {} false', ' { }, {}'].each do |json|
28
+ assert_equal(expected, events(json))
29
+ end
30
+ end
31
+
32
+ # Whitespace around tokens should be ignored. Whitespace whithin strings
33
+ # must be preserved.
34
+ def test_whitespace
35
+ json = %Q{
36
+ { " key 1 " : \t [
37
+ 1, 2, " my string ",
38
+ false, true, null ]
39
+ }
40
+ }
41
+ expected = [:start_document, :start_object,
42
+ [:key, " key 1 "],
43
+ :start_array,
44
+ [:value, 1],
45
+ [:value, 2],
46
+ [:value, " my string "],
47
+ [:value, false],
48
+ [:value, true],
49
+ [:value, nil],
50
+ :end_array, :end_object, :end_document]
51
+ assert_equal(expected, events(json))
52
+ end
53
+
54
+ def test_keyword
55
+ expected = [:start_document, :start_array, :error]
56
+ ['[tru]', '[fal]', '[nul,true]', '[fals1]'].each do |json|
57
+ assert_equal(expected, events(json))
58
+ end
59
+
60
+ expected = [:start_document, :start_array, [:value, true], :end_array, :end_document]
61
+ assert_equal(expected, events('[true]'))
62
+
63
+ expected = [:start_document, :start_array, [:value, true], [:value, nil], :end_array, :end_document]
64
+ assert_equal(expected, events('[true, null]'))
65
+ end
66
+
67
+ def test_negative
68
+ expected = [:start_document, :start_array, :error]
69
+ assert_equal(expected, events('[-]'))
70
+
71
+ expected = [:start_document, :start_array, [:value, 1], :error]
72
+ assert_equal(expected, events('[1-0]'))
73
+ end
74
+
75
+ def test_int_zero
76
+ expected = [:start_document, :start_array, [:value, 0], :end_array, :end_document]
77
+ assert_equal(expected, events('[0]'))
78
+ assert_equal(expected, events('[-0]'))
79
+ end
80
+
81
+ def test_float_zero
82
+ expected = [:start_document, :start_array, [:value, 0.0], :end_array, :end_document]
83
+ assert_equal(expected, events('[0.0]'))
84
+ assert_equal(expected, events('[-0.0]'))
85
+ end
86
+
87
+ def test_multi_zero
88
+ expected = [:start_document, :start_array, [:value, 0], :error]
89
+ assert_equal(expected, events('[00]'))
90
+ assert_equal(expected, events('[-00]'))
91
+ end
92
+
93
+ def test_starts_with_zero
94
+ expected = [:start_document, :start_array, [:value, 0], :error]
95
+ assert_equal(expected, events('[01]'))
96
+ assert_equal(expected, events('[-01]'))
97
+ end
98
+
99
+ def test_int
100
+ expected = [:start_document, :start_array, [:value, 1], :end_array, :end_document]
101
+ assert_equal(expected, events('[1]'))
102
+
103
+ expected = [:start_document, :start_array, [:value, -1], :end_array, :end_document]
104
+ assert_equal(expected, events('[-1]'))
105
+
106
+ expected = [:start_document, :start_array, [:value, 123], :end_array, :end_document]
107
+ assert_equal(expected, events('[123]'))
108
+
109
+ expected = [:start_document, :start_array, [:value, -123], :end_array, :end_document]
110
+ assert_equal(expected, events('[-123]'))
111
+ end
112
+
113
+ def test_float
114
+ expected = [:start_document, :start_array, [:value, 1.0], :end_array, :end_document]
115
+ assert_equal(expected, events('[1.0]'))
116
+ assert_equal(expected, events('[1.00]'))
117
+
118
+ expected = [:start_document, :start_array, [:value, -1.0], :end_array, :end_document]
119
+ assert_equal(expected, events('[-1.0]'))
120
+ assert_equal(expected, events('[-1.00]'))
121
+
122
+ expected = [:start_document, :start_array, [:value, 123.012], :end_array, :end_document]
123
+ assert_equal(expected, events('[123.012]'))
124
+ assert_equal(expected, events('[123.0120]'))
125
+
126
+ expected = [:start_document, :start_array, [:value, -123.012], :end_array, :end_document]
127
+ assert_equal(expected, events('[-123.012]'))
128
+ assert_equal(expected, events('[-123.0120]'))
129
+ end
130
+
131
+ def test_missing_leading_zero
132
+ expected = [:start_document, :start_array, :error]
133
+ assert_equal(expected, events('[.1]'))
134
+ assert_equal(expected, events('[-.1]'))
135
+ assert_equal(expected, events('[.01]'))
136
+ assert_equal(expected, events('[-.01]'))
137
+ end
138
+
139
+ def test_missing_fraction
140
+ expected = [:start_document, :start_array, :error]
141
+ assert_equal(expected, events('[.]'))
142
+ assert_equal(expected, events('[..]'))
143
+ assert_equal(expected, events('[0.]'))
144
+ assert_equal(expected, events('[12.]'))
145
+ end
146
+
147
+ def test_positive_exponent
148
+ expected = [:start_document, :start_array, [:value, 212], :end_array, :end_document]
149
+ assert_equal(expected, events('[2.12e2]'))
150
+ assert_equal(expected, events('[2.12e02]'))
151
+ assert_equal(expected, events('[2.12e+2]'))
152
+ assert_equal(expected, events('[2.12e+02]'))
153
+
154
+ expected = [:start_document, :start_array, [:value, 21.2], :end_array, :end_document]
155
+ assert_equal(expected, events('[2.12e1]'))
156
+ assert_equal(expected, events('[2.12e01]'))
157
+ assert_equal(expected, events('[2.12e+1]'))
158
+ assert_equal(expected, events('[2.12e+01]'))
159
+ end
160
+
161
+ def test_negative_exponent
162
+ expected = [:start_document, :start_array, [:value, 0.0212], :end_array, :end_document]
163
+ assert_equal(expected, events('[2.12e-2]'))
164
+ assert_equal(expected, events('[2.12e-02]'))
165
+ assert_equal(expected, events('[2.12e-2]'))
166
+ assert_equal(expected, events('[2.12e-02]'))
167
+ end
168
+
169
+ def test_zero_exponent
170
+ expected = [:start_document, :start_array, [:value, 2.12], :end_array, :end_document]
171
+ assert_equal(expected, events('[2.12e0]'))
172
+ assert_equal(expected, events('[2.12e00]'))
173
+ assert_equal(expected, events('[2.12e-0]'))
174
+ assert_equal(expected, events('[2.12e-00]'))
175
+
176
+ expected = [:start_document, :start_array, [:value, 2.0], :end_array, :end_document]
177
+ assert_equal(expected, events('[2e0]'))
178
+ assert_equal(expected, events('[2e00]'))
179
+ assert_equal(expected, events('[2e-0]'))
180
+ assert_equal(expected, events('[2e-00]'))
181
+ end
182
+
183
+ def test_missing_exponent
184
+ expected = [:start_document, :start_array, :error]
185
+ assert_equal(expected, events('[e]'))
186
+ assert_equal(expected, events('[1e]'))
187
+ assert_equal(expected, events('[1e-]'))
188
+ assert_equal(expected, events('[1e--]'))
189
+ assert_equal(expected, events('[1e+]'))
190
+ assert_equal(expected, events('[1e++]'))
191
+ assert_equal(expected, events('[0.e]'))
192
+ assert_equal(expected, events('[10.e]'))
193
+ end
194
+
195
+ def test_non_digit_end_char
196
+ expected = [:start_document, :start_array, [:value, 0.0], :error]
197
+ assert_equal(expected, events('[0.0q]'))
198
+
199
+ expected = [:start_document, :start_array, [:value, 1], :error]
200
+ assert_equal(expected, events('[1q]'))
201
+ end
202
+
203
+ def test_string
204
+ expected = [:start_document, :start_array, :error]
205
+ assert_equal(expected, events(%q{ [" \\a "] }))
206
+
207
+ expected = [:start_document, :start_array, [:value, "\" \\ / \b \f \n \r \t"], :end_array, :end_document]
208
+ assert_equal(expected, events('["\" \\\ \/ \b \f \n \r \t"]'))
209
+
210
+ expected = [:start_document, :start_array, [:value, "\"\\/\b\f\n\r\t"], :end_array, :end_document]
211
+ assert_equal(expected, events('["\"\\\\/\b\f\n\r\t"]'))
212
+
213
+ expected = [:start_document, :start_array, [:value, "\"t\\b/f\bn\f/\nn\rr\t"], :end_array, :end_document]
214
+ assert_equal(expected, events('["\"t\\\b\/f\bn\f/\nn\rr\t"]'))
215
+ end
216
+
217
+ def test_control_char
218
+ expected = [:start_document, :start_array, :error]
219
+ assert_equal(expected, events("[\" \u0000 \"]"))
220
+
221
+ expected = [:start_document, :start_object, :error]
222
+ assert_equal(expected, events("{\" \u0000 \":12}"))
223
+ end
224
+
225
+ def test_unicode_escape
226
+ expected = [:start_document, :start_array, :error]
227
+ [%q{ [" \\u "] }, %q{ [" \\u2 "]}, %q{ [" \\u26 "]}, %q{ [" \\u260 "]}].each do |json|
228
+ assert_equal(expected, events(json))
229
+ end
230
+
231
+ expected = [:start_document, :start_array, [:value, "\u2603"], :end_array, :end_document]
232
+ assert_equal(expected, events(%q{ ["\\u2603"] }))
233
+
234
+ expected = [:start_document, :start_array, [:value, "snow\u2603 man"], :end_array, :end_document]
235
+ assert_equal(expected, events(%q{ ["snow\\u2603 man"] }))
236
+
237
+ expected = [:start_document, :start_array, [:value, "snow\u26033 man"], :end_array, :end_document]
238
+ assert_equal(expected, events(%q{ ["snow\\u26033 man"] }))
239
+
240
+ expected = [:start_document, :start_object, [:key, "snow\u26033 man"], [:value, 1], :end_object, :end_document]
241
+ assert_equal(expected, events(%q{ {"snow\\u26033 man": 1} }))
242
+ end
243
+
244
+ def test_unicode_escape_surrogate_pairs
245
+ expected = [:start_document, :start_array, :error]
246
+ assert_equal(expected, events(%q{ ["\uD834"] }))
247
+ assert_equal(expected, events(%q{ ["\uD834\uD834"] }))
248
+ assert_equal(expected, events(%q{ ["\uDD1E"] }))
249
+ assert_equal(expected, events(%q{ ["\uDD1E\uDD1E"] }))
250
+
251
+ expected = [:start_document, :start_object, [:key, "\u{1D11E}"],
252
+ [:value, "g\u{1D11E}clef"], :end_object, :end_document]
253
+ assert_equal(expected, events(%q{ {"\uD834\uDD1E": "g\uD834\uDD1Eclef"} }))
254
+ end
255
+
256
+ def test_array_trailing_comma
257
+ expected = [:start_document, :start_array, [:value, 12], :error]
258
+ assert_equal(expected, events('[12, ]'))
259
+ end
260
+
261
+ def test_nested_array
262
+ expected = [:start_document, :start_array, :start_array, :end_array, :end_array, :end_document]
263
+ assert_equal(expected, events('[[]]'))
264
+
265
+ expected = [:start_document, :start_array, :start_array, [:value, 2.1], :end_array, :end_array, :end_document]
266
+ assert_equal(expected, events('[[ 2.10 ]]'))
267
+ end
268
+
269
+ def test_array
270
+ expected = [:start_document, :start_array, :error]
271
+ ['[}', '[,]', '[, 12]'].each do |json|
272
+ assert_equal(expected, events(json))
273
+ end
274
+
275
+ expected = [:start_document, :start_array, :start_array, :error]
276
+ assert_equal(expected, events('[[}]'))
277
+ ['[[}]', '[[,]]'].each do |json|
278
+ assert_equal(expected, events(json))
279
+ end
280
+
281
+ expected = [:start_document, :start_array, [:value, "test"], :error]
282
+ ['["test"}', '["test",]', '["test" "test"]', '["test" 12]'].each do |json|
283
+ assert_equal(expected, events(json))
284
+ end
285
+
286
+ expected = [:start_document, :start_array, [:value, "test"], :end_array, :end_document]
287
+ assert_equal(expected, events('["test"]'))
288
+
289
+ expected = [:start_document, :start_array,
290
+ [:value, 1],
291
+ [:value, 2],
292
+ [:value, nil],
293
+ [:value, 12.1],
294
+ [:value, "test"],
295
+ :end_array, :end_document]
296
+ ['[1,2, null, 12.1,"test"]'].each do |json|
297
+ assert_equal(expected, events(json))
298
+ end
299
+ end
300
+
301
+ def test_object
302
+ expected = [:start_document, :start_object, :error]
303
+ ['{]', '{:}'].each do |json|
304
+ assert_equal(expected, events(json))
305
+ end
306
+
307
+ expected = [:start_document, :start_object, [:key, "key 1"], [:value, 12], :end_object, :end_document]
308
+ assert_equal(expected, events('{"key 1" : 12}'))
309
+
310
+ expected = [:start_document, :start_object,
311
+ [:key, "key 1"], [:value, 12],
312
+ [:key, "key 2"], [:value, "two"],
313
+ :end_object, :end_document]
314
+ assert_equal(expected, events('{"key 1" : 12, "key 2":"two"}'))
315
+ end
316
+
317
+ def test_object_key_with_no_value
318
+ expected = [:start_document, :start_object, [:key, "key"],
319
+ :start_array, [:value, nil], [:value, false],
320
+ [:value, true], :end_array,
321
+ [:key, "key 2"],
322
+ :error]
323
+ assert_equal(expected, events('{"key": [ null , false , true ] ,"key 2"}'))
324
+ end
325
+
326
+ def test_object_trailing_comma
327
+ expected = [:start_document, :start_object, [:key, "key 1"], [:value, 12], :error]
328
+ assert_equal(expected, events('{"key 1" : 12,}'))
329
+ end
330
+
331
+ def test_single_byte_utf8
332
+ expected = [:start_document, :start_array, [:value, "test"], :end_array, :end_document]
333
+ assert_equal(expected, events('["test"]'))
334
+ end
335
+
336
+ def test_full_two_byte_utf8
337
+ expected = [:start_document, :start_array, [:value, "résumé"],
338
+ [:value, "éé"], :end_array, :end_document]
339
+ assert_equal(expected, events("[\"résumé\", \"é\xC3\xA9\"]"))
340
+ end
341
+
342
+ # Parser should throw an error when only one byte of a two byte character
343
+ # is available. The \xC3 byte is the first byte of the é character.
344
+ def test_partial_two_byte_utf8
345
+ expected = [:start_document, :start_array, :error]
346
+ assert_equal(expected, events('["\xC3"]'))
347
+
348
+ expected = [:start_document, :start_array, [:value, 'é'], :end_array, :end_document]
349
+ assert_equal(expected, events("[\"\xC3\xA9\"]"))
350
+ end
351
+
352
+ def test_full_three_byte_utf8
353
+ expected = [:start_document, :start_array, [:value, "snow\u2603man"],
354
+ [:value, "\u2603\u2603"], :end_array, :end_document]
355
+ assert_equal(expected, events("[\"snow\u2603man\", \"\u2603\u2603\"]"))
356
+ end
357
+
358
+ def test_partial_three_byte_utf8
359
+ expected = [:start_document, :start_array, :error]
360
+ assert_equal(expected, events('["\xE2"]'))
361
+
362
+ expected = [:start_document, :start_array, :error]
363
+ assert_equal(expected, events('["\xE2\x98"]'))
364
+
365
+ expected = [:start_document, :start_array, [:value, "\u2603"], :end_array, :end_document]
366
+ assert_equal(expected, events("[\"\xE2\x98\x83\"]"))
367
+ end
368
+
369
+ def test_full_four_byte_utf8
370
+ expected = [:start_document, :start_array, [:value, "\u{10102} check mark"],
371
+ :end_array, :end_document]
372
+ assert_equal(expected, events("[\"\u{10102} check mark\"]"))
373
+ end
374
+
375
+ def test_partial_four_byte_utf8
376
+ expected = [:start_document, :start_array, :error]
377
+ assert_equal(expected, events('["\xF0"]'))
378
+
379
+ expected = [:start_document, :start_array, :error]
380
+ assert_equal(expected, events('["\xF0\x90"]'))
381
+
382
+ expected = [:start_document, :start_array, :error]
383
+ assert_equal(expected, events('["\xF0\x90\x84"]'))
384
+
385
+ expected = [:start_document, :start_array, [:value, "\u{10102}"], :end_array, :end_document]
386
+ assert_equal(expected, events("[\"\xF0\x90\x84\x82\"]"))
387
+ end
388
+
389
+ def test_parse
390
+ json = "[1,2,3]"
391
+ obj = JSON::Stream::Parser.parse(json)
392
+ assert_equal([1,2,3], obj)
393
+ end
394
+
395
+ def test_initializer_block
396
+ events = []
397
+ parser = JSON::Stream::Parser.new do
398
+ start_document { events << :start_document }
399
+ end_document { events << :end_document }
400
+ start_object { events << :start_object }
401
+ end_object { events << :end_object }
402
+ key {|k| events << [:key, k] }
403
+ value {|v| events << [:value, v] }
404
+ end
405
+ parser << '{"key":12}'
406
+ expected = [:start_document, :start_object, [:key, "key"], [:value, 12], :end_object, :end_document]
407
+ assert_equal(expected, events)
408
+ end
409
+
410
+ private
411
+
412
+ # Run a worst case, one character at a time, parse against the
413
+ # JSON string and return a list of events generated by the parser.
414
+ # A special :error event is included if the parser threw an exception.
415
+ def events(json)
416
+ parser = JSON::Stream::Parser.new
417
+ collector = Events.new(parser)
418
+ begin
419
+ json.each_char {|ch| parser << ch }
420
+ rescue JSON::Stream::ParserError => e
421
+ collector.error
422
+ end
423
+ collector.events
424
+ end
425
+
426
+ # Dynamically map methods in this class to parser callback methods
427
+ # so we can collect parser events for inspection by test cases.
428
+ class Events
429
+ METHODS = %w[start_document end_document start_object end_object start_array end_array key value]
430
+
431
+ attr_reader :events
432
+
433
+ def initialize(parser)
434
+ @events = []
435
+ METHODS.each do |name|
436
+ parser.send(name, &method(name))
437
+ end
438
+ end
439
+
440
+ METHODS.each do |name|
441
+ define_method(name) do |*args|
442
+ @events << (args.empty? ? name.to_sym : [name.to_sym, *args])
443
+ end
444
+ end
445
+
446
+ def error
447
+ @events << :error
448
+ end
449
+ end
450
+
451
+ end