oj 3.11.5 → 3.16.5
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 +1421 -0
- data/README.md +19 -5
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +20 -6
- data/ext/oj/cache.c +329 -0
- data/ext/oj/cache.h +22 -0
- 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 +19 -33
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +27 -77
- data/ext/oj/custom.c +86 -179
- data/ext/oj/debug.c +126 -0
- data/ext/oj/dump.c +256 -249
- data/ext/oj/dump.h +26 -12
- data/ext/oj/dump_compat.c +565 -642
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +65 -187
- data/ext/oj/dump_strict.c +27 -51
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +24 -8
- data/ext/oj/extconf.rb +21 -6
- data/ext/oj/fast.c +149 -149
- data/ext/oj/intern.c +313 -0
- data/ext/oj/intern.h +22 -0
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +121 -106
- data/ext/oj/object.c +85 -162
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +542 -411
- data/ext/oj/oj.h +99 -73
- data/ext/oj/parse.c +175 -187
- data/ext/oj/parse.h +26 -24
- data/ext/oj/parser.c +1600 -0
- data/ext/oj/parser.h +101 -0
- data/ext/oj/rails.c +112 -159
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +11 -14
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +5 -24
- data/ext/oj/rxclass.c +7 -6
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +22 -33
- data/ext/oj/saj2.c +584 -0
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +5 -28
- data/ext/oj/sparse.c +28 -72
- data/ext/oj/stream_writer.c +50 -40
- data/ext/oj/strict.c +56 -61
- data/ext/oj/string_writer.c +72 -39
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +1218 -0
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +14 -3
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +63 -88
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +1 -2
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +9 -7
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +12 -8
- 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/JsonGem.md +15 -0
- data/pages/Modes.md +8 -3
- data/pages/Options.md +43 -5
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +14 -2
- 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/activesupport6/encoding_test.rb +63 -28
- 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 +86 -50
- 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 +16 -45
- 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 +8 -6
- 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 +56 -38
- 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 +34 -0
- data/test/perf.rb +22 -27
- 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 +59 -0
- data/test/perf_parser.rb +183 -0
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +58 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +74 -82
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +5 -5
- 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 +95 -43
- data/test/test_custom.rb +73 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +135 -79
- 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 +5 -5
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +99 -96
- data/test/test_parser.rb +11 -0
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +337 -0
- data/test/test_parser_usual.rb +251 -0
- 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 +40 -32
- data/test/test_various.rb +165 -84
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -5
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +74 -128
- data/ext/oj/hash.c +0 -131
- data/ext/oj/hash.h +0 -19
- data/ext/oj/hash_test.c +0 -491
- 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 -35
- data/test/baz.rb +0 -16
- data/test/zoo.rb +0 -13
@@ -74,42 +74,77 @@ class TestJSONEncoding < ActiveSupport::TestCase
|
|
74
74
|
ActiveSupport.escape_html_entities_in_json = false
|
75
75
|
end
|
76
76
|
|
77
|
-
def
|
78
|
-
|
79
|
-
# ActiveSupport.escape_html_entities_in_json reverts to true even after
|
80
|
-
# being set to false. I haven't been able to figure that out so the value is
|
81
|
-
# set to true, the default, before running the test. This might be wrong but
|
82
|
-
# for now it will have to do.
|
83
|
-
ActiveSupport.escape_html_entities_in_json = true
|
84
|
-
result = ActiveSupport::JSON.encode("€2.99")
|
85
|
-
assert_equal '"€2.99"', result
|
86
|
-
assert_equal(Encoding::UTF_8, result.encoding)
|
87
|
-
|
88
|
-
result = ActiveSupport::JSON.encode("✎☺")
|
89
|
-
assert_equal '"✎☺"', result
|
90
|
-
assert_equal(Encoding::UTF_8, result.encoding)
|
77
|
+
def test_hash_keys_encoding_without_escaping
|
78
|
+
assert_equal "{\"<>\":\"<>\"}", ActiveSupport::JSON.encode("<>" => "<>")
|
91
79
|
end
|
92
80
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
81
|
+
module UnicodeTests
|
82
|
+
def test_utf8_string_encoded_properly
|
83
|
+
result = ActiveSupport::JSON.encode("€2.99")
|
84
|
+
assert_equal '"€2.99"', result
|
85
|
+
assert_equal(Encoding::UTF_8, result.encoding)
|
86
|
+
|
87
|
+
result = ActiveSupport::JSON.encode("✎☺")
|
88
|
+
assert_equal '"✎☺"', result
|
89
|
+
assert_equal(Encoding::UTF_8, result.encoding)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_non_utf8_string_transcodes
|
93
|
+
s = "二".encode("Shift_JIS")
|
94
|
+
result = ActiveSupport::JSON.encode(s)
|
95
|
+
assert_equal '"二"', result
|
96
|
+
assert_equal Encoding::UTF_8, result.encoding
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_wide_utf8_chars
|
100
|
+
w = "𠜎"
|
101
|
+
result = ActiveSupport::JSON.encode(w)
|
102
|
+
assert_equal '"𠜎"', result
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_wide_utf8_roundtrip
|
106
|
+
hash = { string: "𐒑" }
|
107
|
+
json = ActiveSupport::JSON.encode(hash)
|
108
|
+
decoded_hash = ActiveSupport::JSON.decode(json)
|
109
|
+
assert_equal "𐒑", decoded_hash["string"]
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_invalid_encoding_raises
|
113
|
+
s = "\xAE\xFF\x9F"
|
114
|
+
refute s.valid_encoding?
|
115
|
+
|
116
|
+
# n.b. this raises EncodingError, because we didn't call Oj.mimic_JSON in the test setup; but,
|
117
|
+
# if you do that (even indirectly through Oj.optimize_rails), then this raises a
|
118
|
+
# JSON::GeneratorError instead of an EncodingError.
|
119
|
+
assert_raises(EncodingError) do
|
120
|
+
ActiveSupport::JSON.encode([s])
|
121
|
+
end
|
122
|
+
end
|
98
123
|
end
|
99
124
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
125
|
+
module UnicodeTestsWithEscapingOn
|
126
|
+
def setup
|
127
|
+
ActiveSupport.escape_html_entities_in_json = true
|
128
|
+
end
|
129
|
+
|
130
|
+
def teardown
|
131
|
+
ActiveSupport.escape_html_entities_in_json = false
|
132
|
+
end
|
133
|
+
|
134
|
+
include UnicodeTests
|
104
135
|
end
|
105
136
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
137
|
+
module UnicodeTestsWithEscapingOff
|
138
|
+
def setup
|
139
|
+
ActiveSupport.escape_html_entities_in_json = false
|
140
|
+
end
|
141
|
+
|
142
|
+
include UnicodeTests
|
111
143
|
end
|
112
144
|
|
145
|
+
include UnicodeTestsWithEscapingOn
|
146
|
+
include UnicodeTestsWithEscapingOff
|
147
|
+
|
113
148
|
def test_hash_key_identifiers_are_always_quoted
|
114
149
|
values = { 0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B" }
|
115
150
|
assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(ActiveSupport::JSON.encode(values))
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
ORIG_ARGV = ARGV.dup
|
4
4
|
|
5
|
+
require "bundler/setup"
|
5
6
|
require "active_support/core_ext/kernel/reporting"
|
6
7
|
|
7
8
|
silence_warnings do
|
@@ -27,19 +28,22 @@ ActiveSupport.to_time_preserves_timezone = ENV["PRESERVE_TIMEZONES"] == "1"
|
|
27
28
|
I18n.enforce_available_locales = false
|
28
29
|
|
29
30
|
class ActiveSupport::TestCase
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
skip message if RUBY_ENGINE == "rbx"
|
31
|
+
if Process.respond_to?(:fork) && !Gem.win_platform?
|
32
|
+
parallelize
|
33
|
+
else
|
34
|
+
parallelize(with: :threads)
|
35
35
|
end
|
36
36
|
|
37
|
-
|
38
|
-
private def jruby_skip(message = "")
|
39
|
-
skip message if defined?(JRUBY_VERSION)
|
40
|
-
end
|
37
|
+
include ActiveSupport::Testing::MethodCallAssertions
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
private
|
40
|
+
# Skips the current run on Rubinius using Minitest::Assertions#skip
|
41
|
+
def rubinius_skip(message = "")
|
42
|
+
skip message if RUBY_ENGINE == "rbx"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Skips the current run on JRuby using Minitest::Assertions#skip
|
46
|
+
def jruby_skip(message = "")
|
47
|
+
skip message if defined?(JRUBY_VERSION)
|
48
|
+
end
|
45
49
|
end
|
@@ -5,18 +5,9 @@ require "active_support/json"
|
|
5
5
|
require "active_support/time"
|
6
6
|
require_relative "time_zone_test_helpers"
|
7
7
|
|
8
|
-
require 'oj'
|
9
|
-
|
10
|
-
Oj::Rails.set_decoder()
|
11
|
-
|
12
8
|
class TestJSONDecoding < ActiveSupport::TestCase
|
13
9
|
include TimeZoneTestHelpers
|
14
10
|
|
15
|
-
# Added for testing if Oj is used.
|
16
|
-
test "oj is used as an encoder" do
|
17
|
-
assert_equal ActiveSupport.json_encoder, Oj::Rails::Encoder
|
18
|
-
end
|
19
|
-
|
20
11
|
class Foo
|
21
12
|
def self.json_create(object)
|
22
13
|
"Foo"
|
@@ -49,6 +40,8 @@ class TestJSONDecoding < ActiveSupport::TestCase
|
|
49
40
|
# needs to be *exact*
|
50
41
|
%({"a": " 2007-01-01 01:12:34 Z "}) => { "a" => " 2007-01-01 01:12:34 Z " },
|
51
42
|
%({"a": "2007-01-01 : it's your birthday"}) => { "a" => "2007-01-01 : it's your birthday" },
|
43
|
+
%({"a": "Today is:\\n2020-05-21"}) => { "a" => "Today is:\n2020-05-21" },
|
44
|
+
%({"a": "2007-01-01 01:12:34 Z\\nwas my birthday"}) => { "a" => "2007-01-01 01:12:34 Z\nwas my birthday" },
|
52
45
|
%([]) => [],
|
53
46
|
%({}) => {},
|
54
47
|
%({"a":1}) => { "a" => 1 },
|
@@ -122,7 +115,6 @@ class TestJSONDecoding < ActiveSupport::TestCase
|
|
122
115
|
end
|
123
116
|
|
124
117
|
private
|
125
|
-
|
126
118
|
def with_parse_json_times(value)
|
127
119
|
old_value = ActiveSupport.parse_json_times
|
128
120
|
ActiveSupport.parse_json_times = value
|
@@ -3,26 +3,21 @@
|
|
3
3
|
require "securerandom"
|
4
4
|
require_relative "abstract_unit"
|
5
5
|
require "active_support/core_ext/string/inflections"
|
6
|
-
require "active_support/core_ext/regexp"
|
7
6
|
require "active_support/json"
|
8
7
|
require "active_support/time"
|
9
8
|
require_relative "time_zone_test_helpers"
|
10
9
|
require_relative "encoding_test_cases"
|
11
10
|
|
12
11
|
require 'oj'
|
13
|
-
|
14
|
-
# Sets the ActiveSupport encoder to be Oj and also wraps the setting of
|
15
|
-
# globals.
|
12
|
+
# Sets the ActiveSupport encoder to be Oj and also wraps the setting of globals.
|
16
13
|
Oj::Rails.set_encoder()
|
17
|
-
#Oj::Rails.optimize(Hash, Array, BigDecimal, Time, Range, Regexp, ActiveSupport::TimeWithZone)
|
18
14
|
Oj::Rails.optimize()
|
19
15
|
|
20
16
|
class TestJSONEncoding < ActiveSupport::TestCase
|
21
17
|
include TimeZoneTestHelpers
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
assert_equal ActiveSupport.json_encoder, Oj::Rails::Encoder
|
19
|
+
def test_is_actually_oj
|
20
|
+
assert_equal Oj::Rails::Encoder, ActiveSupport.json_encoder
|
26
21
|
end
|
27
22
|
|
28
23
|
def sorted_json(json)
|
@@ -35,20 +30,18 @@ class TestJSONEncoding < ActiveSupport::TestCase
|
|
35
30
|
|
36
31
|
JSONTest::EncodingTestCases.constants.each do |class_tests|
|
37
32
|
define_method("test_#{class_tests[0..-6].underscore}") do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
assert_equal pair.last, sorted_json(ActiveSupport::JSON.encode(pair.first))
|
47
|
-
end
|
48
|
-
ensure
|
49
|
-
ActiveSupport.escape_html_entities_in_json = false
|
50
|
-
ActiveSupport.use_standard_json_time_format = prev
|
33
|
+
prev = ActiveSupport.use_standard_json_time_format
|
34
|
+
|
35
|
+
standard_class_tests = /Standard/.match?(class_tests)
|
36
|
+
|
37
|
+
ActiveSupport.escape_html_entities_in_json = !standard_class_tests
|
38
|
+
ActiveSupport.use_standard_json_time_format = standard_class_tests
|
39
|
+
JSONTest::EncodingTestCases.const_get(class_tests).each do |pair|
|
40
|
+
assert_equal pair.last, sorted_json(ActiveSupport::JSON.encode(pair.first))
|
51
41
|
end
|
42
|
+
ensure
|
43
|
+
ActiveSupport.escape_html_entities_in_json = false
|
44
|
+
ActiveSupport.use_standard_json_time_format = prev
|
52
45
|
end
|
53
46
|
end
|
54
47
|
|
@@ -77,42 +70,77 @@ class TestJSONEncoding < ActiveSupport::TestCase
|
|
77
70
|
ActiveSupport.escape_html_entities_in_json = false
|
78
71
|
end
|
79
72
|
|
80
|
-
def
|
81
|
-
|
82
|
-
# ActiveSupport.escape_html_entities_in_json reverts to true even after
|
83
|
-
# being set to false. I haven't been able to figure that out so the value is
|
84
|
-
# set to true, the default, before running the test. This might be wrong but
|
85
|
-
# for now it will have to do.
|
86
|
-
ActiveSupport.escape_html_entities_in_json = true
|
87
|
-
result = ActiveSupport::JSON.encode("€2.99")
|
88
|
-
assert_equal '"€2.99"', result
|
89
|
-
assert_equal(Encoding::UTF_8, result.encoding)
|
90
|
-
|
91
|
-
result = ActiveSupport::JSON.encode("✎☺")
|
92
|
-
assert_equal '"✎☺"', result
|
93
|
-
assert_equal(Encoding::UTF_8, result.encoding)
|
73
|
+
def test_hash_keys_encoding_without_escaping
|
74
|
+
assert_equal "{\"<>\":\"<>\"}", ActiveSupport::JSON.encode("<>" => "<>")
|
94
75
|
end
|
95
76
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
77
|
+
module UnicodeTests
|
78
|
+
def test_utf8_string_encoded_properly
|
79
|
+
result = ActiveSupport::JSON.encode("€2.99")
|
80
|
+
assert_equal '"€2.99"', result
|
81
|
+
assert_equal(Encoding::UTF_8, result.encoding)
|
82
|
+
|
83
|
+
result = ActiveSupport::JSON.encode("✎☺")
|
84
|
+
assert_equal '"✎☺"', result
|
85
|
+
assert_equal(Encoding::UTF_8, result.encoding)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_non_utf8_string_transcodes
|
89
|
+
s = "二".encode("Shift_JIS")
|
90
|
+
result = ActiveSupport::JSON.encode(s)
|
91
|
+
assert_equal '"二"', result
|
92
|
+
assert_equal Encoding::UTF_8, result.encoding
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_wide_utf8_chars
|
96
|
+
w = "𠜎"
|
97
|
+
result = ActiveSupport::JSON.encode(w)
|
98
|
+
assert_equal '"𠜎"', result
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_wide_utf8_roundtrip
|
102
|
+
hash = { string: "𐒑" }
|
103
|
+
json = ActiveSupport::JSON.encode(hash)
|
104
|
+
decoded_hash = ActiveSupport::JSON.decode(json)
|
105
|
+
assert_equal "𐒑", decoded_hash["string"]
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_invalid_encoding_raises
|
109
|
+
s = "\xAE\xFF\x9F"
|
110
|
+
refute s.valid_encoding?
|
111
|
+
|
112
|
+
# n.b. this raises EncodingError, because we didn't call Oj.mimic_JSON in the test setup; but,
|
113
|
+
# if you do that (even indirectly through Oj.optimize_rails), then this raises a
|
114
|
+
# JSON::GeneratorError instead of an EncodingError.
|
115
|
+
assert_raises(EncodingError) do
|
116
|
+
ActiveSupport::JSON.encode([s])
|
117
|
+
end
|
118
|
+
end
|
101
119
|
end
|
102
120
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
121
|
+
module UnicodeTestsWithEscapingOn
|
122
|
+
def setup
|
123
|
+
ActiveSupport.escape_html_entities_in_json = true
|
124
|
+
end
|
125
|
+
|
126
|
+
def teardown
|
127
|
+
ActiveSupport.escape_html_entities_in_json = false
|
128
|
+
end
|
129
|
+
|
130
|
+
include UnicodeTests
|
107
131
|
end
|
108
132
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
133
|
+
module UnicodeTestsWithEscapingOff
|
134
|
+
def setup
|
135
|
+
ActiveSupport.escape_html_entities_in_json = false
|
136
|
+
end
|
137
|
+
|
138
|
+
include UnicodeTests
|
114
139
|
end
|
115
140
|
|
141
|
+
include UnicodeTestsWithEscapingOn
|
142
|
+
include UnicodeTestsWithEscapingOff
|
143
|
+
|
116
144
|
def test_hash_key_identifiers_are_always_quoted
|
117
145
|
values = { 0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B" }
|
118
146
|
assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(ActiveSupport::JSON.encode(values))
|
@@ -177,6 +205,15 @@ class TestJSONEncoding < ActiveSupport::TestCase
|
|
177
205
|
assert_equal({ "foo" => "hello" }, JSON.parse(json))
|
178
206
|
end
|
179
207
|
|
208
|
+
def test_struct_to_json_with_options_nested
|
209
|
+
klass = Struct.new(:foo, :bar)
|
210
|
+
struct = klass.new "hello", "world"
|
211
|
+
parent_struct = klass.new struct, "world"
|
212
|
+
json = parent_struct.to_json only: [:foo]
|
213
|
+
|
214
|
+
assert_equal({ "foo" => { "foo" => "hello" } }, JSON.parse(json))
|
215
|
+
end
|
216
|
+
|
180
217
|
def test_hash_should_pass_encoding_options_to_children_in_as_json
|
181
218
|
person = {
|
182
219
|
name: "John",
|
@@ -478,7 +515,6 @@ EXPECTED
|
|
478
515
|
end
|
479
516
|
|
480
517
|
private
|
481
|
-
|
482
518
|
def object_keys(json_object)
|
483
519
|
json_object[1..-2].scan(/([^{}:,\s]+):/).flatten.sort
|
484
520
|
end
|
@@ -68,6 +68,10 @@ module JSONTest
|
|
68
68
|
[ :this, %("this") ],
|
69
69
|
[ :"a b", %("a b") ]]
|
70
70
|
|
71
|
+
ModuleTests = [[ Module, %("Module") ],
|
72
|
+
[ Class, %("Class") ],
|
73
|
+
[ ActiveSupport, %("ActiveSupport") ],
|
74
|
+
[ ActiveSupport::MessageEncryptor, %("ActiveSupport::MessageEncryptor") ]]
|
71
75
|
ObjectTests = [[ Foo.new(1, 2), %({\"a\":1,\"b\":2}) ]]
|
72
76
|
HashlikeTests = [[ Hashlike.new, %({\"bar\":\"world\",\"foo\":\"hello\"}) ]]
|
73
77
|
StructTests = [[ MyStruct.new(:foo, "bar"), %({\"name\":\"foo\",\"value\":\"bar\"}) ],
|
@@ -86,6 +90,8 @@ module JSONTest
|
|
86
90
|
|
87
91
|
PathnameTests = [[ Pathname.new("lib/index.rb"), %("lib/index.rb") ]]
|
88
92
|
|
93
|
+
IPAddrTests = [[ IPAddr.new("127.0.0.1"), %("127.0.0.1") ]]
|
94
|
+
|
89
95
|
DateTests = [[ Date.new(2005, 2, 1), %("2005/02/01") ]]
|
90
96
|
TimeTests = [[ Time.utc(2005, 2, 1, 15, 15, 10), %("2005/02/01 15:15:10 +0000") ]]
|
91
97
|
DateTimeTests = [[ DateTime.civil(2005, 2, 1, 15, 15, 10), %("2005/02/01 15:15:10 +0000") ]]
|
@@ -36,4 +36,12 @@ module TimeZoneTestHelpers
|
|
36
36
|
ActiveSupport::TimeZone::MAPPING.clear
|
37
37
|
ActiveSupport::TimeZone::MAPPING.merge!(old_mappings)
|
38
38
|
end
|
39
|
+
|
40
|
+
def with_utc_to_local_returns_utc_offset_times(value)
|
41
|
+
old_tzinfo2_format = ActiveSupport.utc_to_local_returns_utc_offset_times
|
42
|
+
ActiveSupport.utc_to_local_returns_utc_offset_times = value
|
43
|
+
yield
|
44
|
+
ensure
|
45
|
+
ActiveSupport.utc_to_local_returns_utc_offset_times = old_tzinfo2_format
|
46
|
+
end
|
39
47
|
end
|
data/test/files.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
#!/usr/bin/env ruby -wW2
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
if $
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
if $PROGRAM_NAME == __FILE__
|
5
|
+
$LOAD_PATH << '.'
|
6
|
+
$LOAD_PATH << '..'
|
7
|
+
$LOAD_PATH << '../lib'
|
8
|
+
$LOAD_PATH << '../ext'
|
8
9
|
end
|
9
10
|
|
10
|
-
require 'pp'
|
11
11
|
require 'sample/file'
|
12
12
|
require 'sample/dir'
|
13
13
|
|
14
14
|
def files(dir)
|
15
|
-
d =
|
15
|
+
d = Sample::Dir.new(dir)
|
16
16
|
Dir.new(dir).each do |fn|
|
17
17
|
next if fn.start_with?('.')
|
18
|
+
|
18
19
|
filename = File.join(dir, fn)
|
19
|
-
#filename = '.' == dir ? fn : File.join(dir, fn)
|
20
|
-
if File.directory?(filename)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
# filename = '.' == dir ? fn : File.join(dir, fn)
|
21
|
+
d << if File.directory?(filename)
|
22
|
+
files(filename)
|
23
|
+
else
|
24
|
+
Sample::File.new(filename)
|
25
|
+
end
|
25
26
|
end
|
26
|
-
#pp d
|
27
|
+
# pp d
|
27
28
|
d
|
28
29
|
end
|
29
|
-
|
data/test/foo.rb
CHANGED
@@ -1,55 +1,26 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
|
4
|
-
$
|
5
|
-
|
6
|
-
$: << File.join($oj_dir, dir)
|
7
|
-
end
|
4
|
+
$LOAD_PATH << '.'
|
5
|
+
$LOAD_PATH << File.join(__dir__, '../lib')
|
6
|
+
$LOAD_PATH << File.join(__dir__, '../ext')
|
8
7
|
|
9
8
|
require 'oj'
|
10
9
|
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
@x = 123
|
14
|
-
end
|
10
|
+
reader, writer = IO.pipe
|
15
11
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
thread =
|
13
|
+
Thread.new do
|
14
|
+
5.times do |id|
|
15
|
+
Oj.to_stream(writer, { "id" => id })
|
16
|
+
sleep(1)
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
def initialize
|
23
|
-
@x = 321
|
19
|
+
writer.close
|
24
20
|
end
|
25
|
-
end
|
26
|
-
|
27
|
-
foo = Foo.new
|
28
|
-
bar = Bar.new
|
29
|
-
|
30
|
-
require 'json'
|
31
|
-
|
32
|
-
puts "JSON: #{JSON.generate(foo)}"
|
33
|
-
puts "to_json: #{foo.to_json}"
|
34
|
-
puts "bar JSON: #{JSON.generate(bar)}"
|
35
|
-
puts "bar to_json: #{bar.to_json}"
|
36
|
-
|
37
|
-
m = bar.method('to_json')
|
38
|
-
puts "*** method: #{m} owner: #{m.owner.name}"
|
39
|
-
|
40
|
-
puts "---- rails"
|
41
|
-
require 'rails'
|
42
|
-
|
43
|
-
m = bar.method('to_json')
|
44
|
-
puts "*** method: #{m} owner: #{m.owner} params: #{m.parameters}"
|
45
|
-
|
46
|
-
puts "JSON: #{JSON.generate(foo)}"
|
47
|
-
puts "to_json: #{foo.to_json}"
|
48
21
|
|
49
|
-
|
50
|
-
|
51
|
-
puts "Oj JSON: #{JSON.generate(foo)}"
|
52
|
-
puts "Oj to_json: #{foo.to_json}"
|
22
|
+
p = Oj::Parser.new(:usual)
|
23
|
+
p.load(reader) { |data| puts "#{Time.now} -- ID: #{data["id"]}" }
|
53
24
|
|
54
|
-
|
55
|
-
|
25
|
+
reader.close
|
26
|
+
thread.join
|
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
|
@@ -128,8 +128,10 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
|
|
128
128
|
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
|
129
129
|
assert_equal too_deep, JSON.dump(eval(too_deep))
|
130
130
|
assert_kind_of String, Marshal.dump(eval(too_deep))
|
131
|
-
|
132
|
-
|
131
|
+
if RUBY_ENGINE != 'truffleruby'
|
132
|
+
assert_raise(ArgumentError) { JSON.dump(eval(too_deep), 100) }
|
133
|
+
assert_raise(ArgumentError) { Marshal.dump(eval(too_deep), 100) }
|
134
|
+
end
|
133
135
|
assert_equal too_deep, JSON.dump(eval(too_deep), 101)
|
134
136
|
assert_kind_of String, Marshal.dump(eval(too_deep), 101)
|
135
137
|
output = StringIO.new
|
File without changes
|