bldr 0.1.2 → 0.2.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/HISTORY.md +4 -1
- data/README.md +35 -1
- data/lib/bldr/node.rb +31 -14
- data/lib/bldr/version.rb +1 -1
- data/spec/functional/tilt_template_spec.rb +0 -12
- data/spec/spec_helper.rb +8 -0
- data/spec/unit/node_spec.rb +254 -50
- metadata +11 -11
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -65,8 +65,42 @@ end
|
|
65
65
|
|
66
66
|
## Examples
|
67
67
|
|
68
|
+
### Rendering a basic object
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
object do
|
72
|
+
attribute :title, "my title"
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
Output:
|
77
|
+
|
78
|
+
```javascript
|
79
|
+
{
|
80
|
+
"title": "my title"
|
81
|
+
}
|
82
|
+
```
|
83
|
+
|
68
84
|
### Rendering a simple list of attributes
|
69
85
|
|
86
|
+
```ruby
|
87
|
+
object :post do
|
88
|
+
attribute :title, "my title"
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
Output:
|
93
|
+
|
94
|
+
```javascript
|
95
|
+
{
|
96
|
+
"post": {
|
97
|
+
"title": "my title"
|
98
|
+
}
|
99
|
+
}
|
100
|
+
```
|
101
|
+
|
102
|
+
### Rendering a simple list of attributes from an object
|
103
|
+
|
70
104
|
```ruby
|
71
105
|
object :post => post do
|
72
106
|
attributes :title, :body
|
@@ -79,7 +113,7 @@ Output:
|
|
79
113
|
{
|
80
114
|
"post": {
|
81
115
|
"title": "my title",
|
82
|
-
|
116
|
+
"body": "..."
|
83
117
|
}
|
84
118
|
}
|
85
119
|
```
|
data/lib/bldr/node.rb
CHANGED
@@ -75,10 +75,13 @@ module Bldr
|
|
75
75
|
#
|
76
76
|
# @return [String] returns a json-encoded string of itself and all
|
77
77
|
# descendant nodes.
|
78
|
-
def object(
|
79
|
-
if
|
80
|
-
key =
|
81
|
-
value =
|
78
|
+
def object(base = nil, &block)
|
79
|
+
if base.kind_of? Hash
|
80
|
+
key = base.keys.first
|
81
|
+
value = base.values.first
|
82
|
+
else
|
83
|
+
key = base
|
84
|
+
value = nil
|
82
85
|
end
|
83
86
|
|
84
87
|
node = Node.new(value, :parent => self, &block)
|
@@ -135,15 +138,7 @@ module Bldr
|
|
135
138
|
#
|
136
139
|
# @return [Nil]
|
137
140
|
def attributes(*args, &block)
|
138
|
-
if
|
139
|
-
if args.size > 1
|
140
|
-
raise(ArgumentError, "You may only pass one argument to #attribute when using the block syntax.")
|
141
|
-
end
|
142
|
-
|
143
|
-
merge_result!(args.first, (block.arity == 1) ? block.call(current_object) : current_object.instance_eval(&block))
|
144
|
-
return nil
|
145
|
-
end
|
146
|
-
|
141
|
+
raise(ArgumentError, "You cannot use #attributes when inferred object is not present.") if current_object.nil?
|
147
142
|
args.each do |arg|
|
148
143
|
if arg.is_a?(Hash)
|
149
144
|
merge_result!(arg.keys.first, current_object.send(arg.values.first))
|
@@ -153,7 +148,29 @@ module Bldr
|
|
153
148
|
end
|
154
149
|
nil
|
155
150
|
end
|
156
|
-
|
151
|
+
|
152
|
+
def attribute(*args,&block)
|
153
|
+
if block_given?
|
154
|
+
raise(ArgumentError, "You may only pass one argument to #attribute when using the block syntax.") if args.size > 1
|
155
|
+
raise(ArgumentError, "You cannot use a block of arity > 0 if inferred object is not present.") if block.arity > 0 and current_object.nil?
|
156
|
+
merge_result!(args.first, (block.arity == 1) ? block.call(current_object) : current_object.instance_eval(&block))
|
157
|
+
else
|
158
|
+
case args.size
|
159
|
+
when 1 # inferred object
|
160
|
+
raise(ArgumentError, "You cannot pass one argument to #attribute when inferred object is not present.") if current_object.nil?
|
161
|
+
if args[0].is_a?(Hash)
|
162
|
+
merge_result!(args[0].keys.first, current_object.send(args[0].values.first))
|
163
|
+
else
|
164
|
+
merge_result!(args[0], current_object.send(args[0]))
|
165
|
+
end
|
166
|
+
when 2 # static property
|
167
|
+
merge_result!(args[0], args[1])
|
168
|
+
else
|
169
|
+
raise(ArgumentError, "You cannot pass more than two arguments to #attribute.")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
nil
|
173
|
+
end
|
157
174
|
|
158
175
|
private
|
159
176
|
|
data/lib/bldr/version.rb
CHANGED
@@ -36,18 +36,6 @@ describe "evaluating a tilt template" do
|
|
36
36
|
let(:alex) { Person.new('alex', 25) }
|
37
37
|
let(:ian) { Person.new('ian', 32) }
|
38
38
|
|
39
|
-
it "returns json for a blank root object " do
|
40
|
-
tpl = Bldr::Template.new {
|
41
|
-
<<-RUBY
|
42
|
-
object do
|
43
|
-
attribute(:url) {"http://google.com"}
|
44
|
-
end
|
45
|
-
RUBY
|
46
|
-
}
|
47
|
-
result = tpl.render(Bldr::Node.new)
|
48
|
-
result.should == jsonify({'url' => 'http://google.com'})
|
49
|
-
end
|
50
|
-
|
51
39
|
it "returns json for a root object" do
|
52
40
|
tpl = Bldr::Template.new {
|
53
41
|
<<-RUBY
|
data/spec/spec_helper.rb
CHANGED
@@ -24,4 +24,12 @@ RSpec.configure do |c|
|
|
24
24
|
def jsonify(hash)
|
25
25
|
Yajl::Encoder.encode(hash)
|
26
26
|
end
|
27
|
+
|
28
|
+
# render the String template and compare to the jsonified hash
|
29
|
+
def it_renders_template_to_hash(template,hash)
|
30
|
+
tpl = Bldr::Template.new {template}
|
31
|
+
result = tpl.render(Bldr::Node.new)
|
32
|
+
result.should == jsonify(hash)
|
33
|
+
end
|
34
|
+
|
27
35
|
end
|
data/spec/unit/node_spec.rb
CHANGED
@@ -1,56 +1,277 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
ERROR_MESSAGES = { :attribute_lambda_one_argument => "You may only pass one argument to #attribute when using the block syntax.",
|
4
|
+
:attribute_inferred_missing_one_argument => "You cannot pass one argument to #attribute when inferred object is not present.",
|
5
|
+
:attribute_more_than_two_arg => "You cannot pass more than two arguments to #attribute.",
|
6
|
+
:attribute_inferred_missing_arity_too_large => "You cannot use a block of arity > 0 if inferred object is not present.",
|
7
|
+
:attributes_inferred_missing => "You cannot use #attributes when inferred object is not present." }
|
8
|
+
|
9
|
+
describe "Node#object" do
|
10
|
+
|
11
|
+
context "a zero arg root object node" do
|
12
|
+
|
13
|
+
def wrap(&block)
|
14
|
+
Bldr::Node.new do
|
15
|
+
object(&block)
|
16
|
+
end
|
8
17
|
end
|
9
|
-
end
|
10
18
|
|
11
|
-
|
12
|
-
node = wrap { attributes(:name, :age) }
|
13
|
-
node.render!.should == {:person => {:name => 'alex', :age => 25}}
|
14
|
-
end
|
19
|
+
describe "#attribute" do
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
it "errors on a single argument" do
|
22
|
+
expect {
|
23
|
+
node_wrap {
|
24
|
+
attribute(:one, :two) do |person|
|
25
|
+
"..."
|
26
|
+
end
|
27
|
+
}
|
28
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_lambda_one_argument])
|
29
|
+
end
|
30
|
+
it "errors on 3 arguments" do
|
31
|
+
expect {
|
32
|
+
node_wrap {
|
33
|
+
attribute(:one, :two, :three)
|
34
|
+
}
|
35
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_more_than_two_arg])
|
36
|
+
end
|
37
|
+
it "errors on 2 arguments and a lambda" do
|
38
|
+
expect {
|
39
|
+
node_wrap {
|
40
|
+
attribute(:one, :two) do |person|
|
41
|
+
"..."
|
42
|
+
end
|
43
|
+
}
|
44
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_lambda_one_argument])
|
45
|
+
end
|
46
|
+
it "errors on 1 argument since there is no inferred object" do
|
47
|
+
expect {
|
48
|
+
node_wrap {
|
49
|
+
attribute(:one)
|
50
|
+
}
|
51
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_inferred_missing_one_argument])
|
52
|
+
end
|
53
|
+
it "renders 2 arguments statically" do
|
54
|
+
node = wrap { attribute(:name, "alex") }
|
55
|
+
node.render!.should == {:name => 'alex'}
|
20
56
|
end
|
57
|
+
it "renders 1 argument and one lambda with zero arity" do
|
58
|
+
node = wrap {
|
59
|
+
attribute(:name) do
|
60
|
+
"alex"
|
61
|
+
end
|
62
|
+
}
|
63
|
+
node.render!.should == {:name => 'alex'}
|
64
|
+
end
|
65
|
+
it "errors on 1 argument and one lambda with arity 1" do
|
66
|
+
expect {
|
67
|
+
node_wrap {
|
68
|
+
attribute(:name) do |name|
|
69
|
+
name
|
70
|
+
end
|
71
|
+
}
|
72
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_inferred_missing_arity_too_large])
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#attributes" do
|
78
|
+
|
79
|
+
it "errors since current_object is nil" do
|
80
|
+
expect {
|
81
|
+
node_wrap {
|
82
|
+
attributes(:name)
|
83
|
+
}
|
84
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attributes_inferred_missing])
|
85
|
+
end
|
86
|
+
|
21
87
|
end
|
22
88
|
|
23
|
-
node.render!.should == {:person => {:oldness => "25 years"}}
|
24
89
|
end
|
25
90
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
91
|
+
context "a single arg root object node" do
|
92
|
+
|
93
|
+
def wrap(&block)
|
94
|
+
Bldr::Node.new do
|
95
|
+
object(:person, &block)
|
30
96
|
end
|
31
97
|
end
|
32
98
|
|
33
|
-
|
99
|
+
describe "#attribute" do
|
100
|
+
|
101
|
+
it "errors on a single argument" do
|
102
|
+
expect {
|
103
|
+
node_wrap {
|
104
|
+
attribute(:one, :two) do |person|
|
105
|
+
"..."
|
106
|
+
end
|
107
|
+
}
|
108
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_lambda_one_argument])
|
109
|
+
end
|
110
|
+
it "errors on 3 arguments" do
|
111
|
+
expect {
|
112
|
+
node_wrap {
|
113
|
+
attribute(:one, :two, :three)
|
114
|
+
}
|
115
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_more_than_two_arg])
|
116
|
+
end
|
117
|
+
it "errors on 2 arguments and a lambda" do
|
118
|
+
expect {
|
119
|
+
node_wrap {
|
120
|
+
attribute(:one, :two) do |person|
|
121
|
+
"..."
|
122
|
+
end
|
123
|
+
}
|
124
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_lambda_one_argument])
|
125
|
+
end
|
126
|
+
it "errors on 1 argument since there is no inferred object" do
|
127
|
+
expect {
|
128
|
+
node_wrap {
|
129
|
+
attribute(:one)
|
130
|
+
}
|
131
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_inferred_missing_one_argument])
|
132
|
+
end
|
133
|
+
it "renders 2 arguments statically" do
|
134
|
+
node = wrap { attribute(:name, "alex") }
|
135
|
+
node.render!.should == {:person => {:name => 'alex'}}
|
136
|
+
end
|
137
|
+
it "renders 1 argument and one lambda with zero arity" do
|
138
|
+
node = wrap {
|
139
|
+
attribute(:name) do
|
140
|
+
"alex"
|
141
|
+
end
|
142
|
+
}
|
143
|
+
node.render!.should == {:person => {:name => 'alex'}}
|
144
|
+
end
|
145
|
+
it "errors on 1 argument and one lambda with arity 1" do
|
146
|
+
expect {
|
147
|
+
node_wrap {
|
148
|
+
attribute(:name) do |name|
|
149
|
+
name
|
150
|
+
end
|
151
|
+
}
|
152
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_inferred_missing_arity_too_large])
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "#attributes" do
|
157
|
+
|
158
|
+
it "errors since current_object is nil" do
|
159
|
+
expect {
|
160
|
+
node_wrap {
|
161
|
+
attributes(:name)
|
162
|
+
}
|
163
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attributes_inferred_missing])
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
34
168
|
end
|
35
169
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
170
|
+
context "a hash-arg root object node" do
|
171
|
+
|
172
|
+
def wrap(&block)
|
173
|
+
alex = Person.new('alex').tap { |p| p.age = 25; p }
|
174
|
+
Bldr::Node.new do
|
175
|
+
object(:person => alex, &block)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "#attribute" do
|
180
|
+
|
181
|
+
it "errors on 3 arguments" do
|
182
|
+
expect {
|
183
|
+
node_wrap {
|
184
|
+
attribute(:one, :two, :three)
|
185
|
+
}
|
186
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_more_than_two_arg])
|
187
|
+
end
|
188
|
+
it "errors on 2 arguments and a lambda" do
|
189
|
+
expect {
|
190
|
+
node_wrap {
|
191
|
+
attribute(:one, :two) do |person|
|
192
|
+
"..."
|
193
|
+
end
|
194
|
+
}
|
195
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attribute_lambda_one_argument])
|
196
|
+
end
|
197
|
+
it "renders 1 argument to the inferred object" do
|
198
|
+
node = wrap { attribute(:name) }
|
199
|
+
node.render!.should == {:person => {:name => 'alex'}}
|
200
|
+
end
|
201
|
+
it "renders 1 argument hash to the inferred object as the different key" do
|
202
|
+
node = wrap { attribute(:fake => :name) }
|
203
|
+
node.render!.should == {:person => {:fake => 'alex'}}
|
204
|
+
end
|
205
|
+
it "renders 2 arguments statically" do
|
206
|
+
node = wrap { attribute(:name, "ian") }
|
207
|
+
node.render!.should == {:person => {:name => 'ian'}}
|
208
|
+
end
|
209
|
+
it "renders 1 argument and one lambda with zero arity" do
|
210
|
+
node = wrap { attribute(:name){"ian"} }
|
211
|
+
node.render!.should == {:person => {:name => 'ian'}}
|
212
|
+
end
|
213
|
+
it "renders 1 argument and one lambda with arity 1" do
|
214
|
+
node = wrap { attribute(:name){|person| person.name} }
|
215
|
+
node.render!.should == {:person => {:name => 'alex'}}
|
216
|
+
end
|
217
|
+
it "renders nil attributes" do
|
218
|
+
node = node_wrap do
|
219
|
+
object :person => Person.new('alex') do
|
220
|
+
attribute :age
|
221
|
+
end
|
41
222
|
end
|
42
|
-
}
|
43
|
-
}.to raise_error(ArgumentError, "You may only pass one argument to #attribute when using the block syntax.")
|
44
|
-
end
|
45
223
|
|
46
|
-
|
47
|
-
node = node_wrap do
|
48
|
-
object :person => Person.new('alex') do
|
49
|
-
attributes :name, :age
|
224
|
+
node.render!.should == {:person => {:age => nil}}
|
50
225
|
end
|
226
|
+
|
51
227
|
end
|
52
228
|
|
53
|
-
|
229
|
+
describe "#attributes" do
|
230
|
+
|
231
|
+
it "errors if the current_object is nil" do
|
232
|
+
expect {
|
233
|
+
node = node_wrap do
|
234
|
+
object(:person => nil) do
|
235
|
+
attributes(:one, :two) do |person|
|
236
|
+
"..."
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
}.to raise_error(ArgumentError, ERROR_MESSAGES[:attributes_inferred_missing])
|
241
|
+
end
|
242
|
+
it "renders each argument against the inferred object" do
|
243
|
+
node = wrap { attributes(:name, :age) }
|
244
|
+
node.render!.should == {:person => {:name => 'alex', :age => 25}}
|
245
|
+
end
|
246
|
+
it "renders nil attributes" do
|
247
|
+
node = node_wrap do
|
248
|
+
object :person => Person.new('alex') do
|
249
|
+
attributes :name, :age
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
node.render!.should == {:person => {:name => 'alex', :age => nil}}
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "embedded objects" do
|
261
|
+
it "evaluates the block and returns json" do
|
262
|
+
node = Bldr::Node.new
|
263
|
+
result = node.object(:dude => Person.new("alex")) do
|
264
|
+
attributes :name
|
265
|
+
|
266
|
+
object(:bro => Person.new("john")) do
|
267
|
+
attributes :name
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
result.should == jsonify({
|
272
|
+
:dude => {:name => 'alex', :bro => {:name => 'john'}}
|
273
|
+
})
|
274
|
+
end
|
54
275
|
end
|
55
276
|
|
56
277
|
end
|
@@ -123,23 +344,6 @@ describe "Node#render!" do
|
|
123
344
|
end
|
124
345
|
end
|
125
346
|
|
126
|
-
describe "Node#object" do
|
127
|
-
it "evaluates the block and returns json" do
|
128
|
-
node = Bldr::Node.new
|
129
|
-
result = node.object(:dude => Person.new("alex")) do
|
130
|
-
attributes :name
|
131
|
-
|
132
|
-
object(:bro => Person.new("john")) do
|
133
|
-
attributes :name
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
result.should == jsonify({
|
138
|
-
:dude => {:name => 'alex', :bro => {:name => 'john'}}
|
139
|
-
})
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
347
|
describe "Node#to_json" do
|
144
348
|
it "recursively returns the result json" do
|
145
349
|
node = node_wrap do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bldr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-09-09 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
16
|
-
requirement: &
|
16
|
+
requirement: &2152503360 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.0.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2152503360
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: json_pure
|
27
|
-
requirement: &
|
27
|
+
requirement: &2152533900 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2152533900
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sinatra
|
38
|
-
requirement: &
|
38
|
+
requirement: &2152533360 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.2.6
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2152533360
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: tilt
|
49
|
-
requirement: &
|
49
|
+
requirement: &2152532860 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.3.2
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2152532860
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: yajl-ruby
|
60
|
-
requirement: &
|
60
|
+
requirement: &2152532480 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2152532480
|
69
69
|
description: Provides a simple and intuitive templating DSL for serializing objects
|
70
70
|
to JSON.
|
71
71
|
email:
|