bldr 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.md CHANGED
@@ -1,3 +1,6 @@
1
- # 0.1.2 (2011-09-08)
1
+ ## 0.2.0 (2011-09-09)
2
+ * Add new `attribute` inferred object syntax (@ihunter)
3
+
4
+ ## 0.1.2 (2011-09-08)
2
5
 
3
6
  * Return an empty collection when a nil value is passed to `collection` method
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
- "body": "..."
116
+ "body": "..."
83
117
  }
84
118
  }
85
119
  ```
@@ -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(hash = nil, &block)
79
- if hash
80
- key = hash.keys.first
81
- value = hash.values.first
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 block_given?
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
- alias :attribute :attributes
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
 
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Bldr
3
- VERSION = '0.1.2'
3
+ VERSION = '0.2.0'
4
4
  end
@@ -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
@@ -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
@@ -1,56 +1,277 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Node#attributes" do
4
- def wrap(&block)
5
- alex = Person.new('alex').tap { |p| p.age = 25; p }
6
- Bldr::Node.new do
7
- object(:person => alex, &block)
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
- it "adds attributes of the person to the result hash" do
12
- node = wrap { attributes(:name, :age) }
13
- node.render!.should == {:person => {:name => 'alex', :age => 25}}
14
- end
19
+ describe "#attribute" do
15
20
 
16
- it "supports dynamic block attributes with explicit object context" do
17
- node = wrap do
18
- attribute(:oldness) do |person|
19
- "#{person.age} years"
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
- it "supports dynamic block attributes with implicit object context" do
27
- node = wrap do
28
- attribute(:oldness) do
29
- "#{age} years"
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
- node.render!.should == {:person => {:oldness => "25 years"}}
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
- it "raises an error when you use the block syntax with more than one attribute" do
37
- expect {
38
- node_wrap {
39
- attributes(:one, :two) do |person|
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
- it "returns nil attributes in the result" do
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
- node.render!.should == {:person => {:name => 'alex', :age => nil}}
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.1.2
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: &2156406360 !ruby/object:Gem::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: *2156406360
24
+ version_requirements: *2152503360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: json_pure
27
- requirement: &2152301980 !ruby/object:Gem::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: *2152301980
35
+ version_requirements: *2152533900
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sinatra
38
- requirement: &2152301440 !ruby/object:Gem::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: *2152301440
46
+ version_requirements: *2152533360
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: tilt
49
- requirement: &2152300940 !ruby/object:Gem::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: *2152300940
57
+ version_requirements: *2152532860
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: yajl-ruby
60
- requirement: &2152300560 !ruby/object:Gem::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: *2152300560
68
+ version_requirements: *2152532480
69
69
  description: Provides a simple and intuitive templating DSL for serializing objects
70
70
  to JSON.
71
71
  email: