json 0.4.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of json might be problematic. Click here for more details.

Files changed (74) hide show
  1. data/CHANGES +6 -1
  2. data/README +49 -7
  3. data/Rakefile +216 -52
  4. data/TODO +1 -0
  5. data/VERSION +1 -1
  6. data/benchmarks/benchmark.txt +133 -0
  7. data/benchmarks/benchmark_generator.rb +44 -0
  8. data/benchmarks/benchmark_parser.rb +22 -0
  9. data/benchmarks/benchmark_rails.rb +26 -0
  10. data/data/example.json +1 -0
  11. data/data/index.html +37 -0
  12. data/data/prototype.js +2515 -0
  13. data/ext/json/ext/generator/Makefile +149 -0
  14. data/ext/json/ext/generator/extconf.rb +9 -0
  15. data/ext/json/ext/generator/generator.c +729 -0
  16. data/ext/json/ext/generator/unicode.c +184 -0
  17. data/ext/json/ext/generator/unicode.h +40 -0
  18. data/ext/json/ext/parser/Makefile +149 -0
  19. data/ext/json/ext/parser/extconf.rb +9 -0
  20. data/ext/json/ext/parser/parser.c +1551 -0
  21. data/ext/json/ext/parser/parser.rl +515 -0
  22. data/ext/json/ext/parser/unicode.c +156 -0
  23. data/ext/json/ext/parser/unicode.h +44 -0
  24. data/install.rb +13 -8
  25. data/lib/json.rb +101 -614
  26. data/lib/json/common.rb +184 -0
  27. data/lib/json/editor.rb +19 -10
  28. data/lib/json/ext.rb +13 -0
  29. data/lib/json/pure.rb +75 -0
  30. data/lib/json/pure/generator.rb +321 -0
  31. data/lib/json/pure/parser.rb +210 -0
  32. data/lib/json/version.rb +8 -0
  33. data/tests/fixtures/fail1.json +1 -0
  34. data/tests/fixtures/fail10.json +1 -0
  35. data/tests/fixtures/fail11.json +1 -0
  36. data/tests/fixtures/fail12.json +1 -0
  37. data/tests/fixtures/fail13.json +1 -0
  38. data/tests/fixtures/fail14.json +1 -0
  39. data/tests/fixtures/fail15.json +1 -0
  40. data/tests/fixtures/fail16.json +1 -0
  41. data/tests/fixtures/fail17.json +1 -0
  42. data/tests/fixtures/fail19.json +1 -0
  43. data/tests/fixtures/fail2.json +1 -0
  44. data/tests/fixtures/fail20.json +1 -0
  45. data/tests/fixtures/fail21.json +1 -0
  46. data/tests/fixtures/fail22.json +1 -0
  47. data/tests/fixtures/fail23.json +1 -0
  48. data/tests/fixtures/fail24.json +1 -0
  49. data/tests/fixtures/fail25.json +1 -0
  50. data/tests/fixtures/fail26.json +1 -0
  51. data/tests/fixtures/fail27.json +2 -0
  52. data/tests/fixtures/fail28.json +2 -0
  53. data/tests/fixtures/fail3.json +1 -0
  54. data/tests/fixtures/fail4.json +1 -0
  55. data/tests/fixtures/fail5.json +1 -0
  56. data/tests/fixtures/fail6.json +1 -0
  57. data/tests/fixtures/fail7.json +1 -0
  58. data/tests/fixtures/fail8.json +1 -0
  59. data/tests/fixtures/fail9.json +1 -0
  60. data/tests/fixtures/pass1.json +56 -0
  61. data/tests/fixtures/pass18.json +1 -0
  62. data/tests/fixtures/pass2.json +1 -0
  63. data/tests/fixtures/pass3.json +6 -0
  64. data/tests/runner.rb +8 -2
  65. data/tests/test_json.rb +102 -154
  66. data/tests/test_json_addition.rb +94 -0
  67. data/tests/test_json_fixtures.rb +30 -0
  68. data/tests/test_json_generate.rb +81 -0
  69. data/tests/test_json_unicode.rb +55 -0
  70. data/tools/fuzz.rb +133 -0
  71. data/tools/server.rb +62 -0
  72. metadata +87 -10
  73. data/bla.json.tmp +0 -0
  74. data/lib/json.rb.orig +0 -708
