Skip to content
This repository was archived by the owner on Feb 19, 2018. It is now read-only.

Commit ffd5cdd

Browse files
author
Klaas Speller
committed
Move assigment logic to Json::Builder.assign!
1 parent 2cf4284 commit ffd5cdd

File tree

2 files changed

+71
-10
lines changed

2 files changed

+71
-10
lines changed

lib/jsonit/builder.rb

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Jsonit
22
class Builder
33

4-
instance_methods.each { |m| undef_method(m) unless m.to_s =~ /^__|object_id|\?$/ }
4+
instance_methods.each { |m| undef_method(m) unless m.to_s =~ /^__|object_id|\?$|!$/ }
55

66
def initialize(scope={})
77
@document = @current_scope = scope
@@ -18,30 +18,41 @@ def to_json(*args)
1818

1919
def set!(key=nil, value=nil, &blk)
2020
if !block_given?
21-
if value.is_a?(Hash) && @current_scope[key].is_a?(Hash)
22-
@current_scope[key].merge!(value)
23-
else
24-
@current_scope[key] = value
25-
end
21+
assign!(key, value)
2622
elsif value.is_a?(Enumerable)
2723
array!(key, value, &blk)
2824
else
2925
object!(key, value, &blk)
3026
end
3127
self
3228
end
33-
alias_method :method_missing, :set!
34-
29+
3530
def object!(key=nil, value=nil, &blk)
3631
@current_scope, previous_scope = {}, @current_scope
3732
yield value
3833
@current_scope, new_scope = previous_scope, @current_scope
39-
!key.nil? ? set!(key, new_scope) : Builder.new(new_scope)
34+
!key.nil? ? assign!(key, new_scope) : Builder.new(new_scope)
4035
end
4136

4237
def array!(key, collection=[], &blk)
4338
collection.map! { |itm| object!(nil, itm, &blk) } if block_given?
44-
set!(key, collection)
39+
assign!(key, collection)
40+
end
41+
42+
def assign!(key, value=nil)
43+
if value.is_a?(Hash) && @current_scope[key].is_a?(Hash)
44+
@current_scope[key].merge!(value)
45+
else
46+
@current_scope[key] = value
47+
end
48+
self
49+
end
50+
51+
def method_missing(meth, *args, &blk)
52+
if (meth.to_s =~ /\?$|!$/).nil?
53+
return set!(meth, *args, &blk)
54+
end
55+
super
4556
end
4657
end
4758
end

spec/jsonit/builder_spec.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,56 @@
9494
end
9595
end
9696

97+
98+
describe "#assign!" do
99+
let(:json) { Jsonit::Builder.new }
100+
101+
it 'returns an instance of self' do
102+
json.assign!(:foo).should be_a Jsonit::Builder
103+
end
104+
105+
it 'creates a key value pair' do
106+
json.assign!(:foo, "bar").to_json.should == %|{"foo":"bar"}|
107+
end
108+
109+
it 'can assign an array' do
110+
json.assign!(:foo, ["a", "b", "c"]).to_json.should == %|{"foo":["a","b","c"]}|
111+
end
112+
113+
it 'can assign an object' do
114+
json.assign!(:foo, {"a" => "b"}).to_json.should == %|{"foo":{"a":"b"}}|
115+
end
116+
117+
it 'continues an object with same key' do
118+
json.assign!(:foo, {"a" => "b"})
119+
json.assign!(:foo, {"c" => "d"})
120+
json.to_json.should == %|{"foo":{"a":"b","c":"d"}}|
121+
end
122+
end
123+
124+
describe "ghost methods" do
125+
let(:json) { Jsonit::Builder.new }
126+
127+
it 'does not raise method missing for method with format /^[a-z][a-z0-9]+$/' do
128+
[:a, :b, :c].each do |m|
129+
expect { json.send(m) }.to_not raise_error
130+
end
131+
end
132+
133+
134+
it 'raises method missing for ending with a "?"' do
135+
[:a?, :b?, :c?].each do |m|
136+
expect { eval("json.#{m.to_s}") }.to raise_error(NoMethodError)
137+
end
138+
end
139+
140+
it 'raises method missing for ending with a "!"' do
141+
[:a!, :b!, :c!].each do |m|
142+
expect { eval("json.#{m.to_s}") }.to raise_error(NoMethodError)
143+
end
144+
end
145+
end
146+
97147
describe "DSL" do
98148
it "can nest multiple levels" do
99149
Jsonit::Builder.new do |json|

0 commit comments

Comments
 (0)