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 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: