nov-jsonbuilder 0.2.1 → 0.2.2
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.
- data/Rakefile +1 -1
- data/lib/builder/hash_structure.rb +7 -9
- data/lib/ext/stackable_array.rb +3 -9
- data/lib/ext/stackable_hash.rb +7 -3
- data/lib/jsonbuilder.rb +1 -1
- data/spec/builder/hash_structure_spec.rb +98 -57
- data/spec/ext/stackable_array_spec.rb +102 -0
- data/spec/ext/stackable_hash_spec.rb +73 -0
- metadata +5 -2
data/Rakefile
CHANGED
@@ -39,7 +39,7 @@ begin
|
|
39
39
|
|
40
40
|
Spec::Rake::SpecTask.new('spec') do |t|
|
41
41
|
t.spec_opts = ["-f specdoc", "-c"]
|
42
|
-
t.spec_files = FileList['spec/*_spec.rb', 'spec/builder/*_spec.rb']
|
42
|
+
t.spec_files = FileList['spec/*_spec.rb', 'spec/builder/*_spec.rb', 'spec/ext/*_spec.rb']
|
43
43
|
end
|
44
44
|
|
45
45
|
rescue LoadError
|
@@ -6,7 +6,7 @@ module Builder
|
|
6
6
|
# in this case, we need some key for value.
|
7
7
|
@default_content_key = (options[:default_content_key] || :content).to_sym
|
8
8
|
@include_root = options[:include_root]
|
9
|
-
@target =
|
9
|
+
@target = {}.stackable
|
10
10
|
@array_mode = false
|
11
11
|
end
|
12
12
|
|
@@ -59,7 +59,7 @@ module Builder
|
|
59
59
|
@target.current << text
|
60
60
|
elsif @target.current.is_a?(Hash) && !@target.current.empty?
|
61
61
|
@default_content_key = default_content_key.to_sym unless default_content_key.nil?
|
62
|
-
@target.current.merge!(
|
62
|
+
@target.current.merge!(@default_content_key => text)
|
63
63
|
else
|
64
64
|
@target.current = text
|
65
65
|
end
|
@@ -71,7 +71,7 @@ module Builder
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def method_missing(key, *args, &block)
|
74
|
-
key, args = _explore_key_and_args(key, *args)
|
74
|
+
key, args = _explore_key_and_args(key, *args, &block)
|
75
75
|
_setup_key(key) do
|
76
76
|
_set_args(args, &block)
|
77
77
|
end
|
@@ -80,12 +80,10 @@ module Builder
|
|
80
80
|
|
81
81
|
private
|
82
82
|
|
83
|
-
def _explore_key_and_args(key, *args)
|
83
|
+
def _explore_key_and_args(key, *args, &block)
|
84
84
|
key = (args.first.is_a?(Symbol) ? "#{key}:#{args.shift}" : key.to_s).gsub(/[-:]/, "_").to_sym
|
85
|
-
args.reject! { |arg| arg.nil? }
|
86
|
-
if args.size > 1 && !args[0].is_a?(Hash)
|
87
|
-
args[0] = StackableHash.new.replace(@default_content_key => args[0])
|
88
|
-
end
|
85
|
+
args.reject! { |arg| arg.nil? } if block_given?
|
86
|
+
args[0] = {@default_content_key => args[0]} if args.size > 1 && !args[0].is_a?(Hash)
|
89
87
|
[key, args]
|
90
88
|
end
|
91
89
|
|
@@ -93,7 +91,7 @@ module Builder
|
|
93
91
|
args.each do |arg|
|
94
92
|
case arg
|
95
93
|
when Hash
|
96
|
-
self <<
|
94
|
+
self << arg.stackable
|
97
95
|
else
|
98
96
|
@target.current = arg
|
99
97
|
end
|
data/lib/ext/stackable_array.rb
CHANGED
@@ -2,9 +2,7 @@ class StackableArray < Array
|
|
2
2
|
attr_accessor :parent, :current_key
|
3
3
|
|
4
4
|
def child(key)
|
5
|
-
hash = StackableHash.new
|
6
|
-
hash[key] = StackableHash.new
|
7
|
-
|
5
|
+
hash = {key => StackableHash.new}.stackable
|
8
6
|
new_target = self.current
|
9
7
|
new_target.merge!(hash)
|
10
8
|
new_target.current_key = key
|
@@ -21,15 +19,11 @@ class StackableArray < Array
|
|
21
19
|
end
|
22
20
|
|
23
21
|
def current=(value)
|
24
|
-
|
25
|
-
self.last[current_key] = value
|
26
|
-
else
|
27
|
-
self << value
|
28
|
-
end
|
22
|
+
self.last[current_key] = value
|
29
23
|
end
|
30
24
|
|
31
25
|
def current
|
32
|
-
self.
|
26
|
+
self.last[current_key]
|
33
27
|
end
|
34
28
|
|
35
29
|
end
|
data/lib/ext/stackable_hash.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
+
class Hash
|
2
|
+
def stackable
|
3
|
+
StackableHash.new.replace(self)
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
1
7
|
class StackableHash < Hash
|
2
8
|
attr_accessor :parent, :current_key
|
3
9
|
|
4
10
|
def child(key)
|
5
|
-
hash = StackableHash.new
|
6
|
-
hash[key] = StackableHash.new
|
7
|
-
|
11
|
+
hash = {key => StackableHash.new}.stackable
|
8
12
|
new_target = self.current || self
|
9
13
|
new_target.merge!(hash)
|
10
14
|
new_target.current_key = key
|
data/lib/jsonbuilder.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
2
|
|
3
3
|
describe Builder::HashStructure, ".new" do
|
4
|
+
|
4
5
|
it "should be accessible" do
|
5
6
|
Builder::HashStructure.should respond_to(:new)
|
6
7
|
end
|
@@ -9,65 +10,11 @@ describe Builder::HashStructure, ".new" do
|
|
9
10
|
builder = Builder::HashStructure.new
|
10
11
|
builder.new!.should be_a(Builder::HashStructure)
|
11
12
|
end
|
13
|
+
|
12
14
|
end
|
13
15
|
|
14
16
|
describe Builder::HashStructure do
|
15
17
|
|
16
|
-
it "should replace ':' and '-' with '_' if those characters are used as a key" do
|
17
|
-
builder = Builder::HashStructure.new
|
18
|
-
builder.root do
|
19
|
-
builder.atom :name, "atom:name" # atom:name
|
20
|
-
builder.thr :"in-reply-to", "thr:in-reply-to" # thr:in-reply-to
|
21
|
-
builder.tag! :"dc:creator", "dc:creator" # thr:in-reply-to
|
22
|
-
end
|
23
|
-
builder.target!.should == {:atom_name => "atom:name", :thr_in_reply_to => "thr:in-reply-to", :dc_creator => "dc:creator"}
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should support root attributes" do
|
27
|
-
builder = Builder::HashStructure.new
|
28
|
-
# XML :: <root><tag>value</tag></root>
|
29
|
-
builder.root(:id => 1) do
|
30
|
-
builder.tag "value"
|
31
|
-
end
|
32
|
-
builder.target!.should == {:id => 1, :tag => "value"}
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should ignore nil attributes" do
|
36
|
-
builder = Builder::HashStructure.new
|
37
|
-
# XML :: <root><tag>value</tag></root>
|
38
|
-
builder.root(nil) do
|
39
|
-
builder.tag "value"
|
40
|
-
end
|
41
|
-
builder.target!.should == {:tag => "value"}
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should remove the root tag" do
|
45
|
-
builder = Builder::HashStructure.new
|
46
|
-
# XML :: <root><tag>value</tag></root>
|
47
|
-
builder.root do
|
48
|
-
builder.tag "value"
|
49
|
-
end
|
50
|
-
builder.target!.should == {:tag => "value"}
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should remove the root tag, but keep the attributes" do
|
54
|
-
builder = Builder::HashStructure.new
|
55
|
-
# XML :: <root><tag>value</tag></root>
|
56
|
-
builder.root(:id => 1) do
|
57
|
-
builder.tag "value"
|
58
|
-
end
|
59
|
-
builder.target!.should == {:id => 1, :tag => "value"}
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should not remove the root tag when include_root is true" do
|
63
|
-
builder = Builder::HashStructure.new(:include_root => true)
|
64
|
-
# XML :: <root><tag>value</tag></root>
|
65
|
-
builder.root do
|
66
|
-
builder.tag "value"
|
67
|
-
end
|
68
|
-
builder.target!.should == {:root => {:tag => "value"}}
|
69
|
-
end
|
70
|
-
|
71
18
|
it "should use the default_content_key when both content and attributes exist" do
|
72
19
|
builder = Builder::HashStructure.new
|
73
20
|
# XML :: <root><tag id="1">value</tag></root>
|
@@ -86,6 +33,10 @@ describe Builder::HashStructure do
|
|
86
33
|
builder.target!.should == {:tag => {:id => 1, :text => "value"}}
|
87
34
|
end
|
88
35
|
|
36
|
+
end
|
37
|
+
|
38
|
+
describe Builder::HashStructure, "#<<" do
|
39
|
+
|
89
40
|
it "should accept strings for insertion" do
|
90
41
|
builder = Builder::HashStructure.new
|
91
42
|
sub_builder = Builder::HashStructure.new
|
@@ -100,6 +51,36 @@ describe Builder::HashStructure do
|
|
100
51
|
builder.target!.should == {:tags => "value"}
|
101
52
|
end
|
102
53
|
|
54
|
+
it "should merge its argument into current target" do
|
55
|
+
builder = Builder::HashStructure.new
|
56
|
+
sub_builder = Builder::HashStructure.new
|
57
|
+
sub_builder.item do
|
58
|
+
sub_builder.text "hello"
|
59
|
+
end
|
60
|
+
|
61
|
+
builder.item do
|
62
|
+
builder << sub_builder.target!
|
63
|
+
end
|
64
|
+
builder.target!.should == {:text => "hello"}
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should insert its argument into current target" do
|
68
|
+
builder = Builder::HashStructure.new
|
69
|
+
sub_builder = Builder::HashStructure.new
|
70
|
+
sub_builder.item do
|
71
|
+
sub_builder.text "hello"
|
72
|
+
end
|
73
|
+
|
74
|
+
builder.items do
|
75
|
+
builder.array_mode do
|
76
|
+
3.times do
|
77
|
+
builder << sub_builder.target!
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
builder.target!.should == [{:text => "hello"}, {:text => "hello"}, {:text => "hello"}]
|
82
|
+
end
|
83
|
+
|
103
84
|
end
|
104
85
|
|
105
86
|
describe Builder::HashStructure, "#cdata!" do
|
@@ -184,20 +165,38 @@ end
|
|
184
165
|
|
185
166
|
describe Builder::HashStructure, "#target!" do
|
186
167
|
|
168
|
+
it "should remove the root tag" do
|
169
|
+
builder = Builder::HashStructure.new
|
170
|
+
# XML :: <root><tag>value</tag></root>
|
171
|
+
builder.root do
|
172
|
+
builder.tag "value"
|
173
|
+
end
|
174
|
+
builder.target!.should == {:tag => "value"}
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should not remove the root tag when include_root is true" do
|
178
|
+
builder = Builder::HashStructure.new(:include_root => true)
|
179
|
+
# XML :: <root><tag>value</tag></root>
|
180
|
+
builder.root do
|
181
|
+
builder.tag "value"
|
182
|
+
end
|
183
|
+
builder.target!.should == {:root => {:tag => "value"}}
|
184
|
+
end
|
185
|
+
|
187
186
|
it "should return a String when there is only a root value" do
|
188
187
|
builder = Builder::HashStructure.new
|
189
188
|
builder.root("value")
|
190
189
|
builder.target!.should == "value"
|
191
190
|
end
|
192
191
|
|
193
|
-
it "should return a
|
192
|
+
it "should return a Hash when there is only a root value and include_root option is true" do
|
194
193
|
builder = Builder::HashStructure.new(:include_root => true)
|
195
194
|
# XML :: <root>value</root>
|
196
195
|
builder.root "value"
|
197
196
|
builder.target!.should == {:root => "value"}
|
198
197
|
end
|
199
198
|
|
200
|
-
it "should return a
|
199
|
+
it "should return a Hash when root has deeper structure" do
|
201
200
|
builder = Builder::HashStructure.new
|
202
201
|
builder.root do
|
203
202
|
builder.item("value")
|
@@ -216,3 +215,45 @@ describe Builder::HashStructure, "#root!" do
|
|
216
215
|
builder.target!.should == {:root => {:tag => 'value'}}
|
217
216
|
end
|
218
217
|
end
|
218
|
+
|
219
|
+
|
220
|
+
describe Builder::HashStructure, "#_explore_key_and_args" do
|
221
|
+
|
222
|
+
it "should replace ':' and '-' with '_' if those characters are used as a key" do
|
223
|
+
builder = Builder::HashStructure.new
|
224
|
+
builder.root do
|
225
|
+
builder.atom :name, "atom:name" # atom:name
|
226
|
+
builder.thr :"in-reply-to", "thr:in-reply-to" # thr:in-reply-to
|
227
|
+
builder.tag! :"dc:creator", "dc:creator" # thr:in-reply-to
|
228
|
+
end
|
229
|
+
builder.target!.should == {:atom_name => "atom:name", :thr_in_reply_to => "thr:in-reply-to", :dc_creator => "dc:creator"}
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should support root attributes" do
|
233
|
+
builder = Builder::HashStructure.new
|
234
|
+
# XML :: <root><tag>value</tag></root>
|
235
|
+
builder.root(:id => 1) do
|
236
|
+
builder.tag "value"
|
237
|
+
end
|
238
|
+
builder.target!.should == {:id => 1, :tag => "value"}
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should ignore nil attributes when block given" do
|
242
|
+
builder = Builder::HashStructure.new
|
243
|
+
# XML :: <root><tag>value</tag></root>
|
244
|
+
builder.root(nil) do
|
245
|
+
builder.tag "value"
|
246
|
+
end
|
247
|
+
builder.target!.should == {:tag => "value"}
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should not ignore nil attributes when block isn't given" do
|
251
|
+
builder = Builder::HashStructure.new
|
252
|
+
# XML :: <root><tag>value</tag></root>
|
253
|
+
builder.root do
|
254
|
+
builder.tag nil
|
255
|
+
end
|
256
|
+
builder.target!.should == {:tag => nil}
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../spec_helper')
|
2
|
+
|
3
|
+
describe StackableArray, "#child" do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@grandparent = StackableHash.new
|
7
|
+
@parent = @grandparent.child(:parent)
|
8
|
+
@parent.current = StackableArray.new
|
9
|
+
@self = @parent.child(:self)
|
10
|
+
@child = @self.child(:child)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should set parent" do
|
14
|
+
@child.parent.should == @self
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return a StackableHash instance" do
|
18
|
+
@self.should be_instance_of(StackableArray)
|
19
|
+
@child.should be_instance_of(StackableHash)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "when duplicated key exists" do
|
23
|
+
it "should insert a StackableHash into itself" do
|
24
|
+
@brother = @parent.child(:self)
|
25
|
+
@self.should == [{:self => {:child => {}}}, {:self => {}}]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "when duplicated key doesn't exist" do
|
30
|
+
it "should merge a StackableHash into the last element" do
|
31
|
+
@brother = @parent.child(:brother)
|
32
|
+
@self.should == [{:self => {:child => {}}, :brother => {}}]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe StackableArray, "#current" do
|
39
|
+
|
40
|
+
before do
|
41
|
+
@grandparent = StackableHash.new
|
42
|
+
@parent = @grandparent.child(:parent)
|
43
|
+
@parent.current = StackableArray.new
|
44
|
+
@brother1 = @parent.child(:brother)
|
45
|
+
@brother2 = @parent.child(:brother)
|
46
|
+
@self = @parent.child(:self)
|
47
|
+
@child = @self.child(:child)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return the last element" do
|
51
|
+
[@self, @brother1, @brother2, @parent.current].each do |arr|
|
52
|
+
arr.current.should == {:child => {}}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
describe StackableArray, "#current=" do
|
59
|
+
|
60
|
+
before do
|
61
|
+
@grandparent = StackableHash.new
|
62
|
+
@parent = @grandparent.child(:parent)
|
63
|
+
@parent.current = StackableArray.new
|
64
|
+
@self_dummy = @parent.child(:self)
|
65
|
+
@self_dummy.current.merge!(:name => "self dummy")
|
66
|
+
@self = @parent.child(:self)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should replace current of the last element" do
|
70
|
+
@self.current_key.should == :self
|
71
|
+
@self.current = "some text"
|
72
|
+
@self.should == [{:self => {:name => "self dummy"}}, {:self => "some text"}]
|
73
|
+
@self_dummy.current = "another text"
|
74
|
+
@self.should == [{:self => {:name => "self dummy"}}, {:self => "another text"}]
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe StackableArray, "#merge!" do
|
80
|
+
|
81
|
+
before do
|
82
|
+
@grandparent = StackableHash.new
|
83
|
+
@parent = @grandparent.child(:parent)
|
84
|
+
@parent.current = StackableArray.new
|
85
|
+
@self = @parent.child(:self)
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "when duplicated key exists" do
|
89
|
+
it "should insert a StackableHash into itself" do
|
90
|
+
@self.merge!(:self => {})
|
91
|
+
@self.should == [{:self => {}}, {:self => {}}]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "when duplicated key doesn't exist" do
|
96
|
+
it "should merge a StackableHash into the last element" do
|
97
|
+
@self.merge!(:brother => {})
|
98
|
+
@self.should == [{:self => {}, :brother => {}}]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../spec_helper')
|
2
|
+
|
3
|
+
describe Hash, "#stackable" do
|
4
|
+
it "should return StackableHash instance" do
|
5
|
+
{:key => "value"}.stackable.should be_instance_of(StackableHash)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe StackableHash, "#child" do
|
10
|
+
|
11
|
+
before do
|
12
|
+
@parent = StackableHash.new
|
13
|
+
@self = @parent.child(:self)
|
14
|
+
@child = @self.child(:child)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return a StackableHash instance" do
|
18
|
+
[@self, @child].each do |hash|
|
19
|
+
hash.should be_instance_of(StackableHash)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should set parent" do
|
24
|
+
@self.parent.should == @parent
|
25
|
+
@child.parent.should == @self
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should merge a new StackableHash instance into itself" do
|
29
|
+
@parent.should == {:self => {:child => {}}}
|
30
|
+
@self.should == {:self => {:child => {}}}
|
31
|
+
@child.should == {:child => {}}
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "when current is a StackableArray instance" do
|
35
|
+
|
36
|
+
before do
|
37
|
+
@self = @parent.child(:self)
|
38
|
+
@self.current = StackableArray.new
|
39
|
+
@child1 = @self.child(:child)
|
40
|
+
@child2 = @self.child(:child)
|
41
|
+
@child3 = @self.child(:child)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should set parent" do
|
45
|
+
@self.parent.should == @parent
|
46
|
+
[@child1, @child2, @child3].each do |child|
|
47
|
+
child.parent.should == @self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return a StackableArray instance" do
|
52
|
+
[@child1, @child2, @child3].each do |child|
|
53
|
+
child.should be_instance_of(StackableArray)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should insert a StackableHash instance into current" do
|
58
|
+
@self.current.should == [{:child => {}}, {:child => {}}, {:child => {}}]
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "all children" do
|
62
|
+
it "should be same" do
|
63
|
+
[@child1, @child2, @child3].each do |child|
|
64
|
+
child.should == [{:child => {}}, {:child => {}}, {:child => {}}]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# TODO: needs more testing
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nov-jsonbuilder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nov
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-28 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -40,6 +40,9 @@ files:
|
|
40
40
|
- spec/builder/hash_structure_spec.rb
|
41
41
|
- spec/builder/json_format_spec.rb
|
42
42
|
- spec/builder/xml_markup_spec.rb
|
43
|
+
- spec/ext
|
44
|
+
- spec/ext/stackable_array_spec.rb
|
45
|
+
- spec/ext/stackable_hash_spec.rb
|
43
46
|
- spec/jsonbuilder_spec.rb
|
44
47
|
- spec/spec_helper.rb
|
45
48
|
- lib/builder
|