test_json.rb 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. #!/usr/bin/env ruby
  2. # -*- coding: utf-8 -*-
  3. require 'test/unit'
  4. require File.join(File.dirname(__FILE__), 'setup_variant')
  5. require 'stringio'
  6. require 'tempfile'
  7. require 'ostruct'
  8. unless Array.method_defined?(:permutation)
  9. begin
  10. require 'enumerator'
  11. require 'permutation'
  12. class Array
  13. def permutation
  14. Permutation.for(self).to_enum.map { |x| x.project }
  15. end
  16. end
  17. rescue LoadError
  18. warn "Skipping permutation tests."
  19. end
  20. end
  21. class TestJSON < Test::Unit::TestCase
  22. include JSON
  23. def setup
  24. @ary = [1, "foo", 3.14, 4711.0, 2.718, nil, [1,-2,3], false, true].map do
  25. |x| [x]
  26. end
  27. @ary_to_parse = ["1", '"foo"', "3.14", "4711.0", "2.718", "null",
  28. "[1,-2,3]", "false", "true"].map do
  29. |x| "[#{x}]"
  30. end
  31. @hash = {
  32. 'a' => 2,
  33. 'b' => 3.141,
  34. 'c' => 'c',
  35. 'd' => [ 1, "b", 3.14 ],
  36. 'e' => { 'foo' => 'bar' },
  37. 'g' => "\"\0\037",
  38. 'h' => 1000.0,
  39. 'i' => 0.001
  40. }
  41. @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
  42. '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}'
  43. end
  44. def test_construction
  45. parser = JSON::Parser.new('test')
  46. assert_equal 'test', parser.source
  47. end
  48. def assert_equal_float(expected, is)
  49. assert_in_delta(expected.first, is.first, 1e-2)
  50. end
  51. def test_parse_simple_arrays
  52. assert_equal([], parse('[]'))
  53. assert_equal([], parse(' [ ] '))
  54. assert_equal([nil], parse('[null]'))
  55. assert_equal([false], parse('[false]'))
  56. assert_equal([true], parse('[true]'))
  57. assert_equal([-23], parse('[-23]'))
  58. assert_equal([23], parse('[23]'))
  59. assert_equal([0.23], parse('[0.23]'))
  60. assert_equal([0.0], parse('[0e0]'))
  61. assert_raises(JSON::ParserError) { parse('[+23.2]') }
  62. assert_raises(JSON::ParserError) { parse('[+23]') }
  63. assert_raises(JSON::ParserError) { parse('[.23]') }
  64. assert_raises(JSON::ParserError) { parse('[023]') }
  65. assert_equal_float [3.141], parse('[3.141]')
  66. assert_equal_float [-3.141], parse('[-3.141]')
  67. assert_equal_float [3.141], parse('[3141e-3]')
  68. assert_equal_float [3.141], parse('[3141.1e-3]')
  69. assert_equal_float [3.141], parse('[3141E-3]')
  70. assert_equal_float [3.141], parse('[3141.0E-3]')
  71. assert_equal_float [-3.141], parse('[-3141.0e-3]')
  72. assert_equal_float [-3.141], parse('[-3141e-3]')
  73. assert_raises(ParserError) { parse('[NaN]') }
  74. assert parse('[NaN]', :allow_nan => true).first.nan?
  75. assert_raises(ParserError) { parse('[Infinity]') }
  76. assert_equal [1.0/0], parse('[Infinity]', :allow_nan => true)
  77. assert_raises(ParserError) { parse('[-Infinity]') }
  78. assert_equal [-1.0/0], parse('[-Infinity]', :allow_nan => true)
  79. assert_equal([""], parse('[""]'))
  80. assert_equal(["foobar"], parse('["foobar"]'))
  81. assert_equal([{}], parse('[{}]'))
  82. end
  83. def test_parse_simple_objects
  84. assert_equal({}, parse('{}'))
  85. assert_equal({}, parse(' { } '))
  86. assert_equal({ "a" => nil }, parse('{ "a" : null}'))
  87. assert_equal({ "a" => nil }, parse('{"a":null}'))
  88. assert_equal({ "a" => false }, parse('{ "a" : false } '))
  89. assert_equal({ "a" => false }, parse('{"a":false}'))
  90. assert_raises(JSON::ParserError) { parse('{false}') }
  91. assert_equal({ "a" => true }, parse('{"a":true}'))
  92. assert_equal({ "a" => true }, parse(' { "a" : true } '))
  93. assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
  94. assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
  95. assert_equal({ "a" => 23 }, parse('{"a":23 } '))
  96. assert_equal({ "a" => 23 }, parse(' { "a" : 23 } '))
  97. assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
  98. assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
  99. end
  100. def test_parse_json_primitive_values
  101. assert_raise(JSON::ParserError) { JSON.parse('') }
  102. assert_raise(JSON::ParserError) { JSON.parse('', :quirks_mode => true) }
  103. assert_raise(TypeError) { JSON::Parser.new(nil).parse }
  104. assert_raise(TypeError) { JSON::Parser.new(nil, :quirks_mode => true).parse }
  105. assert_raise(TypeError) { JSON.parse(nil) }
  106. assert_raise(TypeError) { JSON.parse(nil, :quirks_mode => true) }
  107. assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ') }
  108. assert_raise(JSON::ParserError) { JSON.parse(' /* foo */ ', :quirks_mode => true) }
  109. parser = JSON::Parser.new('null')
  110. assert_equal false, parser.quirks_mode?
  111. assert_raise(JSON::ParserError) { parser.parse }
  112. assert_raise(JSON::ParserError) { JSON.parse('null') }
  113. assert_equal nil, JSON.parse('null', :quirks_mode => true)
  114. parser = JSON::Parser.new('null', :quirks_mode => true)
  115. assert_equal true, parser.quirks_mode?
  116. assert_equal nil, parser.parse
  117. assert_raise(JSON::ParserError) { JSON.parse('false') }
  118. assert_equal false, JSON.parse('false', :quirks_mode => true)
  119. assert_raise(JSON::ParserError) { JSON.parse('true') }
  120. assert_equal true, JSON.parse('true', :quirks_mode => true)
  121. assert_raise(JSON::ParserError) { JSON.parse('23') }
  122. assert_equal 23, JSON.parse('23', :quirks_mode => true)
  123. assert_raise(JSON::ParserError) { JSON.parse('1') }
  124. assert_equal 1, JSON.parse('1', :quirks_mode => true)
  125. assert_raise(JSON::ParserError) { JSON.parse('3.141') }
  126. assert_in_delta 3.141, JSON.parse('3.141', :quirks_mode => true), 1E-3
  127. assert_raise(JSON::ParserError) { JSON.parse('18446744073709551616') }
  128. assert_equal 2 ** 64, JSON.parse('18446744073709551616', :quirks_mode => true)
  129. assert_raise(JSON::ParserError) { JSON.parse('"foo"') }
  130. assert_equal 'foo', JSON.parse('"foo"', :quirks_mode => true)
  131. assert_raise(JSON::ParserError) { JSON.parse('NaN', :allow_nan => true) }
  132. assert JSON.parse('NaN', :quirks_mode => true, :allow_nan => true).nan?
  133. assert_raise(JSON::ParserError) { JSON.parse('Infinity', :allow_nan => true) }
  134. assert JSON.parse('Infinity', :quirks_mode => true, :allow_nan => true).infinite?
  135. assert_raise(JSON::ParserError) { JSON.parse('-Infinity', :allow_nan => true) }
  136. assert JSON.parse('-Infinity', :quirks_mode => true, :allow_nan => true).infinite?
  137. assert_raise(JSON::ParserError) { JSON.parse('[ 1, ]', :quirks_mode => true) }
  138. end
  139. if Array.method_defined?(:permutation)
  140. def test_parse_more_complex_arrays
  141. a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
  142. a.permutation.each do |perm|
  143. json = pretty_generate(perm)
  144. assert_equal perm, parse(json)
  145. end
  146. end
  147. def test_parse_complex_objects
  148. a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
  149. a.permutation.each do |perm|
  150. s = "a"
  151. orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
  152. json = pretty_generate(orig_obj)
  153. assert_equal orig_obj, parse(json)
  154. end
  155. end
  156. end
  157. def test_parse_arrays
  158. assert_equal([1,2,3], parse('[1,2,3]'))
  159. assert_equal([1.2,2,3], parse('[1.2,2,3]'))
  160. assert_equal([[],[[],[]]], parse('[[],[[],[]]]'))
  161. end
  162. def test_parse_values
  163. assert_equal([""], parse('[""]'))
  164. assert_equal(["\\"], parse('["\\\\"]'))
  165. assert_equal(['"'], parse('["\""]'))
  166. assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]'))
  167. assert_equal(["\"\b\n\r\t\0\037"],
  168. parse('["\"\b\n\r\t\u0000\u001f"]'))
  169. for i in 0 ... @ary.size
  170. assert_equal(@ary[i], parse(@ary_to_parse[i]))
  171. end
  172. end
  173. def test_parse_array
  174. assert_equal([], parse('[]'))
  175. assert_equal([], parse(' [ ] '))
  176. assert_equal([1], parse('[1]'))
  177. assert_equal([1], parse(' [ 1 ] '))
  178. assert_equal(@ary,
  179. parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]]'\
  180. ',[false],[true]]'))
  181. assert_equal(@ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s
  182. , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
  183. end
  184. class SubArray < Array
  185. def <<(v)
  186. @shifted = true
  187. super
  188. end
  189. def shifted?
  190. @shifted
  191. end
  192. end
  193. class SubArray2 < Array
  194. def to_json(*a)
  195. {
  196. JSON.create_id => self.class.name,
  197. 'ary' => to_a,
  198. }.to_json(*a)
  199. end
  200. def self.json_create(o)
  201. o.delete JSON.create_id
  202. o['ary']
  203. end
  204. end
  205. class SubArrayWrapper
  206. def initialize
  207. @data = []
  208. end
  209. attr_reader :data
  210. def [](index)
  211. @data[index]
  212. end
  213. def <<(value)
  214. @data << value
  215. @shifted = true
  216. end
  217. def shifted?
  218. @shifted
  219. end
  220. end
  221. def test_parse_array_custom_array_derived_class
  222. res = parse('[1,2]', :array_class => SubArray)
  223. assert_equal([1,2], res)
  224. assert_equal(SubArray, res.class)
  225. assert res.shifted?
  226. end
  227. def test_parse_array_custom_non_array_derived_class
  228. res = parse('[1,2]', :array_class => SubArrayWrapper)
  229. assert_equal([1,2], res.data)
  230. assert_equal(SubArrayWrapper, res.class)
  231. assert res.shifted?
  232. end
  233. def test_parse_object
  234. assert_equal({}, parse('{}'))
  235. assert_equal({}, parse(' { } '))
  236. assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}'))
  237. assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } '))
  238. end
  239. class SubHash < Hash
  240. def []=(k, v)
  241. @item_set = true
  242. super
  243. end
  244. def item_set?
  245. @item_set
  246. end
  247. end
  248. class SubHash2 < Hash
  249. def to_json(*a)
  250. {
  251. JSON.create_id => self.class.name,
  252. }.merge(self).to_json(*a)
  253. end
  254. def self.json_create(o)
  255. o.delete JSON.create_id
  256. self[o]
  257. end
  258. end
  259. class SubOpenStruct < OpenStruct
  260. def [](k)
  261. __send__(k)
  262. end
  263. def []=(k, v)
  264. @item_set = true
  265. __send__("#{k}=", v)
  266. end
  267. def item_set?
  268. @item_set
  269. end
  270. end
  271. def test_parse_object_custom_hash_derived_class
  272. res = parse('{"foo":"bar"}', :object_class => SubHash)
  273. assert_equal({"foo" => "bar"}, res)
  274. assert_equal(SubHash, res.class)
  275. assert res.item_set?
  276. end
  277. def test_parse_object_custom_non_hash_derived_class
  278. res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
  279. assert_equal "bar", res.foo
  280. assert_equal(SubOpenStruct, res.class)
  281. assert res.item_set?
  282. end
  283. def test_parse_generic_object
  284. res = parse('{"foo":"bar", "baz":{}}', :object_class => JSON::GenericObject)
  285. assert_equal(JSON::GenericObject, res.class)
  286. assert_equal "bar", res.foo
  287. assert_equal "bar", res["foo"]
  288. assert_equal "bar", res[:foo]
  289. assert_equal "bar", res.to_hash[:foo]
  290. assert_equal(JSON::GenericObject, res.baz.class)
  291. end
  292. def test_generate_core_subclasses_with_new_to_json
  293. obj = SubHash2["foo" => SubHash2["bar" => true]]
  294. obj_json = JSON(obj)
  295. obj_again = JSON(obj_json)
  296. assert_kind_of SubHash2, obj_again
  297. assert_kind_of SubHash2, obj_again['foo']
  298. assert obj_again['foo']['bar']
  299. assert_equal obj, obj_again
  300. assert_equal ["foo"], JSON(JSON(SubArray2["foo"]))
  301. end
  302. def test_generate_core_subclasses_with_default_to_json
  303. assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"])
  304. assert_equal '["foo"]', JSON(SubArray["foo"])
  305. end
  306. def test_generate_of_core_subclasses
  307. obj = SubHash["foo" => SubHash["bar" => true]]
  308. obj_json = JSON(obj)
  309. obj_again = JSON(obj_json)
  310. assert_kind_of Hash, obj_again
  311. assert_kind_of Hash, obj_again['foo']
  312. assert obj_again['foo']['bar']
  313. assert_equal obj, obj_again
  314. end
  315. def test_parser_reset
  316. parser = Parser.new(@json)
  317. assert_equal(@hash, parser.parse)
  318. assert_equal(@hash, parser.parse)
  319. end
  320. def test_comments
  321. json = <<EOT
  322. {
  323. "key1":"value1", // eol comment
  324. "key2":"value2" /* multi line
  325. * comment */,
  326. "key3":"value3" /* multi line
  327. // nested eol comment
  328. * comment */
  329. }
  330. EOT
  331. assert_equal(
  332. { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
  333. parse(json))
  334. json = <<EOT
  335. {
  336. "key1":"value1" /* multi line
  337. // nested eol comment
  338. /* illegal nested multi line comment */
  339. * comment */
  340. }
  341. EOT
  342. assert_raises(ParserError) { parse(json) }
  343. json = <<EOT
  344. {
  345. "key1":"value1" /* multi line
  346. // nested eol comment
  347. closed multi comment */
  348. and again, throw an Error */
  349. }
  350. EOT
  351. assert_raises(ParserError) { parse(json) }
  352. json = <<EOT
  353. {
  354. "key1":"value1" /*/*/
  355. }
  356. EOT
  357. assert_equal({ "key1" => "value1" }, parse(json))
  358. end
  359. def test_backslash
  360. data = [ '\\.(?i:gif|jpe?g|png)$' ]
  361. json = '["\\\\.(?i:gif|jpe?g|png)$"]'
  362. assert_equal json, JSON.generate(data)
  363. assert_equal data, JSON.parse(json)
  364. #
  365. data = [ '\\"' ]
  366. json = '["\\\\\""]'
  367. assert_equal json, JSON.generate(data)
  368. assert_equal data, JSON.parse(json)
  369. #
  370. json = '["/"]'
  371. data = JSON.parse(json)
  372. assert_equal ['/'], data
  373. assert_equal json, JSON.generate(data)
  374. #
  375. json = '["\""]'
  376. data = JSON.parse(json)
  377. assert_equal ['"'], data
  378. assert_equal json, JSON.generate(data)
  379. json = '["\\\'"]'
  380. data = JSON.parse(json)
  381. assert_equal ["'"], data
  382. assert_equal '["\'"]', JSON.generate(data)
  383. end
  384. def test_wrong_inputs
  385. assert_raises(ParserError) { JSON.parse('"foo"') }
  386. assert_raises(ParserError) { JSON.parse('123') }
  387. assert_raises(ParserError) { JSON.parse('[] bla') }
  388. assert_raises(ParserError) { JSON.parse('[] 1') }
  389. assert_raises(ParserError) { JSON.parse('[] []') }
  390. assert_raises(ParserError) { JSON.parse('[] {}') }
  391. assert_raises(ParserError) { JSON.parse('{} []') }
  392. assert_raises(ParserError) { JSON.parse('{} {}') }
  393. assert_raises(ParserError) { JSON.parse('[NULL]') }
  394. assert_raises(ParserError) { JSON.parse('[FALSE]') }
  395. assert_raises(ParserError) { JSON.parse('[TRUE]') }
  396. assert_raises(ParserError) { JSON.parse('[07] ') }
  397. assert_raises(ParserError) { JSON.parse('[0a]') }
  398. assert_raises(ParserError) { JSON.parse('[1.]') }
  399. assert_raises(ParserError) { JSON.parse(' ') }
  400. end
  401. def test_nesting
  402. assert_raises(JSON::NestingError) { JSON.parse '[[]]', :max_nesting => 1 }
  403. assert_raises(JSON::NestingError) { JSON.parser.new('[[]]', :max_nesting => 1).parse }
  404. assert_equal [[]], JSON.parse('[[]]', :max_nesting => 2)
  405. too_deep = '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]'
  406. too_deep_ary = eval too_deep
  407. assert_raises(JSON::NestingError) { JSON.parse too_deep }
  408. assert_raises(JSON::NestingError) { JSON.parser.new(too_deep).parse }
  409. assert_raises(JSON::NestingError) { JSON.parse too_deep, :max_nesting => 19 }
  410. ok = JSON.parse too_deep, :max_nesting => 20
  411. assert_equal too_deep_ary, ok
  412. ok = JSON.parse too_deep, :max_nesting => nil
  413. assert_equal too_deep_ary, ok
  414. ok = JSON.parse too_deep, :max_nesting => false
  415. assert_equal too_deep_ary, ok
  416. ok = JSON.parse too_deep, :max_nesting => 0
  417. assert_equal too_deep_ary, ok
  418. assert_raises(JSON::NestingError) { JSON.generate [[]], :max_nesting => 1 }
  419. assert_equal '[[]]', JSON.generate([[]], :max_nesting => 2)
  420. assert_raises(JSON::NestingError) { JSON.generate too_deep_ary }
  421. assert_raises(JSON::NestingError) { JSON.generate too_deep_ary, :max_nesting => 19 }
  422. ok = JSON.generate too_deep_ary, :max_nesting => 20
  423. assert_equal too_deep, ok
  424. ok = JSON.generate too_deep_ary, :max_nesting => nil
  425. assert_equal too_deep, ok
  426. ok = JSON.generate too_deep_ary, :max_nesting => false
  427. assert_equal too_deep, ok
  428. ok = JSON.generate too_deep_ary, :max_nesting => 0
  429. assert_equal too_deep, ok
  430. end
  431. def test_symbolize_names
  432. assert_equal({ "foo" => "bar", "baz" => "quux" },
  433. JSON.parse('{"foo":"bar", "baz":"quux"}'))
  434. assert_equal({ :foo => "bar", :baz => "quux" },
  435. JSON.parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
  436. end
  437. def test_load
  438. assert_equal @hash, JSON.load(@json)
  439. tempfile = Tempfile.open('json')
  440. tempfile.write @json
  441. tempfile.rewind
  442. assert_equal @hash, JSON.load(tempfile)
  443. stringio = StringIO.new(@json)
  444. stringio.rewind
  445. assert_equal @hash, JSON.load(stringio)
  446. assert_equal nil, JSON.load(nil)
  447. assert_equal nil, JSON.load('')
  448. end
  449. def test_dump
  450. too_deep = '[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]'
  451. assert_equal too_deep, JSON.dump(eval(too_deep))
  452. assert_kind_of String, Marshal.dump(eval(too_deep))
  453. assert_raises(ArgumentError) { JSON.dump(eval(too_deep), 19) }
  454. assert_raises(ArgumentError) { Marshal.dump(eval(too_deep), 19) }
  455. assert_equal too_deep, JSON.dump(eval(too_deep), 20)
  456. assert_kind_of String, Marshal.dump(eval(too_deep), 20)
  457. output = StringIO.new
  458. JSON.dump(eval(too_deep), output)
  459. assert_equal too_deep, output.string
  460. output = StringIO.new
  461. JSON.dump(eval(too_deep), output, 20)
  462. assert_equal too_deep, output.string
  463. end
  464. def test_big_integers
  465. json1 = JSON([orig = (1 << 31) - 1])
  466. assert_equal orig, JSON[json1][0]
  467. json2 = JSON([orig = 1 << 31])
  468. assert_equal orig, JSON[json2][0]
  469. json3 = JSON([orig = (1 << 62) - 1])
  470. assert_equal orig, JSON[json3][0]
  471. json4 = JSON([orig = 1 << 62])
  472. assert_equal orig, JSON[json4][0]
  473. json5 = JSON([orig = 1 << 64])
  474. assert_equal orig, JSON[json5][0]
  475. end
  476. if defined?(JSON::Ext::Parser)
  477. def test_allocate
  478. parser = JSON::Ext::Parser.new("{}")
  479. assert_raise(TypeError, '[ruby-core:35079]') {parser.__send__(:initialize, "{}")}
  480. parser = JSON::Ext::Parser.allocate
  481. assert_raise(TypeError, '[ruby-core:35079]') {parser.source}
  482. end
  483. end
  484. def test_argument_encoding
  485. source = "{}".force_encoding("ascii-8bit")
  486. JSON::Parser.new(source)
  487. assert_equal Encoding::ASCII_8BIT, source.encoding
  488. end if defined?(Encoding::ASCII_8BIT)
  489. end