json 1.8.6 → 2.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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +5 -3
- data/CHANGES +5 -5
- data/Gemfile +3 -1
- data/README.md +131 -84
- data/Rakefile +17 -10
- data/VERSION +1 -1
- data/ext/json/ext/generator/generator.c +1 -52
- data/ext/json/ext/generator/generator.h +0 -5
- data/ext/json/ext/parser/extconf.rb +3 -0
- data/ext/json/ext/parser/parser.c +304 -458
- data/ext/json/ext/parser/parser.h +0 -1
- data/ext/json/ext/parser/parser.rl +35 -152
- data/ext/json/extconf.rb +0 -1
- data/java/src/json/ext/Generator.java +2 -5
- data/java/src/json/ext/GeneratorState.java +2 -54
- data/java/src/json/ext/OptionsReader.java +1 -1
- data/java/src/json/ext/Parser.java +109 -409
- data/java/src/json/ext/Parser.rl +24 -117
- data/java/src/json/ext/RuntimeInfo.java +0 -4
- data/json.gemspec +0 -0
- data/json_pure.gemspec +7 -7
- data/lib/json.rb +1 -0
- data/lib/json/add/bigdecimal.rb +1 -0
- data/lib/json/add/complex.rb +2 -1
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +1 -0
- data/lib/json/add/regexp.rb +1 -1
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -1
- data/lib/json/add/time.rb +1 -1
- data/lib/json/common.rb +24 -52
- data/lib/json/ext.rb +0 -6
- data/lib/json/generic_object.rb +5 -4
- data/lib/json/pure.rb +2 -8
- data/lib/json/pure/generator.rb +51 -123
- data/lib/json/pure/parser.rb +28 -80
- data/lib/json/version.rb +2 -1
- data/references/rfc7159.txt +899 -0
- data/tests/fixtures/obsolete_fail1.json +1 -0
- data/tests/{test_json_addition.rb → json_addition_test.rb} +22 -25
- data/tests/json_common_interface_test.rb +126 -0
- data/tests/json_encoding_test.rb +105 -0
- data/tests/json_ext_parser_test.rb +15 -0
- data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
- data/tests/{test_json_generate.rb → json_generator_test.rb} +65 -37
- data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
- data/tests/json_parser_test.rb +448 -0
- data/tests/json_string_matching_test.rb +38 -0
- data/tests/test_helper.rb +23 -0
- data/tools/fuzz.rb +1 -9
- metadata +19 -32
- data/TODO +0 -1
- data/tests/fixtures/fail1.json +0 -1
- data/tests/setup_variant.rb +0 -11
- data/tests/test_json.rb +0 -519
- data/tests/test_json_encoding.rb +0 -65
- data/tests/test_json_string_matching.rb +0 -39
- data/tests/test_json_unicode.rb +0 -72
@@ -0,0 +1 @@
|
|
1
|
+
"A JSON payload should be an object or array, not a string."
|
@@ -1,8 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require 'test/unit'
|
5
|
-
require File.join(File.dirname(__FILE__), 'setup_variant')
|
1
|
+
#frozen_string_literal: false
|
2
|
+
require 'test_helper'
|
6
3
|
require 'json/add/core'
|
7
4
|
require 'json/add/complex'
|
8
5
|
require 'json/add/rational'
|
@@ -10,7 +7,7 @@ require 'json/add/bigdecimal'
|
|
10
7
|
require 'json/add/ostruct'
|
11
8
|
require 'date'
|
12
9
|
|
13
|
-
class
|
10
|
+
class JSONAdditionTest < Test::Unit::TestCase
|
14
11
|
include JSON
|
15
12
|
|
16
13
|
class A
|
@@ -64,7 +61,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
64
61
|
|
65
62
|
def to_json(*args)
|
66
63
|
{
|
67
|
-
'json_class' => '
|
64
|
+
'json_class' => 'JSONAdditionTest::Nix',
|
68
65
|
}.to_json(*args)
|
69
66
|
end
|
70
67
|
end
|
@@ -73,7 +70,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
73
70
|
a = A.new(666)
|
74
71
|
assert A.json_creatable?
|
75
72
|
json = generate(a)
|
76
|
-
a_again =
|
73
|
+
a_again = parse(json, :create_additions => true)
|
77
74
|
assert_kind_of a.class, a_again
|
78
75
|
assert_equal a, a_again
|
79
76
|
end
|
@@ -82,7 +79,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
82
79
|
a = A.new(666)
|
83
80
|
assert A.json_creatable?
|
84
81
|
json = generate(a)
|
85
|
-
a_hash =
|
82
|
+
a_hash = parse(json)
|
86
83
|
assert_kind_of Hash, a_hash
|
87
84
|
end
|
88
85
|
|
@@ -90,13 +87,13 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
90
87
|
a = A.new(666)
|
91
88
|
assert A.json_creatable?
|
92
89
|
json = generate(a)
|
93
|
-
a_again =
|
90
|
+
a_again = parse(json, :create_additions => true)
|
94
91
|
assert_kind_of a.class, a_again
|
95
92
|
assert_equal a, a_again
|
96
|
-
a_hash =
|
93
|
+
a_hash = parse(json, :create_additions => false)
|
97
94
|
assert_kind_of Hash, a_hash
|
98
95
|
assert_equal(
|
99
|
-
{"args"=>[666], "json_class"=>"
|
96
|
+
{"args"=>[666], "json_class"=>"JSONAdditionTest::A"}.sort_by { |k,| k },
|
100
97
|
a_hash.sort_by { |k,| k }
|
101
98
|
)
|
102
99
|
end
|
@@ -105,14 +102,14 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
105
102
|
b = B.new
|
106
103
|
assert !B.json_creatable?
|
107
104
|
json = generate(b)
|
108
|
-
assert_equal({ "json_class"=>"
|
105
|
+
assert_equal({ "json_class"=>"JSONAdditionTest::B" }, parse(json))
|
109
106
|
end
|
110
107
|
|
111
108
|
def test_extended_json_fail2
|
112
109
|
c = C.new
|
113
110
|
assert !C.json_creatable?
|
114
111
|
json = generate(c)
|
115
|
-
|
112
|
+
assert_raise(ArgumentError, NameError) { parse(json, :create_additions => true) }
|
116
113
|
end
|
117
114
|
|
118
115
|
def test_raw_strings
|
@@ -130,7 +127,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
130
127
|
assert_match(/\A\{.*\}\z/, json)
|
131
128
|
assert_match(/"json_class":"String"/, json)
|
132
129
|
assert_match(/"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\]/, json)
|
133
|
-
raw_again =
|
130
|
+
raw_again = parse(json, :create_additions => true)
|
134
131
|
assert_equal raw, raw_again
|
135
132
|
end
|
136
133
|
|
@@ -151,7 +148,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
151
148
|
assert_equal s, JSON(JSON(s), :create_additions => true)
|
152
149
|
struct = Struct.new :foo, :bar
|
153
150
|
s = struct.new 4711, 'foot'
|
154
|
-
|
151
|
+
assert_raise(JSONError) { JSON(s) }
|
155
152
|
begin
|
156
153
|
raise TypeError, "test me"
|
157
154
|
rescue TypeError => e
|
@@ -167,19 +164,19 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
167
164
|
|
168
165
|
def test_utc_datetime
|
169
166
|
now = Time.now
|
170
|
-
d = DateTime.parse(now.to_s, :create_additions => true)
|
171
|
-
assert_equal d,
|
172
|
-
d = DateTime.parse(now.utc.to_s)
|
173
|
-
assert_equal d,
|
167
|
+
d = DateTime.parse(now.to_s, :create_additions => true) # usual case
|
168
|
+
assert_equal d, parse(d.to_json, :create_additions => true)
|
169
|
+
d = DateTime.parse(now.utc.to_s) # of = 0
|
170
|
+
assert_equal d, parse(d.to_json, :create_additions => true)
|
174
171
|
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1,24))
|
175
|
-
assert_equal d,
|
172
|
+
assert_equal d, parse(d.to_json, :create_additions => true)
|
176
173
|
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12,24))
|
177
|
-
assert_equal d,
|
174
|
+
assert_equal d, parse(d.to_json, :create_additions => true)
|
178
175
|
end
|
179
176
|
|
180
177
|
def test_rational_complex
|
181
|
-
assert_equal Rational(2, 9),
|
182
|
-
assert_equal Complex(2, 9),
|
178
|
+
assert_equal Rational(2, 9), parse(JSON(Rational(2, 9)), :create_additions => true)
|
179
|
+
assert_equal Complex(2, 9), parse(JSON(Complex(2, 9)), :create_additions => true)
|
183
180
|
end
|
184
181
|
|
185
182
|
def test_bigdecimal
|
@@ -191,6 +188,6 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
191
188
|
o = OpenStruct.new
|
192
189
|
# XXX this won't work; o.foo = { :bar => true }
|
193
190
|
o.foo = { 'bar' => true }
|
194
|
-
assert_equal o,
|
191
|
+
assert_equal o, parse(JSON(o), :create_additions => true)
|
195
192
|
end
|
196
193
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
#frozen_string_literal: false
|
2
|
+
require 'test_helper'
|
3
|
+
require 'stringio'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
class JSONCommonInterfaceTest < Test::Unit::TestCase
|
7
|
+
include JSON
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@hash = {
|
11
|
+
'a' => 2,
|
12
|
+
'b' => 3.141,
|
13
|
+
'c' => 'c',
|
14
|
+
'd' => [ 1, "b", 3.14 ],
|
15
|
+
'e' => { 'foo' => 'bar' },
|
16
|
+
'g' => "\"\0\037",
|
17
|
+
'h' => 1000.0,
|
18
|
+
'i' => 0.001
|
19
|
+
}
|
20
|
+
@json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
|
21
|
+
'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_index
|
25
|
+
assert_equal @json, JSON[@hash]
|
26
|
+
assert_equal @hash, JSON[@json]
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_parser
|
30
|
+
assert_match /::Parser\z/, JSON.parser.name
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_generator
|
34
|
+
assert_match /::Generator\z/, JSON.generator.name
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_state
|
38
|
+
assert_match /::Generator::State\z/, JSON.state.name
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_create_id
|
42
|
+
assert_equal 'json_class', JSON.create_id
|
43
|
+
JSON.create_id = 'foo_bar'
|
44
|
+
assert_equal 'foo_bar', JSON.create_id
|
45
|
+
ensure
|
46
|
+
JSON.create_id = 'json_class'
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_deep_const_get
|
50
|
+
assert_raises(ArgumentError) { JSON.deep_const_get('Nix::Da') }
|
51
|
+
assert_equal File::SEPARATOR, JSON.deep_const_get('File::SEPARATOR')
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_parse
|
55
|
+
assert_equal [ 1, 2, 3, ], JSON.parse('[ 1, 2, 3 ]')
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_parse_bang
|
59
|
+
assert_equal [ 1, NaN, 3, ], JSON.parse!('[ 1, NaN, 3 ]')
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_generate
|
63
|
+
assert_equal '[1,2,3]', JSON.generate([ 1, 2, 3 ])
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_fast_generate
|
67
|
+
assert_equal '[1,2,3]', JSON.generate([ 1, 2, 3 ])
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_pretty_generate
|
71
|
+
assert_equal "[\n 1,\n 2,\n 3\n]", JSON.pretty_generate([ 1, 2, 3 ])
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_load
|
75
|
+
assert_equal @hash, JSON.load(@json)
|
76
|
+
tempfile = Tempfile.open('@json')
|
77
|
+
tempfile.write @json
|
78
|
+
tempfile.rewind
|
79
|
+
assert_equal @hash, JSON.load(tempfile)
|
80
|
+
stringio = StringIO.new(@json)
|
81
|
+
stringio.rewind
|
82
|
+
assert_equal @hash, JSON.load(stringio)
|
83
|
+
assert_equal nil, JSON.load(nil)
|
84
|
+
assert_equal nil, JSON.load('')
|
85
|
+
ensure
|
86
|
+
tempfile.close!
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_load_with_options
|
90
|
+
json = '{ "foo": NaN }'
|
91
|
+
assert JSON.load(json, nil, :allow_nan => true)['foo'].nan?
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_load_null
|
95
|
+
assert_equal nil, JSON.load(nil, nil, :allow_blank => true)
|
96
|
+
assert_raises(TypeError) { JSON.load(nil, nil, :allow_blank => false) }
|
97
|
+
assert_raises(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) }
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_dump
|
101
|
+
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
|
102
|
+
assert_equal too_deep, dump(eval(too_deep))
|
103
|
+
assert_kind_of String, Marshal.dump(eval(too_deep))
|
104
|
+
assert_raise(ArgumentError) { dump(eval(too_deep), 100) }
|
105
|
+
assert_raise(ArgumentError) { Marshal.dump(eval(too_deep), 100) }
|
106
|
+
assert_equal too_deep, dump(eval(too_deep), 101)
|
107
|
+
assert_kind_of String, Marshal.dump(eval(too_deep), 101)
|
108
|
+
output = StringIO.new
|
109
|
+
dump(eval(too_deep), output)
|
110
|
+
assert_equal too_deep, output.string
|
111
|
+
output = StringIO.new
|
112
|
+
dump(eval(too_deep), output, 101)
|
113
|
+
assert_equal too_deep, output.string
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_dump_should_modify_defaults
|
117
|
+
max_nesting = JSON.dump_default_options[:max_nesting]
|
118
|
+
dump([], StringIO.new, 10)
|
119
|
+
assert_equal max_nesting, JSON.dump_default_options[:max_nesting]
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_JSON
|
123
|
+
assert_equal @json, JSON(@hash)
|
124
|
+
assert_equal @hash, JSON(@json)
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#frozen_string_literal: false
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class JSONEncodingTest < Test::Unit::TestCase
|
6
|
+
include JSON
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@utf_8 = '"© ≠ €!"'
|
10
|
+
@ascii_8bit = @utf_8.dup.force_encoding('ascii-8bit')
|
11
|
+
@parsed = "© ≠ €!"
|
12
|
+
@generated = '"\u00a9 \u2260 \u20ac!"'
|
13
|
+
if String.method_defined?(:encode)
|
14
|
+
@utf_16_data = @parsed.encode('utf-16be', 'utf-8')
|
15
|
+
@utf_16be = @utf_8.encode('utf-16be', 'utf-8')
|
16
|
+
@utf_16le = @utf_8.encode('utf-16le', 'utf-8')
|
17
|
+
@utf_32be = @utf_8.encode('utf-32be', 'utf-8')
|
18
|
+
@utf_32le = @utf_8.encode('utf-32le', 'utf-8')
|
19
|
+
else
|
20
|
+
require 'iconv'
|
21
|
+
@utf_16_data, = Iconv.iconv('utf-16be', 'utf-8', @parsed)
|
22
|
+
@utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8)
|
23
|
+
@utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8)
|
24
|
+
@utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8)
|
25
|
+
@utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_parse
|
30
|
+
assert_equal @parsed, JSON.parse(@ascii_8bit)
|
31
|
+
assert_equal @parsed, JSON.parse(@utf_8)
|
32
|
+
assert_equal @parsed, JSON.parse(@utf_16be)
|
33
|
+
assert_equal @parsed, JSON.parse(@utf_16le)
|
34
|
+
assert_equal @parsed, JSON.parse(@utf_32be)
|
35
|
+
assert_equal @parsed, JSON.parse(@utf_32le)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_generate
|
39
|
+
assert_equal @generated, JSON.generate(@parsed, :ascii_only => true)
|
40
|
+
assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_unicode
|
44
|
+
assert_equal '""', ''.to_json
|
45
|
+
assert_equal '"\\b"', "\b".to_json
|
46
|
+
assert_equal '"\u0001"', 0x1.chr.to_json
|
47
|
+
assert_equal '"\u001f"', 0x1f.chr.to_json
|
48
|
+
assert_equal '" "', ' '.to_json
|
49
|
+
assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
|
50
|
+
utf8 = [ "© ≠ €! \01" ]
|
51
|
+
json = '["© ≠ €! \u0001"]'
|
52
|
+
assert_equal json, utf8.to_json(:ascii_only => false)
|
53
|
+
assert_equal utf8, parse(json)
|
54
|
+
json = '["\u00a9 \u2260 \u20ac! \u0001"]'
|
55
|
+
assert_equal json, utf8.to_json(:ascii_only => true)
|
56
|
+
assert_equal utf8, parse(json)
|
57
|
+
utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
|
58
|
+
json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]"
|
59
|
+
assert_equal utf8, parse(json)
|
60
|
+
assert_equal json, utf8.to_json(:ascii_only => false)
|
61
|
+
utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
|
62
|
+
assert_equal utf8, parse(json)
|
63
|
+
json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]"
|
64
|
+
assert_equal json, utf8.to_json(:ascii_only => true)
|
65
|
+
assert_equal utf8, parse(json)
|
66
|
+
utf8 = ['საქართველო']
|
67
|
+
json = '["საქართველო"]'
|
68
|
+
assert_equal json, utf8.to_json(:ascii_only => false)
|
69
|
+
json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]"
|
70
|
+
assert_equal json, utf8.to_json(:ascii_only => true)
|
71
|
+
assert_equal utf8, parse(json)
|
72
|
+
assert_equal '["Ã"]', generate(["Ã"], :ascii_only => false)
|
73
|
+
assert_equal '["\\u00c3"]', generate(["Ã"], :ascii_only => true)
|
74
|
+
assert_equal ["€"], parse('["\u20ac"]')
|
75
|
+
utf8 = ["\xf0\xa0\x80\x81"]
|
76
|
+
json = "[\"\xf0\xa0\x80\x81\"]"
|
77
|
+
assert_equal json, generate(utf8, :ascii_only => false)
|
78
|
+
assert_equal utf8, parse(json)
|
79
|
+
json = '["\ud840\udc01"]'
|
80
|
+
assert_equal json, generate(utf8, :ascii_only => true)
|
81
|
+
assert_equal utf8, parse(json)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_chars
|
85
|
+
(0..0x7f).each do |i|
|
86
|
+
json = '["\u%04x"]' % i
|
87
|
+
if RUBY_VERSION >= "1.9."
|
88
|
+
i = i.chr
|
89
|
+
end
|
90
|
+
assert_equal i, parse(json).first[0]
|
91
|
+
if i == ?\b
|
92
|
+
generated = generate(["" << i])
|
93
|
+
assert '["\b"]' == generated || '["\10"]' == generated
|
94
|
+
elsif [?\n, ?\r, ?\t, ?\f].include?(i)
|
95
|
+
assert_equal '[' << ('' << i).dump << ']', generate(["" << i])
|
96
|
+
elsif i.chr < 0x20.chr
|
97
|
+
assert_equal json, generate(["" << i])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
assert_raise(JSON::GeneratorError) do
|
101
|
+
generate(["\x80"], :ascii_only => true)
|
102
|
+
end
|
103
|
+
assert_equal "\302\200", parse('["\u0080"]').first
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#frozen_string_literal: false
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class JSONExtParserTest < Test::Unit::TestCase
|
5
|
+
if defined?(JSON::Ext::Parser)
|
6
|
+
def test_allocate
|
7
|
+
parser = JSON::Ext::Parser.new("{}")
|
8
|
+
assert_raise(TypeError, '[ruby-core:35079]') do
|
9
|
+
parser.__send__(:initialize, "{}")
|
10
|
+
end
|
11
|
+
parser = JSON::Ext::Parser.allocate
|
12
|
+
assert_raise(TypeError, '[ruby-core:35079]') { parser.source }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,12 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#frozen_string_literal: false
|
2
|
+
require 'test_helper'
|
3
3
|
|
4
|
-
|
5
|
-
require File.join(File.dirname(__FILE__), 'setup_variant')
|
6
|
-
|
7
|
-
class TestJSONFixtures < Test::Unit::TestCase
|
4
|
+
class JSONFixturesTest < Test::Unit::TestCase
|
8
5
|
def setup
|
9
|
-
fixtures = File.join(File.dirname(__FILE__), 'fixtures
|
6
|
+
fixtures = File.join(File.dirname(__FILE__), 'fixtures/{fail,pass}.json')
|
10
7
|
passed, failed = Dir[fixtures].partition { |f| f['pass'] }
|
11
8
|
@passed = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
|
12
9
|
@failed = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
|
@@ -26,7 +23,7 @@ class TestJSONFixtures < Test::Unit::TestCase
|
|
26
23
|
|
27
24
|
def test_failing
|
28
25
|
for name, source in @failed
|
29
|
-
|
26
|
+
assert_raise(JSON::ParserError, JSON::NestingError,
|
30
27
|
"Did not fail for fixture '#{name}': #{source.inspect}") do
|
31
28
|
JSON.parse(source)
|
32
29
|
end
|
@@ -2,10 +2,9 @@
|
|
2
2
|
# encoding: utf-8
|
3
3
|
# frozen_string_literal: false
|
4
4
|
|
5
|
-
require '
|
6
|
-
require File.join(File.dirname(__FILE__), 'setup_variant')
|
5
|
+
require 'test_helper'
|
7
6
|
|
8
|
-
class
|
7
|
+
class JSONGeneratorTest < Test::Unit::TestCase
|
9
8
|
include JSON
|
10
9
|
|
11
10
|
def setup
|
@@ -43,23 +42,23 @@ EOT
|
|
43
42
|
|
44
43
|
def test_generate
|
45
44
|
json = generate(@hash)
|
46
|
-
assert_equal(
|
45
|
+
assert_equal(parse(@json2), parse(json))
|
47
46
|
json = JSON[@hash]
|
48
|
-
assert_equal(
|
47
|
+
assert_equal(parse(@json2), parse(json))
|
49
48
|
parsed_json = parse(json)
|
50
49
|
assert_equal(@hash, parsed_json)
|
51
50
|
json = generate({1=>2})
|
52
51
|
assert_equal('{"1":2}', json)
|
53
52
|
parsed_json = parse(json)
|
54
53
|
assert_equal({"1"=>2}, parsed_json)
|
55
|
-
|
56
|
-
assert_equal '666', generate(666, :quirks_mode => true)
|
54
|
+
assert_equal '666', generate(666)
|
57
55
|
end
|
58
56
|
|
59
57
|
def test_generate_pretty
|
60
58
|
json = pretty_generate(@hash)
|
61
|
-
# hashes aren't (insertion) ordered on every ruby implementation
|
62
|
-
assert_equal(
|
59
|
+
# hashes aren't (insertion) ordered on every ruby implementation
|
60
|
+
# assert_equal(@json3, json)
|
61
|
+
assert_equal(parse(@json3), parse(json))
|
63
62
|
parsed_json = parse(json)
|
64
63
|
assert_equal(@hash, parsed_json)
|
65
64
|
json = pretty_generate({1=>2})
|
@@ -70,8 +69,7 @@ EOT
|
|
70
69
|
EOT
|
71
70
|
parsed_json = parse(json)
|
72
71
|
assert_equal({"1"=>2}, parsed_json)
|
73
|
-
|
74
|
-
assert_equal '666', pretty_generate(666, :quirks_mode => true)
|
72
|
+
assert_equal '666', pretty_generate(666)
|
75
73
|
end
|
76
74
|
|
77
75
|
def test_generate_custom
|
@@ -89,30 +87,26 @@ EOT
|
|
89
87
|
|
90
88
|
def test_fast_generate
|
91
89
|
json = fast_generate(@hash)
|
92
|
-
assert_equal(
|
90
|
+
assert_equal(parse(@json2), parse(json))
|
93
91
|
parsed_json = parse(json)
|
94
92
|
assert_equal(@hash, parsed_json)
|
95
93
|
json = fast_generate({1=>2})
|
96
94
|
assert_equal('{"1":2}', json)
|
97
95
|
parsed_json = parse(json)
|
98
96
|
assert_equal({"1"=>2}, parsed_json)
|
99
|
-
|
100
|
-
assert_equal '666', fast_generate(666, :quirks_mode => true)
|
97
|
+
assert_equal '666', fast_generate(666)
|
101
98
|
end
|
102
99
|
|
103
100
|
def test_own_state
|
104
101
|
state = State.new
|
105
102
|
json = generate(@hash, state)
|
106
|
-
assert_equal(
|
103
|
+
assert_equal(parse(@json2), parse(json))
|
107
104
|
parsed_json = parse(json)
|
108
105
|
assert_equal(@hash, parsed_json)
|
109
106
|
json = generate({1=>2}, state)
|
110
107
|
assert_equal('{"1":2}', json)
|
111
108
|
parsed_json = parse(json)
|
112
109
|
assert_equal({"1"=>2}, parsed_json)
|
113
|
-
assert_raise(GeneratorError) { generate(666, state) }
|
114
|
-
state.quirks_mode = true
|
115
|
-
assert state.quirks_mode?
|
116
110
|
assert_equal '666', generate(666, state)
|
117
111
|
end
|
118
112
|
|
@@ -124,12 +118,12 @@ EOT
|
|
124
118
|
assert s[:check_circular?]
|
125
119
|
h = { 1=>2 }
|
126
120
|
h[3] = h
|
127
|
-
|
128
|
-
|
121
|
+
assert_raise(JSON::NestingError) { generate(h) }
|
122
|
+
assert_raise(JSON::NestingError) { generate(h, s) }
|
129
123
|
s = JSON.state.new
|
130
124
|
a = [ 1, 2 ]
|
131
125
|
a << a
|
132
|
-
|
126
|
+
assert_raise(JSON::NestingError) { generate(a, s) }
|
133
127
|
assert s.check_circular?
|
134
128
|
assert s[:check_circular?]
|
135
129
|
end
|
@@ -141,7 +135,6 @@ EOT
|
|
141
135
|
:array_nl => "\n",
|
142
136
|
:ascii_only => false,
|
143
137
|
:buffer_initial_length => 1024,
|
144
|
-
:quirks_mode => false,
|
145
138
|
:depth => 0,
|
146
139
|
:indent => " ",
|
147
140
|
:max_nesting => 100,
|
@@ -158,7 +151,6 @@ EOT
|
|
158
151
|
:array_nl => "",
|
159
152
|
:ascii_only => false,
|
160
153
|
:buffer_initial_length => 1024,
|
161
|
-
:quirks_mode => false,
|
162
154
|
:depth => 0,
|
163
155
|
:indent => "",
|
164
156
|
:max_nesting => 100,
|
@@ -175,7 +167,6 @@ EOT
|
|
175
167
|
:array_nl => "",
|
176
168
|
:ascii_only => false,
|
177
169
|
:buffer_initial_length => 1024,
|
178
|
-
:quirks_mode => false,
|
179
170
|
:depth => 0,
|
180
171
|
:indent => "",
|
181
172
|
:max_nesting => 0,
|
@@ -186,34 +177,34 @@ EOT
|
|
186
177
|
end
|
187
178
|
|
188
179
|
def test_allow_nan
|
189
|
-
|
180
|
+
assert_raise(GeneratorError) { generate([JSON::NaN]) }
|
190
181
|
assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
|
191
|
-
|
192
|
-
|
182
|
+
assert_raise(GeneratorError) { fast_generate([JSON::NaN]) }
|
183
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
|
193
184
|
assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
|
194
|
-
|
185
|
+
assert_raise(GeneratorError) { generate([JSON::Infinity]) }
|
195
186
|
assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
|
196
|
-
|
197
|
-
|
187
|
+
assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) }
|
188
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
|
198
189
|
assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
|
199
|
-
|
190
|
+
assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
|
200
191
|
assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
|
201
|
-
|
202
|
-
|
192
|
+
assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
|
193
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
|
203
194
|
assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
|
204
195
|
end
|
205
196
|
|
206
197
|
def test_depth
|
207
198
|
ary = []; ary << ary
|
208
199
|
assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
|
209
|
-
|
200
|
+
assert_raise(JSON::NestingError) { generate(ary) }
|
210
201
|
assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
|
211
202
|
assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
|
212
|
-
|
203
|
+
assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
|
213
204
|
assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
|
214
205
|
s = JSON.state.new
|
215
206
|
assert_equal 0, s.depth
|
216
|
-
|
207
|
+
assert_raise(JSON::NestingError) { ary.to_json(s) }
|
217
208
|
assert_equal 100, s.depth
|
218
209
|
end
|
219
210
|
|
@@ -332,10 +323,47 @@ EOT
|
|
332
323
|
|
333
324
|
def test_json_generate
|
334
325
|
assert_raise JSON::GeneratorError do
|
335
|
-
assert_equal true,
|
326
|
+
assert_equal true, generate(["\xea"])
|
336
327
|
end
|
337
328
|
end
|
338
329
|
|
330
|
+
def test_nesting
|
331
|
+
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
|
332
|
+
too_deep_ary = eval too_deep
|
333
|
+
assert_raise(JSON::NestingError) { generate too_deep_ary }
|
334
|
+
assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
|
335
|
+
ok = generate too_deep_ary, :max_nesting => 101
|
336
|
+
assert_equal too_deep, ok
|
337
|
+
ok = generate too_deep_ary, :max_nesting => nil
|
338
|
+
assert_equal too_deep, ok
|
339
|
+
ok = generate too_deep_ary, :max_nesting => false
|
340
|
+
assert_equal too_deep, ok
|
341
|
+
ok = generate too_deep_ary, :max_nesting => 0
|
342
|
+
assert_equal too_deep, ok
|
343
|
+
end
|
344
|
+
|
345
|
+
def test_backslash
|
346
|
+
data = [ '\\.(?i:gif|jpe?g|png)$' ]
|
347
|
+
json = '["\\\\.(?i:gif|jpe?g|png)$"]'
|
348
|
+
assert_equal json, generate(data)
|
349
|
+
#
|
350
|
+
data = [ '\\"' ]
|
351
|
+
json = '["\\\\\""]'
|
352
|
+
assert_equal json, generate(data)
|
353
|
+
#
|
354
|
+
data = [ '/' ]
|
355
|
+
json = '["/"]'
|
356
|
+
assert_equal json, generate(data)
|
357
|
+
#
|
358
|
+
data = ['"']
|
359
|
+
json = '["\""]'
|
360
|
+
assert_equal json, generate(data)
|
361
|
+
#
|
362
|
+
data = ["'"]
|
363
|
+
json = '["\\\'"]'
|
364
|
+
assert_equal '["\'"]', generate(data)
|
365
|
+
end
|
366
|
+
|
339
367
|
def test_string_subclass
|
340
368
|
s = Class.new(String) do
|
341
369
|
def to_s; self; end
|