From 64c88fb5d2caf3c34742a07394ac68b8377c4936 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Wed, 11 Sep 2013 18:36:23 -0700 Subject: Moved all JSON core extensions into core_ext/object/json TL;DR The primary driver is to remove autoload surprise. This is related to #12106. (The root cause for that ticket is that json/add defines Regexp#to_json among others, but here I'll reproduce the problem without json/add.) Before: >> require 'active_support/core_ext/to_json' => true >> //.as_json NoMethodError: undefined method `as_json' for //:Regexp from (irb):3 from /Users/godfrey/.rvm/rubies/ruby-2.0.0-p195/bin/irb:16:in `
' >> //.to_json => "\"(?-mix:)\"" >> //.as_json => "(?-mix:)" After: >> require 'active_support/core_ext/to_json' => true >> //.as_json => "(?-mix:)" This is because ActiveSupport::JSON is autoloaded the first time Object#to_json is called, which causes additional core extentions (previously defined in active_support/json/encoding.rb) to be loaded. When someone require 'active_support/core_ext', the expectation is that it would add certain methods to the core classes NOW. The previous behaviour causes additional methods to be loaded the first time you call `to_json`, which could cause nasty surprises and other unplesant side-effects. This change moves all core extensions in to core_ext/json. AS::JSON is still autoloaded on first #to_json call, but since it nolonger include the core extensions, it should address the aforementioned bug. *Requiring core_ext/object/to_json now causes a deprecation warnning* --- activesupport/test/core_ext/object/json_test.rb | 9 +++++++++ activesupport/test/json/encoding_test.rb | 8 ++++++++ activesupport/test/ordered_hash_test.rb | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 activesupport/test/core_ext/object/json_test.rb (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/object/json_test.rb b/activesupport/test/core_ext/object/json_test.rb new file mode 100644 index 0000000000..d3d31530df --- /dev/null +++ b/activesupport/test/core_ext/object/json_test.rb @@ -0,0 +1,9 @@ +require 'abstract_unit' + +class JsonTest < ActiveSupport::TestCase + # See activesupport/test/json/encoding_test.rb for JSON encoding tests + + def test_deprecated_require_to_json_rb + assert_deprecated { require 'active_support/core_ext/object/to_json' } + end +end diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index ed1326705c..d549113ff4 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -1,4 +1,5 @@ # encoding: utf-8 +require 'securerandom' require 'abstract_unit' require 'active_support/core_ext/string/inflections' require 'active_support/json' @@ -96,6 +97,13 @@ class TestJSONEncoding < ActiveSupport::TestCase end end + def test_process_status + # There doesn't seem to be a good way to get a handle on a Process::Status object without actually + # creating a child process, hence this to populate $? + system("not_a_real_program_#{SecureRandom.hex}") + assert_equal %({"exitstatus":#{$?.exitstatus},"pid":#{$?.pid}}), ActiveSupport::JSON.encode($?) + end + def test_hash_encoding assert_equal %({\"a\":\"b\"}), ActiveSupport::JSON.encode(:a => :b) assert_equal %({\"a\":1}), ActiveSupport::JSON.encode('a' => 1) diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb index c3fe89de4b..0b54026c64 100644 --- a/activesupport/test/ordered_hash_test.rb +++ b/activesupport/test/ordered_hash_test.rb @@ -1,6 +1,6 @@ require 'abstract_unit' require 'active_support/json' -require 'active_support/core_ext/object/to_json' +require 'active_support/core_ext/object/json' require 'active_support/core_ext/hash/indifferent_access' require 'active_support/core_ext/array/extract_options' -- cgit v1.2.3 From 1fb79691548cd370e83625045a0a445c97fa0dea Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Fri, 13 Sep 2013 00:03:12 -0700 Subject: Raise an error when AS::JSON.decode is called with options Rails 4.1 has switched away from MultiJson, and does not currently support any options on `ActiveSupport::JSON.decode`. Passing in unsupported options (i.e. any non-empty options hash) will now raise an ArgumentError. Rationale: 1. We cannot guarantee the underlying JSON parser won't change in the future, hence we cannot guarantee a consistent set of options the method could take 2. The `json` gem, which happens to be the current JSON parser, takes many dangerous options that is irrelevant to the purpose of AS's JSON decoding API 3. To reserve the options hash for future use, e.g. overriding default global options like ActiveSupport.parse_json_times This change *DOES NOT* introduce any changes in the public API. The signature of the method is still decode(json_text, options). The difference is this method previously accepted undocumented options which does different things when the underlying adapter changes. It now correctly raises an ArgumentError when it encounters options that it does not recognize (and currently it does not support any options). --- activesupport/test/json/decoding_test.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/json/decoding_test.rb b/activesupport/test/json/decoding_test.rb index e9780b36e4..07d7e530ca 100644 --- a/activesupport/test/json/decoding_test.rb +++ b/activesupport/test/json/decoding_test.rb @@ -98,10 +98,8 @@ class TestJSONDecoding < ActiveSupport::TestCase assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%()) } end - def test_cannot_force_json_unmarshalling - encodeded = %q({"json_class":"TestJSONDecoding::Foo"}) - decodeded = {"json_class"=>"TestJSONDecoding::Foo"} - assert_equal decodeded, ActiveSupport::JSON.decode(encodeded, create_additions: true) + def test_cannot_pass_unsupported_options + assert_raise(ArgumentError) { ActiveSupport::JSON.decode("", create_additions: true) } end end -- cgit v1.2.3