2 # -*- coding: utf-8 -*-
5 require File.join(File.dirname(__FILE__), 'setup_variant')
9 unless Array.method_defined?(:permutation)
15 Permutation.for(self).to_enum.map { |x| x.project }
19 warn "Skipping permutation tests."
23 class TC_JSON < Test::Unit::TestCase
27 @ary = [1, "foo", 3.14, 4711.0, 2.718, nil, [1,-2,3], false, true].map do
30 @ary_to_parse = ["1", '"foo"', "3.14", "4711.0", "2.718", "null",
31 "[1,-2,3]", "false", "true"].map do
38 'd' => [ 1, "b", 3.14 ],
39 'e' => { 'foo' => 'bar' },
44 @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
45 '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}'
49 parser = JSON::Parser.new('test')
50 assert_equal 'test', parser.source
53 def assert_equal_float(expected, is)
54 assert_in_delta(expected.first, is.first, 1e-2)
57 def test_parse_simple_arrays
58 assert_equal([], parse('[]'))
59 assert_equal([], parse(' [ ] '))
60 assert_equal([nil], parse('[null]'))
61 assert_equal([false], parse('[false]'))
62 assert_equal([true], parse('[true]'))
63 assert_equal([-23], parse('[-23]'))
64 assert_equal([23], parse('[23]'))
65 assert_equal([0.23], parse('[0.23]'))
66 assert_equal([0.0], parse('[0e0]'))
67 assert_raises(JSON::ParserError) { parse('[+23.2]') }
68 assert_raises(JSON::ParserError) { parse('[+23]') }
69 assert_raises(JSON::ParserError) { parse('[.23]') }
70 assert_raises(JSON::ParserError) { parse('[023]') }
71 assert_equal_float [3.141], parse('[3.141]')
72 assert_equal_float [-3.141], parse('[-3.141]')
73 assert_equal_float [3.141], parse('[3141e-3]')
74 assert_equal_float [3.141], parse('[3141.1e-3]')
75 assert_equal_float [3.141], parse('[3141E-3]')
76 assert_equal_float [3.141], parse('[3141.0E-3]')
77 assert_equal_float [-3.141], parse('[-3141.0e-3]')
78 assert_equal_float [-3.141], parse('[-3141e-3]')
79 assert_raises(ParserError) { parse('[NaN]') }
80 assert parse('[NaN]', :allow_nan => true).first.nan?
81 assert_raises(ParserError) { parse('[Infinity]') }
82 assert_equal [1.0/0], parse('[Infinity]', :allow_nan => true)
83 assert_raises(ParserError) { parse('[-Infinity]') }
84 assert_equal [-1.0/0], parse('[-Infinity]', :allow_nan => true)
85 assert_equal([""], parse('[""]'))
86 assert_equal(["foobar"], parse('["foobar"]'))
87 assert_equal([{}], parse('[{}]'))
90 def test_parse_simple_objects
91 assert_equal({}, parse('{}'))
92 assert_equal({}, parse(' { } '))
93 assert_equal({ "a" => nil }, parse('{ "a" : null}'))
94 assert_equal({ "a" => nil }, parse('{"a":null}'))
95 assert_equal({ "a" => false }, parse('{ "a" : false } '))
96 assert_equal({ "a" => false }, parse('{"a":false}'))
97 assert_raises(JSON::ParserError) { parse('{false}') }
98 assert_equal({ "a" => true }, parse('{"a":true}'))
99 assert_equal({ "a" => true }, parse(' { "a" : true } '))
100 assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
101 assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
102 assert_equal({ "a" => 23 }, parse('{"a":23 } '))
103 assert_equal({ "a" => 23 }, parse(' { "a" : 23 } '))
104 assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
105 assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
108 def test_parse_json_primitive_values
109 assert_raise(JSON::ParserError) { JSON.parse('') }
110 assert_raise(JSON::ParserError) { JSON.parse('', :quirks_mode => true) }
111 assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ') }
112 assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ', :quirks_mode => true) }
113 parser = JSON::Parser.new('null')
114 assert_equal false, parser.quirks_mode?
115 assert_raise(JSON::ParserError) { parser.parse }
116 assert_raise(JSON::ParserError) { JSON.parse('null') }
117 assert_equal nil, JSON.parse('null', :quirks_mode => true)
118 parser = JSON::Parser.new('null', :quirks_mode => true)
119 assert_equal true, parser.quirks_mode?
120 assert_equal nil, parser.parse
121 assert_raise(JSON::ParserError) { JSON.parse('false') }
122 assert_equal false, JSON.parse('false', :quirks_mode => true)
123 assert_raise(JSON::ParserError) { JSON.parse('true') }
124 assert_equal true, JSON.parse('true', :quirks_mode => true)
125 assert_raise(JSON::ParserError) { JSON.parse('23') }
126 assert_equal 23, JSON.parse('23', :quirks_mode => true)
127 assert_raise(JSON::ParserError) { JSON.parse('1') }
128 assert_equal 1, JSON.parse('1', :quirks_mode => true)
129 assert_raise(JSON::ParserError) { JSON.parse('3.141') }
130 assert_in_delta 3.141, JSON.parse('3.141', :quirks_mode => true), 1E-3
131 assert_raise(JSON::ParserError) { JSON.parse('18446744073709551616') }
132 assert_equal 2 ** 64, JSON.parse('18446744073709551616', :quirks_mode => true)
133 assert_raise(JSON::ParserError) { JSON.parse('"foo"') }
134 assert_equal 'foo', JSON.parse('"foo"', :quirks_mode => true)
135 assert_raise(JSON::ParserError) { JSON.parse('NaN', :allow_nan => true) }
136 assert JSON.parse('NaN', :quirks_mode => true, :allow_nan => true).nan?
137 assert_raise(JSON::ParserError) { JSON.parse('Infinity', :allow_nan => true) }
138 assert JSON.parse('Infinity', :quirks_mode => true, :allow_nan => true).infinite?
139 assert_raise(JSON::ParserError) { JSON.parse('-Infinity', :allow_nan => true) }
140 assert JSON.parse('-Infinity', :quirks_mode => true, :allow_nan => true).infinite?
141 assert_raise(JSON::ParserError) { JSON.parse('[ 1, ]', :quirks_mode => true) }
144 if Array.method_defined?(:permutation)
145 def test_parse_more_complex_arrays
146 a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
147 a.permutation.each do |perm|
148 json = pretty_generate(perm)
149 assert_equal perm, parse(json)
153 def test_parse_complex_objects
154 a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
155 a.permutation.each do |perm|
157 orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
158 json = pretty_generate(orig_obj)
159 assert_equal orig_obj, parse(json)
164 def test_parse_arrays
165 assert_equal([1,2,3], parse('[1,2,3]'))
166 assert_equal([1.2,2,3], parse('[1.2,2,3]'))
167 assert_equal([[],[[],[]]], parse('[[],[[],[]]]'))
170 def test_parse_values
171 assert_equal([""], parse('[""]'))
172 assert_equal(["\\"], parse('["\\\\"]'))
173 assert_equal(['"'], parse('["\""]'))
174 assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]'))
175 assert_equal(["\"\b\n\r\t\0\037"],
176 parse('["\"\b\n\r\t\u0000\u001f"]'))
177 for i in 0 ... @ary.size
178 assert_equal(@ary[i], parse(@ary_to_parse[i]))
183 assert_equal([], parse('[]'))
184 assert_equal([], parse(' [ ] '))
185 assert_equal([1], parse('[1]'))
186 assert_equal([1], parse(' [ 1 ] '))
188 parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]]'\
190 assert_equal(@ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s
191 , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
194 class SubArray < Array
205 class SubArray2 < Array
208 JSON.create_id => self.class.name,
213 def self.json_create(o)
214 o.delete JSON.create_id
219 def test_parse_array_custom_class
220 res = parse('[1,2]', :array_class => SubArray)
221 assert_equal([1,2], res)
222 assert_equal(SubArray, res.class)
226 def test_parse_object
227 assert_equal({}, parse('{}'))
228 assert_equal({}, parse(' { } '))
229 assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}'))
230 assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } '))
244 class SubHash2 < Hash
247 JSON.create_id => self.class.name,
248 }.merge(self).to_json(*a)
251 def self.json_create(o)
252 o.delete JSON.create_id
257 def test_parse_object_custom_class
258 res = parse('{"foo":"bar"}', :object_class => SubHash)
259 assert_equal({"foo" => "bar"}, res)
260 assert_equal(SubHash, res.class)
264 def test_generation_of_core_subclasses_with_new_to_json
265 obj = SubHash2["foo" => SubHash2["bar" => true]]
267 obj_again = JSON.parse(obj_json, :create_additions => true)
268 assert_kind_of SubHash2, obj_again
269 assert_kind_of SubHash2, obj_again['foo']
270 assert obj_again['foo']['bar']
271 assert_equal obj, obj_again
272 assert_equal ["foo"], JSON(JSON(SubArray2["foo"]), :create_additions => true)
275 def test_generation_of_core_subclasses_with_default_to_json
276 assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"])
277 assert_equal '["foo"]', JSON(SubArray["foo"])
280 def test_generation_of_core_subclasses
281 obj = SubHash["foo" => SubHash["bar" => true]]
283 obj_again = JSON(obj_json)
284 assert_kind_of Hash, obj_again
285 assert_kind_of Hash, obj_again['foo']
286 assert obj_again['foo']['bar']
287 assert_equal obj, obj_again
290 def test_parser_reset
291 parser = Parser.new(@json)
292 assert_equal(@hash, parser.parse)
293 assert_equal(@hash, parser.parse)
299 "key1":"value1", // eol comment
300 "key2":"value2" /* multi line
302 "key3":"value3" /* multi line
303 // nested eol comment
308 { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
312 "key1":"value1" /* multi line
313 // nested eol comment
314 /* illegal nested multi line comment */
318 assert_raises(ParserError) { parse(json) }
321 "key1":"value1" /* multi line
322 // nested eol comment
323 closed multi comment */
324 and again, throw an Error */
327 assert_raises(ParserError) { parse(json) }
330 "key1":"value1" /*/*/
333 assert_equal({ "key1" => "value1" }, parse(json))
337 data = [ '\\.(?i:gif|jpe?g|png)$' ]
338 json = '["\\\\.(?i:gif|jpe?g|png)$"]'
339 assert_equal json, JSON.generate(data)
340 assert_equal data, JSON.parse(json)
344 assert_equal json, JSON.generate(data)
345 assert_equal data, JSON.parse(json)
348 data = JSON.parse(json)
349 assert_equal ['/'], data
350 assert_equal json, JSON.generate(data)
353 data = JSON.parse(json)
354 assert_equal ['"'], data
355 assert_equal json, JSON.generate(data)
357 data = JSON.parse(json)
358 assert_equal ["'"], data
359 assert_equal '["\'"]', JSON.generate(data)
362 def test_wrong_inputs
363 assert_raises(ParserError) { JSON.parse('"foo"') }
364 assert_raises(ParserError) { JSON.parse('123') }
365 assert_raises(ParserError) { JSON.parse('[] bla') }
366 assert_raises(ParserError) { JSON.parse('[] 1') }
367 assert_raises(ParserError) { JSON.parse('[] []') }
368 assert_raises(ParserError) { JSON.parse('[] {}') }
369 assert_raises(ParserError) { JSON.parse('{} []') }
370 assert_raises(ParserError) { JSON.parse('{} {}') }
371 assert_raises(ParserError) { JSON.parse('[NULL]') }
372 assert_raises(ParserError) { JSON.parse('[FALSE]') }
373 assert_raises(ParserError) { JSON.parse('[TRUE]') }
374 assert_raises(ParserError) { JSON.parse('[07] ') }
375 assert_raises(ParserError) { JSON.parse('[0a]') }
376 assert_raises(ParserError) { JSON.parse('[1.]') }
377 assert_raises(ParserError) { JSON.parse(' ') }
381 assert_raises(JSON::NestingError) { JSON.parse '[[]]', :max_nesting => 1 }
382 assert_raises(JSON::NestingError) { JSON.parser.new('[[]]', :max_nesting => 1).parse }
383 assert_equal [[]], JSON.parse('[[]]', :max_nesting => 2)
384 too_deep = '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]'
385 too_deep_ary = eval too_deep
386 assert_raises(JSON::NestingError) { JSON.parse too_deep }
387 assert_raises(JSON::NestingError) { JSON.parser.new(too_deep).parse }
388 assert_raises(JSON::NestingError) { JSON.parse too_deep, :max_nesting => 19 }
389 ok = JSON.parse too_deep, :max_nesting => 20
390 assert_equal too_deep_ary, ok
391 ok = JSON.parse too_deep, :max_nesting => nil
392 assert_equal too_deep_ary, ok
393 ok = JSON.parse too_deep, :max_nesting => false
394 assert_equal too_deep_ary, ok
395 ok = JSON.parse too_deep, :max_nesting => 0
396 assert_equal too_deep_ary, ok
397 assert_raises(JSON::NestingError) { JSON.generate [[]], :max_nesting => 1 }
398 assert_equal '[[]]', JSON.generate([[]], :max_nesting => 2)
399 assert_raises(JSON::NestingError) { JSON.generate too_deep_ary }
400 assert_raises(JSON::NestingError) { JSON.generate too_deep_ary, :max_nesting => 19 }
401 ok = JSON.generate too_deep_ary, :max_nesting => 20
402 assert_equal too_deep, ok
403 ok = JSON.generate too_deep_ary, :max_nesting => nil
404 assert_equal too_deep, ok
405 ok = JSON.generate too_deep_ary, :max_nesting => false
406 assert_equal too_deep, ok
407 ok = JSON.generate too_deep_ary, :max_nesting => 0
408 assert_equal too_deep, ok
411 def test_symbolize_names
412 assert_equal({ "foo" => "bar", "baz" => "quux" },
413 JSON.parse('{"foo":"bar", "baz":"quux"}'))
414 assert_equal({ :foo => "bar", :baz => "quux" },
415 JSON.parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
419 assert_equal @hash, JSON.load(@json)
420 tempfile = Tempfile.open('json')
423 assert_equal @hash, JSON.load(tempfile)
424 stringio = StringIO.new(@json)
426 assert_equal @hash, JSON.load(stringio)
427 assert_raise(NoMethodError) { JSON.load(nil) }
428 assert_raise(JSON::ParserError) {JSON.load('') }
431 def test_load_with_options
432 small_hash = JSON("foo" => 'bar')
433 symbol_hash = { :foo => 'bar' }
434 assert_equal symbol_hash, JSON.load(small_hash, nil, :symbolize_names => true)
438 too_deep = '[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]'
439 assert_equal too_deep, JSON.dump(eval(too_deep))
440 assert_kind_of String, Marshal.dump(eval(too_deep))
441 assert_raises(ArgumentError) { JSON.dump(eval(too_deep), 19) }
442 assert_raises(ArgumentError) { Marshal.dump(eval(too_deep), 19) }
443 assert_equal too_deep, JSON.dump(eval(too_deep), 20)
444 assert_kind_of String, Marshal.dump(eval(too_deep), 20)
445 output = StringIO.new
446 JSON.dump(eval(too_deep), output)
447 assert_equal too_deep, output.string
448 output = StringIO.new
449 JSON.dump(eval(too_deep), output, 20)
450 assert_equal too_deep, output.string
453 def test_big_integers
454 json1 = JSON([orig = (1 << 31) - 1])
455 assert_equal orig, JSON[json1][0]
456 json2 = JSON([orig = 1 << 31])
457 assert_equal orig, JSON[json2][0]
458 json3 = JSON([orig = (1 << 62) - 1])
459 assert_equal orig, JSON[json3][0]
460 json4 = JSON([orig = 1 << 62])
461 assert_equal orig, JSON[json4][0]
462 json5 = JSON([orig = 1 << 64])
463 assert_equal orig, JSON[json5][0]
466 if defined?(JSON::Ext::Parser)
468 parser = JSON::Ext::Parser.new("{}")
469 assert_raise(TypeError, '[ruby-core:35079]') {parser.__send__(:initialize, "{}")}
470 parser = JSON::Ext::Parser.allocate
471 assert_raise(TypeError, '[ruby-core:35079]') {parser.source}
475 def test_argument_encoding
476 source = "{}".force_encoding("ascii-8bit")
477 JSON::Parser.new(source)
478 assert_equal Encoding::ASCII_8BIT, source.encoding
479 end if defined?(Encoding::ASCII_8BIT)