@@ -0,0 +1,210 @@
1
+ require 'strscan'
2
+
3
+ module JSON
4
+ module Pure
5
+ # This class implements the JSON parser that is used to parse a JSON string
6
+ # into a Ruby data structure.
7
+ class Parser < StringScanner
8
+ STRING = /" ((?:[^\x0-\x1f"\\] |
9
+ \\["\\\/bfnrt] |
10
+ \\u[0-9a-fA-F]{4})*)
11
+ "/x
12
+ INTEGER = /(-?0|-?[1-9]\d*)/
13
+ FLOAT = /(-?
14
+ (?:0|[1-9]\d*)
15
+ (?:
16
+ \.\d+(?i:e[+-]?\d+) |
17
+ \.\d+ |
18
+ (?i:e[+-]?\d+)
19
+ )
20
+ )/x
21
+ OBJECT_OPEN = /\{/
22
+ OBJECT_CLOSE = /\}/
23
+ ARRAY_OPEN = /\[/
24
+ ARRAY_CLOSE = /\]/
25
+ PAIR_DELIMITER = /:/
26
+ COLLECTION_DELIMITER = /,/
27
+ TRUE = /true/
28
+ FALSE = /false/
29
+ NULL = /null/
30
+ IGNORE = %r(
31
+ (?:
32
+ //[^\n\r]*[\n\r]| # line comments
33
+ /\* # c-style comments
34
+ (?:
35
+ [^*/]| # normal chars
36
+ /[^*]| # slashes that do not start a nested comment
37
+ \*[^/]| # asterisks that do not end this comment
38
+ /(?=\*/) # single slash before this comment's end
39
+ )*
40
+ \*/ # the End of this comment
41
+ |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
42
+ )+
43
+ )mx
44
+
45
+ UNPARSED = Object.new
46
+
47
+ # Creates a new JSON::Pure::Parser instance for the string _source_.
48
+ def initialize(source)
49
+ super
50
+ @create_id = JSON.create_id
51
+ end
52
+
53
+ alias source string
54
+
55
+ # Parses the current JSON string _source_ and returns the complete data
56
+ # structure as a result.
57
+ def parse
58
+ reset
59
+ obj = nil
60
+ until eos?
61
+ case
62
+ when scan(OBJECT_OPEN)
63
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
64
+ obj = parse_object
65
+ when scan(ARRAY_OPEN)
66
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
67
+ obj = parse_array
68
+ when skip(IGNORE)
69
+ ;
70
+ else
71
+ raise ParserError, "source '#{peek(20)}' not in JSON!"
72
+ end
73
+ end
74
+ obj or raise ParserError, "source did not contain any JSON!"
75
+ obj
76
+ end
77
+
78
+ private
79
+
80
+ def parse_string
81
+ if scan(STRING)
82
+ return '' if self[1].empty?
83
+ self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+))) do
84
+ case $~[0]
85
+ when '\\"' then '"'
86
+ when '\\\\' then '\\'
87
+ when '\\/' then '/'
88
+ when '\\b' then "\b"
89
+ when '\\f' then "\f"
90
+ when '\\n' then "\n"
91
+ when '\\r' then "\r"
92
+ when '\\t' then "\t"
93
+ else
94
+ bytes = ''
95
+ c = $~[0]
96
+ i = 0
97
+ while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
98
+ bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
99
+ i += 1
100
+ end
101
+ JSON::UTF16toUTF8.iconv(bytes)
102
+ end
103
+ end
104
+ else
105
+ UNPARSED
106
+ end
107
+ rescue Iconv::Failure => e
108
+ raise GeneratorError, "Caught #{e.class}: #{e}"
109
+ end
110
+
111
+ def parse_value
112
+ case
113
+ when scan(FLOAT)
114
+ Float(self[1])
115
+ when scan(INTEGER)
116
+ Integer(self[1])
117
+ when scan(TRUE)
118
+ true
119
+ when scan(FALSE)
120
+ false
121
+ when scan(NULL)
122
+ nil
123
+ when (string = parse_string) != UNPARSED
124
+ string
125
+ when scan(ARRAY_OPEN)
126
+ parse_array
127
+ when scan(OBJECT_OPEN)
128
+ parse_object
129
+ else
130
+ UNPARSED
131
+ end
132
+ end
133
+
134
+ def parse_array
135
+ result = []
136
+ delim = false
137
+ until eos?
138
+ case
139
+ when (value = parse_value) != UNPARSED
140
+ delim = false
141
+ result << value
142
+ skip(IGNORE)
143
+ if scan(COLLECTION_DELIMITER)
144
+ delim = true
145
+ elsif match?(ARRAY_CLOSE)
146
+ ;
147
+ else
148
+ raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
149
+ end
150
+ when scan(ARRAY_CLOSE)
151
+ if delim
152
+ raise ParserError, "expected next element in array at '#{peek(20)}'!"
153
+ end
154
+ break
155
+ when skip(IGNORE)
156
+ ;
157
+ else
158
+ raise ParserError, "unexpected token in array at '#{peek(20)}'!"
159
+ end
160
+ end
161
+ result
162
+ end
163
+
164
+ def parse_object
165
+ result = {}
166
+ delim = false
167
+ until eos?
168
+ case
169
+ when (string = parse_string) != UNPARSED
170
+ skip(IGNORE)
171
+ unless scan(PAIR_DELIMITER)
172
+ raise ParserError, "expected ':' in object at '#{peek(20)}'!"
173
+ end
174
+ skip(IGNORE)
175
+ unless (value = parse_value).equal? UNPARSED
176
+ result[string] = value
177
+ delim = false
178
+ skip(IGNORE)
179
+ if scan(COLLECTION_DELIMITER)
180
+ delim = true
181
+ elsif match?(OBJECT_CLOSE)
182
+ ;
183
+ else
184
+ raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
185
+ end
186
+ else
187
+ raise ParserError, "expected value in object at '#{peek(20)}'!"
188
+ end
189
+ when scan(OBJECT_CLOSE)
190
+ if delim
191
+ raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
192
+ end
193
+ if klassname = result[@create_id]
194
+ klass = JSON.deep_const_get klassname
195
+ break unless klass and klass.json_creatable?
196
+ result = klass.json_create(result)
197
+ result
198
+ end
199
+ break
200
+ when skip(IGNORE)
201
+ ;
202
+ else
203
+ raise ParserError, "unexpected token in object at '#{peek(20)}'!"
204
+ end
205
+ end
206
+ result
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,8 @@
1
+ module JSON
2
+ # JSON version
3
+ VERSION = '1.0.0'
4
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
5
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
7
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
8
+ end
@@ -0,0 +1 @@
1
+ "A JSON payload should be an object or array, not a string."
@@ -0,0 +1 @@
1
+ {"Extra value after close": true} "misplaced quoted value"
@@ -0,0 +1 @@
1
+ {"Illegal expression": 1 + 2}
@@ -0,0 +1 @@
1
+ {"Illegal invocation": alert()}
@@ -0,0 +1 @@
1
+ {"Numbers cannot have leading zeroes": 013}
@@ -0,0 +1 @@
1
+ {"Numbers cannot be hex": 0x14}
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \x15"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \'"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \017"]
@@ -0,0 +1 @@
1
+ {"Missing colon" null}
@@ -0,0 +1 @@
1
+ ["Unclosed array"
@@ -0,0 +1 @@
1
+ {"Double colon":: null}
@@ -0,0 +1 @@
1
+ {"Comma instead of colon", null}
@@ -0,0 +1 @@
1
+ ["Colon instead of comma": false]
@@ -0,0 +1 @@
1
+ ["Bad value", truth]
@@ -0,0 +1 @@
1
+ ['single quote']
@@ -0,0 +1 @@
1
+ ["tab character in string "]
@@ -0,0 +1 @@
1
+ ["tab\ character\ in\ string\ "]
@@ -0,0 +1,2 @@
1
+ ["line
2
+ break"]
@@ -0,0 +1,2 @@
1
+ ["line\
2
+ break"]
@@ -0,0 +1 @@
1
+ {unquoted_key: "keys must be quoted"}
@@ -0,0 +1 @@
1
+ ["extra comma",]
@@ -0,0 +1 @@
1
+ ["double extra comma",,]
@@ -0,0 +1 @@
1
+ [ , "<-- missing value"]
@@ -0,0 +1 @@
1
+ ["Comma after the close"],
@@ -0,0 +1 @@
1
+ ["Extra close"]]
@@ -0,0 +1 @@
1
+ {"Extra comma": true,}
@@ -0,0 +1,56 @@
1
+ [
2
+ "JSON Test Pattern pass1",
3
+ {"object with 1 member":["array with 1 element"]},
4
+ {},
5
+ [],
6
+ -42,
7
+ true,
8
+ false,
9
+ null,
10
+ {
11
+ "integer": 1234567890,
12
+ "real": -9876.543210,
13
+ "e": 0.123456789e-12,
14
+ "E": 1.234567890E+34,
15
+ "": 23456789012E666,
16
+ "zero": 0,
17
+ "one": 1,
18
+ "space": " ",
19
+ "quote": "\"",
20
+ "backslash": "\\",
21
+ "controls": "\b\f\n\r\t",
22
+ "slash": "/ & \/",
23
+ "alpha": "abcdefghijklmnopqrstuvwyz",
24
+ "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
25
+ "digit": "0123456789",
26
+ "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
27
+ "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
28
+ "true": true,
29
+ "false": false,
30
+ "null": null,
31
+ "array":[ ],
32
+ "object":{ },
33
+ "address": "50 St. James Street",
34
+ "url": "http://www.JSON.org/",
35
+ "comment": "// /* <!-- --",
36
+ "# -- --> */": " ",
37
+ " s p a c e d " :[1,2 , 3
38
+
39
+ ,
40
+
41
+ 4 , 5 , 6 ,7 ],
42
+ "compact": [1,2,3,4,5,6,7],
43
+ "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
44
+ "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
45
+ "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
46
+ : "A key can be any string"
47
+ },
48
+ 0.5 ,98.6
49
+ ,
50
+ 99.44
51
+ ,
52
+
53
+ 1066
54
+
55
+
56
+ ,"rosebud"]
@@ -0,0 +1 @@
1
+ [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] // No, we don't limit our depth: Moved to pass...
@@ -0,0 +1 @@
1
+ [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
@@ -0,0 +1,6 @@
1
+ {
2
+ "JSON Test Pattern pass3": {
3
+ "The outermost value": "must be an object or array.",
4
+ "In this test": "It is an object."
5
+ }
6
+ }
@@ -3,15 +3,21 @@
3
3
  require 'test/unit/ui/console/testrunner'
4
4
  require 'test/unit/testsuite'
5
5
  $:.unshift File.expand_path(File.dirname($0))
6
- $:.unshift 'lib'
7
- $:.unshift '../lib'
8
6
  $:.unshift 'tests'
9
7
  require 'test_json'
8
+ require 'test_json_generate'
9
+ require 'test_json_unicode'
10
+ require 'test_json_addition'
11
+ require 'test_json_fixtures'
10
12
 
11
13
  class TS_AllTests
12
14
  def self.suite
13
15
  suite = Test::Unit::TestSuite.new name
16
+ suite << TC_JSONGenerate.suite
14
17
  suite << TC_JSON.suite
18
+ suite << TC_JSONUnicode.suite
19
+ suite << TC_JSONAddition.suite
20
+ suite << TC_JSONFixtures.suite
15
21
  end
16
22
  end
17
23
  Test::Unit::UI::Console::TestRunner.run(TS_AllTests)
@@ -6,29 +6,6 @@ require 'json'
6
6
  class TC_JSON < Test::Unit::TestCase
7
7
  include JSON
8
8
 
9
- class A
10
- def initialize(a)
11
- @a = a
12
- end
13
-
14
- attr_reader :a
15
-
16
- def ==(other)
17
- a == other.a
18
- end
19
-
20
- def self.json_create(object)
21
- new(*object['args'])
22
- end
23
-
24
- def to_json(*args)
25
- {
26
- 'json_class' => self.class,
27
- 'args' => [ @a ],
28
- }.to_json(*args)
29
- end
30
- end
31
-
32
9
  def setup
33
10
  $KCODE = 'UTF8'
34
11
  @ary = [1, "foo", 3.14, 4711.0, 2.718, nil, [1,-2,3], false, true].map do
@@ -50,35 +27,101 @@ class TC_JSON < Test::Unit::TestCase
50
27
  }
51
28
  @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
52
29
  '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}'
53
- @json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
54
- '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
55
- @json3 = <<'EOT'.chomp
56
- {
57
- "a": 2,
58
- "b": 3.141,
59
- "c": "c",
60
- "d": [
61
- 1,
62
- "b",
63
- 3.14
64
- ],
65
- "e": {
66
- "foo": "bar"
67
- },
68
- "g": "\"\u0000\u001f",
69
- "h": 1000.0,
70
- "i": 0.001
71
- }
72
- EOT
30
+ end
31
+ suite << TC_JSON.suite
32
+
33
+ def test_construction
34
+ parser = JSON::Parser.new('test')
35
+ assert_equal 'test', parser.source
73
36
  end
74
37
 
75
- def test_parse_value
38
+ def assert_equal_float(expected, is)
39
+ assert_in_delta(expected.first, is.first, 1e-2)
40
+ end
41
+
42
+ def test_parse_simple_arrays
43
+ assert_equal([], parse('[]'))
44
+ assert_equal([], parse(' [ ] '))
45
+ assert_equal([nil], parse('[null]'))
46
+ assert_equal([false], parse('[false]'))
47
+ assert_equal([true], parse('[true]'))
48
+ assert_equal([-23], parse('[-23]'))
49
+ assert_equal([23], parse('[23]'))
50
+ assert_equal([0.23], parse('[0.23]'))
51
+ assert_raises(JSON::ParserError) { parse('[+23.2]') }
52
+ assert_raises(JSON::ParserError) { parse('[+23]') }
53
+ assert_raises(JSON::ParserError) { parse('[.23]') }
54
+ assert_raises(JSON::ParserError) { parse('[023]') }
55
+ assert_equal_float [3.141], parse('[3.141]')
56
+ assert_equal_float [-3.141], parse('[-3.141]')
57
+ assert_equal_float [3.141], parse('[3141e-3]')
58
+ assert_equal_float [3.141], parse('[3141.1e-3]')
59
+ assert_equal_float [3.141], parse('[3141E-3]')
60
+ assert_equal_float [3.141], parse('[3141.0E-3]')
61
+ assert_equal_float [-3.141], parse('[-3141.0e-3]')
62
+ assert_equal_float [-3.141], parse('[-3141e-3]')
63
+ assert_equal([""], parse('[""]'))
64
+ assert_equal(["foobar"], parse('["foobar"]'))
65
+ assert_equal([{}], parse('[{}]'))
66
+ end
67
+
68
+ def test_parse_simple_objects
69
+ assert_equal({}, parse('{}'))
70
+ assert_equal({}, parse(' { } '))
71
+ assert_equal({ "a" => nil }, parse('{ "a" : null}'))
72
+ assert_equal({ "a" => nil }, parse('{"a":null}'))
73
+ assert_equal({ "a" => false }, parse('{ "a" : false } '))
74
+ assert_equal({ "a" => false }, parse('{"a":false}'))
75
+ assert_raises(JSON::ParserError) { parse('{false}') }
76
+ assert_equal({ "a" => true }, parse('{"a":true}'))
77
+ assert_equal({ "a" => true }, parse(' { "a" : true } '))
78
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
79
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
80
+ assert_equal({ "a" => 23 }, parse('{"a":23 } '))
81
+ assert_equal({ "a" => 23 }, parse(' { "a" : 23 } '))
82
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
83
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
84
+ end
85
+
86
+ begin
87
+ require 'permutation'
88
+ def test_parse_more_complex_arrays
89
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
90
+ perms = Permutation.for a
91
+ perms.each do |perm|
92
+ orig_ary = perm.project
93
+ json = pretty_generate(orig_ary)
94
+ assert_equal orig_ary, parse(json)
95
+ end
96
+ end
97
+
98
+ def test_parse_complex_objects
99
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
100
+ perms = Permutation.for a
101
+ perms.each do |perm|
102
+ s = "a"
103
+ orig_obj = perm.project.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
104
+ json = pretty_generate(orig_obj)
105
+ assert_equal orig_obj, parse(json)
106
+ end
107
+ end
108
+ rescue LoadError
109
+ warn "Skipping permutation tests."
110
+ end
111
+
112
+ def test_parse_arrays
113
+ assert_equal([1,2,3], parse('[1,2,3]'))
114
+ assert_equal([1.2,2,3], parse('[1.2,2,3]'))
115
+ assert_equal([[],[[],[]]], parse('[[],[[],[]]]'))
116
+ end
117
+
118
+ def test_parse_values
76
119
  assert_equal([""], parse('[""]'))
77
120
  assert_equal(["\\"], parse('["\\\\"]'))
78
121
  assert_equal(['"'], parse('["\""]'))
79
122
  assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]'))
80
- assert_equal(["\\a\"\b\f\n\r\t\0\037"],
81
- parse('["\\a\"\b\f\n\r\t\u0000\u001f"]'))
123
+ assert_equal(["\"\b\n\r\t\0\037"],
124
+ parse('["\"\b\n\r\t\u0000\u001f"]'))
82
125
  for i in 0 ... @ary.size
83
126
  assert_equal(@ary[i], parse(@ary_to_parse[i]))
84
127
  end
@@ -93,7 +136,7 @@ EOT
93
136
  parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]]'\
94
137
  ',[false],[true]]'))
