blocks 1.2.5 → 2.1.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/CHANGELOG.rdoc +49 -0
- data/README.rdoc +1 -141
- data/Rakefile +22 -0
- data/VERSION +1 -0
- data/lib/blocks.rb +31 -5
- data/lib/blocks/base.rb +672 -0
- data/lib/blocks/controller_additions.rb +9 -0
- data/lib/blocks/view_additions.rb +12 -0
- data/rails/init.rb +1 -0
- data/spec/blocks/base_spec.rb +659 -0
- data/spec/blocks/blocks_spec.rb +24 -0
- data/spec/blocks/view_additions_spec.rb +22 -0
- data/spec/spec_helper.rb +19 -0
- metadata +287 -25
- data/LICENSE +0 -21
- data/app/helpers/blocks/helper_methods.rb +0 -35
- data/app/views/blocks/_list.html.erb +0 -31
- data/app/views/blocks/_table.html.erb +0 -105
- data/lib/blocks/builder.rb +0 -236
- data/lib/blocks/engine.rb +0 -12
- data/lib/blocks/list_for.rb +0 -14
- data/lib/blocks/table_for.rb +0 -18
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'blocks'
|
@@ -0,0 +1,659 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Blocks::Base do
|
4
|
+
before :each do
|
5
|
+
@view = ActionView::Base.new
|
6
|
+
@builder = Blocks::Base.new(@view)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be able change the default global partials directory" do
|
10
|
+
Blocks.template_folder = "shared"
|
11
|
+
Blocks.use_partials = true
|
12
|
+
@builder = Blocks::Base.new(@view)
|
13
|
+
@builder.expects(:render_before_blocks).at_least_once
|
14
|
+
@builder.expects(:render_after_blocks).at_least_once
|
15
|
+
@view.expects(:capture).with(:value1 => 1, :value2 => 2).never
|
16
|
+
@view.expects(:render).with("some_block", :value1 => 1, :value2 => 2).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
17
|
+
@view.expects(:render).with("shared/some_block", :value1 => 1, :value2 => 2).once
|
18
|
+
@builder.render :some_block, :value1 => 1, :value2 => 2
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "defined? method" do
|
22
|
+
it "should be able to determine if a block by a specific name is already defined" do
|
23
|
+
@builder.defined?(:test_block).should be_false
|
24
|
+
@builder.define :test_block do end
|
25
|
+
@builder.defined?(:test_block).should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not care whether the block name was defined with a string or a symbol" do
|
29
|
+
@builder.defined?(:test_block).should be_false
|
30
|
+
@builder.define "test_block" do end
|
31
|
+
@builder.defined?(:test_block).should be_true
|
32
|
+
|
33
|
+
@builder.defined?(:test_block2).should be_false
|
34
|
+
@builder.define :test_block2 do end
|
35
|
+
@builder.defined?(:test_block2).should be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not care whether the defined? method is passed a string or a symbol" do
|
39
|
+
@builder.defined?("test_block").should be_false
|
40
|
+
@builder.define :test_block do end
|
41
|
+
@builder.defined?("test_block").should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "define method" do
|
46
|
+
it "should be able to define a new block" do
|
47
|
+
block = Proc.new { |options| }
|
48
|
+
|
49
|
+
@builder.define :test_block, :option1 => "value1", :option2 => "value2", &block
|
50
|
+
|
51
|
+
test_block = @builder.blocks[:test_block]
|
52
|
+
test_block.options[:option1].should eql("value1")
|
53
|
+
test_block.options[:option2].should eql("value2")
|
54
|
+
test_block.name.should eql(:test_block)
|
55
|
+
test_block.block.should eql(block)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should not replace a defined block with another attempted definition" do
|
59
|
+
block1 = Proc.new do |options| end
|
60
|
+
@builder.define :test_block, :option1 => "value1", :option2 => "value2", &block1
|
61
|
+
|
62
|
+
block2 = Proc.new do |options| end
|
63
|
+
@builder.define :test_block, :option3 => "value3", :option4 => "value4", &block2
|
64
|
+
|
65
|
+
test_block = @builder.blocks[:test_block]
|
66
|
+
test_block.options[:option1].should eql("value1")
|
67
|
+
test_block.options[:option2].should eql("value2")
|
68
|
+
test_block.options[:option3].should be_nil
|
69
|
+
test_block.options[:option4].should be_nil
|
70
|
+
test_block.name.should eql(:test_block)
|
71
|
+
test_block.block.should eql(block1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "replace method" do
|
76
|
+
it "should be able to replace a defined block" do
|
77
|
+
block1 = Proc.new do |options| end
|
78
|
+
@builder.define :test_block, :option1 => "value1", :option2 => "value2", &block1
|
79
|
+
|
80
|
+
block2 = Proc.new do |options| end
|
81
|
+
@builder.replace :test_block, :option3 => "value3", :option4 => "value4", &block2
|
82
|
+
|
83
|
+
test_block = @builder.blocks[:test_block]
|
84
|
+
test_block.options[:option1].should be_nil
|
85
|
+
test_block.options[:option2].should be_nil
|
86
|
+
test_block.options[:option3].should eql("value3")
|
87
|
+
test_block.options[:option4].should eql("value4")
|
88
|
+
test_block.name.should eql(:test_block)
|
89
|
+
test_block.block.should eql(block2)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "queue method" do
|
94
|
+
it "should store all queued blocks in the queued_blocks array" do
|
95
|
+
@builder.queued_blocks.should be_empty
|
96
|
+
@builder.queue :test_block
|
97
|
+
@builder.queued_blocks.length.should eql 1
|
98
|
+
@builder.queued_blocks.map(&:name).first.should eql(:test_block)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should convert a string block name to a symbol" do
|
102
|
+
@builder.queue "test_block"
|
103
|
+
@builder.queued_blocks.map(&:name).first.should eql(:test_block)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should queue blocks as Blocks::Container objects" do
|
107
|
+
@builder.queue :test_block, :a => 1, :b => 2, :c => 3
|
108
|
+
container = @builder.queued_blocks.first
|
109
|
+
container.should be_a(Blocks::Container)
|
110
|
+
container.name.should eql(:test_block)
|
111
|
+
container.options.should eql(:a => 1, :b => 2, :c => 3)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should not require a name for the block being queued" do
|
115
|
+
@builder.queue
|
116
|
+
@builder.queue
|
117
|
+
@builder.queued_blocks.length.should eql 2
|
118
|
+
@builder.queued_blocks.map(&:name).first.should eql(:block_1)
|
119
|
+
@builder.queued_blocks.map(&:name).second.should eql(:block_2)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should anonymously define the name of a block if not specified" do
|
123
|
+
@builder.queue
|
124
|
+
@builder.queue :my_block
|
125
|
+
@builder.queue
|
126
|
+
@builder.queued_blocks.map(&:name).first.should eql(:block_1)
|
127
|
+
@builder.queued_blocks.map(&:name).second.should eql(:my_block)
|
128
|
+
@builder.queued_blocks.map(&:name).third.should eql(:block_2)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should store queued blocks in the order in which they are queued" do
|
132
|
+
@builder.queue :block1
|
133
|
+
@builder.queue :block3
|
134
|
+
@builder.queue :block2
|
135
|
+
@builder.queued_blocks.map(&:name).first.should eql(:block1)
|
136
|
+
@builder.queued_blocks.map(&:name).second.should eql(:block3)
|
137
|
+
@builder.queued_blocks.map(&:name).third.should eql(:block2)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should allow a definition to be provided for a queued block" do
|
141
|
+
block = Proc.new do |options| end
|
142
|
+
@builder.queue :test_block, &block
|
143
|
+
container = @builder.queued_blocks.first
|
144
|
+
container.block.should eql block
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "render_template method" do
|
149
|
+
it "should attempt to render a partial specified as the :template parameter" do
|
150
|
+
view = mock()
|
151
|
+
builder = Blocks::Base.new(view)
|
152
|
+
view.expects(:render).with{ |template, options| template == "my_template"}
|
153
|
+
builder.render_template("my_template")
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should set all of the global options as local variables to the partial it renders" do
|
157
|
+
view = mock()
|
158
|
+
builder = Blocks::Base.new(view)
|
159
|
+
view.expects(:render).with { |template, options| template == 'some_template' && options[:blocks] == builder }
|
160
|
+
builder.render_template("some_template")
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should capture the data of a block if a block has been specified" do
|
164
|
+
block = Proc.new { |options| "my captured block" }
|
165
|
+
builder = Blocks::Base.new(@view)
|
166
|
+
@view.expects(:render).with { |tempate, options| options[:captured_block] == "my captured block" }
|
167
|
+
builder.render_template("template", &block)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should by default add a variable to the partial called 'blocks' as a pointer to the Blocks::Base instance" do
|
171
|
+
view = mock()
|
172
|
+
builder = Blocks::Base.new(view)
|
173
|
+
view.expects(:render).with { |template, options| options[:blocks] == builder }
|
174
|
+
builder.render_template("some_template")
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should allow the user to override the local variable passed to the partial as a pointer to the Blocks::Base instance" do
|
178
|
+
view = mock()
|
179
|
+
builder = Blocks::Base.new(view, :variable => "my_variable")
|
180
|
+
view.expects(:render).with { |template, options| options[:blocks].should be_nil }
|
181
|
+
builder.render_template("some_template")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "before method" do
|
186
|
+
it "should be aliased with prepend" do
|
187
|
+
block = Proc.new { |options| }
|
188
|
+
@builder.prepend :some_block, &block
|
189
|
+
@builder.blocks[:before_some_block].should be_present
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should defined before blocks as the block name with the word 'before_' prepended to it" do
|
193
|
+
block = Proc.new { |options| }
|
194
|
+
@builder.before :some_block, &block
|
195
|
+
@builder.blocks[:before_some_block].should be_present
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should store a before block in an array" do
|
199
|
+
block = Proc.new { |options| }
|
200
|
+
@builder.before :some_block, &block
|
201
|
+
before_blocks = @builder.blocks[:before_some_block]
|
202
|
+
before_blocks.should be_a(Array)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should store a before block as a Blocks::Container" do
|
206
|
+
block = Proc.new { |options| }
|
207
|
+
@builder.before :some_block, :option1 => "some option", &block
|
208
|
+
before_blocks = @builder.blocks[:before_some_block]
|
209
|
+
block_container = before_blocks.first
|
210
|
+
block_container.should be_a(Blocks::Container)
|
211
|
+
block_container.options.should eql :option1 => "some option"
|
212
|
+
block_container.block.should eql block
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should queue before blocks if there are multiple defined" do
|
216
|
+
block = Proc.new { |options| }
|
217
|
+
block2 = Proc.new { |options| }
|
218
|
+
@builder.before :some_block, &block
|
219
|
+
@builder.before :some_block, &block2
|
220
|
+
before_blocks = @builder.blocks[:before_some_block]
|
221
|
+
before_blocks.length.should eql 2
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should store before blocks in the order in which they are defined" do
|
225
|
+
block = Proc.new { |options| }
|
226
|
+
block2 = Proc.new { |options| }
|
227
|
+
block3 = Proc.new { |options| }
|
228
|
+
@builder.before :some_block, &block
|
229
|
+
@builder.before :some_block, &block2
|
230
|
+
@builder.before :some_block, &block3
|
231
|
+
before_blocks = @builder.blocks[:before_some_block]
|
232
|
+
before_blocks.first.block.should eql block
|
233
|
+
before_blocks.second.block.should eql block2
|
234
|
+
before_blocks.third.block.should eql block3
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe "after method" do
|
239
|
+
it "should be aliased with append and for" do
|
240
|
+
block = Proc.new { |options| }
|
241
|
+
@builder.append :some_block, &block
|
242
|
+
@builder.blocks[:after_some_block].should be_present
|
243
|
+
|
244
|
+
block = Proc.new { |options| }
|
245
|
+
@builder.for :some_block, &block
|
246
|
+
@builder.blocks[:after_some_block].should be_present
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should defined after blocks as the block name with the word 'after_' prepended to it" do
|
250
|
+
block = Proc.new { |options| }
|
251
|
+
@builder.after :some_block, &block
|
252
|
+
@builder.blocks[:after_some_block].should be_present
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should store a after block in an array" do
|
256
|
+
block = Proc.new { |options| }
|
257
|
+
@builder.after :some_block, &block
|
258
|
+
after_blocks = @builder.blocks[:after_some_block]
|
259
|
+
after_blocks.should be_a(Array)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should store a after block as a Blocks::Container" do
|
263
|
+
block = Proc.new { |options| }
|
264
|
+
@builder.after :some_block, :option1 => "some option", &block
|
265
|
+
after_blocks = @builder.blocks[:after_some_block]
|
266
|
+
block_container = after_blocks.first
|
267
|
+
block_container.should be_a(Blocks::Container)
|
268
|
+
block_container.options.should eql :option1 => "some option"
|
269
|
+
block_container.block.should eql block
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should queue after blocks if there are multiple defined" do
|
273
|
+
block = Proc.new { |options| }
|
274
|
+
block2 = Proc.new { |options| }
|
275
|
+
@builder.after :some_block, &block
|
276
|
+
@builder.after :some_block, &block2
|
277
|
+
after_blocks = @builder.blocks[:after_some_block]
|
278
|
+
after_blocks.length.should eql 2
|
279
|
+
end
|
280
|
+
|
281
|
+
it "should store after blocks in the order in which they are defined" do
|
282
|
+
block = Proc.new { |options| }
|
283
|
+
block2 = Proc.new { |options| }
|
284
|
+
block3 = Proc.new { |options| }
|
285
|
+
@builder.after :some_block, &block
|
286
|
+
@builder.after :some_block, &block2
|
287
|
+
@builder.after :some_block, &block3
|
288
|
+
after_blocks = @builder.blocks[:after_some_block]
|
289
|
+
after_blocks.first.block.should eql block
|
290
|
+
after_blocks.second.block.should eql block2
|
291
|
+
after_blocks.third.block.should eql block3
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
describe "render method" do
|
296
|
+
it "should alias the render method as use" do
|
297
|
+
block = Proc.new {"output"}
|
298
|
+
@builder.define :some_block, &block
|
299
|
+
@builder.use(:some_block).should eql "output"
|
300
|
+
end
|
301
|
+
|
302
|
+
it "should be able to use a defined block by its name" do
|
303
|
+
block = Proc.new {"output"}
|
304
|
+
@builder.define :some_block, &block
|
305
|
+
@builder.render(:some_block).should eql "output"
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should automatically pass in an options hash to a defined block that takes one paramter when that block is used" do
|
309
|
+
block = Proc.new {|options| "Options are #{options.inspect}"}
|
310
|
+
@builder.define :some_block, &block
|
311
|
+
@builder.render(:some_block).should eql "Options are {}"
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should be able to use a defined block by its name and pass in runtime arguments as a hash" do
|
315
|
+
block = Proc.new do |options|
|
316
|
+
print_hash(options)
|
317
|
+
end
|
318
|
+
@builder.define :some_block, &block
|
319
|
+
@builder.render(:some_block, :param1 => 1, :param2 => "value2").should eql print_hash(:param1 => 1, :param2 => "value2")
|
320
|
+
end
|
321
|
+
|
322
|
+
it "should be able to use a defined block by its name and pass in runtime arguments one by one" do
|
323
|
+
block = Proc.new do |first_param, second_param, options|
|
324
|
+
"first_param: #{first_param}, second_param: #{second_param}, #{print_hash options}"
|
325
|
+
end
|
326
|
+
@builder.define :some_block, &block
|
327
|
+
@builder.render(:some_block, 3, 4, :param1 => 1, :param2 => "value2").should eql("first_param: 3, second_param: 4, #{print_hash(:param1 => 1, :param2 => "value2")}")
|
328
|
+
end
|
329
|
+
|
330
|
+
it "should match up the number of arguments to a defined block with the parameters passed when a block is used" do
|
331
|
+
block = Proc.new {|first_param| "first_param = #{first_param}"}
|
332
|
+
@builder.define :some_block, &block
|
333
|
+
@builder.render(:some_block, 3, 4, :param1 => 1, :param2 => "value2").should eql "first_param = 3"
|
334
|
+
|
335
|
+
block = Proc.new {|first_param, second_param| "first_param = #{first_param}, second_param = #{second_param}"}
|
336
|
+
@builder.replace :some_block, &block
|
337
|
+
@builder.render(:some_block, 3, 4, :param1 => 1, :param2 => "value2").should eql "first_param = 3, second_param = 4"
|
338
|
+
|
339
|
+
block = Proc.new do |first_param, second_param, options|
|
340
|
+
"first_param: #{first_param}, second_param: #{second_param}, #{print_hash options}"
|
341
|
+
end
|
342
|
+
@builder.replace :some_block, &block
|
343
|
+
@builder.render(:some_block, 3, 4, :param1 => 1, :param2 => "value2").should eql("first_param: 3, second_param: 4, #{print_hash(:param1 => 1, :param2 => "value2")}")
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should not render anything if using a block that has been defined" do
|
347
|
+
@builder.use_partials = true
|
348
|
+
@view.expects(:capture).never
|
349
|
+
@view.expects(:render).with("some_block", {}).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
350
|
+
@view.expects(:render).with("blocks/some_block", {}).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
351
|
+
@builder.render :some_block
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should first attempt to capture a block's contents when blocks.render is called" do
|
355
|
+
block = Proc.new {|options|}
|
356
|
+
@view.expects(:capture).with(:value1 => 1, :value2 => 2)
|
357
|
+
@view.expects(:render).with("some_block", :value1 => 1, :value2 => 2).never
|
358
|
+
@view.expects(:render).with("blocks/some_block", :value1 => 1, :value2 => 2).never
|
359
|
+
@builder.define :some_block, &block
|
360
|
+
@builder.render :some_block, :value1 => 1, :value2 => 2
|
361
|
+
end
|
362
|
+
|
363
|
+
it "should second attempt to render a local partial by the block's name when blocks.render is called" do
|
364
|
+
@builder.use_partials = true
|
365
|
+
@view.expects(:capture).with(:value1 => 1, :value2 => 2).never
|
366
|
+
@view.expects(:render).with("some_block", :value1 => 1, :value2 => 2).once
|
367
|
+
@view.expects(:render).with("blocks/some_block", :value1 => 1, :value2 => 2).never
|
368
|
+
@builder.render :some_block, :value1 => 1, :value2 => 2
|
369
|
+
end
|
370
|
+
|
371
|
+
it "should third attempt to render a global partial by the block's name when blocks.render is called" do
|
372
|
+
@builder.use_partials = true
|
373
|
+
@view.expects(:capture).with(:value1 => 1, :value2 => 2).never
|
374
|
+
@view.expects(:render).with("some_block", :value1 => 1, :value2 => 2).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
375
|
+
@view.expects(:render).with("blocks/some_block", :value1 => 1, :value2 => 2).once
|
376
|
+
@builder.render :some_block, :value1 => 1, :value2 => 2
|
377
|
+
end
|
378
|
+
|
379
|
+
it "should fourth attempt to render a default block when blocks.render is called" do
|
380
|
+
block = Proc.new {|options|}
|
381
|
+
@builder.use_partials = true
|
382
|
+
@view.expects(:render).with("some_block", :value1 => 1, :value2 => 2).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
383
|
+
@view.expects(:render).with("blocks/some_block", :value1 => 1, :value2 => 2).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
384
|
+
@view.expects(:capture).with(:value1 => 1, :value2 => 2)
|
385
|
+
@builder.render :some_block, :value1 => 1, :value2 => 2, &block
|
386
|
+
end
|
387
|
+
|
388
|
+
it "should not attempt to render a partial if use_partials is set to false" do
|
389
|
+
@builder.use_partials = false
|
390
|
+
block = Proc.new {|options|}
|
391
|
+
@view.expects(:render).with("some_block", :value1 => 1, :value2 => 2).never
|
392
|
+
@view.expects(:render).with("blocks/some_block", :value1 => 1, :value2 => 2).never
|
393
|
+
@view.expects(:capture).with(:value1 => 1, :value2 => 2)
|
394
|
+
@builder.render :some_block, :value1 => 1, :value2 => 2, &block
|
395
|
+
end
|
396
|
+
|
397
|
+
it "should not attempt to render a partial if use_partials is passed in as false as an option to Blocks::Base.new" do
|
398
|
+
mocha_teardown
|
399
|
+
@builder = Blocks::Base.new(@view, :use_partials => false)
|
400
|
+
@builder.expects(:render_before_blocks).at_least_once
|
401
|
+
@builder.expects(:render_after_blocks).at_least_once
|
402
|
+
block = Proc.new {|options|}
|
403
|
+
@view.expects(:render).with("some_block", :value1 => 1, :value2 => 2).never
|
404
|
+
@view.expects(:render).with("blocks/some_block", :value1 => 1, :value2 => 2).never
|
405
|
+
@view.expects(:capture).with(:value1 => 1, :value2 => 2)
|
406
|
+
@builder.render :some_block, :value1 => 1, :value2 => 2, &block
|
407
|
+
end
|
408
|
+
|
409
|
+
it "should override hash options for a block by merging the runtime options the define default options into the queue level options into the global options" do
|
410
|
+
block = Proc.new {|options|}
|
411
|
+
@builder.global_options.merge!(:param1 => "global level", :param2 => "global level", :param3 => "global level", :param4 => "global level")
|
412
|
+
@builder.queue(:my_before_block, :param1 => "queue level", :param2 => "queue level")
|
413
|
+
@builder.define(:my_before_block, :param1 => "define level", :param2 => "define level", :param3 => "define level", &block)
|
414
|
+
block_container = @builder.queued_blocks.first
|
415
|
+
@view.expects(:capture).with(:param4 => 'global level', :param1 => 'use level', :param2 => 'queue level', :param3 => 'define level')
|
416
|
+
@builder.render block_container, :param1 => "use level"
|
417
|
+
end
|
418
|
+
|
419
|
+
it "should render the contents of a defined block when that block is used" do
|
420
|
+
block = Proc.new {}
|
421
|
+
@view.expects(:capture).with(nil).returns("rendered content")
|
422
|
+
@builder.define :some_block, &block
|
423
|
+
buffer = @builder.render :some_block
|
424
|
+
buffer.should eql "rendered content"
|
425
|
+
end
|
426
|
+
|
427
|
+
describe "with a collection passed in" do
|
428
|
+
it "should render a block for each element of the collection with the name of the block used as the name of the element passed into the block" do
|
429
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
430
|
+
@builder.define :some_block, &block
|
431
|
+
@builder.render(:some_block, :collection => [1,2,3]).should eql "output1 output2 output3 "
|
432
|
+
end
|
433
|
+
|
434
|
+
it "should render a block for each element of the collection with the 'as' option specifying the name of the element passed into the block" do
|
435
|
+
block = Proc.new {|item, options| "output#{options[:my_block_name]} "}
|
436
|
+
@builder.define :some_block, &block
|
437
|
+
@builder.render(:some_block, :collection => [1,2,3], :as => "my_block_name").should eql "output1 output2 output3 "
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should render a block for each element of the collection with a surrounding element if that option is specified" do
|
441
|
+
block = Proc.new {|item, options| "output#{options[:my_block_name]} "}
|
442
|
+
@builder.define :some_block, &block
|
443
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div").should eql "<div>output </div><div>output </div><div>output </div>"
|
444
|
+
end
|
445
|
+
|
446
|
+
it "should render a block for each element of the collection with a surrounding element and specified html options if those options are specified" do
|
447
|
+
block = Proc.new {|item, options| "output#{options[:my_block_name]} "}
|
448
|
+
@builder.define :some_block, &block
|
449
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div", :surrounding_tag_html => {:class => lambda { @view.cycle("even", "odd")}, :style => "color:red"}).should eql "<div class=\"even\" style=\"color:red\">output </div><div class=\"odd\" style=\"color:red\">output </div><div class=\"even\" style=\"color:red\">output </div>"
|
450
|
+
end
|
451
|
+
|
452
|
+
it "should be able to render before blocks before each element of a collection" do
|
453
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
454
|
+
@builder.before :some_block, &before_block
|
455
|
+
|
456
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
457
|
+
@builder.define :some_block, &block
|
458
|
+
@builder.render(:some_block, :collection => [1,2,3]).should eql "before1 output1 before2 output2 before3 output3 "
|
459
|
+
end
|
460
|
+
|
461
|
+
it "should be able to render after blocks before each element of a collection" do
|
462
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
463
|
+
@builder.after :some_block, &after_block
|
464
|
+
|
465
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
466
|
+
@builder.define :some_block, &block
|
467
|
+
@builder.render(:some_block, :collection => [1,2,3]).should eql "output1 after1 output2 after2 output3 after3 "
|
468
|
+
end
|
469
|
+
|
470
|
+
it "should be able to render before and after blocks before each element of a collection" do
|
471
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
472
|
+
@builder.before :some_block, &before_block
|
473
|
+
|
474
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
475
|
+
@builder.after :some_block, &after_block
|
476
|
+
|
477
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
478
|
+
@builder.define :some_block, &block
|
479
|
+
@builder.render(:some_block, :collection => [1,2,3]).should eql "before1 output1 after1 before2 output2 after2 before3 output3 after3 "
|
480
|
+
end
|
481
|
+
|
482
|
+
it "should by default put surrounding elements around before and after blocks" do
|
483
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
484
|
+
@builder.before :some_block, &before_block
|
485
|
+
|
486
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
487
|
+
@builder.after :some_block, &after_block
|
488
|
+
|
489
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
490
|
+
@builder.define :some_block, &block
|
491
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div").should eql "<div>before1 output1 after1 </div><div>before2 output2 after2 </div><div>before3 output3 after3 </div>"
|
492
|
+
end
|
493
|
+
|
494
|
+
it "should allow the global option to be set to render before and after blocks outside of surrounding elements" do
|
495
|
+
Blocks.surrounding_tag_surrounds_before_and_after_blocks = false
|
496
|
+
@builder = Blocks::Base.new(@view)
|
497
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
498
|
+
@builder.before :some_block, &before_block
|
499
|
+
|
500
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
501
|
+
@builder.after :some_block, &after_block
|
502
|
+
|
503
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
504
|
+
@builder.define :some_block, &block
|
505
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div").should eql "before1 <div>output1 </div>after1 before2 <div>output2 </div>after2 before3 <div>output3 </div>after3 "
|
506
|
+
end
|
507
|
+
|
508
|
+
it "should allow the option to be set to render before and after blocks outside of surrounding elements to be specified when Blocks is initialized" do
|
509
|
+
@builder = Blocks::Base.new(@view, :surrounding_tag_surrounds_before_and_after_blocks => false)
|
510
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
511
|
+
@builder.before :some_block, &before_block
|
512
|
+
|
513
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
514
|
+
@builder.after :some_block, &after_block
|
515
|
+
|
516
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
517
|
+
@builder.define :some_block, &block
|
518
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div").should eql "before1 <div>output1 </div>after1 before2 <div>output2 </div>after2 before3 <div>output3 </div>after3 "
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
describe "render method - before blocks" do
|
524
|
+
before :each do
|
525
|
+
@builder.expects(:render_block).at_least_once
|
526
|
+
@builder.expects(:render_after_blocks).at_least_once
|
527
|
+
end
|
528
|
+
|
529
|
+
it "should render before blocks when using a block" do
|
530
|
+
block = Proc.new {|value1, value2, options|}
|
531
|
+
@builder.before("my_before_block", &block)
|
532
|
+
@view.expects(:capture).with(1, 2, :value3 => 3, :value4 => 4)
|
533
|
+
@builder.render :my_before_block, 1, 2, :value3 => 3, :value4 => 4
|
534
|
+
end
|
535
|
+
|
536
|
+
it "should override hash options for before blocks by merging the runtime options into the before block options into the block options into the global options" do
|
537
|
+
block = Proc.new {|options|}
|
538
|
+
@builder.global_options.merge!(:param1 => "global level", :param2 => "global level", :param3 => "global level", :param4 => "global level")
|
539
|
+
@builder.define(:my_before_block, :param1 => "block level", :param2 => "block level", :param3 => "block level", &block)
|
540
|
+
@builder.before(:my_before_block, :param1 => "before block level", :param2 => "before block level", &block)
|
541
|
+
@view.expects(:capture).with(:param4 => 'global level', :param1 => 'top level', :param2 => 'before block level', :param3 => 'block level')
|
542
|
+
@builder.render :my_before_block, :param1 => "top level"
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
describe "render method - around blocks" do
|
547
|
+
it "should be able to render code around another block" do
|
548
|
+
my_block = Proc.new { "test" }
|
549
|
+
around_block = Proc.new { |content_block| "<span>#{content_block.call}</span>" }
|
550
|
+
@builder.define(:my_block, &my_block)
|
551
|
+
@builder.around(:my_block, &around_block)
|
552
|
+
@builder.render(:my_block).should eql("<span>test</span>")
|
553
|
+
end
|
554
|
+
|
555
|
+
it "should be able to nest multiple around blocks with the last defined around block on the outside" do
|
556
|
+
my_block = Proc.new { "test" }
|
557
|
+
around_block1 = Proc.new { |content_block| "<h1>#{content_block.call}</h1>" }
|
558
|
+
around_block2 = Proc.new { |content_block| "<span style='font-size: 100px'>#{content_block.call}</span>" }
|
559
|
+
around_block3 = Proc.new { |content_block| "<span style='color:red'>#{content_block.call}</span>" }
|
560
|
+
@builder.define(:my_block, &my_block)
|
561
|
+
@builder.around(:my_block, &around_block1)
|
562
|
+
@builder.around(:my_block, &around_block2)
|
563
|
+
@builder.around(:my_block, &around_block3)
|
564
|
+
@builder.render(:my_block).should eql("<h1>&lt;span style='font-size: 100px'&gt;&amp;lt;span style='color:red'&amp;gt;test&amp;lt;/span&amp;gt;&lt;/span&gt;</h1>")
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
describe "render method - after blocks" do
|
569
|
+
before :each do
|
570
|
+
@builder.expects(:render_block).at_least_once
|
571
|
+
@builder.expects(:render_before_blocks).at_least_once
|
572
|
+
end
|
573
|
+
|
574
|
+
it "should render after blocks when using a block" do
|
575
|
+
block = Proc.new {|value1, value2, options|}
|
576
|
+
@builder.after("my_after_block", &block)
|
577
|
+
@view.expects(:capture).with(1, 2, :value3 => 3, :value4 => 4)
|
578
|
+
@builder.render :my_after_block, 1, 2, :value3 => 3, :value4 => 4
|
579
|
+
end
|
580
|
+
|
581
|
+
it "should override hash options for after blocks by merging the runtime options into the after block options into the block options into the global options" do
|
582
|
+
block = Proc.new {|options|}
|
583
|
+
@builder.global_options.merge!(:param1 => "global level", :param2 => "global level", :param3 => "global level", :param4 => "global level")
|
584
|
+
@builder.define(:my_after_block, :param1 => "block level", :param2 => "block level", :param3 => "block level", &block)
|
585
|
+
@builder.after(:my_after_block, :param1 => "after block level", :param2 => "after block level", &block)
|
586
|
+
@view.expects(:capture).with(:param4 => 'global level', :param1 => 'top level', :param2 => 'after block level', :param3 => 'block level')
|
587
|
+
@builder.render :my_after_block, :param1 => "top level"
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
describe "method_missing method" do
|
592
|
+
it "should start a new block group if a method is missing" do
|
593
|
+
@builder.some_method
|
594
|
+
queued_blocks = @builder.block_groups[:some_method]
|
595
|
+
queued_blocks.should eql []
|
596
|
+
end
|
597
|
+
|
598
|
+
it "should add items to a queue when a new block group is started" do
|
599
|
+
@builder.some_method do
|
600
|
+
@builder.queue :myblock1
|
601
|
+
@builder.queue :myblock2
|
602
|
+
end
|
603
|
+
@builder.some_method2 do
|
604
|
+
@builder.queue :myblock3
|
605
|
+
end
|
606
|
+
queued_blocks = @builder.block_groups[:some_method]
|
607
|
+
queued_blocks.length.should eql 2
|
608
|
+
queued_blocks.first.name.should eql :myblock1
|
609
|
+
queued_blocks.second.name.should eql :myblock2
|
610
|
+
queued_blocks = @builder.block_groups[:some_method2]
|
611
|
+
queued_blocks.length.should eql 1
|
612
|
+
queued_blocks.first.name.should eql :myblock3
|
613
|
+
@builder.queued_blocks.should eql []
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
describe "evaluated_procs method" do
|
618
|
+
it "should evaluate any proc options" do
|
619
|
+
proc1 = lambda {@view.cycle("even", "odd")}
|
620
|
+
proc2 = lambda {@view.cycle("one", "two")}
|
621
|
+
evaluated_procs = @builder.evaluated_procs(:class => proc1, :id => proc2, :style => "color:red")
|
622
|
+
evaluated_procs[:class].should eql "even"
|
623
|
+
evaluated_procs[:id].should eql "one"
|
624
|
+
evaluated_procs[:style].should eql "color:red"
|
625
|
+
end
|
626
|
+
|
627
|
+
it "should pass any additional arguments to evaluated procs" do
|
628
|
+
proc1 = lambda { |param1, param2| "user_#{param1}_#{param2}"}
|
629
|
+
evaluated_procs = @builder.evaluated_procs({:class => proc1}, 1, 2)
|
630
|
+
evaluated_procs[:class].should eql "user_1_2"
|
631
|
+
end
|
632
|
+
end
|
633
|
+
|
634
|
+
describe "evaluated_proc method" do
|
635
|
+
it "should evaluate a proc" do
|
636
|
+
proc = lambda {@view.cycle("even", "odd")}
|
637
|
+
@builder.evaluated_proc(proc).should eql "even"
|
638
|
+
@builder.evaluated_proc(proc).should eql "odd"
|
639
|
+
@builder.evaluated_proc(proc).should eql "even"
|
640
|
+
end
|
641
|
+
|
642
|
+
it "should just return the value if it is not a proc" do
|
643
|
+
@builder.evaluated_proc("1234").should eql "1234"
|
644
|
+
end
|
645
|
+
|
646
|
+
it "should return nil if no arguments are specified" do
|
647
|
+
@builder.evaluated_proc.should be_nil
|
648
|
+
end
|
649
|
+
|
650
|
+
it "should treat the first argument as the potential proc to evaluate" do
|
651
|
+
@builder.evaluated_proc(1, 2, 3).should eql 1
|
652
|
+
end
|
653
|
+
|
654
|
+
it "should pass any additional arguments to the evaluated proc" do
|
655
|
+
proc1 = lambda { |param1, param2| "user_#{param1}_#{param2}"}
|
656
|
+
@builder.evaluated_proc(proc1, 1, 2).should eql "user_1_2"
|
657
|
+
end
|
658
|
+
end
|
659
|
+
end
|