bldr 0.6.0 → 0.7.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/.travis.yml +1 -2
- data/Gemfile +1 -0
- data/HISTORY.md +11 -1
- data/MIT-LICENSE +1 -1
- data/README.md +72 -2
- data/bldr.gemspec +3 -3
- data/lib/bldr/node.rb +43 -11
- data/lib/bldr/template.rb +3 -0
- data/lib/bldr/version.rb +1 -1
- data/lib/sinatra/bldr.rb +5 -3
- data/spec/fixtures/ivar.bldr +3 -0
- data/spec/fixtures/nested_ivars.bldr +5 -0
- data/spec/fixtures/nested_objects.json.bldr +2 -2
- data/spec/functional/tilt_template_spec.rb +191 -93
- data/spec/integration/sinatra_spec.rb +21 -1
- data/spec/models/song.rb +6 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/node_spec.rb +501 -490
- metadata +20 -14
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/HISTORY.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 0.7.0 (2013-xx-xx)
|
2
|
+
* Support for inherited instance variables
|
3
|
+
* Breaking change: Node#attribute block syntax no longer inherits
|
4
|
+
context from current_object. See 941608e7 for more
|
5
|
+
* Breaking change: Drop ruby 1.8 support
|
6
|
+
|
7
|
+
## 0.6.1 (2013-02-18) -- yanked
|
8
|
+
* Feature: Add the ability to access instance variables set in sinatra
|
9
|
+
actions in bldr templates.
|
10
|
+
|
1
11
|
## 0.6.0 (2012-xx-xx)
|
2
12
|
* Feature: Add the ability to pass-through objects directly to `object` and
|
3
13
|
`collection` DSL methods
|
@@ -21,4 +31,4 @@
|
|
21
31
|
* Add new `attribute` inferred object syntax (@ihunter)
|
22
32
|
|
23
33
|
## 0.1.2 (2011-09-08)
|
24
|
-
* Return an empty collection when a nil value is passed to `collection` method
|
34
|
+
* Return an empty collection when a nil value is passed to `collection` method
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[](https://travis-ci.org/ajsharp/bldr)
|
2
2
|
|
3
3
|
|
4
4
|
# Bldr
|
@@ -52,6 +52,75 @@ end
|
|
52
52
|
|
53
53
|
See the [Documentation & Examples](https://github.com/ajsharp/bldr/wiki/Documentation-&-Examples) page on the wiki.
|
54
54
|
|
55
|
+
## Deprecations & Breaking Changes
|
56
|
+
|
57
|
+
### 0.7.0: current_object deprecation
|
58
|
+
|
59
|
+
The use of `current_object` is now deprecated. Instead of referencing `current_object` in bldr templates
|
60
|
+
use block variables in `object` and `collection` methods:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
# OLD (deprecated)
|
64
|
+
collection :people => people do
|
65
|
+
attribute(:name) { current_object.name }
|
66
|
+
end
|
67
|
+
|
68
|
+
# NEW
|
69
|
+
collection :people => people do |person|
|
70
|
+
attribute(:name) { person.name }
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
Make use of block variables the same way for the `object` method:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
# OLD (deprecated)
|
78
|
+
object :person => person do
|
79
|
+
attributes :name, :age
|
80
|
+
|
81
|
+
person = current_object
|
82
|
+
object :address => person.address do
|
83
|
+
# current_object here would be assigned to person.address
|
84
|
+
attribute(:zip) { current_object.zip_code }
|
85
|
+
attribute(:address_title) { person.display_name }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# NEW
|
90
|
+
object :person => person do |person|
|
91
|
+
attributes :name, :age
|
92
|
+
|
93
|
+
object :adress => person.address do |address|
|
94
|
+
attribute(:zip) { address.zip_code }
|
95
|
+
attribute(:address_title) { person.display_name }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
### 0.7.0: attribute method breaking change
|
101
|
+
|
102
|
+
One of the forms of the `attribute` method has changed in the 0.7.0 release.
|
103
|
+
Previously, using the dynamic block form of `attribute`, if you did not pass
|
104
|
+
in a block variable, the block would be eval'd in context of the `current_object`.
|
105
|
+
This behavior fails the "principle of least surprise" test.
|
106
|
+
|
107
|
+
0.7.0 changes this behavior by simply executing the block in context of `Bldr::Node`, which provides
|
108
|
+
access to instance variables and locals available in that context.
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
# OLD
|
112
|
+
object :person => person do
|
113
|
+
attribute(:name) { display_name } # equivalent to doing attribute(:name) { |person| person.display_name }
|
114
|
+
end
|
115
|
+
|
116
|
+
# NEW
|
117
|
+
object :person => @person do
|
118
|
+
attribute(:name) { @person.display_name }
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
See [941608e](https://github.com/ajsharp/bldr/commit/d0bfbd8) and [d0bfbd8](https://github.com/ajsharp/bldr/commit/d0bfbd8) for more info.
|
123
|
+
|
55
124
|
## Editor Syntax Support
|
56
125
|
|
57
126
|
To get proper syntax highlighting in vim, add this line to your .vimrc:
|
@@ -75,8 +144,9 @@ au BufRead,BufNewFile *.bldr set filetype=ruby
|
|
75
144
|
|
76
145
|
* Ian Hunter (@ihunter)
|
77
146
|
* Justin Smestad (@jsmestad)
|
147
|
+
* Adam LaFave (@lafave)
|
78
148
|
|
79
149
|
## Copyright
|
80
150
|
|
81
|
-
Copyright (c) 2011-
|
151
|
+
Copyright (c) 2011-2013 Alex Sharp. See the MIT-LICENSE file for full
|
82
152
|
copyright information.
|
data/bldr.gemspec
CHANGED
@@ -22,8 +22,8 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency 'multi_json'
|
23
23
|
|
24
24
|
s.add_development_dependency 'json_pure'
|
25
|
-
s.add_development_dependency 'sinatra'
|
26
|
-
s.add_development_dependency 'tilt'
|
25
|
+
s.add_development_dependency 'sinatra'
|
26
|
+
s.add_development_dependency 'tilt'
|
27
27
|
s.add_development_dependency 'yajl-ruby', '>= 1.0'
|
28
|
-
s.add_development_dependency 'actionpack'
|
28
|
+
s.add_development_dependency 'actionpack'
|
29
29
|
end
|
data/lib/bldr/node.rb
CHANGED
@@ -3,6 +3,8 @@ module Bldr
|
|
3
3
|
|
4
4
|
class Node
|
5
5
|
|
6
|
+
PROTECTED_IVARS = [:@current_object, :@result, :@parent, :@opts, :@views, :@locals]
|
7
|
+
|
6
8
|
attr_reader :current_object, :result, :parent, :opts, :views, :locals
|
7
9
|
|
8
10
|
# Initialize a new Node instance.
|
@@ -17,6 +19,8 @@ module Bldr
|
|
17
19
|
#
|
18
20
|
#
|
19
21
|
# @param [Object] value an object to serialize.
|
22
|
+
# @param [Hash] opts
|
23
|
+
# @option [Object] opts :parent used to copy instance variables into self
|
20
24
|
def initialize(value = nil, opts = {}, &block)
|
21
25
|
@current_object = value
|
22
26
|
@opts = opts
|
@@ -24,11 +28,24 @@ module Bldr
|
|
24
28
|
@views = opts[:views]
|
25
29
|
@locals = opts[:locals]
|
26
30
|
# Storage hash for all descendant nodes
|
27
|
-
@result
|
31
|
+
@result = {}
|
32
|
+
|
33
|
+
copy_instance_variables_from(opts[:parent]) if opts[:parent]
|
28
34
|
|
29
|
-
|
35
|
+
if block_given?
|
36
|
+
if value && block.arity > 0
|
37
|
+
instance_exec(value, &block)
|
38
|
+
else
|
39
|
+
instance_eval(&block)
|
40
|
+
end
|
41
|
+
end
|
30
42
|
end
|
31
|
-
|
43
|
+
|
44
|
+
def current_object
|
45
|
+
warn "[DEPRECATION] `current_object` is deprecated. Please use object or collection block varibles instead."
|
46
|
+
@current_object
|
47
|
+
end
|
48
|
+
|
32
49
|
# Create and render a node.
|
33
50
|
#
|
34
51
|
# @example A keyed object
|
@@ -182,15 +199,15 @@ module Bldr
|
|
182
199
|
#
|
183
200
|
# @return [Nil]
|
184
201
|
def attributes(*args, &block)
|
185
|
-
if current_object.nil?
|
202
|
+
if @current_object.nil?
|
186
203
|
raise(ArgumentError, "No current_object to apply #attributes to.")
|
187
204
|
end
|
188
205
|
|
189
206
|
args.each do |arg|
|
190
207
|
if arg.is_a?(Hash)
|
191
|
-
merge_result!(arg.keys.first, current_object.send(arg.values.first))
|
208
|
+
merge_result!(arg.keys.first, @current_object.send(arg.values.first))
|
192
209
|
else
|
193
|
-
merge_result!(arg, current_object.send(arg))
|
210
|
+
merge_result!(arg, @current_object.send(arg))
|
194
211
|
end
|
195
212
|
end
|
196
213
|
self
|
@@ -199,16 +216,20 @@ module Bldr
|
|
199
216
|
def attribute(*args,&block)
|
200
217
|
if block_given?
|
201
218
|
raise(ArgumentError, "You may only pass one argument to #attribute when using the block syntax.") if args.size > 1
|
202
|
-
raise(ArgumentError, "You cannot use a block of arity > 0 if current_object is not present.") if block.arity > 0 and current_object.nil?
|
203
|
-
|
219
|
+
raise(ArgumentError, "You cannot use a block of arity > 0 if current_object is not present.") if block.arity > 0 and @current_object.nil?
|
220
|
+
if block.arity > 0
|
221
|
+
merge_result! args.first, block.call(@current_object)
|
222
|
+
else
|
223
|
+
merge_result! args.first, block.call
|
224
|
+
end
|
204
225
|
else
|
205
226
|
case args.size
|
206
227
|
when 1 # inferred object
|
207
|
-
raise(ArgumentError, "#attribute can't be used when there is no current_object.") if current_object.nil?
|
228
|
+
raise(ArgumentError, "#attribute can't be used when there is no current_object.") if @current_object.nil?
|
208
229
|
if args[0].is_a?(Hash)
|
209
|
-
merge_result!(args[0].keys.first, current_object.send(args[0].values.first))
|
230
|
+
merge_result!(args[0].keys.first, @current_object.send(args[0].values.first))
|
210
231
|
else
|
211
|
-
merge_result!(args[0], current_object.send(args[0]))
|
232
|
+
merge_result!(args[0], @current_object.send(args[0]))
|
212
233
|
end
|
213
234
|
when 2 # static property
|
214
235
|
merge_result!(args[0], args[1])
|
@@ -244,6 +265,17 @@ module Bldr
|
|
244
265
|
|
245
266
|
private
|
246
267
|
|
268
|
+
# Retrieves all instance variables from an object and sets them in the
|
269
|
+
# current scope.
|
270
|
+
#
|
271
|
+
# @param [Object] object The object to copy instance variables from.
|
272
|
+
def copy_instance_variables_from(object)
|
273
|
+
ivar_names = (object.instance_variables - PROTECTED_IVARS).map(&:to_s)
|
274
|
+
ivar_names.map do |name|
|
275
|
+
instance_variable_set(name, object.instance_variable_get(name))
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
247
279
|
# Determines if an object was passed in with a key pointing to it, or if
|
248
280
|
# it was passed in as the "root" of the current object. Essentially, this
|
249
281
|
# checks if `obj` quacks like a hash.
|
data/lib/bldr/template.rb
CHANGED
@@ -2,6 +2,7 @@ require 'tilt'
|
|
2
2
|
|
3
3
|
module Bldr
|
4
4
|
|
5
|
+
# This class is required for Tilt compatibility
|
5
6
|
class Template < Tilt::Template
|
6
7
|
|
7
8
|
self.default_mime_type = 'application/json'
|
@@ -14,6 +15,8 @@ module Bldr
|
|
14
15
|
defined? ::Bldr
|
15
16
|
end
|
16
17
|
|
18
|
+
# Called at the end of Tilt::Template#initialize.
|
19
|
+
# Use this method to access or mutate any state available to Tilt::Template
|
17
20
|
def prepare
|
18
21
|
# We get NotImplementedError by Tilt when we don't have this method
|
19
22
|
end
|
data/lib/bldr/version.rb
CHANGED
data/lib/sinatra/bldr.rb
CHANGED
@@ -4,7 +4,6 @@ module Sinatra
|
|
4
4
|
|
5
5
|
module Bldr
|
6
6
|
module Helpers
|
7
|
-
|
8
7
|
# Wrapper for Tilt's `render` method
|
9
8
|
#
|
10
9
|
# We use this to properly set the scope the template gets rendered
|
@@ -24,10 +23,13 @@ module Sinatra
|
|
24
23
|
# @param [Hash] opts a hash of options
|
25
24
|
# @option opts [Hash] :locals a hash of local variables to be used in the template
|
26
25
|
def bldr(template, opts = {}, &block)
|
26
|
+
opts[:parent] = self
|
27
27
|
opts[:scope] = ::Bldr::Node.new(nil, opts.merge(:views => (settings.views || "./views")))
|
28
|
-
|
29
|
-
|
28
|
+
|
29
|
+
locals = opts.delete(:locals) || {}
|
30
|
+
|
30
31
|
# @todo add support for alternate formats, like plist
|
32
|
+
MultiJson.encode render(:bldr, template, opts, locals, &block).result
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
@@ -1,75 +1,172 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
module Bldr
|
4
|
+
describe 'local variable access' do
|
5
|
+
it 'provides access to locals in nested object blocks' do
|
6
|
+
Template.new do
|
7
|
+
<<-RUBY
|
8
|
+
object :person => person do
|
9
|
+
attribute(:name) { person.name }
|
10
|
+
object :address => Object.new do |address|
|
11
|
+
attribute(:display_name) { person.name }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
RUBY
|
15
|
+
end.render(Node.new(nil), {person: Person.new('alex')})
|
16
|
+
.result
|
17
|
+
.should == {:person => {:name => 'alex', :address => {:display_name => 'alex'}}}
|
18
|
+
end
|
6
19
|
end
|
7
20
|
|
8
|
-
|
9
|
-
|
10
|
-
|
21
|
+
describe "instance variables" do
|
22
|
+
let(:ctx) { Object.new }
|
23
|
+
|
24
|
+
describe "collection blocks" do
|
25
|
+
it 'has access to instance variables' do
|
26
|
+
ctx.instance_variable_set(:@person, Person.new("John Denver"))
|
27
|
+
|
28
|
+
Template.new do
|
29
|
+
<<-RUBY
|
30
|
+
collection :artists => [@person] do
|
31
|
+
attribute(:name) { @person.name }
|
32
|
+
end
|
33
|
+
RUBY
|
34
|
+
end.render(Node.new(nil, :parent => ctx))
|
35
|
+
.result
|
36
|
+
.should == {:artists => [{:name => 'John Denver'}]}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'has access to instance variables in included template partials' do
|
41
|
+
ctx.instance_variable_set(:@person, Person.new('john denver'))
|
42
|
+
|
43
|
+
Template.new {
|
44
|
+
<<-RUBY
|
45
|
+
template('spec/fixtures/ivar.bldr')
|
46
|
+
RUBY
|
47
|
+
}.render(Node.new(nil, :parent => ctx))
|
48
|
+
.result
|
49
|
+
.should == {:person => {:name => 'john denver', :age => nil}}
|
50
|
+
end
|
11
51
|
|
12
|
-
|
13
|
-
|
52
|
+
it 'has access to ivars in attribute blocks with no arity' do
|
53
|
+
ctx.instance_variable_set(:@person, Person.new('john denver'))
|
54
|
+
|
55
|
+
Template.new {
|
56
|
+
<<-RUBY
|
57
|
+
object :person do
|
58
|
+
attribute(:name) { @person.name }
|
59
|
+
end
|
60
|
+
RUBY
|
61
|
+
}.render(Node.new(nil, :parent => ctx))
|
62
|
+
.result
|
63
|
+
.should == {:person => {:name => 'john denver'}}
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'has access to ivars in attribute blocks with arity of 1' do
|
67
|
+
ctx.instance_variable_set(:@denver, Person.new('john denver'))
|
68
|
+
ctx.instance_variable_set(:@rich, Person.new('charlie rich'))
|
69
|
+
Template.new {
|
70
|
+
<<-RUBY
|
71
|
+
object :person => @denver do
|
72
|
+
attribute(:name) { |p| @rich.name }
|
73
|
+
end
|
74
|
+
RUBY
|
75
|
+
}.render(Node.new(nil, :parent => ctx))
|
76
|
+
.result
|
77
|
+
.should == {:person => {:name => 'charlie rich'}}
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'has access to ivars in nested object blocks' do
|
81
|
+
ctx.instance_variable_set(:@batman, Person.new('batman'))
|
82
|
+
ctx.instance_variable_set(:@bane, Person.new('bane'))
|
83
|
+
Template.new {
|
84
|
+
<<-RUBY
|
85
|
+
object :hero => @batman do
|
86
|
+
attribute(:name) { @batman.name }
|
87
|
+
object :nemesis do
|
88
|
+
attribute(:name) { @bane.name }
|
89
|
+
attribute(:nemesis_name) { @batman.name }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
RUBY
|
93
|
+
}.render(Node.new(nil, :parent => ctx))
|
94
|
+
.result
|
95
|
+
.should == {hero: {name: 'batman', nemesis: {name: 'bane', nemesis_name: 'batman'}}}
|
96
|
+
end
|
14
97
|
end
|
15
98
|
|
16
|
-
|
17
|
-
|
99
|
+
|
100
|
+
describe "evaluating a tilt template" do
|
101
|
+
it "registers with Tilt" do
|
102
|
+
Tilt['test.bldr'].should == Bldr::Template
|
103
|
+
end
|
104
|
+
|
105
|
+
it "renders a template" do
|
106
|
+
alex = Person.new
|
107
|
+
alex.name = 'alex'
|
108
|
+
|
109
|
+
tpl = Bldr::Template.new { "object(:person => alex) { attribute(:name) }" }
|
110
|
+
tpl.render(Bldr::Node.new, :alex => alex).result.should == {:person => {:name => 'alex'}}
|
111
|
+
end
|
112
|
+
|
113
|
+
it "allows attribute to be used at the root-level" do
|
114
|
+
tpl = Bldr::Template.new {
|
18
115
|
<<-RUBY
|
19
116
|
attribute(:foo) { "bar" }
|
20
117
|
RUBY
|
21
|
-
|
22
|
-
|
23
|
-
|
118
|
+
}
|
119
|
+
tpl.render(Bldr::Node.new(nil)).result.should == {:foo => 'bar'}
|
120
|
+
end
|
24
121
|
|
25
|
-
|
26
|
-
|
27
|
-
|
122
|
+
it "works when render two top-level objects" do
|
123
|
+
alex = Person.new('alex')
|
124
|
+
john = Person.new('john')
|
28
125
|
|
29
|
-
|
126
|
+
tpl = Bldr::Template.new {
|
30
127
|
<<-RUBY
|
31
128
|
object(:person_1 => alex) { attribute(:name) }
|
32
129
|
object(:person_2 => john) { attribute(:name) }
|
33
130
|
RUBY
|
34
|
-
|
131
|
+
}
|
35
132
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
133
|
+
result = tpl.render(Bldr::Node.new, :alex => alex, :john => john).result
|
134
|
+
result.should == {
|
135
|
+
:person_1 => {:name => 'alex'},
|
136
|
+
:person_2 => {:name => 'john'}
|
137
|
+
}
|
138
|
+
end
|
42
139
|
|
43
|
-
|
44
|
-
|
45
|
-
|
140
|
+
it "renders nil -> null correctly" do
|
141
|
+
alex = Person.new('alex')
|
142
|
+
tpl = Bldr::Template.new {
|
46
143
|
<<-RUBY
|
47
144
|
object(:person_1 => alex) { attributes(:age) }
|
48
145
|
RUBY
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
146
|
+
}
|
147
|
+
result = tpl.render(Bldr::Node.new, :alex => alex).result
|
148
|
+
result.should == {:person_1 => {:age => nil}}
|
149
|
+
end
|
53
150
|
|
54
|
-
|
151
|
+
describe "root Object nodes" do
|
55
152
|
|
56
|
-
|
57
|
-
|
153
|
+
let(:alex) { Person.new('alex', 25) }
|
154
|
+
let(:ian) { Person.new('ian', 32) }
|
58
155
|
|
59
|
-
|
60
|
-
|
156
|
+
it "returns json for a root object" do
|
157
|
+
tpl = Bldr::Template.new {
|
61
158
|
<<-RUBY
|
62
159
|
object :person => alex do
|
63
160
|
attributes :name, :age
|
64
161
|
end
|
65
162
|
RUBY
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
163
|
+
}
|
164
|
+
result = tpl.render(Bldr::Node.new, :alex => alex, :ian => ian).result
|
165
|
+
result.should == {:person => {:name => 'alex', :age => 25}}
|
166
|
+
end
|
70
167
|
|
71
|
-
|
72
|
-
|
168
|
+
it "returns json for root object templates with nested collections" do
|
169
|
+
tpl = Bldr::Template.new {
|
73
170
|
<<-RUBY
|
74
171
|
object :person => alex do
|
75
172
|
attributes :name, :age
|
@@ -79,78 +176,79 @@ describe "evaluating a tilt template" do
|
|
79
176
|
end
|
80
177
|
end
|
81
178
|
RUBY
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
179
|
+
}
|
180
|
+
result = tpl.render(Bldr::Node.new, :alex => alex, :friends => [ian]).result
|
181
|
+
result.should == {
|
182
|
+
:person=> {:name => 'alex', :age => 25, :friends => [{:name => 'ian', :age => 32}]}
|
183
|
+
}
|
184
|
+
end
|
185
|
+
|
186
|
+
it "renders nil -> null correctly" do
|
187
|
+
alex = Person.new('alex')
|
188
|
+
tpl = Bldr::Template.new {
|
92
189
|
<<-RUBY
|
93
190
|
object :person_1 => alex do
|
94
191
|
attributes(:age)
|
95
192
|
end
|
96
193
|
RUBY
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
194
|
+
}
|
195
|
+
result = tpl.render(Bldr::Node.new, :alex => alex).result
|
196
|
+
result.should == {:person_1 => {:age => nil}}
|
197
|
+
end
|
101
198
|
|
102
|
-
|
199
|
+
end
|
103
200
|
|
104
|
-
|
201
|
+
describe "root Collection nodes" do
|
105
202
|
|
106
|
-
|
107
|
-
|
203
|
+
let(:alex) { Person.new('alex', 25, [Person.new('bo',33)]) }
|
204
|
+
let(:ian) { Person.new('ian', 32, [Person.new('eric',34)]) }
|
108
205
|
|
109
|
-
|
110
|
-
|
206
|
+
it "returns json for a root collection template" do
|
207
|
+
tpl = Bldr::Template.new {
|
111
208
|
<<-RUBY
|
112
209
|
collection :people => people do
|
113
210
|
attributes :name, :age
|
114
211
|
end
|
115
212
|
RUBY
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
213
|
+
}
|
214
|
+
result = tpl.render(Bldr::Node.new, :people => [alex,ian]).result
|
215
|
+
result.should == {
|
216
|
+
:people => [{:name => 'alex', :age => 25}, {:name => 'ian', :age => 32}]
|
217
|
+
}
|
218
|
+
end
|
219
|
+
|
220
|
+
it "returns json for a root collection with embedded collection template" do
|
221
|
+
tpl = Bldr::Template.new {
|
125
222
|
<<-RUBY
|
126
|
-
collection :people => people do
|
223
|
+
collection :people => people do |person|
|
127
224
|
attributes :name, :age
|
128
|
-
collection :friends =>
|
225
|
+
collection :friends => person.friends do
|
129
226
|
attributes :name, :age
|
130
227
|
end
|
131
228
|
end
|
132
229
|
RUBY
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
230
|
+
}
|
231
|
+
result = tpl.render(Bldr::Node.new, :people => [alex,ian]).result
|
232
|
+
result.should == {
|
233
|
+
:people=> [{
|
234
|
+
:name => 'alex',
|
235
|
+
:age => 25,
|
236
|
+
:friends => [{:name => 'bo', :age => 33}]
|
237
|
+
},{
|
238
|
+
:name => 'ian',
|
239
|
+
:age => 32,
|
240
|
+
:friends => [{:name => 'eric', :age => 34}]
|
241
|
+
}]
|
242
|
+
}
|
243
|
+
end
|
147
244
|
|
245
|
+
end
|
148
246
|
end
|
149
|
-
end
|
150
247
|
|
151
|
-
describe "using a partial template at the root of another template" do
|
152
|
-
|
153
|
-
|
154
|
-
|
248
|
+
describe "using a partial template at the root of another template" do
|
249
|
+
it "works as expected" do
|
250
|
+
template = Bldr::Template.new('./spec/fixtures/root_partial.bldr')
|
251
|
+
template.render(Bldr::Node.new(nil, :views => './spec')).result.should == {:foo => 'bar'}
|
252
|
+
end
|
155
253
|
end
|
156
|
-
end
|
254
|
+
end
|