jsonbuilder 0.0.7 → 0.1.0
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/lib/builder/abstract.rb +7 -0
- data/lib/builder/hash_structure.rb +61 -20
- data/lib/builder/json_format.rb +32 -9
- data/lib/builder/xml_markup.rb +19 -0
- data/lib/jsonbuilder.rb +3 -3
- data/spec/builder/array_mode_spec.rb +298 -0
- data/spec/builder/hash_structure_spec.rb +68 -137
- data/spec/builder/json_format_spec.rb +80 -3
- data/spec/builder/xml_markup_spec.rb +37 -0
- metadata +3 -2
data/lib/builder/abstract.rb
CHANGED
@@ -12,19 +12,16 @@ module Builder
|
|
12
12
|
|
13
13
|
# NOTICE: you have to call this method to use array in json
|
14
14
|
def array_mode(key = nil, &block)
|
15
|
-
raise RuntimeError.new("cannot call inside array_mode block") if @array_mode
|
16
|
-
@array_mode = true
|
17
15
|
if eval("#{_current}").is_a?(::Hash)
|
18
16
|
key ||= :entry
|
19
17
|
eval("#{_current}.merge!(key => [])")
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
_move_current(key.to_sym) do
|
19
|
+
_array_mode(&block)
|
20
|
+
end
|
23
21
|
else
|
24
22
|
eval("#{_current} = []")
|
25
|
-
|
23
|
+
_array_mode(&block)
|
26
24
|
end
|
27
|
-
@array_mode = false
|
28
25
|
end
|
29
26
|
|
30
27
|
def target!
|
@@ -35,17 +32,38 @@ module Builder
|
|
35
32
|
end
|
36
33
|
end
|
37
34
|
|
35
|
+
def serialization_method!
|
36
|
+
:to_hash
|
37
|
+
end
|
38
|
+
|
39
|
+
def root!(key, *attrs, &block)
|
40
|
+
@include_root = true
|
41
|
+
method_missing(key, *attrs, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def content!(key, default_content_key, *attrs, &block)
|
45
|
+
@default_content_key = default_content_key.to_sym
|
46
|
+
method_missing(key, *attrs, &block)
|
47
|
+
end
|
48
|
+
|
38
49
|
def <<(_target)
|
39
50
|
if @array_mode
|
51
|
+
key = @path.pop
|
40
52
|
eval("#{_current} << _target")
|
53
|
+
@path.push(key)
|
41
54
|
else
|
42
|
-
|
43
|
-
|
55
|
+
if _target.is_a?(String)
|
56
|
+
puts _current
|
57
|
+
eval("#{_current} = _target")
|
58
|
+
else
|
59
|
+
eval("#{_current} ||= {}")
|
60
|
+
eval("#{_current}.merge!(_target)")
|
61
|
+
end
|
44
62
|
end
|
45
63
|
end
|
46
64
|
|
47
|
-
def text!(text)
|
48
|
-
|
65
|
+
def text!(text, default_content_key = nil)
|
66
|
+
@default_content_key = default_content_key.to_sym unless default_content_key.nil?
|
49
67
|
if eval("#{_current}").is_a?(::Hash)
|
50
68
|
eval("#{_current}.merge!({@default_content_key => text})")
|
51
69
|
else
|
@@ -61,10 +79,10 @@ module Builder
|
|
61
79
|
def method_missing(key, *args, &block)
|
62
80
|
key = args.first.is_a?(Symbol) ? "#{key}:#{args.shift}".to_sym : key.to_sym
|
63
81
|
args[0] = {@default_content_key => args[0]} if args.size > 1 && !args[0].is_a?(::Hash)
|
64
|
-
|
65
|
-
_root(key, args, &block)
|
66
|
-
else
|
82
|
+
if @root
|
67
83
|
_child(key, args, &block)
|
84
|
+
else
|
85
|
+
_root(key, args, &block)
|
68
86
|
end
|
69
87
|
target!
|
70
88
|
end
|
@@ -80,10 +98,10 @@ module Builder
|
|
80
98
|
end
|
81
99
|
|
82
100
|
def _child(key, args, &block)
|
83
|
-
eval("#{_current} ||= {}")
|
84
|
-
|
85
|
-
|
86
|
-
|
101
|
+
eval("#{_current} ||= {}") unless @array_mode
|
102
|
+
_move_current(key) do
|
103
|
+
_set_args(args, &block)
|
104
|
+
end
|
87
105
|
end
|
88
106
|
|
89
107
|
def _set_args(args, &block)
|
@@ -95,11 +113,34 @@ module Builder
|
|
95
113
|
eval("#{_current} = arg")
|
96
114
|
end
|
97
115
|
end
|
98
|
-
|
116
|
+
if @array_mode && block_given?
|
117
|
+
@array_mode = false
|
118
|
+
yield(self)
|
119
|
+
@array_mode = true
|
120
|
+
elsif block_given?
|
121
|
+
yield(self)
|
122
|
+
end
|
99
123
|
end
|
100
124
|
|
101
125
|
def _current
|
102
|
-
|
126
|
+
current_path = @path.inject('') do |current_path, key|
|
127
|
+
current_path += key.is_a?(Integer) ? "[#{key}]" : "[:\"#{key}\"]"
|
128
|
+
end
|
129
|
+
"@target#{current_path}"
|
130
|
+
end
|
131
|
+
|
132
|
+
def _move_current(key, &block)
|
133
|
+
@path.push(key) unless @array_mode
|
134
|
+
yield
|
135
|
+
@array_mode ? @path[@path.size - 1] += 1 : @path.pop
|
136
|
+
end
|
137
|
+
|
138
|
+
def _array_mode(&block)
|
139
|
+
@array_mode = true
|
140
|
+
@path.push(0)
|
141
|
+
yield
|
142
|
+
@path.pop
|
143
|
+
@array_mode = false
|
103
144
|
end
|
104
145
|
|
105
146
|
end
|
data/lib/builder/json_format.rb
CHANGED
@@ -1,22 +1,45 @@
|
|
1
|
-
require '
|
1
|
+
require 'activesupport'
|
2
2
|
|
3
3
|
module Builder
|
4
4
|
class JsonFormat < HashStructure
|
5
5
|
|
6
6
|
def initialize(options = {})
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
super(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def serialization_method!
|
11
|
+
:to_json
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
target!.to_json
|
16
|
+
end
|
17
|
+
|
18
|
+
def <<(_target)
|
19
|
+
if _target.is_a?(String)
|
20
|
+
_target = ::ActiveSupport::JSON.decode(_target)
|
21
|
+
_target.symbolize_keys! if _target.is_a?(Hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
if @array_mode
|
25
|
+
key = @path.pop
|
26
|
+
eval("#{_current} << _target")
|
27
|
+
@path.push(key)
|
28
|
+
else
|
29
|
+
if _target.is_a?(String)
|
30
|
+
eval("#{_current} = _target")
|
31
|
+
else
|
32
|
+
eval("#{_current} ||= {}")
|
33
|
+
eval("#{_current}.merge!(_target)")
|
34
|
+
end
|
35
|
+
end
|
13
36
|
end
|
14
37
|
|
15
38
|
def target!
|
16
39
|
if @include_root
|
17
|
-
@target
|
40
|
+
@target
|
18
41
|
else
|
19
|
-
@target[@root]
|
42
|
+
@target[@root]
|
20
43
|
end
|
21
44
|
end
|
22
45
|
end
|
data/lib/builder/xml_markup.rb
CHANGED
@@ -3,6 +3,25 @@ require 'builder/xmlmarkup'
|
|
3
3
|
module Builder
|
4
4
|
class XmlMarkup
|
5
5
|
|
6
|
+
def serialization_method!
|
7
|
+
:to_xml
|
8
|
+
end
|
9
|
+
|
10
|
+
def new!
|
11
|
+
Builder::XmlMarkup.new
|
12
|
+
end
|
13
|
+
|
14
|
+
# Rooted element only needed by XML
|
15
|
+
def root!(key, *attrs, &block)
|
16
|
+
tag!(key, *attrs, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
alias :single_argument_cdata! :cdata!
|
20
|
+
|
21
|
+
def cdata!(key, default_content_key = nil)
|
22
|
+
single_argument_cdata!(key)
|
23
|
+
end
|
24
|
+
|
6
25
|
# Add this no-op
|
7
26
|
def array_mode(key = nil, &block)
|
8
27
|
yield(self)
|
data/lib/jsonbuilder.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module JsonBuilder
|
2
2
|
module Version
|
3
3
|
MAJOR = 0
|
4
|
-
MINOR =
|
5
|
-
REVISION =
|
4
|
+
MINOR = 1
|
5
|
+
REVISION = 0
|
6
6
|
class << self
|
7
7
|
def to_version
|
8
8
|
"#{MAJOR}.#{MINOR}.#{REVISION}"
|
@@ -16,6 +16,6 @@ module JsonBuilder
|
|
16
16
|
end
|
17
17
|
|
18
18
|
require 'builder/abstract'
|
19
|
-
require 'builder/hash_structure'
|
20
19
|
require 'builder/xml_markup'
|
20
|
+
require 'builder/hash_structure'
|
21
21
|
require 'builder/json_format'
|
@@ -0,0 +1,298 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Builder::HashStructure, "#array_mode" do
|
4
|
+
|
5
|
+
it "should treat an empty block as a blank Array" do
|
6
|
+
# XML ::
|
7
|
+
# <root>
|
8
|
+
# <items>
|
9
|
+
# </items>
|
10
|
+
# </root>
|
11
|
+
builder = Builder::HashStructure.new
|
12
|
+
builder.root do
|
13
|
+
builder.items do
|
14
|
+
builder.array_mode do
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
builder.target!.should == {:items => []}
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should support tag_method (method_missing)" do
|
22
|
+
builder = Builder::HashStructure.new
|
23
|
+
builder.root do
|
24
|
+
builder.items do
|
25
|
+
builder.array_mode do
|
26
|
+
2.times do |i|
|
27
|
+
builder.item do
|
28
|
+
builder.text "hello world #{i}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
builder.target!.should == {
|
35
|
+
:items => [{:text => "hello world 0"}, {:text => "hello world 1"}]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should support tag_method (method_missing) which includes cdata!" do
|
40
|
+
builder = Builder::HashStructure.new
|
41
|
+
builder.root do
|
42
|
+
builder.items do
|
43
|
+
builder.array_mode do
|
44
|
+
2.times do |i|
|
45
|
+
builder.item do
|
46
|
+
builder.cdata! "hello world #{i}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
builder.target!.should == {:items=>["hello world 0", "hello world 1"]}
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should support tag_method (method_missing) which includes attributes and contents" do
|
56
|
+
builder = Builder::HashStructure.new
|
57
|
+
builder.root do
|
58
|
+
builder.items do
|
59
|
+
builder.array_mode do
|
60
|
+
2.times do |i|
|
61
|
+
builder.item(:id => i) do
|
62
|
+
builder.text "hello world #{i}"
|
63
|
+
builder.sentence(:id => i) do
|
64
|
+
builder.text "Hello world!!"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
builder.target!.should == {
|
72
|
+
:items => [{
|
73
|
+
:text => "hello world 0",
|
74
|
+
:sentence => {:text => "Hello world!!", :id => 0},
|
75
|
+
:id => 0
|
76
|
+
},
|
77
|
+
{
|
78
|
+
:text => "hello world 1",
|
79
|
+
:sentence => {:text => "Hello world!!", :id => 1},
|
80
|
+
:id => 1
|
81
|
+
}]
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should support <<(hash)" do
|
86
|
+
builder = Builder::HashStructure.new
|
87
|
+
# XML ::
|
88
|
+
# <root>
|
89
|
+
# <items>
|
90
|
+
# <item id="0">
|
91
|
+
# <text>hello world 0</text>
|
92
|
+
# <sentence id="0"></sentence>
|
93
|
+
# </item>
|
94
|
+
# <item id="0">
|
95
|
+
# <text>hello world 1</text>
|
96
|
+
# <sentence id="1">Hello world!!</sentence>
|
97
|
+
# </item>
|
98
|
+
# </items>
|
99
|
+
# </root>
|
100
|
+
builder.root do
|
101
|
+
builder.items do
|
102
|
+
builder.array_mode do
|
103
|
+
2.times do |i|
|
104
|
+
builder << builder.new!.item(:id => i) do |_builder|
|
105
|
+
_builder.text "hello world #{i}"
|
106
|
+
_builder.sentence(:id => i) do
|
107
|
+
_builder.text "Hello world!!"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
builder.target!.should == {
|
115
|
+
:items => [{
|
116
|
+
:text => "hello world 0",
|
117
|
+
:sentence => {:text => "Hello world!!", :id => 0},
|
118
|
+
:id => 0
|
119
|
+
},
|
120
|
+
{
|
121
|
+
:text => "hello world 1",
|
122
|
+
:sentence => {:text => "Hello world!!", :id => 1},
|
123
|
+
:id => 1
|
124
|
+
}]
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
# you have to make new builder instance for now
|
129
|
+
it "should allow root!" do
|
130
|
+
builder = Builder::HashStructure.new
|
131
|
+
# XML ::
|
132
|
+
# <root>
|
133
|
+
# <items>
|
134
|
+
# <item id="0">
|
135
|
+
# <text>hello world 0</text>
|
136
|
+
# <sentence id="0"></sentence>
|
137
|
+
# </item>
|
138
|
+
# <item id="0">
|
139
|
+
# <text>hello world 1</text>
|
140
|
+
# <sentence id="1">Hello world!!</sentence>
|
141
|
+
# </item>
|
142
|
+
# </items>
|
143
|
+
# </root>
|
144
|
+
builder.root do
|
145
|
+
builder.items do
|
146
|
+
builder.array_mode do
|
147
|
+
2.times do |i|
|
148
|
+
builder << builder.new!.root!(:item, :id => i) do |_builder|
|
149
|
+
_builder.text "hello world #{i}"
|
150
|
+
_builder.sentence(:id => i) do
|
151
|
+
_builder.text "Hello world!!"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
builder.target!.should == {
|
159
|
+
:items => [{
|
160
|
+
:item =>{
|
161
|
+
:text => "hello world 0",
|
162
|
+
:sentence => {:text => "Hello world!!", :id => 0},
|
163
|
+
:id => 0
|
164
|
+
}
|
165
|
+
},{
|
166
|
+
:item => {
|
167
|
+
:text => "hello world 1",
|
168
|
+
:sentence => {:text => "Hello world!!", :id => 1},
|
169
|
+
:id => 1
|
170
|
+
}
|
171
|
+
}]
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
# it "should allow root! without constructing a new instance" do
|
176
|
+
# builder = Builder::HashStructure.new
|
177
|
+
# # XML ::
|
178
|
+
# # <root>
|
179
|
+
# # <items>
|
180
|
+
# # <item id="0">
|
181
|
+
# # <text>hello world 0</text>
|
182
|
+
# # <sentence id="0"></sentence>
|
183
|
+
# # </item>
|
184
|
+
# # <item id="0">
|
185
|
+
# # <text>hello world 1</text>
|
186
|
+
# # <sentence id="1">Hello world!!</sentence>
|
187
|
+
# # </item>
|
188
|
+
# # </items>
|
189
|
+
# # </root>
|
190
|
+
# builder.root do
|
191
|
+
# builder.items do
|
192
|
+
# builder.array_mode do
|
193
|
+
# 2.times do |i|
|
194
|
+
# builder.root!(:item, :id => i) do
|
195
|
+
# builder.text "hello world #{i}"
|
196
|
+
# builder.sentence(:id => i) do
|
197
|
+
# builder.text "Hello world!!"
|
198
|
+
# end
|
199
|
+
# end
|
200
|
+
# end
|
201
|
+
# end
|
202
|
+
# end
|
203
|
+
# end
|
204
|
+
# builder.target!.should == {
|
205
|
+
# :items => [{
|
206
|
+
# :item =>{
|
207
|
+
# :text => "hello world 0",
|
208
|
+
# :sentence => {:text => "Hello world!!", :id => 0},
|
209
|
+
# :id => 0
|
210
|
+
# }
|
211
|
+
# },{
|
212
|
+
# :item => {
|
213
|
+
# :text => "hello world 1",
|
214
|
+
# :sentence => {:text => "Hello world!!", :id => 1},
|
215
|
+
# :id => 1
|
216
|
+
# }
|
217
|
+
# }]
|
218
|
+
# }
|
219
|
+
# end
|
220
|
+
|
221
|
+
|
222
|
+
it "should generate a new key if needed" do
|
223
|
+
builder = Builder::HashStructure.new
|
224
|
+
# XML ::
|
225
|
+
# <root>
|
226
|
+
# <items site="smart.fm">
|
227
|
+
# <item>
|
228
|
+
# <text>hello world 0</text>
|
229
|
+
# </item>
|
230
|
+
# <item>
|
231
|
+
# <text>hello world 1</text>
|
232
|
+
# </item>
|
233
|
+
# </items>
|
234
|
+
# </root>
|
235
|
+
builder.root do
|
236
|
+
builder.items(:site => "smart.fm") do
|
237
|
+
builder.array_mode(:item) do
|
238
|
+
2.times do |i|
|
239
|
+
builder.item do
|
240
|
+
builder.text "hello world #{i}"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
builder.target!.should == {
|
247
|
+
:items => {
|
248
|
+
:item => [{:text => "hello world 0"}, {:text=>"hello world 1"}],
|
249
|
+
:site=>"smart.fm"
|
250
|
+
}
|
251
|
+
}
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should allow nested array_mode" do
|
255
|
+
builder = Builder::HashStructure.new
|
256
|
+
builder.root do
|
257
|
+
builder.items do
|
258
|
+
builder.array_mode do
|
259
|
+
2.times do |i|
|
260
|
+
builder.item(:id => i) do
|
261
|
+
builder.text "hello world #{i}"
|
262
|
+
builder.sentences do
|
263
|
+
builder.array_mode(:hoge) do
|
264
|
+
2.times do |j|
|
265
|
+
builder.sentence(:id => "#{i}_#{j}") do
|
266
|
+
builder.text "hello world #{i}"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
builder.target!.should == {
|
277
|
+
:items => [{
|
278
|
+
:text => "hello world 0",
|
279
|
+
:sentences => [{
|
280
|
+
:text => "hello world 0", :id => "0_0"
|
281
|
+
}, {
|
282
|
+
:text => "hello world 0", :id => "0_1"
|
283
|
+
}],
|
284
|
+
:id => 0
|
285
|
+
},
|
286
|
+
{
|
287
|
+
:text => "hello world 1",
|
288
|
+
:sentences => [{
|
289
|
+
:text => "hello world 1", :id => "1_0"
|
290
|
+
}, {
|
291
|
+
:text => "hello world 1", :id => "1_1"
|
292
|
+
}],
|
293
|
+
:id => 1
|
294
|
+
}]
|
295
|
+
}
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
@@ -4,6 +4,11 @@ describe Builder::HashStructure, ".new" do
|
|
4
4
|
it "should be accessible" do
|
5
5
|
Builder::HashStructure.should respond_to(:new)
|
6
6
|
end
|
7
|
+
|
8
|
+
it 'should create new instances of self with new!' do
|
9
|
+
builder = Builder::HashStructure.new
|
10
|
+
builder.new!.should be_a Builder::HashStructure
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
describe Builder::HashStructure do
|
@@ -17,6 +22,15 @@ describe Builder::HashStructure do
|
|
17
22
|
builder.target!.should == {:tag => "value"}
|
18
23
|
end
|
19
24
|
|
25
|
+
it "should remove the root tag, but keep the attributes" do
|
26
|
+
builder = Builder::HashStructure.new
|
27
|
+
# XML :: <root><tag>value</tag></root>
|
28
|
+
builder.root(:id => 1) do
|
29
|
+
builder.tag "value"
|
30
|
+
end
|
31
|
+
builder.target!.should == {:id => 1, :tag => "value"}
|
32
|
+
end
|
33
|
+
|
20
34
|
it "should not remove the root tag when include_root is true" do
|
21
35
|
builder = Builder::HashStructure.new(:include_root => true)
|
22
36
|
# XML :: <root><tag>value</tag></root>
|
@@ -35,6 +49,15 @@ describe Builder::HashStructure do
|
|
35
49
|
builder.target!.should == {:tag => {:id => 1, :content => "value"}}
|
36
50
|
end
|
37
51
|
|
52
|
+
it "should use the specified default_content_key when both content and attributes exist" do
|
53
|
+
builder = Builder::HashStructure.new(:default_content_key => :text)
|
54
|
+
# XML :: <root><tag id="1">value</tag></root>
|
55
|
+
builder.root do
|
56
|
+
builder.tag("value", :id => 1)
|
57
|
+
end
|
58
|
+
builder.target!.should == {:tag => {:id => 1, :text => "value"}}
|
59
|
+
end
|
60
|
+
|
38
61
|
it "should use the default_content_key when both cdata! and attributes exist" do
|
39
62
|
builder = Builder::HashStructure.new
|
40
63
|
# XML :: <root><tag id="1"><![CDATA[value]]></tag></root>
|
@@ -46,6 +69,46 @@ describe Builder::HashStructure do
|
|
46
69
|
builder.target!.should == {:tag => {:id => 1, :content => "value"}}
|
47
70
|
end
|
48
71
|
|
72
|
+
it "should allow the default_content_key to be specified as a second argument to cdata!" do
|
73
|
+
builder = Builder::HashStructure.new
|
74
|
+
# XML :: <quotes><quote id=\"1\"><![CDATA[All generalizations are false, including this one.]]></quote></quotes>
|
75
|
+
builder.quotes do
|
76
|
+
builder.quote(:id => 1) do
|
77
|
+
builder.cdata!("All generalizations are false, including this one.", :text)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
builder.target!.should == {:quote => {:id => 1, :text => "All generalizations are false, including this one."}}
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should use the specified default_content_key when it and content and attributes are specified via the content!" do
|
84
|
+
builder = Builder::HashStructure.new
|
85
|
+
# XML :: <root><tag id="1">value</tag></root>
|
86
|
+
builder.root do
|
87
|
+
builder.content!(:tag, :text, "value", :id => 1)
|
88
|
+
end
|
89
|
+
builder.target!.should == {:tag => {:id => 1, :text => "value"}}
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should accept strings for insertion" do
|
93
|
+
builder = Builder::HashStructure.new
|
94
|
+
sub_builder = Builder::HashStructure.new
|
95
|
+
sub_builder.tag('value')
|
96
|
+
|
97
|
+
# XML :: <root><tag id="1">value</tag></root>
|
98
|
+
builder.root do
|
99
|
+
builder.tags do |tag|
|
100
|
+
builder << sub_builder.target!
|
101
|
+
end
|
102
|
+
end
|
103
|
+
builder.target!.should == {:tags => "value"}
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
describe Builder::HashStructure, '#serialization_method!' do
|
109
|
+
it 'should report the to_hash method' do
|
110
|
+
Builder::HashStructure.new.serialization_method!.should == :to_hash
|
111
|
+
end
|
49
112
|
end
|
50
113
|
|
51
114
|
describe Builder::HashStructure, "#target!" do
|
@@ -74,145 +137,13 @@ describe Builder::HashStructure, "#target!" do
|
|
74
137
|
|
75
138
|
end
|
76
139
|
|
77
|
-
describe Builder::HashStructure, "#
|
140
|
+
describe Builder::HashStructure, "#root!" do
|
78
141
|
|
79
|
-
it "should
|
142
|
+
it "should force the root tag" do
|
80
143
|
builder = Builder::HashStructure.new
|
81
|
-
|
82
|
-
|
83
|
-
# <items>
|
84
|
-
# <item>
|
85
|
-
# <text>hello world 0</text>
|
86
|
-
# </item>
|
87
|
-
# <item>
|
88
|
-
# <text>hello world 1</text>
|
89
|
-
# </item>
|
90
|
-
# </items>
|
91
|
-
# </root>
|
92
|
-
builder.root do
|
93
|
-
builder.items do
|
94
|
-
builder.array_mode do
|
95
|
-
2.times do |i|
|
96
|
-
_builder = Builder::HashStructure.new
|
97
|
-
builder << _builder.item do
|
98
|
-
_builder.text "hello world #{i}"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
builder.target!.should == {
|
105
|
-
:items => [{:text => "hello world 0"}, {:text => "hello world 1"}]
|
106
|
-
}
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should generate a new key if needed" do
|
110
|
-
builder = Builder::HashStructure.new
|
111
|
-
# XML ::
|
112
|
-
# <root>
|
113
|
-
# <items site="smart.fm">
|
114
|
-
# <item>
|
115
|
-
# <text>hello world 0</text>
|
116
|
-
# </item>
|
117
|
-
# <item>
|
118
|
-
# <text>hello world 1</text>
|
119
|
-
# </item>
|
120
|
-
# </items>
|
121
|
-
# </root>
|
122
|
-
builder.root do
|
123
|
-
builder.items(:site => "smart.fm") do
|
124
|
-
builder.array_mode do
|
125
|
-
2.times do |i|
|
126
|
-
_builder = Builder::HashStructure.new
|
127
|
-
builder << _builder.item do
|
128
|
-
_builder.text "hello world #{i}"
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
builder.target!.should == {
|
135
|
-
:items => {
|
136
|
-
:entry => [{:text => "hello world 0"}, {:text=>"hello world 1"}],
|
137
|
-
:site=>"smart.fm"
|
138
|
-
}
|
139
|
-
}
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should treat an empty block as a blank Array" do
|
143
|
-
# XML ::
|
144
|
-
# <root>
|
145
|
-
# <items>
|
146
|
-
# </items>
|
147
|
-
# </root>
|
148
|
-
builder = Builder::HashStructure.new
|
149
|
-
builder.root do
|
150
|
-
builder.items do
|
151
|
-
builder.array_mode do
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
builder.target!.should == {:items => []}
|
156
|
-
end
|
157
|
-
|
158
|
-
it "should raise error if tag methods (method_missing) is used inside block"do
|
159
|
-
builder = Builder::HashStructure.new
|
160
|
-
builder.root do
|
161
|
-
builder.items do
|
162
|
-
lambda do
|
163
|
-
builder.array_mode do
|
164
|
-
builder.item("hello world")
|
165
|
-
end
|
166
|
-
end.should raise_error
|
167
|
-
lambda do
|
168
|
-
builder.array_mode do
|
169
|
-
builder.item do
|
170
|
-
builder.text("hello world")
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end.should raise_error
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
it "should raise error if tag! is used inside block"do
|
179
|
-
builder = Builder::HashStructure.new
|
180
|
-
builder.root do
|
181
|
-
builder.items do
|
182
|
-
lambda do
|
183
|
-
builder.array_mode do
|
184
|
-
builder.tag!("item", "item1")
|
185
|
-
end
|
186
|
-
end.should raise_error
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
it "should raise error if cdata! (or text!) is used inside block"do
|
192
|
-
builder = Builder::HashStructure.new
|
193
|
-
builder.root do
|
194
|
-
builder.items do
|
195
|
-
lambda do
|
196
|
-
builder.array_mode do
|
197
|
-
builder.cdata!("text")
|
198
|
-
end
|
199
|
-
end.should raise_error
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
it "should raise error if array_mode is used inside block"do
|
205
|
-
builder = Builder::HashStructure.new
|
206
|
-
builder.root do
|
207
|
-
builder.items do
|
208
|
-
lambda do
|
209
|
-
builder.array_mode do
|
210
|
-
builder.array_mode do
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end.should raise_error
|
214
|
-
end
|
144
|
+
builder.root!(:root) do
|
145
|
+
builder.tag "value"
|
215
146
|
end
|
147
|
+
builder.target!.should == {:root => {:tag => 'value'}}
|
216
148
|
end
|
217
|
-
|
218
149
|
end
|
@@ -1,11 +1,78 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
2
|
|
3
|
+
class TestObject
|
4
|
+
|
5
|
+
def initialize(text)
|
6
|
+
@text = text
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_json(options = {})
|
10
|
+
builder = Builder::JsonFormat.new
|
11
|
+
builder.content do
|
12
|
+
builder.text(@text)
|
13
|
+
end
|
14
|
+
builder.target!.to_json
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
3
18
|
describe Builder::JsonFormat, ".new" do
|
4
19
|
it "should be accessible" do
|
5
20
|
Builder::JsonFormat.should respond_to(:new)
|
6
21
|
end
|
7
22
|
end
|
8
23
|
|
24
|
+
describe Builder::JsonFormat, '#serialization_method!' do
|
25
|
+
it 'should report the to_json method' do
|
26
|
+
Builder::JsonFormat.new.serialization_method!.should == :to_json
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe Builder::JsonFormat do
|
31
|
+
|
32
|
+
it 'should allow string inserts to support recursive calls' do
|
33
|
+
builder = Builder::JsonFormat.new
|
34
|
+
builder.objects do
|
35
|
+
builder << TestObject.new("Recursive Json!").to_json
|
36
|
+
end
|
37
|
+
|
38
|
+
builder.to_s.should == "{\"text\": \"Recursive Json!\"}"
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should allow string inserts to support recursive calls' do
|
42
|
+
builder = Builder::JsonFormat.new
|
43
|
+
builder.objects do
|
44
|
+
builder << "\"my text\""
|
45
|
+
end
|
46
|
+
|
47
|
+
builder.to_s.should == "\"my text\""
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should allow string inserts to support recursive calls in array mode' do
|
51
|
+
builder = Builder::JsonFormat.new
|
52
|
+
builder.objects do
|
53
|
+
builder.texts do
|
54
|
+
builder.array_mode do
|
55
|
+
builder << "\"my text\""
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
builder.to_s.should == "{\"texts\": [\"my text\"]}"
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should allow string inserts to support recursive calls in array mode' do
|
64
|
+
builder = Builder::JsonFormat.new
|
65
|
+
builder.objects do
|
66
|
+
builder.key('value')
|
67
|
+
builder << TestObject.new("Recursive Json!").to_json
|
68
|
+
end
|
69
|
+
|
70
|
+
builder.target!.should == {:key => "value", :text => "Recursive Json!"}
|
71
|
+
# NOTICE: The order of Hash keys may change.
|
72
|
+
# builder.to_s.should == "{\"text\": \"Recursive Json!\", \"key\": \"value\"}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
9
76
|
describe Builder::JsonFormat, "#target!" do
|
10
77
|
|
11
78
|
it "should return a String when there is only a root value" do
|
@@ -14,13 +81,23 @@ describe Builder::JsonFormat, "#target!" do
|
|
14
81
|
builder.target!.should be_a(String)
|
15
82
|
end
|
16
83
|
|
17
|
-
it "should return a
|
84
|
+
it "should return a Hash object when root has deeper structure" do
|
18
85
|
builder = Builder::JsonFormat.new
|
19
86
|
builder.root do
|
20
87
|
builder.item("value")
|
21
88
|
end
|
22
|
-
builder.target!.should be_a(
|
23
|
-
builder.
|
89
|
+
builder.target!.should be_a(Hash)
|
90
|
+
builder.to_s.should =="{\"item\": \"value\"}"
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should return a Hash object when include_root is true" do
|
94
|
+
builder = Builder::JsonFormat.new(:include_root => true)
|
95
|
+
# XML :: <root><tag>value</tag></root>
|
96
|
+
builder.root do
|
97
|
+
builder.tag "value"
|
98
|
+
end
|
99
|
+
builder.target!.should be_a(Hash)
|
100
|
+
builder.to_s.should == '{"root": {"tag": "value"}}'
|
24
101
|
end
|
25
102
|
|
26
103
|
end
|
@@ -1,5 +1,13 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
2
|
|
3
|
+
describe Builder::XmlMarkup, "#new!" do
|
4
|
+
|
5
|
+
it "should return new instance of same class" do
|
6
|
+
builder = Builder::XmlMarkup.new
|
7
|
+
builder.new!.should be_a Builder::XmlMarkup
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
3
11
|
describe Builder::XmlMarkup, "#array_mode" do
|
4
12
|
|
5
13
|
it "should do nothing" do
|
@@ -15,5 +23,34 @@ describe Builder::XmlMarkup, "#array_mode" do
|
|
15
23
|
end
|
16
24
|
builder.target!.should == builder2.target!
|
17
25
|
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe Builder::XmlMarkup, '#serialization_method!' do
|
29
|
+
it 'should report the to_xml method' do
|
30
|
+
Builder::XmlMarkup.new.serialization_method!.should == :to_xml
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Builder::XmlMarkup, "#xml_root!" do
|
35
|
+
|
36
|
+
it "should create an element as normal" do
|
37
|
+
builder = Builder::XmlMarkup.new
|
38
|
+
builder.root!("root") do
|
39
|
+
builder.tag "value"
|
40
|
+
end
|
41
|
+
builder.target!.should == "<root><tag>value</tag></root>"
|
42
|
+
end
|
43
|
+
end
|
18
44
|
|
45
|
+
describe Builder::XmlMarkup, "#cdata!" do
|
46
|
+
|
47
|
+
it "should support a second argument which does nothing" do
|
48
|
+
builder = Builder::XmlMarkup.new
|
49
|
+
builder.quotes do
|
50
|
+
builder.quote(:id => 1) do
|
51
|
+
builder.cdata!("All generalizations are false, including this one.", :text)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
builder.target!.should == "<quotes><quote id=\"1\"><![CDATA[All generalizations are false, including this one.]]></quote></quotes>"
|
55
|
+
end
|
19
56
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonbuilder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
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-06-
|
12
|
+
date: 2009-06-24 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -36,6 +36,7 @@ files:
|
|
36
36
|
- ChangeLog
|
37
37
|
- Rakefile
|
38
38
|
- spec/builder
|
39
|
+
- spec/builder/array_mode_spec.rb
|
39
40
|
- spec/builder/hash_structure_spec.rb
|
40
41
|
- spec/builder/json_format_spec.rb
|
41
42
|
- spec/builder/xml_markup_spec.rb
|