oj 3.8.0 → 3.10.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/oj/custom.c +61 -36
  4. data/ext/oj/dump.c +9 -12
  5. data/ext/oj/dump_compat.c +6 -9
  6. data/ext/oj/dump_object.c +14 -9
  7. data/ext/oj/extconf.rb +1 -0
  8. data/ext/oj/mimic_json.c +4 -2
  9. data/ext/oj/object.c +8 -5
  10. data/ext/oj/oj.c +47 -30
  11. data/ext/oj/oj.h +6 -4
  12. data/ext/oj/parse.c +15 -2
  13. data/ext/oj/parse.h +1 -0
  14. data/ext/oj/rails.c +9 -2
  15. data/ext/oj/resolve.c +3 -3
  16. data/ext/oj/sparse.c +4 -0
  17. data/ext/oj/util.c +5 -5
  18. data/ext/oj/val_stack.c +9 -9
  19. data/ext/oj/val_stack.h +9 -9
  20. data/lib/oj/json.rb +1 -1
  21. data/lib/oj/version.rb +1 -1
  22. data/pages/Options.md +4 -0
  23. data/pages/Rails.md +21 -21
  24. data/test/activesupport5/abstract_unit.rb +45 -0
  25. data/test/activesupport5/decoding_test.rb +68 -60
  26. data/test/activesupport5/encoding_test.rb +111 -96
  27. data/test/activesupport5/encoding_test_cases.rb +33 -25
  28. data/test/activesupport5/test_helper.rb +43 -21
  29. data/test/activesupport5/time_zone_test_helpers.rb +18 -3
  30. data/test/activesupport6/abstract_unit.rb +44 -0
  31. data/test/activesupport6/decoding_test.rb +133 -0
  32. data/test/activesupport6/encoding_test.rb +507 -0
  33. data/test/activesupport6/encoding_test_cases.rb +98 -0
  34. data/test/activesupport6/test_common.rb +17 -0
  35. data/test/activesupport6/test_helper.rb +163 -0
  36. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  37. data/test/bar.rb +8 -11
  38. data/test/baz.rb +16 -0
  39. data/test/test_compat.rb +0 -7
  40. data/test/test_custom.rb +6 -2
  41. data/test/test_integer_range.rb +1 -2
  42. data/test/test_object.rb +4 -3
  43. data/test/test_strict.rb +24 -1
  44. data/test/test_various.rb +41 -62
  45. metadata +20 -2
@@ -1,7 +1,9 @@
1
- require 'activesupport5/test_helper'
2
- require 'active_support/json'
3
- require 'active_support/time'
4
- require 'activesupport5/time_zone_test_helpers'
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"
5
7
 
6
8
  require 'oj'
7
9
 
@@ -10,6 +12,11 @@ Oj::Rails.set_decoder()
10
12
  class TestJSONDecoding < ActiveSupport::TestCase
11
13
  include TimeZoneTestHelpers
12
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
+
13
20
  class Foo
14
21
  def self.json_create(object)
15
22
  "Foo"
@@ -17,76 +24,78 @@ class TestJSONDecoding < ActiveSupport::TestCase
17
24
  end
18
25
 
19
26
  TESTS = {
20
- %q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
21
- %q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
22
- %q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
23
- %({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
24
- %({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
25
- %({"a": "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
26
- %({"a": "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
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" },
27
34
  # multibyte
28
- %({"matzue": "松江", "asakusa": "浅草"}) => {"matzue" => "松江", "asakusa" => "浅草"},
29
- %({"a": "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
30
- %({"a": "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
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) },
31
38
  %(["2007-01-01 01:12:34 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34)],
32
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)],
33
40
  # no time zone
34
- %({"a": "2007-01-01 01:12:34"}) => {'a' => Time.new(2007, 1, 1, 1, 12, 34, "-05:00")},
41
+ %({"a": "2007-01-01 01:12:34"}) => { "a" => Time.new(2007, 1, 1, 1, 12, 34, "-05:00") },
35
42
  # invalid date
36
- %({"a": "1089-10-40"}) => {'a' => "1089-10-40"},
43
+ %({"a": "1089-10-40"}) => { "a" => "1089-10-40" },
37
44
  # xmlschema date notation
38
- %({"a": "2009-08-10T19:01:02"}) => {'a' => Time.new(2009, 8, 10, 19, 1, 2, "-04:00")},
39
- %({"a": "2009-08-10T19:01:02Z"}) => {'a' => Time.utc(2009, 8, 10, 19, 1, 2)},
40
- %({"a": "2009-08-10T19:01:02+02:00"}) => {'a' => Time.utc(2009, 8, 10, 17, 1, 2)},
41
- %({"a": "2009-08-10T19:01:02-05:00"}) => {'a' => Time.utc(2009, 8, 11, 00, 1, 2)},
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) },
42
49
  # needs to be *exact*
43
- %({"a": " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
44
- %({"a": "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
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" },
45
52
  %([]) => [],
46
53
  %({}) => {},
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
- %q({"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
- %q({"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>"]},
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>"] },
59
66
  # test combination of dates and escaped or unicode encoded data in arrays
60
67
  %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'}],
68
+ [{ "d" => Date.new(1970, 1, 1), "s" => " escape" }, { "d" => Date.new(1970, 1, 1), "s" => " escape" }],
62
69
  %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'}],
70
+ [{ "d" => Date.new(1970, 1, 1), "s" => "http://example.com" },
71
+ { "d" => Date.new(1970, 1, 1), "s" => "http://example.com" }],
65
72
  # 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"},
73
+ %q({"a":"\n"}) => { "a" => "\n" },
74
+ %q({"a":"\u000a"}) => { "a" => "\n" },
75
+ %q({"a":"Line1\u000aLine2"}) => { "a" => "Line1\nLine2" },
69
76
  # prevent json unmarshalling
70
- %q({"json_class":"TestJSONDecoding::Foo"}) => {"json_class"=>"TestJSONDecoding::Foo"},
77
+ '{"json_class":"TestJSONDecoding::Foo"}' => { "json_class" => "TestJSONDecoding::Foo" },
71
78
  # json "fragments" - these are invalid JSON, but ActionPack relies on this
72
- %q("a string") => "a string",
73
- %q(1.1) => 1.1,
74
- %q(1) => 1,
75
- %q(-1) => -1,
76
- %q(true) => true,
77
- %q(false) => false,
78
- %q(null) => nil
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
79
86
  }
80
87
 
81
88
  TESTS.each_with_index do |(json, expected), index|
89
+ fail_message = "JSON decoding failed for #{json}"
90
+
82
91
  test "json decodes #{index}" do
83
- with_tz_default 'Eastern Time (US & Canada)' do
92
+ with_tz_default "Eastern Time (US & Canada)" do
84
93
  with_parse_json_times(true) do
85
94
  silence_warnings do
86
95
  if expected.nil?
87
- assert_nil(ActiveSupport::JSON.decode(json), "JSON failed for #{json}")
96
+ assert_nil ActiveSupport::JSON.decode(json), fail_message
88
97
  else
89
- assert_equal(expected, ActiveSupport::JSON.decode(json), "JSON failed for #{json}")
98
+ assert_equal expected, ActiveSupport::JSON.decode(json), fail_message
90
99
  end
91
100
  end
92
101
  end
@@ -96,7 +105,7 @@ class TestJSONDecoding < ActiveSupport::TestCase
96
105
 
97
106
  test "json decodes time json with time parsing disabled" do
98
107
  with_parse_json_times(false) do
99
- expected = {"a" => "2007-01-01 01:12:34 Z"}
108
+ expected = { "a" => "2007-01-01 01:12:34 Z" }
100
109
  assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
101
110
  end
102
111
  end
@@ -114,12 +123,11 @@ class TestJSONDecoding < ActiveSupport::TestCase
114
123
 
115
124
  private
116
125
 
117
- def with_parse_json_times(value)
118
- old_value = ActiveSupport.parse_json_times
119
- ActiveSupport.parse_json_times = value
120
- yield
121
- ensure
122
- ActiveSupport.parse_json_times = old_value
123
- end
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
124
133
  end
125
-
@@ -1,11 +1,13 @@
1
- # coding: utf-8
2
- require 'activesupport5/test_helper'
3
- require 'securerandom'
4
- require 'active_support/core_ext/string/inflections'
5
- require 'active_support/json'
6
- require 'active_support/time'
7
- require 'activesupport5/time_zone_test_helpers'
8
- require 'activesupport5/encoding_test_cases'
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+ require_relative "abstract_unit"
5
+ require "active_support/core_ext/string/inflections"
6
+ require "active_support/core_ext/regexp"
7
+ require "active_support/json"
8
+ require "active_support/time"
9
+ require_relative "time_zone_test_helpers"
10
+ require_relative "encoding_test_cases"
9
11
 
10
12
  require 'oj'
11
13
 
@@ -18,9 +20,17 @@ Oj::Rails.optimize()
18
20
  class TestJSONEncoding < ActiveSupport::TestCase
19
21
  include TimeZoneTestHelpers
20
22
 
23
+ # Added for testing if Oj is used.
24
+ test "oj is used as an encoder" do
25
+ assert_equal ActiveSupport.json_encoder, Oj::Rails::Encoder
26
+ end
27
+
21
28
  def sorted_json(json)
22
- return json unless json =~ /^\{.*\}$/
23
- '{' + json[1..-2].split(',').sort.join(',') + '}'
29
+ if json.start_with?("{") && json.end_with?("}")
30
+ "{" + json[1..-2].split(",").sort.join(",") + "}"
31
+ else
32
+ json
33
+ end
24
34
  end
25
35
 
26
36
  JSONTest::EncodingTestCases.constants.each do |class_tests|
@@ -28,8 +38,10 @@ class TestJSONEncoding < ActiveSupport::TestCase
28
38
  begin
29
39
  prev = ActiveSupport.use_standard_json_time_format
30
40
 
31
- ActiveSupport.escape_html_entities_in_json = class_tests !~ /^Standard/
32
- ActiveSupport.use_standard_json_time_format = class_tests =~ /^Standard/
41
+ standard_class_tests = /Standard/.match?(class_tests)
42
+
43
+ ActiveSupport.escape_html_entities_in_json = !standard_class_tests
44
+ ActiveSupport.use_standard_json_time_format = standard_class_tests
33
45
  JSONTest::EncodingTestCases.const_get(class_tests).each do |pair|
34
46
  assert_equal pair.last, sorted_json(ActiveSupport::JSON.encode(pair.first))
35
47
  end
@@ -50,12 +62,12 @@ class TestJSONEncoding < ActiveSupport::TestCase
50
62
  end
51
63
 
52
64
  def test_hash_encoding
53
- assert_equal %({\"a\":\"b\"}), ActiveSupport::JSON.encode(:a => :b)
54
- assert_equal %({\"a\":1}), ActiveSupport::JSON.encode('a' => 1)
55
- assert_equal %({\"a\":[1,2]}), ActiveSupport::JSON.encode('a' => [1,2])
65
+ assert_equal %({\"a\":\"b\"}), ActiveSupport::JSON.encode(a: :b)
66
+ assert_equal %({\"a\":1}), ActiveSupport::JSON.encode("a" => 1)
67
+ assert_equal %({\"a\":[1,2]}), ActiveSupport::JSON.encode("a" => [1, 2])
56
68
  assert_equal %({"1":2}), ActiveSupport::JSON.encode(1 => 2)
57
69
 
58
- assert_equal %({\"a\":\"b\",\"c\":\"d\"}), sorted_json(ActiveSupport::JSON.encode(:a => :b, :c => :d))
70
+ assert_equal %({\"a\":\"b\",\"c\":\"d\"}), sorted_json(ActiveSupport::JSON.encode(a: :b, c: :d))
59
71
  end
60
72
 
61
73
  def test_hash_keys_encoding
@@ -68,28 +80,28 @@ class TestJSONEncoding < ActiveSupport::TestCase
68
80
  def test_utf8_string_encoded_properly
69
81
  # The original test seems to expect that
70
82
  # ActiveSupport.escape_html_entities_in_json reverts to true even after
71
- # being set to false. I haven't been able to figure that out so the value
72
- # is set to true, the default, before running the test. This might be
73
- # wrong but for now it will have to do.
74
- ActiveSupport.escape_html_entities_in_json = true
75
- result = ActiveSupport::JSON.encode('€2.99')
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")
76
88
  assert_equal '"€2.99"', result
77
89
  assert_equal(Encoding::UTF_8, result.encoding)
78
90
 
79
- result = ActiveSupport::JSON.encode('✎☺')
91
+ result = ActiveSupport::JSON.encode("✎☺")
80
92
  assert_equal '"✎☺"', result
81
93
  assert_equal(Encoding::UTF_8, result.encoding)
82
94
  end
83
95
 
84
96
  def test_non_utf8_string_transcodes
85
- s = ''.encode('Shift_JIS')
97
+ s = "".encode("Shift_JIS")
86
98
  result = ActiveSupport::JSON.encode(s)
87
99
  assert_equal '"二"', result
88
100
  assert_equal Encoding::UTF_8, result.encoding
89
101
  end
90
102
 
91
103
  def test_wide_utf8_chars
92
- w = '𠜎'
104
+ w = "𠜎"
93
105
  result = ActiveSupport::JSON.encode(w)
94
106
  assert_equal '"𠜎"', result
95
107
  end
@@ -98,33 +110,33 @@ class TestJSONEncoding < ActiveSupport::TestCase
98
110
  hash = { string: "𐒑" }
99
111
  json = ActiveSupport::JSON.encode(hash)
100
112
  decoded_hash = ActiveSupport::JSON.decode(json)
101
- assert_equal "𐒑", decoded_hash['string']
113
+ assert_equal "𐒑", decoded_hash["string"]
102
114
  end
103
115
 
104
116
  def test_hash_key_identifiers_are_always_quoted
105
- values = {0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B"}
117
+ values = { 0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B" }
106
118
  assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(ActiveSupport::JSON.encode(values))
107
119
  end
108
120
 
109
121
  def test_hash_should_allow_key_filtering_with_only
110
- assert_equal %({"a":1}), ActiveSupport::JSON.encode({'a' => 1, :b => 2, :c => 3}, :only => 'a')
122
+ assert_equal %({"a":1}), ActiveSupport::JSON.encode({ "a" => 1, :b => 2, :c => 3 }, { only: "a" })
111
123
  end
112
124
 
113
125
  def test_hash_should_allow_key_filtering_with_except
114
- assert_equal %({"b":2}), ActiveSupport::JSON.encode({'foo' => 'bar', :b => 2, :c => 3}, :except => ['foo', :c])
126
+ assert_equal %({"b":2}), ActiveSupport::JSON.encode({ "foo" => "bar", :b => 2, :c => 3 }, { except: ["foo", :c] })
115
127
  end
116
128
 
117
129
  def test_time_to_json_includes_local_offset
118
130
  with_standard_json_time_format(true) do
119
- with_env_tz 'US/Eastern' do
120
- assert_equal %("2005-02-01T15:15:10.000-05:00"), ActiveSupport::JSON.encode(Time.local(2005,2,1,15,15,10))
131
+ with_env_tz "US/Eastern" do
132
+ assert_equal %("2005-02-01T15:15:10.000-05:00"), ActiveSupport::JSON.encode(Time.local(2005, 2, 1, 15, 15, 10))
121
133
  end
122
134
  end
123
135
  end
124
136
 
125
137
  def test_hash_with_time_to_json
126
138
  with_standard_json_time_format(false) do
127
- assert_equal '{"time":"2009/01/01 00:00:00 +0000"}', { :time => Time.utc(2009) }.to_json
139
+ assert_equal '{"time":"2009/01/01 00:00:00 +0000"}', { time: Time.utc(2009) }.to_json
128
140
  end
129
141
  end
130
142
 
@@ -132,8 +144,8 @@ class TestJSONEncoding < ActiveSupport::TestCase
132
144
  assert_nothing_raised do
133
145
  hash = {
134
146
  "CHI" => {
135
- :display_name => "chicago",
136
- :latitude => 123.234
147
+ display_name: "chicago",
148
+ latitude: 123.234
137
149
  }
138
150
  }
139
151
  ActiveSupport::JSON.encode(hash)
@@ -142,64 +154,64 @@ class TestJSONEncoding < ActiveSupport::TestCase
142
154
 
143
155
  def test_hash_like_with_options
144
156
  h = JSONTest::Hashlike.new
145
- json = h.to_json :only => [:foo]
157
+ json = h.to_json only: [:foo]
146
158
 
147
- assert_equal({"foo"=>"hello"}, JSON.parse(json))
159
+ assert_equal({ "foo" => "hello" }, JSON.parse(json))
148
160
  end
149
161
 
150
162
  def test_object_to_json_with_options
151
163
  obj = Object.new
152
164
  obj.instance_variable_set :@foo, "hello"
153
165
  obj.instance_variable_set :@bar, "world"
154
- json = obj.to_json :only => ["foo"]
166
+ json = obj.to_json only: ["foo"]
155
167
 
156
- assert_equal({"foo"=>"hello"}, JSON.parse(json))
168
+ assert_equal({ "foo" => "hello" }, JSON.parse(json))
157
169
  end
158
170
 
159
171
  def test_struct_to_json_with_options
160
172
  struct = Struct.new(:foo, :bar).new
161
173
  struct.foo = "hello"
162
174
  struct.bar = "world"
163
- json = struct.to_json :only => [:foo]
175
+ json = struct.to_json only: [:foo]
164
176
 
165
- assert_equal({"foo"=>"hello"}, JSON.parse(json))
177
+ assert_equal({ "foo" => "hello" }, JSON.parse(json))
166
178
  end
167
179
 
168
180
  def test_hash_should_pass_encoding_options_to_children_in_as_json
169
181
  person = {
170
- :name => 'John',
171
- :address => {
172
- :city => 'London',
173
- :country => 'UK'
182
+ name: "John",
183
+ address: {
184
+ city: "London",
185
+ country: "UK"
174
186
  }
175
187
  }
176
- json = person.as_json :only => [:address, :city]
188
+ json = person.as_json only: [:address, :city]
177
189
 
178
- assert_equal({ 'address' => { 'city' => 'London' }}, json)
190
+ assert_equal({ "address" => { "city" => "London" } }, json)
179
191
  end
180
192
 
181
193
  def test_hash_should_pass_encoding_options_to_children_in_to_json
182
194
  person = {
183
- :name => 'John',
184
- :address => {
185
- :city => 'London',
186
- :country => 'UK'
195
+ name: "John",
196
+ address: {
197
+ city: "London",
198
+ country: "UK"
187
199
  }
188
200
  }
189
- json = person.to_json :only => [:address, :city]
201
+ json = person.to_json only: [:address, :city]
190
202
 
191
203
  assert_equal(%({"address":{"city":"London"}}), json)
192
204
  end
193
205
 
194
206
  def test_array_should_pass_encoding_options_to_children_in_as_json
195
207
  people = [
196
- { :name => 'John', :address => { :city => 'London', :country => 'UK' }},
197
- { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }}
208
+ { name: "John", address: { city: "London", country: "UK" } },
209
+ { name: "Jean", address: { city: "Paris", country: "France" } }
198
210
  ]
199
- json = people.as_json :only => [:address, :city]
211
+ json = people.as_json only: [:address, :city]
200
212
  expected = [
201
- { 'address' => { 'city' => 'London' }},
202
- { 'address' => { 'city' => 'Paris' }}
213
+ { "address" => { "city" => "London" } },
214
+ { "address" => { "city" => "Paris" } }
203
215
  ]
204
216
 
205
217
  assert_equal(expected, json)
@@ -207,20 +219,20 @@ class TestJSONEncoding < ActiveSupport::TestCase
207
219
 
208
220
  def test_array_should_pass_encoding_options_to_children_in_to_json
209
221
  people = [
210
- { :name => 'John', :address => { :city => 'London', :country => 'UK' }},
211
- { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }}
222
+ { name: "John", address: { city: "London", country: "UK" } },
223
+ { name: "Jean", address: { city: "Paris", country: "France" } }
212
224
  ]
213
- json = people.to_json :only => [:address, :city]
225
+ json = people.to_json only: [:address, :city]
214
226
 
215
227
  assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json)
216
228
  end
217
229
 
218
230
  People = Class.new(BasicObject) do
219
231
  include Enumerable
220
- def initialize()
232
+ def initialize
221
233
  @people = [
222
- { :name => 'John', :address => { :city => 'London', :country => 'UK' }},
223
- { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }}
234
+ { name: "John", address: { city: "London", country: "UK" } },
235
+ { name: "Jean", address: { city: "Paris", country: "France" } }
224
236
  ]
225
237
  end
226
238
  def each(*, &blk)
@@ -232,32 +244,32 @@ class TestJSONEncoding < ActiveSupport::TestCase
232
244
  end
233
245
 
234
246
  def test_enumerable_should_generate_json_with_as_json
235
- json = People.new.as_json :only => [:address, :city]
247
+ json = People.new.as_json only: [:address, :city]
236
248
  expected = [
237
- { 'address' => { 'city' => 'London' }},
238
- { 'address' => { 'city' => 'Paris' }}
249
+ { "address" => { "city" => "London" } },
250
+ { "address" => { "city" => "Paris" } }
239
251
  ]
240
252
 
241
253
  assert_equal(expected, json)
242
254
  end
243
255
 
244
256
  def test_enumerable_should_generate_json_with_to_json
245
- json = People.new.to_json :only => [:address, :city]
257
+ json = People.new.to_json only: [:address, :city]
246
258
  assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json)
247
259
  end
248
260
 
249
261
  def test_enumerable_should_pass_encoding_options_to_children_in_as_json
250
- json = People.new.each.as_json :only => [:address, :city]
262
+ json = People.new.each.as_json only: [:address, :city]
251
263
  expected = [
252
- { 'address' => { 'city' => 'London' }},
253
- { 'address' => { 'city' => 'Paris' }}
264
+ { "address" => { "city" => "London" } },
265
+ { "address" => { "city" => "Paris" } }
254
266
  ]
255
267
 
256
268
  assert_equal(expected, json)
257
269
  end
258
270
 
259
271
  def test_enumerable_should_pass_encoding_options_to_children_in_to_json
260
- json = People.new.each.to_json :only => [:address, :city]
272
+ json = People.new.each.to_json only: [:address, :city]
261
273
 
262
274
  assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json)
263
275
  end
@@ -265,7 +277,7 @@ class TestJSONEncoding < ActiveSupport::TestCase
265
277
  class CustomWithOptions
266
278
  attr_accessor :foo, :bar
267
279
 
268
- def as_json(options={})
280
+ def as_json(options = {})
269
281
  options[:only] = %w(foo bar)
270
282
  super(options)
271
283
  end
@@ -276,9 +288,9 @@ class TestJSONEncoding < ActiveSupport::TestCase
276
288
  f.foo = "hello"
277
289
  f.bar = "world"
278
290
 
279
- hash = {"foo" => f, "other_hash" => {"foo" => "other_foo", "test" => "other_test"}}
280
- assert_equal({"foo"=>{"foo"=>"hello","bar"=>"world"},
281
- "other_hash" => {"foo"=>"other_foo","test"=>"other_test"}}, ActiveSupport::JSON.decode(hash.to_json))
291
+ hash = { "foo" => f, "other_hash" => { "foo" => "other_foo", "test" => "other_test" } }
292
+ assert_equal({ "foo" => { "foo" => "hello", "bar" => "world" },
293
+ "other_hash" => { "foo" => "other_foo", "test" => "other_test" } }, ActiveSupport::JSON.decode(hash.to_json))
282
294
  end
283
295
 
284
296
  def test_array_to_json_should_not_keep_options_around
@@ -286,9 +298,9 @@ class TestJSONEncoding < ActiveSupport::TestCase
286
298
  f.foo = "hello"
287
299
  f.bar = "world"
288
300
 
289
- array = [f, {"foo" => "other_foo", "test" => "other_test"}]
290
- assert_equal([{"foo"=>"hello","bar"=>"world"},
291
- {"foo"=>"other_foo","test"=>"other_test"}], ActiveSupport::JSON.decode(array.to_json))
301
+ array = [f, { "foo" => "other_foo", "test" => "other_test" }]
302
+ assert_equal([{ "foo" => "hello", "bar" => "world" },
303
+ { "foo" => "other_foo", "test" => "other_test" }], ActiveSupport::JSON.decode(array.to_json))
292
304
  end
293
305
 
294
306
  class OptionsTest
@@ -299,7 +311,7 @@ class TestJSONEncoding < ActiveSupport::TestCase
299
311
 
300
312
  def test_hash_as_json_without_options
301
313
  json = { foo: OptionsTest.new }.as_json
302
- assert_equal({"foo" => :default}, json)
314
+ assert_equal({ "foo" => :default }, json)
303
315
  end
304
316
 
305
317
  def test_array_as_json_without_options
@@ -308,13 +320,12 @@ class TestJSONEncoding < ActiveSupport::TestCase
308
320
  end
309
321
 
310
322
  def test_struct_encoding
311
- Struct.new('UserNameAndEmail', :name, :email)
312
- Struct.new('UserNameAndDate', :name, :date)
313
- Struct.new('Custom', :name, :sub)
314
- user_email = Struct::UserNameAndEmail.new 'David', 'sample@example.com'
315
- user_birthday = Struct::UserNameAndDate.new 'David', Date.new(2010, 01, 01)
316
- custom = Struct::Custom.new 'David', user_birthday
317
-
323
+ Struct.new("UserNameAndEmail", :name, :email)
324
+ Struct.new("UserNameAndDate", :name, :date)
325
+ Struct.new("Custom", :name, :sub)
326
+ user_email = Struct::UserNameAndEmail.new "David", "sample@example.com"
327
+ user_birthday = Struct::UserNameAndDate.new "David", Date.new(2010, 01, 01)
328
+ custom = Struct::Custom.new "David", user_birthday
318
329
 
319
330
  json_strings = ""
320
331
  json_string_and_date = ""
@@ -326,20 +337,20 @@ class TestJSONEncoding < ActiveSupport::TestCase
326
337
  json_custom = custom.to_json
327
338
  end
328
339
 
329
- assert_equal({"name" => "David",
340
+ assert_equal({ "name" => "David",
330
341
  "sub" => {
331
342
  "name" => "David",
332
- "date" => "2010-01-01" }}, ActiveSupport::JSON.decode(json_custom))
343
+ "date" => "2010-01-01" } }, ActiveSupport::JSON.decode(json_custom))
333
344
 
334
- assert_equal({"name" => "David", "email" => "sample@example.com"},
345
+ assert_equal({ "name" => "David", "email" => "sample@example.com" },
335
346
  ActiveSupport::JSON.decode(json_strings))
336
347
 
337
- assert_equal({"name" => "David", "date" => "2010-01-01"},
348
+ assert_equal({ "name" => "David", "date" => "2010-01-01" },
338
349
  ActiveSupport::JSON.decode(json_string_and_date))
339
350
  end
340
351
 
341
352
  def test_nil_true_and_false_represented_as_themselves
342
- assert_nil nil.as_json
353
+ assert_nil nil.as_json
343
354
  assert_equal true, true.as_json
344
355
  assert_equal false, false.as_json
345
356
  end
@@ -351,7 +362,7 @@ class TestJSONEncoding < ActiveSupport::TestCase
351
362
  super
352
363
  end
353
364
 
354
- def as_json(options={})
365
+ def as_json(options = {})
355
366
  @as_json_called = true
356
367
  super
357
368
  end
@@ -391,7 +402,7 @@ EXPECTED
391
402
 
392
403
  def test_twz_to_json_with_use_standard_json_time_format_config_set_to_false
393
404
  with_standard_json_time_format(false) do
394
- zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
405
+ zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
395
406
  time = ActiveSupport::TimeWithZone.new(Time.utc(2000), zone)
396
407
  assert_equal "\"1999/12/31 19:00:00 -0500\"", ActiveSupport::JSON.encode(time)
397
408
  end
@@ -399,7 +410,7 @@ EXPECTED
399
410
 
400
411
  def test_twz_to_json_with_use_standard_json_time_format_config_set_to_true
401
412
  with_standard_json_time_format(true) do
402
- zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
413
+ zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
403
414
  time = ActiveSupport::TimeWithZone.new(Time.utc(2000), zone)
404
415
  assert_equal "\"1999-12-31T19:00:00.000-05:00\"", ActiveSupport::JSON.encode(time)
405
416
  end
@@ -408,7 +419,7 @@ EXPECTED
408
419
  def test_twz_to_json_with_custom_time_precision
409
420
  with_standard_json_time_format(true) do
410
421
  with_time_precision(0) do
411
- zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
422
+ zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
412
423
  time = ActiveSupport::TimeWithZone.new(Time.utc(2000), zone)
413
424
  assert_equal "\"1999-12-31T19:00:00-05:00\"", ActiveSupport::JSON.encode(time)
414
425
  end
@@ -432,7 +443,7 @@ EXPECTED
432
443
  end
433
444
 
434
445
  def test_twz_to_json_when_wrapping_a_date_time
435
- zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
446
+ zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
436
447
  time = ActiveSupport::TimeWithZone.new(DateTime.new(2000), zone)
437
448
  assert_equal '"1999-12-31T19:00:00.000-05:00"', ActiveSupport::JSON.encode(time)
438
449
  end
@@ -454,7 +465,7 @@ EXPECTED
454
465
 
455
466
  class NaNNumber
456
467
  def as_json(options = nil)
457
- { "number" => Float::INFINITY }
468
+ { "number" => Float::NAN }
458
469
  end
459
470
  end
460
471
 
@@ -462,7 +473,11 @@ EXPECTED
462
473
  assert_equal '{"number":null}', NaNNumber.new.to_json
463
474
  end
464
475
 
465
- protected
476
+ def test_to_json_works_on_io_objects
477
+ assert_equal STDOUT.to_s.to_json, STDOUT.to_json
478
+ end
479
+
480
+ private
466
481
 
467
482
  def object_keys(json_object)
468
483
  json_object[1..-2].scan(/([^{}:,\s]+):/).flatten.sort