oj 3.13.11 → 3.15.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +74 -0
- data/README.md +4 -2
- data/ext/oj/buf.h +11 -6
- data/ext/oj/cache.c +25 -24
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +8 -6
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +17 -24
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +17 -44
- data/ext/oj/custom.c +70 -141
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +128 -118
- data/ext/oj/dump.h +12 -8
- data/ext/oj/dump_compat.c +564 -641
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +70 -199
- data/ext/oj/dump_strict.c +22 -46
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +14 -5
- data/ext/oj/fast.c +75 -103
- data/ext/oj/intern.c +52 -50
- data/ext/oj/intern.h +4 -8
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +75 -47
- data/ext/oj/object.c +49 -66
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +140 -99
- data/ext/oj/oj.h +80 -51
- data/ext/oj/parse.c +162 -184
- data/ext/oj/parse.h +7 -10
- data/ext/oj/parser.c +89 -34
- data/ext/oj/parser.h +18 -7
- data/ext/oj/rails.c +82 -146
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +11 -12
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +20 -31
- data/ext/oj/saj2.c +329 -93
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +26 -70
- data/ext/oj/stream_writer.c +12 -22
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +21 -21
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +105 -150
- data/ext/oj/usual.h +68 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +31 -68
- data/lib/oj/active_support_helper.rb +0 -1
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +4 -2
- data/lib/oj/mimic.rb +4 -2
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +9 -6
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Compatibility.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +10 -0
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
- data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
- data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
- data/test/files.rb +15 -15
- data/test/foo.rb +9 -71
- data/test/helper.rb +11 -8
- data/test/isolated/shared.rb +3 -2
- data/test/json_gem/json_addition_test.rb +2 -2
- data/test/json_gem/json_common_interface_test.rb +4 -4
- data/test/json_gem/json_encoding_test.rb +0 -0
- data/test/json_gem/json_ext_parser_test.rb +1 -0
- data/test/json_gem/json_fixtures_test.rb +3 -2
- data/test/json_gem/json_generator_test.rb +48 -36
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +54 -47
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/json_gem/test_helper.rb +7 -3
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +50 -0
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -69
- data/test/perf_once.rb +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- data/test/sample/change.rb +0 -1
- data/test/sample/dir.rb +0 -1
- data/test/sample/doc.rb +0 -1
- data/test/sample/file.rb +0 -1
- data/test/sample/group.rb +0 -1
- data/test/sample/hasprops.rb +0 -1
- data/test/sample/layer.rb +0 -1
- data/test/sample/rect.rb +0 -1
- data/test/sample/shape.rb +0 -1
- data/test/sample/text.rb +0 -1
- data/test/sample.rb +16 -16
- data/test/sample_json.rb +8 -8
- data/test/test_compat.rb +76 -42
- data/test/test_custom.rb +72 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +86 -90
- data/test/test_file.rb +41 -30
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +85 -96
- data/test/test_parser.rb +6 -22
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +115 -23
- data/test/test_parser_usual.rb +6 -6
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +30 -32
- data/test/test_various.rb +147 -99
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -4
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +33 -144
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/bar.rb +0 -16
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/test/foo.rb
CHANGED
@@ -1,77 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
$LOAD_PATH << '.'
|
5
|
+
$LOAD_PATH << File.join(__dir__, '../lib')
|
6
|
+
$LOAD_PATH << File.join(__dir__, '../ext')
|
6
7
|
|
7
|
-
require
|
8
|
-
require "socket"
|
9
|
-
require 'io/nonblock'
|
8
|
+
require 'oj'
|
10
9
|
|
11
|
-
=
|
12
|
-
#pid = spawn("nc -d 0.1 -l 5000", out: "/dev/null")
|
13
|
-
pid = spawn("nc -i 1 -l 7777", out: "/dev/null")
|
14
|
-
at_exit { Process.kill 9, pid }
|
15
|
-
sleep 0.2
|
16
|
-
s = Socket.tcp("localhost", 7777)
|
17
|
-
#s.nonblock = false
|
18
|
-
1_000_000.times do |x|
|
19
|
-
Oj.to_stream(s, { x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]})
|
20
|
-
end
|
21
|
-
=end
|
10
|
+
GC.stress = true
|
22
11
|
|
23
|
-
|
24
|
-
IO.pipe do |r, w|
|
25
|
-
if fork
|
26
|
-
r.close
|
27
|
-
#w.nonblock = false
|
28
|
-
1_000_000.times do |i|
|
29
|
-
begin
|
30
|
-
Oj.to_stream(w, { x: i})
|
31
|
-
rescue IOError => e
|
32
|
-
puts "*** #{i} raised #{e.class}: #{e}"
|
33
|
-
IO.select(nil, [w])
|
34
|
-
retry
|
35
|
-
end
|
36
|
-
w.puts
|
37
|
-
end
|
38
|
-
else
|
39
|
-
w.close
|
40
|
-
sleep(0.1)
|
41
|
-
r.each_line { |b|
|
42
|
-
#print b
|
43
|
-
}
|
44
|
-
r.close
|
45
|
-
Process.exit(0)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
=end
|
12
|
+
Oj.mimic_JSON
|
49
13
|
|
50
|
-
|
51
|
-
|
52
|
-
r.close
|
53
|
-
#w.nonblock = false
|
54
|
-
a = []
|
55
|
-
10_000.times do |i|
|
56
|
-
a << i
|
57
|
-
end
|
58
|
-
begin
|
59
|
-
Oj.to_stream(w, a, indent: 2)
|
60
|
-
rescue IOError => e
|
61
|
-
puts "*** raised #{e.class}: #{e}"
|
62
|
-
puts "*** fileno: #{w.fileno}"
|
63
|
-
puts "*** is an IO?: #{w.kind_of?(IO)}"
|
64
|
-
IO.select(nil, [w])
|
65
|
-
retry
|
66
|
-
end
|
67
|
-
w.puts
|
68
|
-
else
|
69
|
-
w.close
|
70
|
-
sleep(0.5)
|
71
|
-
r.each_line { |b|
|
72
|
-
#print b
|
73
|
-
}
|
74
|
-
r.close
|
75
|
-
Process.exit(0)
|
76
|
-
end
|
77
|
-
end
|
14
|
+
Oj.add_to_json(Hash)
|
15
|
+
pp JSON('{ "a": 1, "b": 2 }', :object_class => JSON::GenericObject)
|
data/test/helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
3
|
# Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is
|
4
4
|
# required. That can be set in the RUBYOPT environment variable.
|
5
5
|
# export RUBYOPT=-w
|
@@ -15,22 +15,25 @@ require 'minitest/autorun'
|
|
15
15
|
require 'stringio'
|
16
16
|
require 'date'
|
17
17
|
require 'bigdecimal'
|
18
|
-
require 'pp'
|
19
18
|
require 'oj'
|
20
19
|
|
21
|
-
|
22
|
-
if defined?(GC.verify_compaction_references) == 'method'
|
20
|
+
def verify_gc_compaction
|
23
21
|
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
24
22
|
# move objects around, helping to find object movement bugs.
|
25
|
-
GC.verify_compaction_references
|
23
|
+
if defined?(GC.verify_compaction_references) == 'method' && RbConfig::CONFIG['host_os'] !~ /(mingw|mswin)/
|
24
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0')
|
25
|
+
GC.verify_compaction_references(expand_heap: true, toward: :empty)
|
26
|
+
else
|
27
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
28
|
+
end
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
|
-
|
29
32
|
$ruby = RUBY_DESCRIPTION.split(' ')[0]
|
30
33
|
$ruby = 'ree' if 'ruby' == $ruby && RUBY_DESCRIPTION.include?('Ruby Enterprise Edition')
|
31
34
|
|
32
35
|
class Range
|
33
|
-
def to_hash
|
34
|
-
{ 'begin' => self.begin, 'end' => self.end, 'exclude_end' =>
|
36
|
+
def to_hash
|
37
|
+
{ 'begin' => self.begin, 'end' => self.end, 'exclude_end' => exclude_end? }
|
35
38
|
end
|
36
39
|
end
|
data/test/isolated/shared.rb
CHANGED
@@ -21,7 +21,7 @@ class SharedMimicTest < Minitest::Test
|
|
21
21
|
alias == eql?
|
22
22
|
|
23
23
|
def as_json()
|
24
|
-
{"json_class" => self.class.to_s,"x" => @x,"y" => @y}
|
24
|
+
{"json_class" => self.class.to_s, "x" => @x, "y" => @y}
|
25
25
|
end
|
26
26
|
|
27
27
|
def self.json_create(h)
|
@@ -207,7 +207,6 @@ class SharedMimicTest < Minitest::Test
|
|
207
207
|
--],#
|
208
208
|
--"a"~:*1#
|
209
209
|
}} == json)
|
210
|
-
|
211
210
|
end
|
212
211
|
|
213
212
|
# fast_generate
|
@@ -261,6 +260,8 @@ class SharedMimicTest < Minitest::Test
|
|
261
260
|
obj = JSON.parse(json, :create_additions => true)
|
262
261
|
JSON.create_id = 'json_class'
|
263
262
|
assert_equal(jam, obj)
|
263
|
+
|
264
|
+
assert_nothing_raised { JSON.create_id = nil }
|
264
265
|
end
|
265
266
|
def test_parse_bang
|
266
267
|
json = %{{"a":1,"b":[true,false]}}
|
@@ -191,9 +191,9 @@ class JSONAdditionTest < Test::Unit::TestCase
|
|
191
191
|
assert_equal d, JSON.parse(d.to_json, :create_additions => true)
|
192
192
|
d = DateTime.parse(now.utc.to_s) # of = 0
|
193
193
|
assert_equal d, JSON.parse(d.to_json, :create_additions => true)
|
194
|
-
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1,24))
|
194
|
+
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1, 24))
|
195
195
|
assert_equal d, JSON.parse(d.to_json, :create_additions => true)
|
196
|
-
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12,24))
|
196
|
+
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12, 24))
|
197
197
|
assert_equal d, JSON.parse(d.to_json, :create_additions => true)
|
198
198
|
end
|
199
199
|
|
@@ -29,7 +29,7 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
|
|
29
29
|
#@json = '{"a":2,"b":5.23683071,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
|
30
30
|
#'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
|
31
31
|
@json = '{"a":2,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
|
32
|
-
|
32
|
+
'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_index
|
@@ -43,15 +43,15 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
|
|
43
43
|
# functionality and perform better.
|
44
44
|
|
45
45
|
def test_parser
|
46
|
-
assert_match
|
46
|
+
assert_match(/::Parser\z/, JSON.parser.name)
|
47
47
|
end
|
48
48
|
|
49
49
|
def test_generator
|
50
|
-
assert_match
|
50
|
+
assert_match(/::Generator\z/, JSON.generator.name)
|
51
51
|
end
|
52
52
|
|
53
53
|
def test_state
|
54
|
-
assert_match
|
54
|
+
assert_match(/::Generator::State\z/, JSON.state.name)
|
55
55
|
end
|
56
56
|
|
57
57
|
# This doesn't have anything to do with JSON parsing or generation. It seems
|
File without changes
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# encoding: UTF-8
|
3
3
|
|
4
4
|
#frozen_string_literal: false
|
5
|
+
|
5
6
|
require 'json_gem/test_helper'
|
6
7
|
|
7
8
|
class JSONFixturesTest < Test::Unit::TestCase
|
@@ -16,7 +17,7 @@ class JSONFixturesTest < Test::Unit::TestCase
|
|
16
17
|
for name, source in @passed
|
17
18
|
begin
|
18
19
|
assert JSON.parse(source),
|
19
|
-
|
20
|
+
"Did not pass for fixture '#{name}': #{source.inspect}"
|
20
21
|
rescue => e
|
21
22
|
warn "\nCaught #{e.class}(#{e}) for fixture '#{name}': #{source.inspect}\n#{e.backtrace * "\n"}"
|
22
23
|
raise e
|
@@ -27,7 +28,7 @@ class JSONFixturesTest < Test::Unit::TestCase
|
|
27
28
|
def test_failing
|
28
29
|
for name, source in @failed
|
29
30
|
assert_raise(JSON::ParserError, JSON::NestingError,
|
30
|
-
|
31
|
+
"Did not fail for fixture '#{name}': #{source.inspect}") do
|
31
32
|
JSON.parse(source)
|
32
33
|
end
|
33
34
|
end
|
@@ -22,24 +22,24 @@ class JSONGeneratorTest < Test::Unit::TestCase
|
|
22
22
|
}
|
23
23
|
@json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
|
24
24
|
'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
|
25
|
-
@json3 =
|
26
|
-
{
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
}
|
42
|
-
EOT
|
25
|
+
@json3 = <<~'EOT'.chomp
|
26
|
+
{
|
27
|
+
"a": 2,
|
28
|
+
"b": 3.141,
|
29
|
+
"c": "c",
|
30
|
+
"d": [
|
31
|
+
1,
|
32
|
+
"b",
|
33
|
+
3.14
|
34
|
+
],
|
35
|
+
"e": {
|
36
|
+
"foo": "bar"
|
37
|
+
},
|
38
|
+
"g": "\"\u0000\u001f",
|
39
|
+
"h": 1000.0,
|
40
|
+
"i": 0.001
|
41
|
+
}
|
42
|
+
EOT
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_generate
|
@@ -64,27 +64,29 @@ EOT
|
|
64
64
|
parsed_json = JSON.parse(json)
|
65
65
|
assert_equal(@hash, parsed_json)
|
66
66
|
json = JSON.pretty_generate({1=>2})
|
67
|
-
assert_equal(
|
68
|
-
{
|
69
|
-
|
70
|
-
}
|
71
|
-
EOT
|
67
|
+
assert_equal(<<~'EOT'.chomp, json)
|
68
|
+
{
|
69
|
+
"1": 2
|
70
|
+
}
|
71
|
+
EOT
|
72
72
|
parsed_json = JSON.parse(json)
|
73
73
|
assert_equal({"1"=>2}, parsed_json)
|
74
74
|
assert_equal '666', JSON.pretty_generate(666)
|
75
|
+
json_nil_opts = JSON.pretty_generate({1=>2}, nil)
|
76
|
+
assert_equal json, json_nil_opts
|
75
77
|
end
|
76
78
|
|
77
79
|
def test_generate_custom
|
78
80
|
state = JSON::State.new(:space_before => " ", :space => " ", :indent => "<i>", :object_nl => "\n", :array_nl => "<a_nl>")
|
79
|
-
json = JSON.generate({1=>{2=>3,4=>[5,6]}}, state)
|
80
|
-
assert_equal(
|
81
|
-
{
|
82
|
-
<i>"1" : {
|
83
|
-
<i><i>"2" : 3,
|
84
|
-
<i><i>"4" : [<a_nl><i><i><i>5,<a_nl><i><i><i>6<a_nl><i><i>]
|
85
|
-
<i>}
|
86
|
-
}
|
87
|
-
EOT
|
81
|
+
json = JSON.generate({1=>{2=>3, 4=>[5, 6]}}, state)
|
82
|
+
assert_equal(<<~'EOT'.chomp, json)
|
83
|
+
{
|
84
|
+
<i>"1" : {
|
85
|
+
<i><i>"2" : 3,
|
86
|
+
<i><i>"4" : [<a_nl><i><i><i>5,<a_nl><i><i><i>6<a_nl><i><i>]
|
87
|
+
<i>}
|
88
|
+
}
|
89
|
+
EOT
|
88
90
|
end
|
89
91
|
|
90
92
|
def test_fast_generate
|
@@ -292,7 +294,9 @@ EOT
|
|
292
294
|
assert_equal '2', state.indent
|
293
295
|
end
|
294
296
|
|
295
|
-
if defined?(JSON::Ext::Generator)
|
297
|
+
if defined?(JSON::Ext::Generator) && Process.respond_to?(:fork)
|
298
|
+
# forking to avoid modifying core class of a parent process and
|
299
|
+
# introducing race conditions of tests are run in parallel
|
296
300
|
def test_broken_bignum # [ruby-core:38867]
|
297
301
|
pid = fork do
|
298
302
|
x = 1 << 64
|
@@ -309,9 +313,6 @@ EOT
|
|
309
313
|
end
|
310
314
|
_, status = Process.waitpid2(pid)
|
311
315
|
assert status.success?
|
312
|
-
rescue NotImplementedError
|
313
|
-
# forking to avoid modifying core class of a parent process and
|
314
|
-
# introducing race conditions of tests are run in parallel
|
315
316
|
end
|
316
317
|
end
|
317
318
|
|
@@ -392,4 +393,15 @@ EOT
|
|
392
393
|
assert_equal '["foo"]', JSON.generate([s.new('foo')])
|
393
394
|
end
|
394
395
|
end
|
396
|
+
|
397
|
+
def test_invalid_to_json
|
398
|
+
omit if REAL_JSON_GEM
|
399
|
+
|
400
|
+
data = Object.new
|
401
|
+
def data.to_json(*)
|
402
|
+
nil
|
403
|
+
end
|
404
|
+
|
405
|
+
assert_raises(TypeError) { JSON.generate(data) }
|
406
|
+
end
|
395
407
|
end
|
@@ -29,26 +29,26 @@ class JSONGenericObjectTest < Test::Unit::TestCase
|
|
29
29
|
|
30
30
|
def test_parse_json
|
31
31
|
x = JSON(
|
32
|
-
'{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
|
33
|
-
:create_additions => true
|
34
|
-
)
|
35
|
-
assert_kind_of Hash,
|
36
|
-
JSON(
|
37
32
|
'{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
|
38
33
|
:create_additions => true
|
39
34
|
)
|
35
|
+
assert_kind_of Hash,
|
36
|
+
JSON(
|
37
|
+
'{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
|
38
|
+
:create_additions => true
|
39
|
+
)
|
40
40
|
switch_json_creatable do
|
41
41
|
assert_equal @go, l =
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
JSON(
|
43
|
+
'{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
|
44
|
+
:create_additions => true
|
45
|
+
)
|
46
46
|
assert_equal 1, l.a
|
47
47
|
assert_equal @go,
|
48
|
-
|
48
|
+
l = JSON('{ "a": 1, "b": 2 }', :object_class => JSON::GenericObject)
|
49
49
|
assert_equal 1, l.a
|
50
50
|
assert_equal JSON::GenericObject[:a => JSON::GenericObject[:b => 2]],
|
51
|
-
|
51
|
+
l = JSON('{ "a": { "b": 2 } }', :object_class => JSON::GenericObject)
|
52
52
|
assert_equal 2, l.a.b
|
53
53
|
end
|
54
54
|
end
|
@@ -31,7 +31,7 @@ class JSONParserTest < Test::Unit::TestCase
|
|
31
31
|
}
|
32
32
|
assert_equal(Encoding::UTF_8, e.message.encoding, bug10705)
|
33
33
|
assert_include(e.message, json, bug10705)
|
34
|
-
end if defined?(Encoding::UTF_8)
|
34
|
+
end if defined?(Encoding::UTF_8) and defined?(JSON::Ext::Parser)
|
35
35
|
|
36
36
|
def test_parsing
|
37
37
|
parser = JSON::Parser.new('"test"')
|
@@ -95,21 +95,21 @@ class JSONParserTest < Test::Unit::TestCase
|
|
95
95
|
assert_raise(JSON::ParserError) { JSON.parse('.23') }
|
96
96
|
assert_raise(JSON::ParserError) { JSON.parse('023') }
|
97
97
|
assert_equal 23, JSON.parse('23')
|
98
|
-
assert_equal
|
98
|
+
assert_equal(-23, JSON.parse('-23'))
|
99
99
|
assert_equal_float 3.141, JSON.parse('3.141')
|
100
|
-
assert_equal_float
|
100
|
+
assert_equal_float(-3.141, JSON.parse('-3.141'))
|
101
101
|
assert_equal_float 3.141, JSON.parse('3141e-3')
|
102
102
|
assert_equal_float 3.141, JSON.parse('3141.1e-3')
|
103
103
|
assert_equal_float 3.141, JSON.parse('3141E-3')
|
104
104
|
assert_equal_float 3.141, JSON.parse('3141.0E-3')
|
105
|
-
assert_equal_float
|
106
|
-
assert_equal_float
|
105
|
+
assert_equal_float(-3.141, JSON.parse('-3141.0e-3'))
|
106
|
+
assert_equal_float(-3.141, JSON.parse('-3141e-3'))
|
107
107
|
assert_raise(JSON::ParserError) { JSON.parse('NaN') }
|
108
108
|
assert JSON.parse('NaN', :allow_nan => true).nan?
|
109
109
|
assert_raise(JSON::ParserError) { JSON.parse('Infinity') }
|
110
110
|
assert_equal 1.0/0, JSON.parse('Infinity', :allow_nan => true)
|
111
111
|
assert_raise(JSON::ParserError) { JSON.parse('-Infinity') }
|
112
|
-
assert_equal
|
112
|
+
assert_equal(-1.0/0, JSON.parse('-Infinity', :allow_nan => true))
|
113
113
|
end
|
114
114
|
|
115
115
|
if Array.method_defined?(:permutation)
|
@@ -133,17 +133,17 @@ class JSONParserTest < Test::Unit::TestCase
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def test_parse_arrays
|
136
|
-
assert_equal([1,2,3], JSON.parse('[1,2,3]'))
|
137
|
-
assert_equal([1.2,2,3], JSON.parse('[1.2,2,3]'))
|
138
|
-
assert_equal([[],[[],[]]], JSON.parse('[[],[[],[]]]'))
|
136
|
+
assert_equal([1, 2, 3], JSON.parse('[1,2,3]'))
|
137
|
+
assert_equal([1.2, 2, 3], JSON.parse('[1.2,2,3]'))
|
138
|
+
assert_equal([[], [[], []]], JSON.parse('[[],[[],[]]]'))
|
139
139
|
assert_equal([], JSON.parse('[]'))
|
140
140
|
assert_equal([], JSON.parse(' [ ] '))
|
141
141
|
assert_equal([1], JSON.parse('[1]'))
|
142
142
|
assert_equal([1], JSON.parse(' [ 1 ] '))
|
143
143
|
ary = [[1], ["foo"], [3.14], [4711.0], [2.718], [nil],
|
144
|
-
|
144
|
+
[[1, -2, 3]], [false], [true]]
|
145
145
|
assert_equal(ary,
|
146
|
-
|
146
|
+
JSON.parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]],[false],[true]]'))
|
147
147
|
assert_equal(ary, JSON.parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]\s
|
148
148
|
, [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
|
149
149
|
end
|
@@ -208,51 +208,51 @@ class JSONParserTest < Test::Unit::TestCase
|
|
208
208
|
|
209
209
|
def test_symbolize_names
|
210
210
|
assert_equal({ "foo" => "bar", "baz" => "quux" },
|
211
|
-
|
211
|
+
JSON.parse('{"foo":"bar", "baz":"quux"}'))
|
212
212
|
assert_equal({ :foo => "bar", :baz => "quux" },
|
213
|
-
|
213
|
+
JSON.parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
|
214
214
|
assert_raise(ArgumentError) do
|
215
215
|
JSON.parse('{}', :symbolize_names => true, :create_additions => true)
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
219
|
def test_parse_comments
|
220
|
-
json =
|
221
|
-
{
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
}
|
229
|
-
EOT
|
220
|
+
json = <<~EOT
|
221
|
+
{
|
222
|
+
"key1":"value1", // eol comment
|
223
|
+
"key2":"value2" /* multi line
|
224
|
+
* comment */,
|
225
|
+
"key3":"value3" /* multi line
|
226
|
+
// nested eol comment
|
227
|
+
* comment */
|
228
|
+
}
|
229
|
+
EOT
|
230
230
|
assert_equal(
|
231
231
|
{ "key1" => "value1", "key2" => "value2", "key3" => "value3" },
|
232
232
|
JSON.parse(json))
|
233
|
-
json =
|
234
|
-
{
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
}
|
240
|
-
EOT
|
233
|
+
json = <<~EOT
|
234
|
+
{
|
235
|
+
"key1":"value1" /* multi line
|
236
|
+
// nested eol comment
|
237
|
+
/* illegal nested multi line comment */
|
238
|
+
* comment */
|
239
|
+
}
|
240
|
+
EOT
|
241
241
|
assert_raise(JSON::ParserError) { JSON.parse(json) }
|
242
|
-
json =
|
243
|
-
{
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
}
|
249
|
-
EOT
|
242
|
+
json = <<~EOT
|
243
|
+
{
|
244
|
+
"key1":"value1" /* multi line
|
245
|
+
// nested eol comment
|
246
|
+
closed multi comment */
|
247
|
+
and again, throw an Error */
|
248
|
+
}
|
249
|
+
EOT
|
250
250
|
assert_raise(JSON::ParserError) { JSON.parse(json) }
|
251
|
-
json =
|
252
|
-
{
|
253
|
-
|
254
|
-
}
|
255
|
-
EOT
|
251
|
+
json = <<~EOT
|
252
|
+
{
|
253
|
+
"key1":"value1" /*/*/
|
254
|
+
}
|
255
|
+
EOT
|
256
256
|
assert_equal({ "key1" => "value1" }, JSON.parse(json))
|
257
257
|
end
|
258
258
|
|
@@ -269,6 +269,13 @@ EOT
|
|
269
269
|
assert_equal too_deep_ary, ok
|
270
270
|
ok = JSON.parse too_deep, :max_nesting => 0
|
271
271
|
assert_equal too_deep_ary, ok
|
272
|
+
|
273
|
+
unless ENV['REAL_JSON_GEM']
|
274
|
+
# max_nesting should be reset to 0 if not included in options
|
275
|
+
# This behavior is not compatible with Ruby standard JSON gem
|
276
|
+
ok = JSON.parse too_deep, {}
|
277
|
+
assert_equal too_deep_ary, ok
|
278
|
+
end
|
272
279
|
end
|
273
280
|
|
274
281
|
def test_backslash
|
@@ -341,7 +348,7 @@ EOT
|
|
341
348
|
|
342
349
|
def test_parse_array_custom_array_derived_class
|
343
350
|
res = JSON.parse('[1,2]', :array_class => SubArray)
|
344
|
-
assert_equal([1,2], res)
|
351
|
+
assert_equal([1, 2], res)
|
345
352
|
assert_equal(SubArray, res.class)
|
346
353
|
assert res.shifted?
|
347
354
|
end
|
@@ -349,7 +356,7 @@ EOT
|
|
349
356
|
def test_parse_array_custom_non_array_derived_class
|
350
357
|
res = JSON.parse('[1,2]', :array_class => SubArrayWrapper)
|
351
358
|
assert_equal(SubArrayWrapper, res.class)
|
352
|
-
assert_equal([1,2], res.data)
|
359
|
+
assert_equal([1, 2], res.data)
|
353
360
|
assert res.shifted?
|
354
361
|
end
|
355
362
|
|
@@ -435,7 +442,7 @@ EOT
|
|
435
442
|
assert obj_again['foo']['bar']
|
436
443
|
assert_equal obj, obj_again
|
437
444
|
assert_equal ["foo"],
|
438
|
-
|
445
|
+
JSON(JSON(SubArray2["foo"]), :create_additions => true)
|
439
446
|
end
|
440
447
|
|
441
448
|
def test_generate_core_subclasses_with_default_to_json
|
@@ -28,15 +28,15 @@ class JSONStringMatchingTest < Test::Unit::TestCase
|
|
28
28
|
t_json = [ t ].to_json
|
29
29
|
time_regexp = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/
|
30
30
|
assert_equal [ t ],
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
JSON.parse(
|
32
|
+
t_json,
|
33
|
+
:create_additions => true,
|
34
|
+
:match_string => { time_regexp => TestTime }
|
35
|
+
)
|
36
36
|
assert_equal [ t.strftime('%FT%T%z') ],
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
JSON.parse(
|
38
|
+
t_json,
|
39
|
+
:match_string => { time_regexp => TestTime }
|
40
|
+
)
|
41
41
|
end
|
42
42
|
end
|
@@ -15,10 +15,14 @@ else
|
|
15
15
|
require 'oj'
|
16
16
|
Oj.mimic_JSON
|
17
17
|
|
18
|
+
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
19
|
+
# move objects around, helping to find object movement bugs.
|
18
20
|
if defined?(GC.verify_compaction_references) == 'method'
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.2.0")
|
22
|
+
GC.verify_compaction_references(expand_heap: true, toward: :empty)
|
23
|
+
else
|
24
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
data/test/mem.rb
CHANGED
@@ -1,29 +1,30 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
2
|
+
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
require 'English'
|
5
|
+
$LOAD_PATH << '.'
|
6
|
+
$LOAD_PATH << File.join(__dir__, '../lib')
|
7
|
+
$LOAD_PATH << File.join(__dir__, '../ext')
|
7
8
|
|
8
9
|
require 'oj'
|
9
10
|
|
10
11
|
Oj.default_options = { mode: :rails, cache_keys: false, cache_str: -1 }
|
11
12
|
|
12
13
|
def mem
|
13
|
-
`ps -o rss= -p #{
|
14
|
+
`ps -o rss= -p #{$PROCESS_ID}`.to_i
|
14
15
|
end
|
15
16
|
|
16
17
|
('a'..'z').each { |a|
|
17
18
|
('a'..'z').each { |b|
|
18
19
|
('a'..'z').each { |c|
|
19
20
|
('a'..'z').each { |d|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
('a'..'z').each { |e|
|
22
|
+
('a'..'z').each { |f|
|
23
|
+
key = "#{a}#{b}#{c}#{d}#{e}#{f}"
|
24
|
+
Oj.load(%|{ "#{key}": 101}|)
|
25
|
+
# Oj.dump(x)
|
26
|
+
}
|
27
|
+
}
|
27
28
|
}
|
28
29
|
}
|
29
30
|
puts "#{a}#{b} #{mem}"
|