PageRenderTime 81ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/test/json/test_json.rb

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