Skip to content

Commit

Permalink
working around monkey patch pains
Browse files Browse the repository at this point in the history
  • Loading branch information
ohler55 committed Aug 16, 2016
1 parent d717131 commit d0f5c2c
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 33 deletions.
67 changes: 44 additions & 23 deletions lib/oj/mimic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,71 +23,92 @@ def self.mimic_loaded(mimic_paths=[])

if Object.const_defined?('OpenStruct')
OpenStruct.class_eval do
def as_json(*)
name = self.class.name.to_s
raise JSON::JSONError, "Only named structs are supported!" if 0 == name.length
{ JSON.create_id => name, 't' => table }
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
unless defined?(self.as_json)
def as_json(*)
name = self.class.name.to_s
raise JSON::JSONError, "Only named structs are supported!" if 0 == name.length
{ JSON.create_id => name, 't' => table }
end
end
def self.json_create(h)
new(h['t'])
end
end
end

Range.class_eval do
def as_json(*)
{JSON.create_id => 'Range', 'a' => [first, last, exclude_end?]}
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
unless defined?(self.as_json)
def as_json(*)
{JSON.create_id => 'Range', 'a' => [first, last, exclude_end?]}
end
end
def self.json_create(h)
new(h['a'])
end
end

Rational.class_eval do
def as_json(*)
{JSON.create_id => 'Rational', 'n' => numerator, 'd' => denominator }
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
unless defined?(self.as_json)
def as_json(*)
{JSON.create_id => 'Rational', 'n' => numerator, 'd' => denominator }
end
end
def self.json_create(h)
Rational(h['n'], h['d'])
end
end

Regexp.class_eval do
def as_json(*)
{JSON.create_id => 'Regexp', 'o' => options, 's' => source }
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
unless defined?(self.as_json)
def as_json(*)
{JSON.create_id => 'Regexp', 'o' => options, 's' => source }
end
end
def self.json_create(h)
new(h['s'], h['o'])
end
end

Struct.class_eval do
def as_json(*)
name = self.class.name.to_s
raise JSON::JSONError, "Only named structs are supported!" if 0 == name.length
{ JSON.create_id => name, 'v' => values }
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
unless defined?(self.as_json)
def as_json(*)
name = self.class.name.to_s
raise JSON::JSONError, "Only named structs are supported!" if 0 == name.length
{ JSON.create_id => name, 'v' => values }
end
end
def self.json_create(h)
new(h['v'])
end
end

Symbol.class_eval do
def as_json(*)
{JSON.create_id => 'Symbol', 's' => to_s }
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
unless defined?(self.as_json)
def as_json(*)
{JSON.create_id => 'Symbol', 's' => to_s }
end
end
def self.json_create(h)
h['s'].to_sym
end
end

Time.class_eval do
def as_json(*)
{JSON.create_id => 'Symbol', 's' => to_s }
nsecs = [ tv_usec * 1000 ]
nsecs << tv_nsec if respond_to?(:tv_nsec)
nsecs = nsecs.max
{ JSON.create_id => 'Time', 's' => tv_sec, 'n' => nsecs }
# Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
unless defined?(self.as_json)
def as_json(*)
{JSON.create_id => 'Symbol', 's' => to_s }
nsecs = [ tv_usec * 1000 ]
nsecs << tv_nsec if respond_to?(:tv_nsec)
nsecs = nsecs.max
{ JSON.create_id => 'Time', 's' => tv_sec, 'n' => nsecs }
end
end
def self.json_create(h)
if usec = h.delete('u')
Expand Down
4 changes: 4 additions & 0 deletions notes
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
^c^d hide subtree
^c^s show subtree

- as_json
- if ActiveSupport defined and as_json exists then define one
- maybe just check as_json defined

- debug
- instrument for parsing floats/bigdecimal
- branch
Expand Down
17 changes: 8 additions & 9 deletions test/isolated/shared.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# encoding: UTF-8

$rails_monkey = false unless defined?($rails_monkey)

class SharedMimicTest < Minitest::Test
class Jam
attr_accessor :x, :y
Expand Down Expand Up @@ -56,7 +58,8 @@ def test_exception
# dump
def test_dump_string
json = JSON.dump([1, true, nil, @time])
assert_equal(%{[1,true,null,{"json_class":"Time","s":1400000000,"n":0}]}, json)
assert_equal(%{[1,true,null,#{@expected_time_string}]}, json)
#assert_equal(%{[1,true,null,{"json_class":"Time","s":1400000000,"n":0}]}, json)
end

def test_dump_with_options
Expand All @@ -66,11 +69,7 @@ def test_dump_with_options
1,
true,
null,
{
"json_class":"Time",
"s":1400000000,
"n":0
}
#{@expected_time_string}
]
}, json)
end
Expand All @@ -79,7 +78,7 @@ def test_dump_io
s = StringIO.new()
json = JSON.dump([1, true, nil, @time], s)
assert_equal(s, json)
assert_equal(%{[1,true,null,{"json_class":"Time","s":1400000000,"n":0}]}, s.string)
assert_equal(%{[1,true,null,#{@expected_time_string}]}, s.string)
end
# TBD options

Expand All @@ -94,8 +93,8 @@ def test_dump_struct
json = JSON.dump(o)
# Rails add the as_json method and changes the behavior.
if o.respond_to?(:as_json)
assert_equal(%|{"json_class":"Struct::Abc","v":[1,"two",[true,false]]}|, json)
#assert_equal(%|{"a":1,"b":"two","c":[true,false]}|, json)
assert_equal(%|{"a":1,"b":"two","c":[true,false]}|, json)
#assert_equal(%|{"json_class":"Struct::Abc","v":[1,"two",[true,false]]}|, json)
else
j = '"' + o.to_s.gsub('"', '\\"') + '"'
assert_equal(j, json)
Expand Down
Empty file modified test/isolated/test_mimic_as_json.rb
100644 → 100755
Empty file.
3 changes: 2 additions & 1 deletion test/isolated/test_mimic_rails_before.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

require 'isolated/shared'

$rails_monkey = true

class MimicRailsBefore < SharedMimicRailsTest
end # MimicRailsBefore

0 comments on commit d0f5c2c

Please sign in to comment.