bldr 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](
|
1
|
+
[![Build Status](https://travis-ci.org/ajsharp/bldr.png)](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
|