PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/test/json/test_json.rb

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