json 1.8.3 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +7 -10
- data/{CHANGES → CHANGES.md} +186 -90
- data/Gemfile +10 -6
- data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
- data/{README.rdoc → README.md} +184 -133
- data/Rakefile +33 -37
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +0 -3
- data/ext/json/ext/generator/generator.c +47 -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 +374 -459
- data/ext/json/ext/parser/parser.h +4 -5
- data/ext/json/ext/parser/parser.rl +133 -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 +132 -415
- 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 +3 -3
- 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/set.rb +29 -0
- 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} +32 -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 +472 -0
- data/tests/json_string_matching_test.rb +38 -0
- data/tests/{setup_variant.rb → test_helper.rb} +6 -0
- data/tools/diff.sh +18 -0
- data/tools/fuzz.rb +1 -9
- metadata +29 -47
- data/COPYING +0 -58
- data/COPYING-json-jruby +0 -57
- data/GPL +0 -340
- data/TODO +0 -1
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
- 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,16 +1,14 @@
|
|
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'
|
9
6
|
require 'json/add/bigdecimal'
|
10
7
|
require 'json/add/ostruct'
|
8
|
+
require 'json/add/set'
|
11
9
|
require 'date'
|
12
10
|
|
13
|
-
class
|
11
|
+
class JSONAdditionTest < Test::Unit::TestCase
|
14
12
|
include JSON
|
15
13
|
|
16
14
|
class A
|
@@ -64,7 +62,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
64
62
|
|
65
63
|
def to_json(*args)
|
66
64
|
{
|
67
|
-
'json_class' => '
|
65
|
+
'json_class' => 'JSONAdditionTest::Nix',
|
68
66
|
}.to_json(*args)
|
69
67
|
end
|
70
68
|
end
|
@@ -73,7 +71,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
73
71
|
a = A.new(666)
|
74
72
|
assert A.json_creatable?
|
75
73
|
json = generate(a)
|
76
|
-
a_again =
|
74
|
+
a_again = parse(json, :create_additions => true)
|
77
75
|
assert_kind_of a.class, a_again
|
78
76
|
assert_equal a, a_again
|
79
77
|
end
|
@@ -82,7 +80,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
82
80
|
a = A.new(666)
|
83
81
|
assert A.json_creatable?
|
84
82
|
json = generate(a)
|
85
|
-
a_hash =
|
83
|
+
a_hash = parse(json)
|
86
84
|
assert_kind_of Hash, a_hash
|
87
85
|
end
|
88
86
|
|
@@ -90,13 +88,13 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
90
88
|
a = A.new(666)
|
91
89
|
assert A.json_creatable?
|
92
90
|
json = generate(a)
|
93
|
-
a_again =
|
91
|
+
a_again = parse(json, :create_additions => true)
|
94
92
|
assert_kind_of a.class, a_again
|
95
93
|
assert_equal a, a_again
|
96
|
-
a_hash =
|
94
|
+
a_hash = parse(json, :create_additions => false)
|
97
95
|
assert_kind_of Hash, a_hash
|
98
96
|
assert_equal(
|
99
|
-
{"args"=>[666], "json_class"=>"
|
97
|
+
{"args"=>[666], "json_class"=>"JSONAdditionTest::A"}.sort_by { |k,| k },
|
100
98
|
a_hash.sort_by { |k,| k }
|
101
99
|
)
|
102
100
|
end
|
@@ -105,14 +103,14 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
105
103
|
b = B.new
|
106
104
|
assert !B.json_creatable?
|
107
105
|
json = generate(b)
|
108
|
-
assert_equal({ "json_class"=>"
|
106
|
+
assert_equal({ "json_class"=>"JSONAdditionTest::B" }, parse(json))
|
109
107
|
end
|
110
108
|
|
111
109
|
def test_extended_json_fail2
|
112
110
|
c = C.new
|
113
111
|
assert !C.json_creatable?
|
114
112
|
json = generate(c)
|
115
|
-
|
113
|
+
assert_raise(ArgumentError, NameError) { parse(json, :create_additions => true) }
|
116
114
|
end
|
117
115
|
|
118
116
|
def test_raw_strings
|
@@ -130,7 +128,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
130
128
|
assert_match(/\A\{.*\}\z/, json)
|
131
129
|
assert_match(/"json_class":"String"/, json)
|
132
130
|
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 =
|
131
|
+
raw_again = parse(json, :create_additions => true)
|
134
132
|
assert_equal raw, raw_again
|
135
133
|
end
|
136
134
|
|
@@ -151,7 +149,7 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
151
149
|
assert_equal s, JSON(JSON(s), :create_additions => true)
|
152
150
|
struct = Struct.new :foo, :bar
|
153
151
|
s = struct.new 4711, 'foot'
|
154
|
-
|
152
|
+
assert_raise(JSONError) { JSON(s) }
|
155
153
|
begin
|
156
154
|
raise TypeError, "test me"
|
157
155
|
rescue TypeError => e
|
@@ -167,19 +165,19 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
167
165
|
|
168
166
|
def test_utc_datetime
|
169
167
|
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,
|
168
|
+
d = DateTime.parse(now.to_s, :create_additions => true) # usual case
|
169
|
+
assert_equal d, parse(d.to_json, :create_additions => true)
|
170
|
+
d = DateTime.parse(now.utc.to_s) # of = 0
|
171
|
+
assert_equal d, parse(d.to_json, :create_additions => true)
|
174
172
|
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1,24))
|
175
|
-
assert_equal d,
|
173
|
+
assert_equal d, parse(d.to_json, :create_additions => true)
|
176
174
|
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12,24))
|
177
|
-
assert_equal d,
|
175
|
+
assert_equal d, parse(d.to_json, :create_additions => true)
|
178
176
|
end
|
179
177
|
|
180
178
|
def test_rational_complex
|
181
|
-
assert_equal Rational(2, 9),
|
182
|
-
assert_equal Complex(2, 9),
|
179
|
+
assert_equal Rational(2, 9), parse(JSON(Rational(2, 9)), :create_additions => true)
|
180
|
+
assert_equal Complex(2, 9), parse(JSON(Complex(2, 9)), :create_additions => true)
|
183
181
|
end
|
184
182
|
|
185
183
|
def test_bigdecimal
|
@@ -191,6 +189,15 @@ class TestJSONAddition < Test::Unit::TestCase
|
|
191
189
|
o = OpenStruct.new
|
192
190
|
# XXX this won't work; o.foo = { :bar => true }
|
193
191
|
o.foo = { 'bar' => true }
|
194
|
-
assert_equal o,
|
192
|
+
assert_equal o, parse(JSON(o), :create_additions => true)
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_set
|
196
|
+
s = Set.new([:a, :b, :c, :a])
|
197
|
+
assert_equal s, JSON.parse(JSON(s), :create_additions => true)
|
198
|
+
ss = SortedSet.new([:d, :b, :a, :c])
|
199
|
+
ss_again = JSON.parse(JSON(ss), :create_additions => true)
|
200
|
+
assert_kind_of ss.class, ss_again
|
201
|
+
assert_equal ss, ss_again
|
195
202
|
end
|
196
203
|
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
|