Skip to content

Commit

Permalink
Bypass as_json for json_ready without hash options
Browse files Browse the repository at this point in the history
It's relatively common to pass bogus (or at least non-applicable)
options to the ActiveSupport JSON encoder, but with a JSON-ready value.
In this case we can also skip the as_json pass and deep-dup.
  • Loading branch information
jhawthorn committed Jul 30, 2024
1 parent e274bf6 commit 61df84a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 15 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ gem "rake", "~> 13.0"
gem "rake-compiler"
gem "minitest", "~> 5.0"

gem "activesupport"

group :benchmark do
gem "benchmark-ips"
gem "oj"
Expand Down
21 changes: 21 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,41 @@ PATH
GEM
remote: https://rubygems.org/
specs:
activesupport (7.1.3.4)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
base64 (0.2.0)
benchmark-ips (2.10.0)
bigdecimal (3.1.8)
concurrent-ruby (1.3.3)
connection_pool (2.4.1)
drb (2.2.1)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
json (2.6.1)
minitest (5.15.0)
mutex_m (0.2.0)
oj (3.13.11)
rake (13.0.6)
rake-compiler (1.1.9)
rake
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
yajl-ruby (1.4.1)

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES
activesupport
benchmark-ips
json
minitest (~> 5.0)
Expand Down
4 changes: 3 additions & 1 deletion lib/rapidjson/active_support_encoder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ def initialize(options = nil)
# Encode the given object into a JSON string
def encode(value)
if @options && !@options.empty?
value = value.as_json(@options.dup)
if !RapidJSON.json_ready?(value) || @options.key?(:only) || @options.key?(:except)
value = value.as_json(@options.dup)
end
end
json = @coder.dump(value)
if ActiveSupport::JSON::Encoding.escape_html_entities_in_json
Expand Down
31 changes: 17 additions & 14 deletions test/test_active_support_encoder.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
# frozen_string_literal: true

require "test_helper"

# Sorry
unless defined?(ActiveSupport::JSON::Encoding)
module ActiveSupport
module JSON
module Encoding
class << self
attr_accessor :escape_html_entities_in_json
end
self.escape_html_entities_in_json = false
end
end
end
end
require "active_support"
require "active_support/core_ext/object/json"

class TestActiveSupportEncoder < Minitest::Test
class AsJSON
Expand Down Expand Up @@ -67,6 +55,21 @@ def test_basic_types
assert_includes ex.message, "as_json"
end

def test_hash_options
assert_equal %q{{"key":"value"}}, encode({key: :value, bogus: :garbo}, only: :key)
assert_equal %q{{"key":"value"}}, encode({key: :value, bogus: :garbo}, only: [:key])
assert_equal %q{{"key":"value"}}, encode({key: :value, bogus: :garbo}, except: :bogus)
assert_equal %q{{"key":"value"}}, encode({key: :value, bogus: :garbo}, except: [:bogus])

assert_equal %q{[{"key":"value"}]}, encode([{key: :value, bogus: :garbo}], only: :key)
assert_equal %q{[{"key":"value"}]}, encode([{key: :value, bogus: :garbo}], only: [:key])
assert_equal %q{[{"key":"value"}]}, encode([{key: :value, bogus: :garbo}], except: :bogus)
assert_equal %q{[{"key":"value"}]}, encode([{key: :value, bogus: :garbo}], except: [:bogus])

assert_equal %q{{}}, encode({bogus: :garbo}, only: [:key])
assert_equal %q{{"key":"value"}}, encode({key: :value}, except: [:bogus])
end

FloatOverride = Module.new

def test_non_finite_floats
Expand Down

0 comments on commit 61df84a

Please sign in to comment.