oj 3.9.2 → 3.10.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/oj/buf.h +2 -30
  4. data/ext/oj/cache8.h +1 -29
  5. data/ext/oj/circarray.c +4 -8
  6. data/ext/oj/circarray.h +1 -4
  7. data/ext/oj/code.c +3 -6
  8. data/ext/oj/code.h +1 -4
  9. data/ext/oj/compat.c +6 -9
  10. data/ext/oj/custom.c +8 -7
  11. data/ext/oj/dump.c +33 -26
  12. data/ext/oj/dump.h +1 -4
  13. data/ext/oj/dump_compat.c +9 -14
  14. data/ext/oj/dump_leaf.c +2 -5
  15. data/ext/oj/dump_object.c +19 -15
  16. data/ext/oj/dump_strict.c +7 -9
  17. data/ext/oj/encode.h +1 -29
  18. data/ext/oj/err.c +1 -4
  19. data/ext/oj/err.h +1 -29
  20. data/ext/oj/extconf.rb +5 -0
  21. data/ext/oj/fast.c +14 -42
  22. data/ext/oj/hash.c +4 -32
  23. data/ext/oj/hash.h +1 -29
  24. data/ext/oj/hash_test.c +1 -29
  25. data/ext/oj/mimic_json.c +28 -10
  26. data/ext/oj/object.c +4 -6
  27. data/ext/oj/odd.c +1 -4
  28. data/ext/oj/odd.h +1 -4
  29. data/ext/oj/oj.c +74 -38
  30. data/ext/oj/oj.h +9 -7
  31. data/ext/oj/parse.c +127 -52
  32. data/ext/oj/parse.h +4 -5
  33. data/ext/oj/rails.c +38 -8
  34. data/ext/oj/rails.h +1 -4
  35. data/ext/oj/reader.c +5 -8
  36. data/ext/oj/reader.h +2 -5
  37. data/ext/oj/resolve.c +1 -4
  38. data/ext/oj/resolve.h +1 -4
  39. data/ext/oj/rxclass.c +3 -6
  40. data/ext/oj/rxclass.h +1 -4
  41. data/ext/oj/saj.c +6 -9
  42. data/ext/oj/scp.c +1 -4
  43. data/ext/oj/sparse.c +31 -26
  44. data/ext/oj/stream_writer.c +4 -9
  45. data/ext/oj/strict.c +3 -6
  46. data/ext/oj/string_writer.c +1 -4
  47. data/ext/oj/trace.c +5 -8
  48. data/ext/oj/trace.h +1 -4
  49. data/ext/oj/util.c +1 -1
  50. data/ext/oj/util.h +1 -1
  51. data/ext/oj/val_stack.c +1 -29
  52. data/ext/oj/val_stack.h +1 -29
  53. data/ext/oj/wab.c +10 -13
  54. data/lib/oj/mimic.rb +45 -1
  55. data/lib/oj/version.rb +1 -1
  56. data/lib/oj.rb +0 -8
  57. data/pages/Modes.md +1 -1
  58. data/pages/Options.md +15 -11
  59. data/pages/Rails.md +60 -21
  60. data/test/activesupport5/abstract_unit.rb +45 -0
  61. data/test/activesupport5/decoding_test.rb +68 -60
  62. data/test/activesupport5/encoding_test.rb +111 -96
  63. data/test/activesupport5/encoding_test_cases.rb +33 -25
  64. data/test/activesupport5/test_helper.rb +43 -21
  65. data/test/activesupport5/time_zone_test_helpers.rb +18 -3
  66. data/test/activesupport6/abstract_unit.rb +44 -0
  67. data/test/activesupport6/decoding_test.rb +133 -0
  68. data/test/activesupport6/encoding_test.rb +507 -0
  69. data/test/activesupport6/encoding_test_cases.rb +98 -0
  70. data/test/activesupport6/test_common.rb +17 -0
  71. data/test/activesupport6/test_helper.rb +163 -0
  72. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  73. data/test/bar.rb +21 -11
  74. data/test/baz.rb +16 -0
  75. data/test/foo.rb +39 -8
  76. data/test/json_gem/json_common_interface_test.rb +8 -3
  77. data/test/prec.rb +23 -0
  78. data/test/sample_json.rb +1 -1
  79. data/test/test_compat.rb +14 -8
  80. data/test/test_custom.rb +36 -6
  81. data/test/test_integer_range.rb +1 -2
  82. data/test/test_object.rb +12 -3
  83. data/test/test_rails.rb +35 -0
  84. data/test/test_strict.rb +24 -1
  85. data/test/test_various.rb +42 -64
  86. data/test/tests.rb +1 -0
  87. metadata +29 -7
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TimeZoneTestHelpers
2
4
  def with_tz_default(tz = nil)
3
5
  old_tz = Time.zone