95
138
  assert_equal(@ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]
96
- , [2718.0E-3 ],\n[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
139
+ , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
97
140
  end
98
141
 
99
142
  def test_parse_object
@@ -103,64 +146,12 @@ EOT
103
146
  assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } '))
104
147
  end
105
148
 
106
- def test_unparse
107
- json = unparse(@hash)
108
- assert_equal(@json2, json)
109
- parsed_json = parse(json)
110
- assert_equal(@hash, parsed_json)
111
- json = generate({1=>2})
112
- assert_equal('{"1":2}', json)
113
- parsed_json = parse(json)
114
- assert_equal({"1"=>2}, parsed_json)
115
- end
116
-
117
- def test_unparse
118
- json = pretty_unparse(@hash)
119
- assert_equal(@json3, json)
120
- parsed_json = parse(json)
121
- assert_equal(@hash, parsed_json)
122
- json = pretty_generate({1=>2})
123
- assert_equal(<<'EOT'.chomp, json)
124
- {
125
- "1": 2
126
- }
127
- EOT
128
- parsed_json = parse(json)
129
- assert_equal({"1"=>2}, parsed_json)
130
- end
131
-
132
-
133
149
  def test_parser_reset
134
150
  parser = Parser.new(@json)
135
151
  assert_equal(@hash, parser.parse)
