json 1.8.3 → 2.1.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 +1 -0
- data/.travis.yml +3 -10
- data/{CHANGES → CHANGES.md} +183 -90
- data/Gemfile +11 -5
- data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
- data/{README.rdoc → README.md} +147 -113
- data/Rakefile +32 -36
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +0 -3
- data/ext/json/ext/generator/generator.c +46 -61
- data/ext/json/ext/generator/generator.h +7 -2
- data/ext/json/ext/parser/extconf.rb +3 -0
- data/ext/json/ext/parser/parser.c +353 -460
- data/ext/json/ext/parser/parser.h +4 -5
- data/ext/json/ext/parser/parser.rl +111 -181
- data/ext/json/extconf.rb +0 -1
- data/java/src/json/ext/ByteListTranscoder.java +1 -2
- data/java/src/json/ext/Generator.java +11 -12
- data/java/src/json/ext/GeneratorMethods.java +1 -2
- data/java/src/json/ext/GeneratorService.java +1 -2
- data/java/src/json/ext/GeneratorState.java +3 -56
- data/java/src/json/ext/OptionsReader.java +2 -3
- data/java/src/json/ext/Parser.java +135 -418
- data/java/src/json/ext/Parser.rl +48 -124
- data/java/src/json/ext/ParserService.java +1 -2
- data/java/src/json/ext/RuntimeInfo.java +1 -6
- data/java/src/json/ext/StringDecoder.java +1 -2
- data/java/src/json/ext/StringEncoder.java +5 -0
- data/java/src/json/ext/Utils.java +1 -2
- data/json-java.gemspec +15 -0
- data/json.gemspec +0 -0
- data/json_pure.gemspec +24 -26
- 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 +2 -2
- 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/generator.rb +61 -125
- data/lib/json/pure/parser.rb +33 -81
- data/lib/json/pure.rb +2 -8
- data/lib/json/version.rb +2 -1
- data/lib/json.rb +1 -0
- 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 +107 -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} +79 -39
- data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
- data/tests/json_parser_test.rb +471 -0
- data/tests/json_string_matching_test.rb +38 -0
- data/tests/{setup_variant.rb → test_helper.rb} +10 -0
- data/tools/diff.sh +18 -0
- data/tools/fuzz.rb +1 -9
- metadata +28 -43
- data/COPYING +0 -58
- data/COPYING-json-jruby +0 -57
- data/GPL +0 -340
- data/TODO +0 -1
- data/tests/fixtures/fail1.json +0 -1
- data/tests/test_json.rb +0 -553
- 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_raise(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_raise(TypeError) { JSON.load(nil, nil, :allow_blank => false) }
|
97
|
+
assert_raise(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,107 @@
|
|
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
|
+
assert_raise(JSON::ParserError) { parse('"\u"') }
|
83
|
+
assert_raise(JSON::ParserError) { parse('"\ud800"') }
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_chars
|
87
|
+
(0..0x7f).each do |i|
|
88
|
+
json = '["\u%04x"]' % i
|
89
|
+
if RUBY_VERSION >= "1.9."
|
90
|
+
i = i.chr
|
91
|
+
end
|
92
|
+
assert_equal i, parse(json).first[0]
|
93
|
+
if i == ?\b
|
94
|
+
generated = generate(["" << i])
|
95
|
+
assert '["\b"]' == generated || '["\10"]' == generated
|
96
|
+
elsif [?\n, ?\r, ?\t, ?\f].include?(i)
|
97
|
+
assert_equal '[' << ('' << i).dump << ']', generate(["" << i])
|
98
|
+
elsif i.chr < 0x20.chr
|
99
|
+
assert_equal json, generate(["" << i])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
assert_raise(JSON::GeneratorError) do
|
103
|
+
generate(["\x80"], :ascii_only => true)
|
104
|
+
end
|
105
|
+
assert_equal "\302\200", parse('["\u0080"]').first
|
106
|
+
end
|
107
|
+
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
|
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: utf-8
|
3
|
+
# frozen_string_literal: false
|
3
4
|
|
4
|
-
require '
|
5
|
-
require File.join(File.dirname(__FILE__), 'setup_variant')
|
5
|
+
require 'test_helper'
|
6
6
|
|
7
|
-
class
|
7
|
+
class JSONGeneratorTest < Test::Unit::TestCase
|
8
8
|
include JSON
|
9
9
|
|
10
10
|
def setup
|
@@ -42,23 +42,23 @@ EOT
|
|
42
42
|
|
43
43
|
def test_generate
|
44
44
|
json = generate(@hash)
|
45
|
-
assert_equal(
|
45
|
+
assert_equal(parse(@json2), parse(json))
|
46
46
|
json = JSON[@hash]
|
47
|
-
assert_equal(
|
47
|
+
assert_equal(parse(@json2), parse(json))
|
48
48
|
parsed_json = parse(json)
|
49
49
|
assert_equal(@hash, parsed_json)
|
50
50
|
json = generate({1=>2})
|
51
51
|
assert_equal('{"1":2}', json)
|
52
52
|
parsed_json = parse(json)
|
53
53
|
assert_equal({"1"=>2}, parsed_json)
|
54
|
-
|
55
|
-
assert_equal '666', generate(666, :quirks_mode => true)
|
54
|
+
assert_equal '666', generate(666)
|
56
55
|
end
|
57
56
|
|
58
57
|
def test_generate_pretty
|
59
58
|
json = pretty_generate(@hash)
|
60
|
-
# hashes aren't (insertion) ordered on every ruby implementation
|
61
|
-
assert_equal(
|
59
|
+
# hashes aren't (insertion) ordered on every ruby implementation
|
60
|
+
# assert_equal(@json3, json)
|
61
|
+
assert_equal(parse(@json3), parse(json))
|
62
62
|
parsed_json = parse(json)
|
63
63
|
assert_equal(@hash, parsed_json)
|
64
64
|
json = pretty_generate({1=>2})
|
@@ -69,8 +69,7 @@ EOT
|
|
69
69
|
EOT
|
70
70
|
parsed_json = parse(json)
|
71
71
|
assert_equal({"1"=>2}, parsed_json)
|
72
|
-
|
73
|
-
assert_equal '666', pretty_generate(666, :quirks_mode => true)
|
72
|
+
assert_equal '666', pretty_generate(666)
|
74
73
|
end
|
75
74
|
|
76
75
|
def test_generate_custom
|
@@ -88,30 +87,26 @@ EOT
|
|
88
87
|
|
89
88
|
def test_fast_generate
|
90
89
|
json = fast_generate(@hash)
|
91
|
-
assert_equal(
|
90
|
+
assert_equal(parse(@json2), parse(json))
|
92
91
|
parsed_json = parse(json)
|
93
92
|
assert_equal(@hash, parsed_json)
|
94
93
|
json = fast_generate({1=>2})
|
95
94
|
assert_equal('{"1":2}', json)
|
96
95
|
parsed_json = parse(json)
|
97
96
|
assert_equal({"1"=>2}, parsed_json)
|
98
|
-
|
99
|
-
assert_equal '666', fast_generate(666, :quirks_mode => true)
|
97
|
+
assert_equal '666', fast_generate(666)
|
100
98
|
end
|
101
99
|
|
102
100
|
def test_own_state
|
103
101
|
state = State.new
|
104
102
|
json = generate(@hash, state)
|
105
|
-
assert_equal(
|
103
|
+
assert_equal(parse(@json2), parse(json))
|
106
104
|
parsed_json = parse(json)
|
107
105
|
assert_equal(@hash, parsed_json)
|
108
106
|
json = generate({1=>2}, state)
|
109
107
|
assert_equal('{"1":2}', json)
|
110
108
|
parsed_json = parse(json)
|
111
109
|
assert_equal({"1"=>2}, parsed_json)
|
112
|
-
assert_raise(GeneratorError) { generate(666, state) }
|
113
|
-
state.quirks_mode = true
|
114
|
-
assert state.quirks_mode?
|
115
110
|
assert_equal '666', generate(666, state)
|
116
111
|
end
|
117
112
|
|
@@ -123,12 +118,12 @@ EOT
|
|
123
118
|
assert s[:check_circular?]
|
124
119
|
h = { 1=>2 }
|
125
120
|
h[3] = h
|
126
|
-
|
127
|
-
|
121
|
+
assert_raise(JSON::NestingError) { generate(h) }
|
122
|
+
assert_raise(JSON::NestingError) { generate(h, s) }
|
128
123
|
s = JSON.state.new
|
129
124
|
a = [ 1, 2 ]
|
130
125
|
a << a
|
131
|
-
|
126
|
+
assert_raise(JSON::NestingError) { generate(a, s) }
|
132
127
|
assert s.check_circular?
|
133
128
|
assert s[:check_circular?]
|
134
129
|
end
|
@@ -140,7 +135,6 @@ EOT
|
|
140
135
|
:array_nl => "\n",
|
141
136
|
:ascii_only => false,
|
142
137
|
:buffer_initial_length => 1024,
|
143
|
-
:quirks_mode => false,
|
144
138
|
:depth => 0,
|
145
139
|
:indent => " ",
|
146
140
|
:max_nesting => 100,
|
@@ -157,7 +151,6 @@ EOT
|
|
157
151
|
:array_nl => "",
|
158
152
|
:ascii_only => false,
|
159
153
|
:buffer_initial_length => 1024,
|
160
|
-
:quirks_mode => false,
|
161
154
|
:depth => 0,
|
162
155
|
:indent => "",
|
163
156
|
:max_nesting => 100,
|
@@ -174,7 +167,6 @@ EOT
|
|
174
167
|
:array_nl => "",
|
175
168
|
:ascii_only => false,
|
176
169
|
:buffer_initial_length => 1024,
|
177
|
-
:quirks_mode => false,
|
178
170
|
:depth => 0,
|
179
171
|
:indent => "",
|
180
172
|
:max_nesting => 0,
|
@@ -185,34 +177,34 @@ EOT
|
|
185
177
|
end
|
186
178
|
|
187
179
|
def test_allow_nan
|
188
|
-
|
180
|
+
assert_raise(GeneratorError) { generate([JSON::NaN]) }
|
189
181
|
assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
|
190
|
-
|
191
|
-
|
182
|
+
assert_raise(GeneratorError) { fast_generate([JSON::NaN]) }
|
183
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
|
192
184
|
assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
|
193
|
-
|
185
|
+
assert_raise(GeneratorError) { generate([JSON::Infinity]) }
|
194
186
|
assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
|
195
|
-
|
196
|
-
|
187
|
+
assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) }
|
188
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
|
197
189
|
assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
|
198
|
-
|
190
|
+
assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
|
199
191
|
assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
|
200
|
-
|
201
|
-
|
192
|
+
assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
|
193
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
|
202
194
|
assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
|
203
195
|
end
|
204
196
|
|
205
197
|
def test_depth
|
206
198
|
ary = []; ary << ary
|
207
199
|
assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
|
208
|
-
|
200
|
+
assert_raise(JSON::NestingError) { generate(ary) }
|
209
201
|
assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
|
210
202
|
assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
|
211
|
-
|
203
|
+
assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
|
212
204
|
assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
|
213
205
|
s = JSON.state.new
|
214
206
|
assert_equal 0, s.depth
|
215
|
-
|
207
|
+
assert_raise(JSON::NestingError) { ary.to_json(s) }
|
216
208
|
assert_equal 100, s.depth
|
217
209
|
end
|
218
210
|
|
@@ -285,12 +277,13 @@ EOT
|
|
285
277
|
if defined?(JSON::Ext::Generator)
|
286
278
|
def test_broken_bignum # [ruby-core:38867]
|
287
279
|
pid = fork do
|
288
|
-
|
280
|
+
x = 1 << 64
|
281
|
+
x.class.class_eval do
|
289
282
|
def to_s
|
290
283
|
end
|
291
284
|
end
|
292
285
|
begin
|
293
|
-
JSON::Ext::Generator::State.new.generate(
|
286
|
+
JSON::Ext::Generator::State.new.generate(x)
|
294
287
|
exit 1
|
295
288
|
rescue TypeError
|
296
289
|
exit 0
|
@@ -331,7 +324,54 @@ EOT
|
|
331
324
|
|
332
325
|
def test_json_generate
|
333
326
|
assert_raise JSON::GeneratorError do
|
334
|
-
assert_equal true,
|
327
|
+
assert_equal true, generate(["\xea"])
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_nesting
|
332
|
+
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
|
333
|
+
too_deep_ary = eval too_deep
|
334
|
+
assert_raise(JSON::NestingError) { generate too_deep_ary }
|
335
|
+
assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
|
336
|
+
ok = generate too_deep_ary, :max_nesting => 101
|
337
|
+
assert_equal too_deep, ok
|
338
|
+
ok = generate too_deep_ary, :max_nesting => nil
|
339
|
+
assert_equal too_deep, ok
|
340
|
+
ok = generate too_deep_ary, :max_nesting => false
|
341
|
+
assert_equal too_deep, ok
|
342
|
+
ok = generate too_deep_ary, :max_nesting => 0
|
343
|
+
assert_equal too_deep, ok
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_backslash
|
347
|
+
data = [ '\\.(?i:gif|jpe?g|png)$' ]
|
348
|
+
json = '["\\\\.(?i:gif|jpe?g|png)$"]'
|
349
|
+
assert_equal json, generate(data)
|
350
|
+
#
|
351
|
+
data = [ '\\"' ]
|
352
|
+
json = '["\\\\\""]'
|
353
|
+
assert_equal json, generate(data)
|
354
|
+
#
|
355
|
+
data = [ '/' ]
|
356
|
+
json = '["/"]'
|
357
|
+
assert_equal json, generate(data)
|
358
|
+
#
|
359
|
+
data = ['"']
|
360
|
+
json = '["\""]'
|
361
|
+
assert_equal json, generate(data)
|
362
|
+
#
|
363
|
+
data = ["'"]
|
364
|
+
json = '["\\\'"]'
|
365
|
+
assert_equal '["\'"]', generate(data)
|
366
|
+
end
|
367
|
+
|
368
|
+
def test_string_subclass
|
369
|
+
s = Class.new(String) do
|
370
|
+
def to_s; self; end
|
371
|
+
undef to_json
|
372
|
+
end
|
373
|
+
assert_nothing_raised(SystemStackError) do
|
374
|
+
assert_equal '["foo"]', JSON.generate([s.new('foo')])
|
335
375
|
end
|
336
376
|
end
|
337
377
|
end
|