oj 3.7.4 → 3.13.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1352 -0
  3. data/README.md +29 -8
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +53 -72
  6. data/ext/oj/cache.c +326 -0
  7. data/ext/oj/cache.h +21 -0
  8. data/ext/oj/cache8.c +61 -64
  9. data/ext/oj/cache8.h +12 -39
  10. data/ext/oj/circarray.c +37 -43
  11. data/ext/oj/circarray.h +16 -17
  12. data/ext/oj/code.c +165 -179
  13. data/ext/oj/code.h +27 -29
  14. data/ext/oj/compat.c +174 -194
  15. data/ext/oj/custom.c +809 -866
  16. data/ext/oj/debug.c +132 -0
  17. data/ext/oj/dump.c +848 -863
  18. data/ext/oj/dump.h +81 -67
  19. data/ext/oj/dump_compat.c +85 -123
  20. data/ext/oj/dump_leaf.c +100 -188
  21. data/ext/oj/dump_object.c +527 -656
  22. data/ext/oj/dump_strict.c +315 -338
  23. data/ext/oj/encode.h +7 -34
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +40 -29
  26. data/ext/oj/err.h +48 -48
  27. data/ext/oj/extconf.rb +17 -4
  28. data/ext/oj/fast.c +1070 -1087
  29. data/ext/oj/intern.c +301 -0
  30. data/ext/oj/intern.h +26 -0
  31. data/ext/oj/mimic_json.c +469 -436
  32. data/ext/oj/object.c +525 -593
  33. data/ext/oj/odd.c +154 -138
  34. data/ext/oj/odd.h +37 -38
  35. data/ext/oj/oj.c +1325 -986
  36. data/ext/oj/oj.h +333 -316
  37. data/ext/oj/parse.c +1002 -846
  38. data/ext/oj/parse.h +92 -87
  39. data/ext/oj/parser.c +1557 -0
  40. data/ext/oj/parser.h +91 -0
  41. data/ext/oj/rails.c +888 -878
  42. data/ext/oj/rails.h +11 -14
  43. data/ext/oj/reader.c +141 -147
  44. data/ext/oj/reader.h +73 -89
  45. data/ext/oj/resolve.c +41 -62
  46. data/ext/oj/resolve.h +7 -9
  47. data/ext/oj/rxclass.c +71 -75
  48. data/ext/oj/rxclass.h +18 -19
  49. data/ext/oj/saj.c +443 -486
  50. data/ext/oj/saj2.c +602 -0
  51. data/ext/oj/scp.c +88 -113
  52. data/ext/oj/sparse.c +787 -709
  53. data/ext/oj/stream_writer.c +133 -159
  54. data/ext/oj/strict.c +127 -118
  55. data/ext/oj/string_writer.c +230 -249
  56. data/ext/oj/trace.c +34 -41
  57. data/ext/oj/trace.h +19 -19
  58. data/ext/oj/usual.c +1254 -0
  59. data/ext/oj/util.c +136 -0
  60. data/ext/oj/util.h +20 -0
  61. data/ext/oj/val_stack.c +59 -67
  62. data/ext/oj/val_stack.h +91 -129
  63. data/ext/oj/validate.c +46 -0
  64. data/ext/oj/wab.c +342 -353
  65. data/lib/oj/bag.rb +1 -0
  66. data/lib/oj/easy_hash.rb +5 -4
  67. data/lib/oj/error.rb +1 -1
  68. data/lib/oj/json.rb +1 -1
  69. data/lib/oj/mimic.rb +48 -14
  70. data/lib/oj/saj.rb +20 -6
  71. data/lib/oj/state.rb +8 -7
  72. data/lib/oj/version.rb +2 -2
  73. data/lib/oj.rb +0 -8
  74. data/pages/Compatibility.md +1 -1
  75. data/pages/JsonGem.md +15 -0
  76. data/pages/Modes.md +53 -46
  77. data/pages/Options.md +72 -11
  78. data/pages/Parser.md +309 -0
  79. data/pages/Rails.md +73 -22
  80. data/pages/Security.md +1 -1
  81. data/test/activerecord/result_test.rb +7 -2
  82. data/test/activesupport5/abstract_unit.rb +45 -0
  83. data/test/activesupport5/decoding_test.rb +68 -60
  84. data/test/activesupport5/encoding_test.rb +111 -96
  85. data/test/activesupport5/encoding_test_cases.rb +33 -25
  86. data/test/activesupport5/test_helper.rb +43 -21
  87. data/test/activesupport5/time_zone_test_helpers.rb +18 -3
  88. data/test/activesupport6/abstract_unit.rb +44 -0
  89. data/test/activesupport6/decoding_test.rb +133 -0
  90. data/test/activesupport6/encoding_test.rb +507 -0
  91. data/test/activesupport6/encoding_test_cases.rb +98 -0
  92. data/test/activesupport6/test_common.rb +17 -0
  93. data/test/activesupport6/test_helper.rb +163 -0
  94. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  95. data/test/activesupport7/abstract_unit.rb +49 -0
  96. data/test/activesupport7/decoding_test.rb +125 -0
  97. data/test/activesupport7/encoding_test.rb +486 -0
  98. data/test/activesupport7/encoding_test_cases.rb +104 -0
  99. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  100. data/test/bar.rb +6 -12
  101. data/test/baz.rb +16 -0
  102. data/test/bug.rb +16 -0
  103. data/test/foo.rb +69 -75
  104. data/test/helper.rb +16 -0
  105. data/test/json_gem/json_common_interface_test.rb +8 -3
  106. data/test/json_gem/json_generator_test.rb +18 -4
  107. data/test/json_gem/json_parser_test.rb +9 -0
  108. data/test/json_gem/test_helper.rb +12 -0
  109. data/test/mem.rb +33 -0
  110. data/test/perf.rb +1 -1
  111. data/test/perf_dump.rb +50 -0
  112. data/test/perf_once.rb +58 -0
  113. data/test/perf_parser.rb +189 -0
  114. data/test/perf_scp.rb +11 -10
  115. data/test/perf_strict.rb +17 -23
  116. data/test/prec.rb +23 -0
  117. data/test/sample_json.rb +1 -1
  118. data/test/test_compat.rb +46 -10
  119. data/test/test_custom.rb +147 -8
  120. data/test/test_fast.rb +62 -2
  121. data/test/test_file.rb +25 -2
  122. data/test/test_gc.rb +13 -0
  123. data/test/test_generate.rb +21 -0
  124. data/test/test_hash.rb +11 -1
  125. data/test/test_integer_range.rb +7 -2
  126. data/test/test_object.rb +85 -9
  127. data/test/test_parser.rb +27 -0
  128. data/test/test_parser_saj.rb +335 -0
  129. data/test/test_parser_usual.rb +217 -0
  130. data/test/test_rails.rb +35 -0
  131. data/test/test_saj.rb +1 -1
  132. data/test/test_scp.rb +5 -5
  133. data/test/test_strict.rb +26 -1
  134. data/test/test_various.rb +87 -65
  135. data/test/test_wab.rb +2 -0
  136. data/test/test_writer.rb +19 -2
  137. data/test/tests.rb +1 -1
  138. data/test/zoo.rb +13 -0
  139. metadata +60 -110
  140. data/ext/oj/hash.c +0 -163
  141. data/ext/oj/hash.h +0 -46
  142. data/ext/oj/hash_test.c +0 -512
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem "minitest" # make sure we get the gem, not stdlib
4
+ require "minitest"
5
+ require "active_support/testing/tagged_logging"
6
+ require "active_support/testing/setup_and_teardown"
7
+ require "active_support/testing/assertions"
8
+ require "active_support/testing/deprecation"
9
+ require "active_support/testing/declarative"
10
+ require "active_support/testing/isolation"
11
+ require "active_support/testing/constant_lookup"
12
+ require "active_support/testing/time_helpers"
13
+ require "active_support/testing/file_fixtures"
14
+ require "active_support/testing/parallelization"
15
+ require "concurrent/utility/processor_counter"
16
+
17
+ module ActiveSupport
18
+ class TestCase < ::Minitest::Test
19
+ Assertion = Minitest::Assertion
20
+
21
+ class << self
22
+ # Sets the order in which test cases are run.
23
+ #
24
+ # ActiveSupport::TestCase.test_order = :random # => :random
25
+ #
26
+ # Valid values are:
27
+ # * +:random+ (to run tests in random order)
28
+ # * +:parallel+ (to run tests in parallel)
29
+ # * +:sorted+ (to run tests alphabetically by method name)
30
+ # * +:alpha+ (equivalent to +:sorted+)
31
+ def test_order=(new_order)
32
+ ActiveSupport.test_order = new_order
33
+ end
34
+
35
+ # Returns the order in which test cases are run.
36
+ #
37
+ # ActiveSupport::TestCase.test_order # => :random
38
+ #
39
+ # Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+.
40
+ # Defaults to +:random+.
41
+ def test_order
42
+ ActiveSupport.test_order ||= :random
43
+ end
44
+
45
+ # Parallelizes the test suite.
46
+ #
47
+ # Takes a +workers+ argument that controls how many times the process
48
+ # is forked. For each process a new database will be created suffixed
49
+ # with the worker number.
50
+ #
51
+ # test-database-0
52
+ # test-database-1
53
+ #
54
+ # If <tt>ENV["PARALLEL_WORKERS"]</tt> is set the workers argument will be ignored
55
+ # and the environment variable will be used instead. This is useful for CI
56
+ # environments, or other environments where you may need more workers than
57
+ # you do for local testing.
58
+ #
59
+ # If the number of workers is set to +1+ or fewer, the tests will not be
60
+ # parallelized.
61
+ #
62
+ # If +workers+ is set to +:number_of_processors+, the number of workers will be
63
+ # set to the actual core count on the machine you are on.
64
+ #
65
+ # The default parallelization method is to fork processes. If you'd like to
66
+ # use threads instead you can pass <tt>with: :threads</tt> to the +parallelize+
67
+ # method. Note the threaded parallelization does not create multiple
68
+ # database and will not work with system tests at this time.
69
+ #
70
+ # parallelize(workers: :number_of_processors, with: :threads)
71
+ #
72
+ # The threaded parallelization uses minitest's parallel executor directly.
73
+ # The processes parallelization uses a Ruby DRb server.
74
+ def parallelize(workers: :number_of_processors, with: :processes)
75
+ workers = Concurrent.physical_processor_count if workers == :number_of_processors
76
+ workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
77
+
78
+ return if workers <= 1
79
+
80
+ executor = case with
81
+ when :processes
82
+ Testing::Parallelization.new(workers)
83
+ when :threads
84
+ Minitest::Parallel::Executor.new(workers)
85
+ else
86
+ raise ArgumentError, "#{with} is not a supported parallelization executor."
87
+ end
88
+
89
+ self.lock_threads = false if defined?(self.lock_threads) && with == :threads
90
+
91
+ Minitest.parallel_executor = executor
92
+
93
+ parallelize_me!
94
+ end
95
+
96
+ # Set up hook for parallel testing. This can be used if you have multiple
97
+ # databases or any behavior that needs to be run after the process is forked
98
+ # but before the tests run.
99
+ #
100
+ # Note: this feature is not available with the threaded parallelization.
101
+ #
102
+ # In your +test_helper.rb+ add the following:
103
+ #
104
+ # class ActiveSupport::TestCase
105
+ # parallelize_setup do
106
+ # # create databases
107
+ # end
108
+ # end
109
+ def parallelize_setup(&block)
110
+ ActiveSupport::Testing::Parallelization.after_fork_hook do |worker|
111
+ yield worker
112
+ end
113
+ end
114
+
115
+ # Clean up hook for parallel testing. This can be used to drop databases
116
+ # if your app uses multiple write/read databases or other clean up before
117
+ # the tests finish. This runs before the forked process is closed.
118
+ #
119
+ # Note: this feature is not available with the threaded parallelization.
120
+ #
121
+ # In your +test_helper.rb+ add the following:
122
+ #
123
+ # class ActiveSupport::TestCase
124
+ # parallelize_teardown do
125
+ # # drop databases
126
+ # end
127
+ # end
128
+ def parallelize_teardown(&block)
129
+ ActiveSupport::Testing::Parallelization.run_cleanup_hook do |worker|
130
+ yield worker
131
+ end
132
+ end
133
+ end
134
+
135
+ alias_method :method_name, :name
136
+
137
+ include ActiveSupport::Testing::TaggedLogging
138
+ prepend ActiveSupport::Testing::SetupAndTeardown
139
+ include ActiveSupport::Testing::Assertions
140
+ include ActiveSupport::Testing::Deprecation
141
+ include ActiveSupport::Testing::TimeHelpers
142
+ include ActiveSupport::Testing::FileFixtures
143
+ extend ActiveSupport::Testing::Declarative
144
+
145
+ # test/unit backwards compatibility methods
146
+ alias :assert_raise :assert_raises
147
+ alias :assert_not_empty :refute_empty
148
+ alias :assert_not_equal :refute_equal
149
+ alias :assert_not_in_delta :refute_in_delta
150
+ alias :assert_not_in_epsilon :refute_in_epsilon
151
+ alias :assert_not_includes :refute_includes
152
+ alias :assert_not_instance_of :refute_instance_of
153
+ alias :assert_not_kind_of :refute_kind_of
154
+ alias :assert_no_match :refute_match
155
+ alias :assert_not_nil :refute_nil
156
+ alias :assert_not_operator :refute_operator
157
+ alias :assert_not_predicate :refute_predicate
158
+ alias :assert_not_respond_to :refute_respond_to
159
+ alias :assert_not_same :refute_same
160
+
161
+ ActiveSupport.run_load_hooks(:active_support_test_case, self)
162
+ end
163
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TimeZoneTestHelpers
4
+ def with_tz_default(tz = nil)
5
+ old_tz = Time.zone
6
+ Time.zone = tz
7
+ yield
8
+ ensure
9
+ Time.zone = old_tz
10
+ end
11
+
12
+ def with_env_tz(new_tz = "US/Eastern")
13
+ old_tz, ENV["TZ"] = ENV["TZ"], new_tz
14
+ yield
15
+ ensure
16
+ old_tz ? ENV["TZ"] = old_tz : ENV.delete("TZ")
17
+ end
18
+
19
+ def with_preserve_timezone(value)
20
+ old_preserve_tz = ActiveSupport.to_time_preserves_timezone
21
+ ActiveSupport.to_time_preserves_timezone = value
22
+ yield
23
+ ensure
24
+ ActiveSupport.to_time_preserves_timezone = old_preserve_tz
25
+ end
26
+
27
+ def with_tz_mappings(mappings)
28
+ old_mappings = ActiveSupport::TimeZone::MAPPING.dup
29
+ ActiveSupport::TimeZone.clear
30
+ ActiveSupport::TimeZone::MAPPING.clear
31
+ ActiveSupport::TimeZone::MAPPING.merge!(mappings)
32
+
33
+ yield
34
+ ensure
35
+ ActiveSupport::TimeZone.clear
36
+ ActiveSupport::TimeZone::MAPPING.clear
37
+ ActiveSupport::TimeZone::MAPPING.merge!(old_mappings)
38
+ end
39
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ ORIG_ARGV = ARGV.dup
4
+
5
+ require "bundler/setup"
6
+ require "active_support/core_ext/kernel/reporting"
7
+
8
+ silence_warnings do
9
+ Encoding.default_internal = Encoding::UTF_8
10
+ Encoding.default_external = Encoding::UTF_8
11
+ end
12
+
13
+ require "active_support/testing/autorun"
14
+ require "active_support/testing/method_call_assertions"
15
+
16
+ ENV["NO_RELOAD"] = "1"
17
+ require "active_support"
18
+
19
+ Thread.abort_on_exception = true
20
+
21
+ # Show backtraces for deprecated behavior for quicker cleanup.
22
+ ActiveSupport::Deprecation.debug = true
23
+
24
+ # Default to old to_time behavior but allow running tests with new behavior
25
+ ActiveSupport.to_time_preserves_timezone = ENV["PRESERVE_TIMEZONES"] == "1"
26
+
27
+ # Disable available locale checks to avoid warnings running the test suite.
28
+ I18n.enforce_available_locales = false
29
+
30
+ class ActiveSupport::TestCase
31
+ if Process.respond_to?(:fork) && !Gem.win_platform?
32
+ parallelize
33
+ else
34
+ parallelize(with: :threads)
35
+ end
36
+
37
+ include ActiveSupport::Testing::MethodCallAssertions
38
+
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
49
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "abstract_unit"
4
+ require "active_support/json"
5
+ require "active_support/time"
6
+ require_relative "time_zone_test_helpers"
7
+
8
+ class TestJSONDecoding < ActiveSupport::TestCase
9
+ include TimeZoneTestHelpers
10
+
11
+ class Foo
12
+ def self.json_create(object)
13
+ "Foo"
14
+ end
15
+ end
16
+
17
+ TESTS = {
18
+ %q({"returnTo":{"\/categories":"\/"}}) => { "returnTo" => { "/categories" => "/" } },
19
+ %q({"return\\"To\\":":{"\/categories":"\/"}}) => { "return\"To\":" => { "/categories" => "/" } },
20
+ %q({"returnTo":{"\/categories":1}}) => { "returnTo" => { "/categories" => 1 } },
21
+ %({"returnTo":[1,"a"]}) => { "returnTo" => [1, "a"] },
22
+ %({"returnTo":[1,"\\"a\\",", "b"]}) => { "returnTo" => [1, "\"a\",", "b"] },
23
+ %({"a": "'", "b": "5,000"}) => { "a" => "'", "b" => "5,000" },
24
+ %({"a": "a's, b's and c's", "b": "5,000"}) => { "a" => "a's, b's and c's", "b" => "5,000" },
25
+ # multibyte
26
+ %({"matzue": "松江", "asakusa": "浅草"}) => { "matzue" => "松江", "asakusa" => "浅草" },
27
+ %({"a": "2007-01-01"}) => { "a" => Date.new(2007, 1, 1) },
28
+ %({"a": "2007-01-01 01:12:34 Z"}) => { "a" => Time.utc(2007, 1, 1, 1, 12, 34) },
29
+ %(["2007-01-01 01:12:34 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34)],
30
+ %(["2007-01-01 01:12:34 Z", "2007-01-01 01:12:35 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34), Time.utc(2007, 1, 1, 1, 12, 35)],
31
+ # no time zone
32
+ %({"a": "2007-01-01 01:12:34"}) => { "a" => Time.new(2007, 1, 1, 1, 12, 34, "-05:00") },
33
+ # invalid date
34
+ %({"a": "1089-10-40"}) => { "a" => "1089-10-40" },
35
+ # xmlschema date notation
36
+ %({"a": "2009-08-10T19:01:02"}) => { "a" => Time.new(2009, 8, 10, 19, 1, 2, "-04:00") },
37
+ %({"a": "2009-08-10T19:01:02Z"}) => { "a" => Time.utc(2009, 8, 10, 19, 1, 2) },
38
+ %({"a": "2009-08-10T19:01:02+02:00"}) => { "a" => Time.utc(2009, 8, 10, 17, 1, 2) },
39
+ %({"a": "2009-08-10T19:01:02-05:00"}) => { "a" => Time.utc(2009, 8, 11, 00, 1, 2) },
40
+ # needs to be *exact*
41
+ %({"a": " 2007-01-01 01:12:34 Z "}) => { "a" => " 2007-01-01 01:12:34 Z " },
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" },
45
+ %([]) => [],
46
+ %({}) => {},
47
+ %({"a":1}) => { "a" => 1 },
48
+ %({"a": ""}) => { "a" => "" },
49
+ %({"a":"\\""}) => { "a" => "\"" },
50
+ %({"a": null}) => { "a" => nil },
51
+ %({"a": true}) => { "a" => true },
52
+ %({"a": false}) => { "a" => false },
53
+ '{"bad":"\\\\","trailing":""}' => { "bad" => "\\", "trailing" => "" },
54
+ %q({"a": "http:\/\/test.host\/posts\/1"}) => { "a" => "http://test.host/posts/1" },
55
+ %q({"a": "\u003cunicode\u0020escape\u003e"}) => { "a" => "<unicode escape>" },
56
+ '{"a": "\\\\u0020skip double backslashes"}' => { "a" => "\\u0020skip double backslashes" },
57
+ %q({"a": "\u003cbr /\u003e"}) => { "a" => "<br />" },
58
+ %q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => { "b" => ["<i>", "<b>", "<u>"] },
59
+ # test combination of dates and escaped or unicode encoded data in arrays
60
+ %q([{"d":"1970-01-01", "s":"\u0020escape"},{"d":"1970-01-01", "s":"\u0020escape"}]) =>
61
+ [{ "d" => Date.new(1970, 1, 1), "s" => " escape" }, { "d" => Date.new(1970, 1, 1), "s" => " escape" }],
62
+ %q([{"d":"1970-01-01","s":"http:\/\/example.com"},{"d":"1970-01-01","s":"http:\/\/example.com"}]) =>
63
+ [{ "d" => Date.new(1970, 1, 1), "s" => "http://example.com" },
64
+ { "d" => Date.new(1970, 1, 1), "s" => "http://example.com" }],
65
+ # tests escaping of "\n" char with Yaml backend
66
+ %q({"a":"\n"}) => { "a" => "\n" },
67
+ %q({"a":"\u000a"}) => { "a" => "\n" },
68
+ %q({"a":"Line1\u000aLine2"}) => { "a" => "Line1\nLine2" },
69
+ # prevent json unmarshalling
70
+ '{"json_class":"TestJSONDecoding::Foo"}' => { "json_class" => "TestJSONDecoding::Foo" },
71
+ # json "fragments" - these are invalid JSON, but ActionPack relies on this
72
+ '"a string"' => "a string",
73
+ "1.1" => 1.1,
74
+ "1" => 1,
75
+ "-1" => -1,
76
+ "true" => true,
77
+ "false" => false,
78
+ "null" => nil
79
+ }
80
+
81
+ TESTS.each_with_index do |(json, expected), index|
82
+ fail_message = "JSON decoding failed for #{json}"
83
+
84
+ test "json decodes #{index}" do
85
+ with_tz_default "Eastern Time (US & Canada)" do
86
+ with_parse_json_times(true) do
87
+ silence_warnings do
88
+ if expected.nil?
89
+ assert_nil ActiveSupport::JSON.decode(json), fail_message
90
+ else
91
+ assert_equal expected, ActiveSupport::JSON.decode(json), fail_message
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ test "json decodes time json with time parsing disabled" do
100
+ with_parse_json_times(false) do
101
+ expected = { "a" => "2007-01-01 01:12:34 Z" }
102
+ assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
103
+ end
104
+ end
105
+
106
+ def test_failed_json_decoding
107
+ assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%(undefined)) }
108
+ assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%({a: 1})) }
109
+ assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%({: 1})) }
110
+ assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%()) }
111
+ end
112
+
113
+ def test_cannot_pass_unsupported_options
114
+ assert_raise(ArgumentError) { ActiveSupport::JSON.decode("", create_additions: true) }
115
+ end
116
+
117
+ private
118
+ def with_parse_json_times(value)
119
+ old_value = ActiveSupport.parse_json_times
120
+ ActiveSupport.parse_json_times = value
121
+ yield
122
+ ensure
123
+ ActiveSupport.parse_json_times = old_value
124
+ end
125
+ end