136
152
  assert_equal(@hash, parser.parse)
137
153
  end
138
154
 
139
- def test_unicode
140
- assert_equal '""', ''.to_json
141
- assert_equal '"\\b"', "\b".to_json
142
- assert_equal '"\u0001"', 0x1.chr.to_json
143
- assert_equal '"\u001f"', 0x1f.chr.to_json
144
- assert_equal '" "', ' '.to_json
145
- assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
146
- if JSON.support_unicode?
147
- utf8 = [ '© ≠ €!' ]
148
- json = '["\u00a9 \u2260 \u20ac!"]'
149
- assert_equal json, utf8.to_json
150
- assert_equal utf8, parse(json)
151
- utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
152
- json = '["\u3042\u3044\u3046\u3048\u304a"]'
153
- assert_equal json, utf8.to_json
154
- assert_equal utf8, parse(json)
155
- utf8 = ['საქართველო']
156
- json = '["\u10e1\u10d0\u10e5\u10d0\u10e0\u10d7\u10d5\u10d4\u10da\u10dd"]'
157
- assert_equal json, utf8.to_json
158
- assert_equal utf8, parse(json)
159
- else
160
- warn "No unicode support found - skipping test"
161
- end
162
- end
163
-
164
155
  def test_comments
165
156
  json = <<EOT
