json_pure 1.8.6 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +18 -31
- 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
|