@@ -7,11 +9,11 @@ module TimeZoneTestHelpers
7
9
  Time.zone = old_tz
8
10
  end
9
11
 
10
- def with_env_tz(new_tz = 'US/Eastern')
11
- old_tz, ENV['TZ'] = ENV['TZ'], new_tz
12
+ def with_env_tz(new_tz = "US/Eastern")
13
+ old_tz, ENV["TZ"] = ENV["TZ"], new_tz
12
14
  yield
13
15
  ensure
14
- old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
16
+ old_tz ? ENV["TZ"] = old_tz : ENV.delete("TZ")
15
17
  end
16
18
 
17
19
  def with_preserve_timezone(value)
@@ -21,4 +23,17 @@ module TimeZoneTestHelpers
21
23
  ensure
22
24
  ActiveSupport.to_time_preserves_timezone = old_preserve_tz
23
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
24
39
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ ORIG_ARGV = ARGV.dup
4
+
5
+ require "active_support/core_ext/kernel/reporting"
6
+
7
+ silence_warnings do
8
+ Encoding.default_internal = Encoding::UTF_8
9
+ Encoding.default_external = Encoding::UTF_8
10
+ end
11
+
12
+ require "active_support/testing/autorun"
13
+ require "active_support/testing/method_call_assertions"
14
+
15
+ ENV["NO_RELOAD"] = "1"
16
+ require "active_support"
17
+
18
+ Thread.abort_on_exception = true
19
+
20
+ # Show backtraces for deprecated behavior for quicker cleanup.
21
+ ActiveSupport::Deprecation.debug = true
22
+
23
+ # Default to old to_time behavior but allow running tests with new behavior
24
+ ActiveSupport.to_time_preserves_timezone = ENV["PRESERVE_TIMEZONES"] == "1"
25
+
26
+ # Disable available locale checks to avoid warnings running the test suite.
27
+ I18n.enforce_available_locales = false
28
+
29
+ class ActiveSupport::TestCase
30
+ include ActiveSupport::Testing::MethodCallAssertions
31
+
32
+ private
33
+ # Skips the current run on Rubinius using Minitest::Assertions#skip
34
+ def rubinius_skip(message = "")
35
+ skip message if RUBY_ENGINE == "rbx"
36
+ end
37
+
38
+ # Skips the current run on JRuby using Minitest::Assertions#skip
39
+ def jruby_skip(message = "")
40
+ skip message if defined?(JRUBY_VERSION)
41
+ end
42
+ end
43
+
44
+ require_relative "test_common"
@@ -0,0 +1,133 @@
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
+ require 'oj'
9
+
10
+ Oj::Rails.set_decoder()
11
+
12
+ class TestJSONDecoding < ActiveSupport::TestCase
13
+ include TimeZoneTestHelpers
14
+
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
+ class Foo
21
+ def self.json_create(object)
22
+ "Foo"
23
+ end
24
+ end
25
+
26
+ TESTS = {
27
+ %q({"returnTo":{"\/categories":"\/"}}) => { "returnTo" => { "/categories" => "/" } },
28
+ %q({"return\\"To\\":":{"\/categories":"\/"}}) => { "return\"To\":" => { "/categories" => "/" } },
29
+ %q({"returnTo":{"\/categories":1}}) => { "returnTo" => { "/categories" => 1 } },
30
+ %({"returnTo":[1,"a"]}) => { "returnTo" => [1, "a"] },
31
+ %({"returnTo":[1,"\\"a\\",", "b"]}) => { "returnTo" => [1, "\"a\",", "b"] },
32
+ %({"a": "'", "b": "5,000"}) => { "a" => "'", "b" => "5,000" },
33
+ %({"a": "a's, b's and c's", "b": "5,000"}) => { "a" => "a's, b's and c's", "b" => "5,000" },
34
+ # multibyte
35
+ %({"matzue": "松江", "asakusa": "浅草"}) => { "matzue" => "松江", "asakusa" => "浅草" },
36
+ %({"a": "2007-01-01"}) => { "a" => Date.new(2007, 1, 1) },
37
+ %({"a": "2007-01-01 01:12:34 Z"}) => { "a" => Time.utc(2007, 1, 1, 1, 12, 34) },
38
+ %(["2007-01-01 01:12:34 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34)],
39
+ %(["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)],
40
+ # no time zone
41
+ %({"a": "2007-01-01 01:12:34"}) => { "a" => Time.new(2007, 1, 1, 1, 12, 34, "-05:00") },
42
+ # invalid date
43
+ %({"a": "1089-10-40"}) => { "a" => "1089-10-40" },
44
+ # xmlschema date notation
45
+ %({"a": "2009-08-10T19:01:02"}) => { "a" => Time.new(2009, 8, 10, 19, 1, 2, "-04:00") },
46
+ %({"a": "2009-08-10T19:01:02Z"}) => { "a" => Time.utc(2009, 8, 10, 19, 1, 2) },
47
+ %({"a": "2009-08-10T19:01:02+02:00"}) => { "a" => Time.utc(2009, 8, 10, 17, 1, 2) },
48
+ %({"a": "2009-08-10T19:01:02-05:00"}) => { "a" => Time.utc(2009, 8, 11, 00, 1, 2) },
49
+ # needs to be *exact*
50
+ %({"a": " 2007-01-01 01:12:34 Z "}) => { "a" => " 2007-01-01 01:12:34 Z " },
51
+ %({"a": "2007-01-01 : it's your birthday"}) => { "a" => "2007-01-01 : it's your birthday" },
52
+ %([]) => [],
53
+ %({}) => {},
54
+ %({"a":1}) => { "a" => 1 },
55
+ %({"a": ""}) => { "a" => "" },
56
+ %({"a":"\\""}) => { "a" => "\"" },
57
+ %({"a": null}) => { "a" => nil },
58
+ %({"a": true}) => { "a" => true },
59
+ %({"a": false}) => { "a" => false },
60
+ '{"bad":"\\\\","trailing":""}' => { "bad" => "\\", "trailing" => "" },
61
+ %q({"a": "http:\/\/test.host\/posts\/1"}) => { "a" => "http://test.host/posts/1" },
62
+ %q({"a": "\u003cunicode\u0020escape\u003e"}) => { "a" => "<unicode escape>" },
63
+ '{"a": "\\\\u0020skip double backslashes"}' => { "a" => "\\u0020skip double backslashes" },
64
+ %q({"a": "\u003cbr /\u003e"}) => { "a" => "<br />" },
65
+ %q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => { "b" => ["<i>", "<b>", "<u>"] },
66
+ # test combination of dates and escaped or unicode encoded data in arrays
67
+ %q([{"d":"1970-01-01", "s":"\u0020escape"},{"d":"1970-01-01", "s":"\u0020escape"}]) =>
68
+ [{ "d" => Date.new(1970, 1, 1), "s" => " escape" }, { "d" => Date.new(1970, 1, 1), "s" => " escape" }],
69
+ %q([{"d":"1970-01-01","s":"http:\/\/example.com"},{"d":"1970-01-01","s":"http:\/\/example.com"}]) =>
70
+ [{ "d" => Date.new(1970, 1, 1), "s" => "http://example.com" },
71
+ { "d" => Date.new(1970, 1, 1), "s" => "http://example.com" }],
72
+ # tests escaping of "\n" char with Yaml backend
73
+ %q({"a":"\n"}) => { "a" => "\n" },
74
+ %q({"a":"\u000a"}) => { "a" => "\n" },
75
+ %q({"a":"Line1\u000aLine2"}) => { "a" => "Line1\nLine2" },
76
+ # prevent json unmarshalling
77
+ '{"json_class":"TestJSONDecoding::Foo"}' => { "json_class" => "TestJSONDecoding::Foo" },
78
+ # json "fragments" - these are invalid JSON, but ActionPack relies on this
79
+ '"a string"' => "a string",
80
+ "1.1" => 1.1,
81
+ "1" => 1,
82
+ "-1" => -1,
83
+ "true" => true,
84
+ "false" => false,
85
+ "null" => nil
86
+ }
87
+
88
+ TESTS.each_with_index do |(json, expected), index|
89
+ fail_message = "JSON decoding failed for #{json}"
90
+
91
+ test "json decodes #{index}" do
92
+ with_tz_default "Eastern Time (US & Canada)" do
93
+ with_parse_json_times(true) do
94
+ silence_warnings do
95
+ if expected.nil?
96
+ assert_nil ActiveSupport::JSON.decode(json), fail_message
97
+ else
98
+ assert_equal expected, ActiveSupport::JSON.decode(json), fail_message
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ test "json decodes time json with time parsing disabled" do
107
+ with_parse_json_times(false) do
108
+ expected = { "a" => "2007-01-01 01:12:34 Z" }
109
+ assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
110
+ end
111
+ end
112
+
113
+ def test_failed_json_decoding
114
+ assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%(undefined)) }
115
+ assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%({a: 1})) }
116
+ assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%({: 1})) }
117
+ assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%()) }
118
+ end
119
+
120
+ def test_cannot_pass_unsupported_options
121
+ assert_raise(ArgumentError) { ActiveSupport::JSON.decode("", create_additions: true) }
122
+ end
123
+
124
+ private
125
+
126
+ def with_parse_json_times(value)
127
+ old_value = ActiveSupport.parse_json_times
128
+ ActiveSupport.parse_json_times = value
129
+ yield
130
+ ensure
131
+ ActiveSupport.parse_json_times = old_value
132
+ end
133
+ end