166
157
  {
@@ -201,69 +192,26 @@ EOT
201
192
  assert_equal({ "key1" => "value1" }, parse(json))
202
193
  end
203
194
 
204
- def test_extended_json
205
- a = A.new(666)
206
- json = generate(a)
207
- a_again = JSON.parse(json)
208
- assert_kind_of a.class, a_again
209
- assert_equal a, a_again
210
- end
211
-
212
- def test_raw_strings
213
- raw = ''
214
- raw_array = []
215
- for i in 0..255
216
- raw << i
217
- raw_array << i
218
- end
219
- json = raw.to_json_raw
220
- json_raw_object = raw.to_json_raw_object
221
- hash = { 'json_class' => 'String', 'raw'=> raw_array }
222
- assert_equal hash, json_raw_object
223
- json_raw = <<EOT.chomp
224
- {\"json_class\":\"String\",\"raw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]}
225
- EOT
226
- # "
227
- assert_equal json_raw, json
228
- raw_again = JSON.parse(json)
229
- assert_equal raw, raw_again
230
- end
231
-
232
- def test_utf8_mode
233
- unless JSON.support_unicode?
234
- warn "No unicode support found - skipping test"
235
- return
236
- end
237
- $KCODE = 'NONE'
238
- utf8 = ["© ≠ €! - \001"]
239
- json = "[\"© ≠ €! - \\u0001\"]"
240
- assert_equal json, generate(utf8)
241
- assert_equal utf8, parse(json)
242
- assert JSON.support_unicode?
243
- $KCODE = 'UTF8'
244
- utf8 = ['© ≠ €!']
245
- json = '["\u00a9 \u2260 \u20ac!"]'
246
- assert_equal json, unparse(utf8)
247
- assert_equal utf8, parse(json)
248
- JSON.support_unicode = false
249
- assert !JSON.support_unicode?
250
- utf8 = ["© ≠ €! - \001"]
251
- json = "[\"© ≠ €! - \\u0001\"]"
252
- assert_equal json, unparse(utf8)
253
- assert_equal utf8, parse(json)
254
- end
255
-
256
195
  def test_backslash
196
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
257
197
  json = '["\\\\.(?i:gif|jpe?g|png)$"]'
258
- data = JSON.parse(json)
259
198
  assert_equal json, JSON.unparse(data)
260
- json = '["\\""]'
261
- data = JSON.parse(json)
199
+ assert_equal data, JSON.parse(json)
200
+ #
201
+ data = [ '\\"' ]
202
+ json = '["\\\\\""]'
262
203
  assert_equal json, JSON.unparse(data)
204
+ assert_equal data, JSON.parse(json)
205
+ #
263
206
  json = '["\/"]'
264
207
  data = JSON.parse(json)
265
208
  assert_equal ['/'], data
266
209
  assert_equal json, JSON.unparse(data)
210
+ #
211
+ json = '["\""]'
212
+ data = JSON.parse(json)
213
+ assert_equal ['"'], data
214
+ assert_equal json, JSON.unparse(data)
267
215
  end
268
216
 
269
217
  def test_wrong_inputs