flavour_saver 0.3.7 → 2.0.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.
Files changed (36) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +47 -0
  3. data/CHANGELOG.md +40 -0
  4. data/Gemfile.lock +34 -62
  5. data/README.md +34 -11
  6. data/flavour_saver.gemspec +14 -9
  7. data/lib/flavour_saver/helpers.rb +28 -13
  8. data/lib/flavour_saver/lexer.rb +19 -6
  9. data/lib/flavour_saver/nodes.rb +1 -1
  10. data/lib/flavour_saver/parser.rb +8 -7
  11. data/lib/flavour_saver/runtime.rb +8 -8
  12. data/lib/flavour_saver/version.rb +1 -1
  13. data/spec/acceptance/backtrack_spec.rb +1 -1
  14. data/spec/acceptance/comment_spec.rb +1 -1
  15. data/spec/acceptance/custom_block_helper_spec.rb +2 -2
  16. data/spec/acceptance/custom_helper_spec.rb +1 -1
  17. data/spec/acceptance/ensure_no_rce_spec.rb +2 -2
  18. data/spec/acceptance/handlebars_qunit_spec.rb +299 -214
  19. data/spec/acceptance/if_else_spec.rb +37 -6
  20. data/spec/acceptance/multi_level_with_spec.rb +1 -1
  21. data/spec/acceptance/one_character_identifier_spec.rb +2 -2
  22. data/spec/acceptance/raw_block_spec.rb +1 -1
  23. data/spec/acceptance/runtime_run_spec.rb +1 -1
  24. data/spec/acceptance/sections_spec.rb +3 -3
  25. data/spec/acceptance/segment_literals_spec.rb +3 -3
  26. data/spec/acceptance/simple_expression_spec.rb +3 -3
  27. data/spec/acceptance/subexpression_spec.rb +37 -0
  28. data/spec/acceptance/unless_spec.rb +48 -0
  29. data/spec/fixtures/if_else.hbs +3 -3
  30. data/spec/fixtures/unless.hbs +5 -0
  31. data/spec/lib/flavour_saver/lexer_spec.rb +104 -28
  32. data/spec/lib/flavour_saver/parser_spec.rb +115 -82
  33. data/spec/lib/flavour_saver/runtime_spec.rb +44 -33
  34. metadata +27 -72
  35. data/.travis.yml +0 -14
  36. data/Guardfile +0 -12
@@ -22,8 +22,8 @@ describe FlavourSaver do
22
22
  let(:template) { "{{foo}}" }
23
23
 
24
24
  it 'returns "foo"' do
25
- context.stub(:foo).and_return('foo')
26
- subject.should == 'foo'
25
+ allow(context).to receive(:foo).and_return('foo')
26
+ expect(subject).to eq 'foo'
27
27
  end
28
28
  end
29
29
 
@@ -31,9 +31,9 @@ describe FlavourSaver do
31
31
  let(:template) { "Goodbye\n{{cruel}}\n{{world}}!" }
32
32
 
33
33
  it 'it works if all the required keys are provided' do
34
- context.should_receive(:cruel).and_return('cruel')
35
- context.should_receive(:world).and_return('world')
36
- subject.should == "Goodbye\ncruel\nworld!"
34
+ expect(context).to receive(:cruel).and_return('cruel')
35
+ expect(context).to receive(:world).and_return('world')
36
+ expect(subject).to eq "Goodbye\ncruel\nworld!"
37
37
  end
38
38
  end
39
39
 
@@ -41,9 +41,9 @@ describe FlavourSaver do
41
41
  let(:template) {"{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!"}
42
42
 
43
43
  it 'comments are ignored' do
44
- context.should_receive(:cruel).and_return('cruel')
45
- context.should_receive(:world).and_return('world')
46
- subject.should == "Goodbye\ncruel\nworld!"
44
+ expect(context).to receive(:cruel).and_return('cruel')
45
+ expect(context).to receive(:world).and_return('world')
46
+ expect(subject).to eq "Goodbye\ncruel\nworld!"
47
47
  end
48
48
  end
49
49
 
@@ -51,15 +51,15 @@ describe FlavourSaver do
51
51
  let(:template) { "{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!" }
52
52
 
53
53
  it 'booleans show the contents when true' do
54
- context.stub(:goodbye).and_return(true)
55
- context.stub(:world).and_return('world')
56
- subject.should == "GOODBYE cruel world!"
54
+ allow(context).to receive(:goodbye).and_return(true)
55
+ allow(context).to receive(:world).and_return('world')
56
+ expect(subject).to eq "GOODBYE cruel world!"
57
57
  end
58
58
 
59
59
  it 'booleans do not show the contents when false' do
60
- context.stub(:goodbye).and_return(false)
61
- context.stub(:world).and_return('world')
62
- subject.should == "cruel world!"
60
+ allow(context).to receive(:goodbye).and_return(false)
61
+ allow(context).to receive(:world).and_return('world')
62
+ expect(subject).to eq "cruel world!"
63
63
  end
64
64
  end
65
65
 
@@ -68,9 +68,9 @@ describe FlavourSaver do
68
68
  let (:template) { "num1: {{num1}}, num2: {{num2}}" }
69
69
 
70
70
  it 'should compile to "num1: 42, num2: 0"' do
71
- context.stub(:num1).and_return(42)
72
- context.stub(:num2).and_return(0)
73
- subject.should == 'num1: 42, num2: 0'
71
+ allow(context).to receive(:num1).and_return(42)
72
+ allow(context).to receive(:num2).and_return(0)
73
+ expect(subject).to eq 'num1: 42, num2: 0'
74
74
  end
75
75
  end
76
76
 
@@ -78,7 +78,7 @@ describe FlavourSaver do
78
78
  let (:template) { 'num: {{.}}' }
79
79
 
80
80
  it 'should compile to "num: 0"' do
81
- FlavourSaver.evaluate(template,0).should == 'num: 0'
81
+ expect(FlavourSaver.evaluate(template,0)).to eq 'num: 0'
82
82
  end
83
83
  end
84
84
 
@@ -86,8 +86,8 @@ describe FlavourSaver do
86
86
  let(:template) { 'num: {{num1/num2}}' }
87
87
 
88
88
  it 'should compile to "num: 0"' do
89
- context.stub_chain(:num1, :num2).and_return(0)
90
- subject.should == 'num: 0'
89
+ allow(context).to receive_message_chain(:num1, :num2).and_return(0)
90
+ expect(subject).to eq 'num: 0'
91
91
  end
92
92
  end
93
93
  end
@@ -97,7 +97,7 @@ describe FlavourSaver do
97
97
  let(:template) { "Alan's\nTest" }
98
98
 
99
99
  it 'works' do
100
- subject.should == "Alan's\nTest"
100
+ expect(subject).to eq "Alan's\nTest"
101
101
  end
102
102
  end
103
103
 
@@ -105,7 +105,7 @@ describe FlavourSaver do
105
105
  let(:template) { "Alan's\rTest" }
106
106
 
107
107
  it 'works' do
108
- subject.should == "Alan's\rTest"
108
+ expect(subject).to eq "Alan's\rTest"
109
109
  end
110
110
  end
111
111
  end
@@ -115,7 +115,7 @@ describe FlavourSaver do
115
115
  let(:template) {"Awesome's"}
116
116
 
117
117
  it "text is escapes so that it doesn't get caught in single quites" do
118
- subject.should == "Awesome's"
118
+ expect(subject).to eq "Awesome's"
119
119
  end
120
120
  end
121
121
 
@@ -123,7 +123,7 @@ describe FlavourSaver do
123
123
  let(:template) { "Awesome \\" }
124
124
 
125
125
  it "text is escaped so that the closing quote can't be ignored" do
126
- subject.should == "Awesome \\"
126
+ expect(subject).to eq "Awesome \\"
127
127
  end
128
128
  end
129
129
 
@@ -131,7 +131,7 @@ describe FlavourSaver do
131
131
  let(:template) { "Awesome\\\\ foo" }
132
132
 
133
133
  it "text is escapes so that it doesn't mess up the backslashes" do
134
- subject.should == "Awesome\\\\ foo"
134
+ expect(subject).to eq "Awesome\\\\ foo"
135
135
  end
136
136
  end
137
137
 
@@ -139,8 +139,8 @@ describe FlavourSaver do
139
139
  let(:template) { "Awesome {{foo}}" }
140
140
 
141
141
  it "text is escaped so that it doesn't mess up backslashes" do
142
- context.stub(:foo).and_return('\\')
143
- subject.should == "Awesome \\"
142
+ allow(context).to receive(:foo).and_return('\\')
143
+ expect(subject).to eq "Awesome \\"
144
144
  end
145
145
  end
146
146
 
@@ -148,7 +148,7 @@ describe FlavourSaver do
148
148
  let(:template) { ' " " ' }
149
149
 
150
150
  it "double quotes never produce invalid javascript" do
151
- subject.should == ' " " '
151
+ expect(subject).to eq ' " " '
152
152
  end
153
153
  end
154
154
  end
@@ -158,8 +158,8 @@ describe FlavourSaver do
158
158
  let(:template) { "{{{awesome}}}" }
159
159
 
160
160
  it "shouldn't be escaped" do
161
- context.stub(:awesome).and_return("&\"\\<>")
162
- subject.should == "&\"\\<>"
161
+ allow(context).to receive(:awesome).and_return("&\"\\<>")
162
+ expect(subject).to eq "&\"\\<>"
163
163
  end
164
164
  end
165
165
 
@@ -167,8 +167,8 @@ describe FlavourSaver do
167
167
  let(:template) { "{{&awesome}}" }
168
168
 
169
169
  it "shouldn't be escaped" do
170
- context.stub(:awesome).and_return("&\"\\<>")
171
- subject.should == "&\"\\<>"
170
+ allow(context).to receive(:awesome).and_return("&\"\\<>")
171
+ expect(subject).to eq "&\"\\<>"
172
172
  end
173
173
  end
174
174
 
@@ -176,11 +176,11 @@ describe FlavourSaver do
176
176
  let(:template) { "{{awesome}}" }
177
177
 
178
178
  it "should be escaped" do
179
- context.stub(:awesome).and_return("&\"'`\\<>")
179
+ allow(context).to receive(:awesome).and_return("&\"'`\\<>")
180
180
  if RUBY_VERSION >= '2.0.0'
181
- subject.should == "&amp;&quot;&#39;&#x60;\\&lt;&gt;"
181
+ expect(subject).to eq "&amp;&quot;&#39;&#x60;\\&lt;&gt;"
182
182
  else
183
- subject.should == "&amp;&quot;&#x27;&#x60;\\&lt;&gt;"
183
+ expect(subject).to eq "&amp;&quot;&#x27;&#x60;\\&lt;&gt;"
184
184
  end
185
185
  end
186
186
  end
@@ -189,8 +189,8 @@ describe FlavourSaver do
189
189
  let(:template) { "{{awesome}}" }
190
190
 
191
191
  it "should be escaped" do
192
- context.stub(:awesome).and_return("Escaped, <b> looks like: &lt;b&gt;")
193
- subject.should == "Escaped, &lt;b&gt; looks like: &amp;lt;b&amp;gt;"
192
+ allow(context).to receive(:awesome).and_return("Escaped, <b> looks like: &lt;b&gt;")
193
+ expect(subject).to eq "Escaped, &lt;b&gt; looks like: &amp;lt;b&amp;gt;"
194
194
  end
195
195
  end
196
196
  end
@@ -199,8 +199,8 @@ describe FlavourSaver do
199
199
  let(:template) { "{{awesome}}" }
200
200
 
201
201
  it "shouldn't be escaped" do
202
- context.stub(:awesome).and_return("&\"\\<>".html_safe)
203
- subject.should == "&\"\\<>"
202
+ allow(context).to receive(:awesome).and_return("&\"\\<>".html_safe)
203
+ expect(subject).to eq "&\"\\<>"
204
204
  end
205
205
  end
206
206
 
@@ -208,8 +208,8 @@ describe FlavourSaver do
208
208
  let(:template) { "{{awesome}}" }
209
209
 
210
210
  it "are called and render their output" do
211
- context.stub(:awesome).and_return("Awesome")
212
- subject.should == "Awesome"
211
+ allow(context).to receive(:awesome).and_return("Awesome")
212
+ expect(subject).to eq "Awesome"
213
213
  end
214
214
  end
215
215
 
@@ -218,8 +218,8 @@ describe FlavourSaver do
218
218
  let(:template) { "{{foo-bar}}" }
219
219
 
220
220
  it 'paths can contain hyphens (-)' do
221
- context.should_receive(:[]).with('foo-bar').and_return('baz')
222
- subject.should == 'baz'
221
+ expect(context).to receive(:[]).with('foo-bar').and_return('baz')
222
+ expect(subject).to eq 'baz'
223
223
  end
224
224
  end
225
225
 
@@ -227,8 +227,8 @@ describe FlavourSaver do
227
227
  let(:template) { "{{foo.foo-bar}}" }
228
228
 
229
229
  it 'paths can contain hyphens (-)' do
230
- context.stub_chain(:foo, :[]).with('foo-bar').and_return(proc { 'baz' })
231
- subject.should == 'baz'
230
+ allow(context).to receive_message_chain(:foo, :[]).with('foo-bar').and_return(proc { 'baz' })
231
+ expect(subject).to eq 'baz'
232
232
  end
233
233
  end
234
234
 
@@ -236,8 +236,8 @@ describe FlavourSaver do
236
236
  let(:template) { "{{foo/foo-bar}}" }
237
237
 
238
238
  it 'paths can contain hyphens (-)' do
239
- context.stub_chain(:foo, :[]).with('foo-bar').and_return('baz')
240
- subject.should == 'baz'
239
+ allow(context).to receive_message_chain(:foo, :[]).with('foo-bar').and_return('baz')
240
+ expect(subject).to eq 'baz'
241
241
  end
242
242
  end
243
243
 
@@ -245,8 +245,8 @@ describe FlavourSaver do
245
245
  let(:template) {"Goodbye {{alan/expression}} world!"}
246
246
 
247
247
  it 'access nested object' do
248
- context.stub_chain(:alan, :expression).and_return('beautiful')
249
- subject.should == 'Goodbye beautiful world!'
248
+ allow(context).to receive_message_chain(:alan, :expression).and_return('beautiful')
249
+ expect(subject).to eq 'Goodbye beautiful world!'
250
250
  end
251
251
  end
252
252
 
@@ -254,8 +254,8 @@ describe FlavourSaver do
254
254
  let(:template) {"Goodbye {{alan/expression}} world!"}
255
255
 
256
256
  it 'access nested object' do
257
- context.stub_chain(:alan, :expression).and_return('')
258
- subject.should == 'Goodbye world!'
257
+ allow(context).to receive_message_chain(:alan, :expression).and_return('')
258
+ expect(subject).to eq 'Goodbye world!'
259
259
  end
260
260
  end
261
261
 
@@ -264,9 +264,9 @@ describe FlavourSaver do
264
264
 
265
265
  it 'literal paths can be used' do
266
266
  alan = double(:alan)
267
- context.should_receive(:[]).with('@alan').and_return(alan)
268
- alan.should_receive(:expression).and_return('beautiful')
269
- subject.should == 'Goodbye beautiful world!'
267
+ expect(context).to receive(:[]).with('@alan').and_return(alan)
268
+ expect(alan).to receive(:expression).and_return('beautiful')
269
+ expect(subject).to eq 'Goodbye beautiful world!'
270
270
  end
271
271
  end
272
272
 
@@ -274,13 +274,13 @@ describe FlavourSaver do
274
274
  let(:template) { '{{person/name}}' }
275
275
 
276
276
  it 'returns empty string from nested paths' do
277
- context.stub_chain(:person,:name).and_return('')
278
- subject.should == ''
277
+ allow(context).to receive_message_chain(:person,:name).and_return('')
278
+ expect(subject).to eq ''
279
279
  end
280
280
 
281
281
  it 'returns empty string from nil objects' do
282
- context.stub_chain(:person,:name)
283
- subject.should == ''
282
+ allow(context).to receive_message_chain(:person,:name)
283
+ expect(subject).to eq ''
284
284
  end
285
285
  end
286
286
 
@@ -289,8 +289,8 @@ describe FlavourSaver do
289
289
  let(:template) { "{{#goodbyes}}{{this}}{{/goodbyes}}" }
290
290
 
291
291
  it 'evaluates to the current context' do
292
- context.stub(:goodbyes).and_return(["goodbye", "Goodbye", "GOODBYE"])
293
- subject.should == "goodbyeGoodbyeGOODBYE"
292
+ allow(context).to receive(:goodbyes).and_return(["goodbye", "Goodbye", "GOODBYE"])
293
+ expect(subject).to eq "goodbyeGoodbyeGOODBYE"
294
294
  end
295
295
  end
296
296
 
@@ -300,13 +300,13 @@ describe FlavourSaver do
300
300
  it 'evaluates in more complex paths' do
301
301
  hellos = []
302
302
  hellos << double(:hello)
303
- hellos[0].should_receive(:text).and_return('hello')
303
+ expect(hellos[0]).to receive(:text).and_return('hello')
304
304
  hellos << double(:Hello)
305
- hellos[1].should_receive(:text).and_return('Hello')
305
+ expect(hellos[1]).to receive(:text).and_return('Hello')
306
306
  hellos << double(:HELLO)
307
- hellos[2].should_receive(:text).and_return('HELLO')
308
- context.stub(:hellos).and_return(hellos)
309
- subject.should == "helloHelloHELLO"
307
+ expect(hellos[2]).to receive(:text).and_return('HELLO')
308
+ allow(context).to receive(:hellos).and_return(hellos)
309
+ expect(subject).to eq "helloHelloHELLO"
310
310
  end
311
311
  end
312
312
  end
@@ -318,8 +318,8 @@ describe FlavourSaver do
318
318
  let(:template) { "{{#goodbyes}}{{foo this}}{{/goodbyes}}" }
319
319
 
320
320
  it 'evaluates to current context' do
321
- context.stub(:goodbyes).and_return(["goodbye", "Goodbye", "GOODBYE"])
322
- subject.should == "bar goodbyebar Goodbyebar GOODBYE"
321
+ allow(context).to receive(:goodbyes).and_return(["goodbye", "Goodbye", "GOODBYE"])
322
+ expect(subject).to eq "bar goodbyebar Goodbyebar GOODBYE"
323
323
  end
324
324
  end
325
325
 
@@ -329,13 +329,13 @@ describe FlavourSaver do
329
329
  it 'evaluates to current context' do
330
330
  hellos = []
331
331
  hellos << double(:hello)
332
- hellos[0].should_receive(:text).and_return('hello')
332
+ expect(hellos[0]).to receive(:text).and_return('hello')
333
333
  hellos << double(:Hello)
334
- hellos[1].should_receive(:text).and_return('Hello')
334
+ expect(hellos[1]).to receive(:text).and_return('Hello')
335
335
  hellos << double(:HELLO)
336
- hellos[2].should_receive(:text).and_return('HELLO')
337
- context.stub(:hellos).and_return(hellos)
338
- subject.should == "bar hellobar Hellobar HELLO"
336
+ expect(hellos[2]).to receive(:text).and_return('HELLO')
337
+ allow(context).to receive(:hellos).and_return(hellos)
338
+ expect(subject).to eq "bar hellobar Hellobar HELLO"
339
339
  end
340
340
  end
341
341
  end
@@ -347,22 +347,22 @@ describe FlavourSaver do
347
347
 
348
348
  describe 'with unset value' do
349
349
  it 'renders' do
350
- context.stub(:goodbyes)
351
- subject.should == 'Right On!'
350
+ allow(context).to receive(:goodbyes)
351
+ expect(subject).to eq 'Right On!'
352
352
  end
353
353
  end
354
354
 
355
355
  describe 'with false value' do
356
356
  it 'renders' do
357
- context.stub(:goodbyes).and_return(false)
358
- subject.should == 'Right On!'
357
+ allow(context).to receive(:goodbyes).and_return(false)
358
+ expect(subject).to eq 'Right On!'
359
359
  end
360
360
  end
361
361
 
362
362
  describe 'with an empty set' do
363
363
  it 'renders' do
364
- context.stub(:goodbyes).and_return([])
365
- subject.should == 'Right On!'
364
+ allow(context).to receive(:goodbyes).and_return([])
365
+ expect(subject).to eq 'Right On!'
366
366
  end
367
367
  end
368
368
  end
@@ -373,20 +373,20 @@ describe FlavourSaver do
373
373
  it 'arrays iterate the contents with non-empty' do
374
374
  goodbyes = []
375
375
  goodbyes << double(:goodbye)
376
- goodbyes[0].should_receive(:text).and_return('goodbye')
376
+ expect(goodbyes[0]).to receive(:text).and_return('goodbye')
377
377
  goodbyes << double(:Goodbye)
378
- goodbyes[1].should_receive(:text).and_return('Goodbye')
378
+ expect(goodbyes[1]).to receive(:text).and_return('Goodbye')
379
379
  goodbyes << double(:GOODBYE)
380
- goodbyes[2].should_receive(:text).and_return('GOODBYE')
381
- context.stub(:goodbyes).and_return(goodbyes)
382
- context.stub(:world).and_return('world')
383
- subject.should == "goodbye! Goodbye! GOODBYE! cruel world!"
380
+ expect(goodbyes[2]).to receive(:text).and_return('GOODBYE')
381
+ allow(context).to receive(:goodbyes).and_return(goodbyes)
382
+ allow(context).to receive(:world).and_return('world')
383
+ expect(subject).to eq "goodbye! Goodbye! GOODBYE! cruel world!"
384
384
  end
385
385
 
386
386
  it 'ignores the contents when the array is empty' do
387
- context.stub(:goodbyes).and_return([])
388
- context.stub(:world).and_return('world')
389
- subject.should == "cruel world!"
387
+ allow(context).to receive(:goodbyes).and_return([])
388
+ allow(context).to receive(:world).and_return('world')
389
+ expect(subject).to eq "cruel world!"
390
390
  end
391
391
 
392
392
  describe 'array with @index' do
@@ -395,14 +395,14 @@ describe FlavourSaver do
395
395
  it 'the @index variable is used' do
396
396
  goodbyes = []
397
397
  goodbyes << double(:goodbye)
398
- goodbyes[0].should_receive(:text).and_return('goodbye')
398
+ expect(goodbyes[0]).to receive(:text).and_return('goodbye')
399
399
  goodbyes << double(:Goodbye)
400
- goodbyes[1].should_receive(:text).and_return('Goodbye')
400
+ expect(goodbyes[1]).to receive(:text).and_return('Goodbye')
401
401
  goodbyes << double(:GOODBYE)
402
- goodbyes[2].should_receive(:text).and_return('GOODBYE')
403
- context.stub(:goodbyes).and_return(goodbyes)
404
- context.stub(:world).and_return('world')
405
- subject.should == "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!"
402
+ expect(goodbyes[2]).to receive(:text).and_return('GOODBYE')
403
+ allow(context).to receive(:goodbyes).and_return(goodbyes)
404
+ allow(context).to receive(:world).and_return('world')
405
+ expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!"
406
406
  end
407
407
  end
408
408
 
@@ -412,20 +412,20 @@ describe FlavourSaver do
412
412
  it 'arrays iterate the contents with non-empty' do
413
413
  goodbyes = []
414
414
  goodbyes << double(:goodbye)
415
- goodbyes[0].stub(:text).and_return('goodbye')
415
+ allow(goodbyes[0]).to receive(:text).and_return('goodbye')
416
416
  goodbyes << double(:Goodbye)
417
- goodbyes[1].stub(:text).and_return('Goodbye')
417
+ allow(goodbyes[1]).to receive(:text).and_return('Goodbye')
418
418
  goodbyes << double(:GOODBYE)
419
- goodbyes[2].stub(:text).and_return('GOODBYE')
420
- context.stub(:goodbyes).and_return(goodbyes)
421
- context.stub(:world).and_return('world')
422
- subject.should == "cruel world!"
419
+ allow(goodbyes[2]).to receive(:text).and_return('GOODBYE')
420
+ allow(context).to receive(:goodbyes).and_return(goodbyes)
421
+ allow(context).to receive(:world).and_return('world')
422
+ expect(subject).to eq "cruel world!"
423
423
  end
424
424
 
425
425
  it 'ignores the contents when the array is empty' do
426
- context.stub(:goodbyes).and_return([])
427
- context.stub(:world).and_return('world')
428
- subject.should == "cruel world!"
426
+ allow(context).to receive(:goodbyes).and_return([])
427
+ allow(context).to receive(:world).and_return('world')
428
+ expect(subject).to eq "cruel world!"
429
429
  end
430
430
  end
431
431
 
@@ -435,16 +435,16 @@ describe FlavourSaver do
435
435
  let(:template) {"{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}"}
436
436
 
437
437
  it 'templates can access variables in contexts up the stack with relative path syntax' do
438
- context.stub(:name).and_return('Alan')
438
+ allow(context).to receive(:name).and_return('Alan')
439
439
  goodbyes = []
440
440
  goodbyes << double(:goodbye)
441
- goodbyes[0].should_receive(:text).and_return('goodbye')
441
+ expect(goodbyes[0]).to receive(:text).and_return('goodbye')
442
442
  goodbyes << double(:Goodbye)
443
- goodbyes[1].should_receive(:text).and_return('Goodbye')
443
+ expect(goodbyes[1]).to receive(:text).and_return('Goodbye')
444
444
  goodbyes << double(:GOODBYE)
445
- goodbyes[2].should_receive(:text).and_return('GOODBYE')
446
- context.stub(:goodbyes).and_return(goodbyes)
447
- subject.should == "goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! "
445
+ expect(goodbyes[2]).to receive(:text).and_return('GOODBYE')
446
+ allow(context).to receive(:goodbyes).and_return(goodbyes)
447
+ expect(subject).to eq "goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! "
448
448
  end
449
449
  end
450
450
 
@@ -457,13 +457,13 @@ describe FlavourSaver do
457
457
  end
458
458
 
459
459
  it 'renders correctly' do
460
- context.stub(:prefix).and_return('/root')
460
+ allow(context).to receive(:prefix).and_return('/root')
461
461
  goodbyes = []
462
462
  goodbyes << double(:Goodbye)
463
- goodbyes[0].should_receive(:text).and_return('Goodbye')
464
- goodbyes[0].should_receive(:url).and_return('goodbye')
465
- context.stub(:goodbyes).and_return(goodbyes)
466
- subject.should == "<a href='/root/goodbye'>Goodbye</a>"
463
+ expect(goodbyes[0]).to receive(:text).and_return('Goodbye')
464
+ expect(goodbyes[0]).to receive(:url).and_return('goodbye')
465
+ allow(context).to receive(:goodbyes).and_return(goodbyes)
466
+ expect(subject).to eq "<a href='/root/goodbye'>Goodbye</a>"
467
467
  end
468
468
  end
469
469
 
@@ -478,8 +478,8 @@ describe FlavourSaver do
478
478
  end
479
479
 
480
480
  it 'renders correctly' do
481
- context.stub(:name).and_return('Alan')
482
- subject.should == "Goodbye Alan! goodbye Alan! GOODBYE Alan! "
481
+ allow(context).to receive(:name).and_return('Alan')
482
+ expect(subject).to eq "Goodbye Alan! goodbye Alan! GOODBYE Alan! "
483
483
  end
484
484
  end
485
485
 
@@ -492,12 +492,12 @@ describe FlavourSaver do
492
492
  end
493
493
 
494
494
  it 'renders correctly' do
495
- context.stub(:prefix).and_return('/root')
495
+ allow(context).to receive(:prefix).and_return('/root')
496
496
  goodbye = double(:goodbye)
497
- goodbye.stub(:text).and_return('Goodbye')
498
- goodbye.stub(:url).and_return('goodbye')
499
- context.stub(:goodbyes).and_return([goodbye])
500
- subject.should == "<a href='/root/goodbye'>Goodbye</a>"
497
+ allow(goodbye).to receive(:text).and_return('Goodbye')
498
+ allow(goodbye).to receive(:url).and_return('goodbye')
499
+ allow(context).to receive(:goodbyes).and_return([goodbye])
500
+ expect(subject).to eq "<a href='/root/goodbye'>Goodbye</a>"
501
501
  end
502
502
  end
503
503
 
@@ -506,12 +506,12 @@ describe FlavourSaver do
506
506
 
507
507
  example do
508
508
  goodbye = double(:goodbye)
509
- goodbye.stub(:text).and_return('goodbye')
509
+ allow(goodbye).to receive(:text).and_return('goodbye')
510
510
  inner = double(:inner)
511
- inner.stub(:inner).and_return([goodbye])
512
- context.stub(:omg).and_return('OMG!')
513
- context.stub(:outer).and_return([inner])
514
- subject.should == "Goodbye cruel OMG!"
511
+ allow(inner).to receive(:inner).and_return([goodbye])
512
+ allow(context).to receive(:omg).and_return('OMG!')
513
+ allow(context).to receive(:outer).and_return([inner])
514
+ expect(subject).to eq "Goodbye cruel OMG!"
515
515
  end
516
516
  end
517
517
 
@@ -524,7 +524,7 @@ describe FlavourSaver do
524
524
  end
525
525
 
526
526
  example do
527
- context.stub(:world).and_return('world')
527
+ allow(context).to receive(:world).and_return('world')
528
528
  end
529
529
  end
530
530
 
@@ -537,8 +537,8 @@ describe FlavourSaver do
537
537
  end
538
538
 
539
539
  example do
540
- context.stub(:name).and_return('Yehuda')
541
- subject.should == "<form><p>Yehuda</p></form>"
540
+ allow(context).to receive(:name).and_return('Yehuda')
541
+ expect(subject).to eq "<form><p>Yehuda</p></form>"
542
542
  end
543
543
  end
544
544
 
@@ -551,15 +551,15 @@ describe FlavourSaver do
551
551
  end
552
552
  example do
553
553
  person = Struct.new(:name, :id)
554
- context.stub(:people).and_return([person.new('Alan', 1), person.new('Yehuda', 2)])
555
- subject.should == "<ul><li><a href=\"/people/1\">Alan</a></li><li><a href=\"/people/2\">Yehuda</a></li></ul>"
554
+ allow(context).to receive(:people).and_return([person.new('Alan', 1), person.new('Yehuda', 2)])
555
+ expect(subject).to eq "<ul><li><a href=\"/people/1\">Alan</a></li><li><a href=\"/people/2\">Yehuda</a></li></ul>"
556
556
  end
557
557
  end
558
558
 
559
559
  describe 'block helper for undefined value' do
560
560
  let(:template) { "{{#empty}}shoulnd't render{{/empty}}" }
561
561
  example do
562
- -> { subject }.should raise_exception(FlavourSaver::UnknownHelperException)
562
+ expect { subject }.to raise_exception(FlavourSaver::UnknownHelperException)
563
563
  end
564
564
  end
565
565
 
@@ -571,8 +571,8 @@ describe FlavourSaver do
571
571
  end
572
572
  end
573
573
  example do
574
- context.stub_chain(:yehuda,:name).and_return('Yehuda')
575
- subject.should == "<form><p>Yehuda</p></form>"
574
+ allow(context).to receive_message_chain(:yehuda,:name).and_return('Yehuda')
575
+ expect(subject).to eq "<form><p>Yehuda</p></form>"
576
576
  end
577
577
  end
578
578
 
@@ -585,10 +585,10 @@ describe FlavourSaver do
585
585
  end
586
586
  example do
587
587
  yehuda = double(:yehuda)
588
- yehuda.stub(:name).and_return('Yehuda')
589
- yehuda.stub_chain(:cat,:name).and_return('Harold')
590
- context.stub(:yehuda).and_return(yehuda)
591
- subject.should == "<form><p>Harold</p></form>"
588
+ allow(yehuda).to receive(:name).and_return('Yehuda')
589
+ allow(yehuda).to receive_message_chain(:cat,:name).and_return('Harold')
590
+ allow(context).to receive(:yehuda).and_return(yehuda)
591
+ expect(subject).to eq "<form><p>Harold</p></form>"
592
592
  end
593
593
  end
594
594
 
@@ -603,26 +603,26 @@ describe FlavourSaver do
603
603
  end
604
604
  end
605
605
  example do
606
- context.stub_chain(:yehuda,:name).and_return('Yehuda')
607
- subject.should == "<form><p>Yehuda</p><a href='Yehuda'>Hello</a></form>"
606
+ allow(context).to receive_message_chain(:yehuda,:name).and_return('Yehuda')
607
+ expect(subject).to eq "<form><p>Yehuda</p><a href='Yehuda'>Hello</a></form>"
608
608
  end
609
609
  end
610
610
 
611
611
  describe 'block inverted sections' do
612
612
  let(:template) { "{{#people}}{{name}}{{^}}{{none}}{{/people}}" }
613
613
  example do
614
- context.stub(:none).and_return("No people")
615
- context.stub(:people).and_return(false)
616
- subject.should == "No people"
614
+ allow(context).to receive(:none).and_return("No people")
615
+ allow(context).to receive(:people).and_return(false)
616
+ expect(subject).to eq "No people"
617
617
  end
618
618
  end
619
619
 
620
620
  describe 'block inverted sections with empty arrays' do
621
621
  let(:template) { "{{#people}}{{name}}{{^}}{{none}}{{/people}}" }
622
622
  example do
623
- context.stub(:none).and_return('No people')
624
- context.stub(:people).and_return([])
625
- subject.should == "No people"
623
+ allow(context).to receive(:none).and_return('No people')
624
+ allow(context).to receive(:people).and_return([])
625
+ expect(subject).to eq "No people"
626
626
  end
627
627
  end
628
628
 
@@ -642,24 +642,24 @@ describe FlavourSaver do
642
642
 
643
643
  example 'an inverse wrapper is passed in as a new context' do
644
644
  person = Struct.new(:name)
645
- context.stub(:people).and_return([person.new('Alan'),person.new('Yehuda')])
646
- subject.should == "<ul><li>Alan</li><li>Yehuda</li></ul>"
645
+ allow(context).to receive(:people).and_return([person.new('Alan'),person.new('Yehuda')])
646
+ expect(subject).to eq "<ul><li>Alan</li><li>Yehuda</li></ul>"
647
647
  end
648
648
 
649
649
  example 'an inverse wrapper can optionally be called' do
650
- context.stub(:people).and_return([])
651
- subject.should == "<p><em>Nobody's here</em></p>"
650
+ allow(context).to receive(:people).and_return([])
651
+ expect(subject).to eq "<p><em>Nobody's here</em></p>"
652
652
  end
653
653
 
654
654
  describe 'the context of an inverse is the parent of the block' do
655
655
  let(:template) { "{{#list people}}Hello{{^}}{{message}}{{/list}}" }
656
656
  example do
657
- context.stub(:people).and_return([])
658
- context.stub(:message).and_return("Nobody's here")
657
+ allow(context).to receive(:people).and_return([])
658
+ allow(context).to receive(:message).and_return("Nobody's here")
659
659
  if RUBY_VERSION >= '2.0.0'
660
- subject.should == "<p>Nobody&#39;s here</p>"
660
+ expect(subject).to eq "<p>Nobody&#39;s here</p>"
661
661
  else
662
- subject.should == "<p>Nobody&#x27;s here</p>"
662
+ expect(subject).to eq "<p>Nobody&#x27;s here</p>"
663
663
  end
664
664
  end
665
665
  end
@@ -673,8 +673,8 @@ describe FlavourSaver do
673
673
  end
674
674
  example do
675
675
  person = Struct.new(:name, :url)
676
- context.stub(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
677
- subject.should == "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
676
+ allow(context).to receive(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
677
+ expect(subject).to eq "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
678
678
  end
679
679
  end
680
680
 
@@ -685,8 +685,8 @@ describe FlavourSaver do
685
685
  end
686
686
  example "Partials can be passed a context" do
687
687
  person = Struct.new(:name, :url)
688
- context.stub(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
689
- subject.should == "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
688
+ allow(context).to receive(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
689
+ expect(subject).to eq "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
690
690
  end
691
691
  end
692
692
 
@@ -698,15 +698,15 @@ describe FlavourSaver do
698
698
  end
699
699
  example "Partials can be passed a context" do
700
700
  person = Struct.new(:name, :url)
701
- context.stub(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
702
- subject.should == "Dudes: Yehuda <a href='http://yehuda'>http://yehuda</a> Alan <a href='http://alan'>http://alan</a> "
701
+ allow(context).to receive(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
702
+ expect(subject).to eq "Dudes: Yehuda <a href='http://yehuda'>http://yehuda</a> Alan <a href='http://alan'>http://alan</a> "
703
703
  end
704
704
  end
705
705
 
706
706
  describe 'rendering undefined partial throws an exception' do
707
707
  let(:template) { "{{> whatever}}" }
708
708
  example do
709
- -> { subject }.should raise_error(FS::UnknownPartialException)
709
+ expect { subject }.to raise_error(FS::UnknownPartialException)
710
710
  end
711
711
  end
712
712
 
@@ -719,8 +719,8 @@ describe FlavourSaver do
719
719
  end
720
720
  example do
721
721
  person = Struct.new(:name, :url)
722
- context.stub(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
723
- subject.should == "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
722
+ allow(context).to receive(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
723
+ expect(subject).to eq "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
724
724
  end
725
725
  end
726
726
 
@@ -730,9 +730,9 @@ describe FlavourSaver do
730
730
  FS.register_partial(:dude, "{{name}}")
731
731
  end
732
732
  example do
733
- context.stub(:name).and_return('Jeepers')
734
- context.stub(:another_dude).and_return('Creepers')
735
- subject.should == "Dudes: Jeepers Creepers"
733
+ allow(context).to receive(:name).and_return('Jeepers')
734
+ allow(context).to receive(:another_dude).and_return('Creepers')
735
+ expect(subject).to eq "Dudes: Jeepers Creepers"
736
736
  end
737
737
  end
738
738
 
@@ -742,9 +742,9 @@ describe FlavourSaver do
742
742
  FS.register_partial(:dude, "{{name}}")
743
743
  end
744
744
  example do
745
- context.stub(:name).and_return('Jeepers')
746
- context.stub(:another_dude).and_return('Creepers')
747
- subject.should == "Dudes: Jeepers"
745
+ allow(context).to receive(:name).and_return('Jeepers')
746
+ allow(context).to receive(:another_dude).and_return('Creepers')
747
+ expect(subject).to eq "Dudes: Jeepers"
748
748
  end
749
749
  end
750
750
 
@@ -754,9 +754,9 @@ describe FlavourSaver do
754
754
  FS.register_partial("dude/man", "{{name}}")
755
755
  end
756
756
  example do
757
- context.stub(:name).and_return('Jeepers')
758
- context.stub(:another_dude).and_return('Creepers')
759
- subject.should == "Dudes: Jeepers"
757
+ allow(context).to receive(:name).and_return('Jeepers')
758
+ allow(context).to receive(:another_dude).and_return('Creepers')
759
+ expect(subject).to eq "Dudes: Jeepers"
760
760
  end
761
761
  end
762
762
 
@@ -766,21 +766,21 @@ describe FlavourSaver do
766
766
  let(:template) { "Message: {{hello \"world\" 12 true false}}" }
767
767
  before do
768
768
  FS.register_helper(:hello) do |param,times,bool1,bool2|
769
- times = "NaN" unless times.is_a? Fixnum
769
+ times = "NaN" unless times.is_a? Integer
770
770
  bool1 = "NaB" unless bool1 == true
771
771
  bool2 = "NaB" unless bool2 == false
772
772
  "Hello #{param} #{times} times: #{bool1} #{bool2}"
773
773
  end
774
774
  end
775
775
  example do
776
- subject.should == "Message: Hello world 12 times: true false"
776
+ expect(subject).to eq "Message: Hello world 12 times: true false"
777
777
  end
778
778
  end
779
779
 
780
780
  describe 'using a quote in the middle of a parameter raises an error' do
781
781
  let(:template) { "Message: {{hello wo\"rld\"}}" }
782
782
  example do
783
- -> { subject }.should raise_error
783
+ expect { subject }.to raise_error(RLTK::NotInLanguage)
784
784
  end
785
785
  end
786
786
 
@@ -792,7 +792,7 @@ describe FlavourSaver do
792
792
  end
793
793
  end
794
794
  example do
795
- subject.should == 'Message: Hello \"world\"'
795
+ expect(subject).to eq 'Message: Hello \"world\"'
796
796
  end
797
797
  end
798
798
 
@@ -804,7 +804,7 @@ describe FlavourSaver do
804
804
  end
805
805
  end
806
806
  example do
807
- subject.should == "Message: Hello Alan's world"
807
+ expect(subject).to eq "Message: Hello Alan's world"
808
808
  end
809
809
  end
810
810
 
@@ -815,9 +815,9 @@ describe FlavourSaver do
815
815
  let(:template) { "Message: {{goodbye cruel world}}" }
816
816
  before { FS.register_helper(:goodbye) { |cruel,world| "Goodbye #{cruel} #{world}" } }
817
817
  example do
818
- context.stub(:cruel).and_return('cruel')
819
- context.stub(:world).and_return('world')
820
- subject.should == "Message: Goodbye cruel world"
818
+ allow(context).to receive(:cruel).and_return('cruel')
819
+ allow(context).to receive(:world).and_return('world')
820
+ expect(subject).to eq "Message: Goodbye cruel world"
821
821
  end
822
822
  end
823
823
 
@@ -825,9 +825,9 @@ describe FlavourSaver do
825
825
  let(:template) { "Message: {{#goodbye cruel world}}{{greeting}} {{adj}} {{noun}}{{/goodbye}}" }
826
826
  before { FS.register_helper(:goodbye) { |adj,noun,&b| b.call.contents Struct.new(:greeting,:adj,:noun).new('Goodbye', adj, noun) } }
827
827
  example do
828
- context.stub(:cruel).and_return('cruel')
829
- context.stub(:world).and_return('world')
830
- subject.should == "Message: Goodbye cruel world"
828
+ allow(context).to receive(:cruel).and_return('cruel')
829
+ allow(context).to receive(:world).and_return('world')
830
+ expect(subject).to eq "Message: Goodbye cruel world"
831
831
  end
832
832
  end
833
833
  end
@@ -836,8 +836,8 @@ describe FlavourSaver do
836
836
  describe 'with' do
837
837
  let(:template) { "{{#with person}}{{first}} {{last}}{{/with}}" }
838
838
  example do
839
- context.stub(:person).and_return(Struct.new(:first,:last).new('Alan','Johnson'))
840
- subject.should == 'Alan Johnson'
839
+ allow(context).to receive(:person).and_return(Struct.new(:first,:last).new('Alan','Johnson'))
840
+ expect(subject).to eq 'Alan Johnson'
841
841
  end
842
842
  end
843
843
 
@@ -845,39 +845,39 @@ describe FlavourSaver do
845
845
  let(:template) { "{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!" }
846
846
 
847
847
  example 'if with boolean argument shows the contents when true' do
848
- context.stub(:goodbye).and_return(true)
849
- context.stub(:world).and_return('world')
850
- subject.should == "GOODBYE cruel world!"
848
+ allow(context).to receive(:goodbye).and_return(true)
849
+ allow(context).to receive(:world).and_return('world')
850
+ expect(subject).to eq "GOODBYE cruel world!"
851
851
  end
852
852
 
853
853
  example 'if with string argument shows the contents with true' do
854
- context.stub(:goodbye).and_return('dummy')
855
- context.stub(:world).and_return('world')
856
- subject.should == "GOODBYE cruel world!"
854
+ allow(context).to receive(:goodbye).and_return('dummy')
855
+ allow(context).to receive(:world).and_return('world')
856
+ expect(subject).to eq "GOODBYE cruel world!"
857
857
  end
858
858
 
859
859
  example 'if with boolean argument does not show the contents when false' do
860
- context.stub(:goodbye).and_return(false)
861
- context.stub(:world).and_return('world')
862
- subject.should == "cruel world!"
860
+ allow(context).to receive(:goodbye).and_return(false)
861
+ allow(context).to receive(:world).and_return('world')
862
+ expect(subject).to eq "cruel world!"
863
863
  end
864
864
 
865
865
  example 'if with undefined does not show the contents' do
866
- context.stub(:goodbye)
867
- context.stub(:world).and_return('world')
868
- subject.should == "cruel world!"
866
+ allow(context).to receive(:goodbye)
867
+ allow(context).to receive(:world).and_return('world')
868
+ expect(subject).to eq "cruel world!"
869
869
  end
870
870
 
871
871
  example 'if with non-empty array shows the contents' do
872
- context.stub(:goodbye).and_return(['foo'])
873
- context.stub(:world).and_return('world')
874
- subject.should == "GOODBYE cruel world!"
872
+ allow(context).to receive(:goodbye).and_return(['foo'])
873
+ allow(context).to receive(:world).and_return('world')
874
+ expect(subject).to eq "GOODBYE cruel world!"
875
875
  end
876
876
 
877
877
  example 'if with empty array does not show the contents' do
878
- context.stub(:goodbye).and_return([])
879
- context.stub(:world).and_return('world')
880
- subject.should == "cruel world!"
878
+ allow(context).to receive(:goodbye).and_return([])
879
+ allow(context).to receive(:world).and_return('world')
880
+ expect(subject).to eq "cruel world!"
881
881
  end
882
882
  end
883
883
 
@@ -886,15 +886,15 @@ describe FlavourSaver do
886
886
 
887
887
  example 'each with array iterates over the contents with non-empty' do
888
888
  g = Struct.new(:text)
889
- context.stub(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
890
- context.stub(:world).and_return('world')
891
- subject.should == "goodbye! Goodbye! GOODBYE! cruel world!"
889
+ allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
890
+ allow(context).to receive(:world).and_return('world')
891
+ expect(subject).to eq "goodbye! Goodbye! GOODBYE! cruel world!"
892
892
  end
893
893
 
894
894
  example 'each with array ignores the contents when empty' do
895
- context.stub(:goodbyes).and_return([])
896
- context.stub(:world).and_return('world')
897
- subject.should == "cruel world!"
895
+ allow(context).to receive(:goodbyes).and_return([])
896
+ allow(context).to receive(:world).and_return('world')
897
+ expect(subject).to eq "cruel world!"
898
898
  end
899
899
  end
900
900
 
@@ -903,9 +903,94 @@ describe FlavourSaver do
903
903
 
904
904
  example 'the @index variable is used' do
905
905
  g = Struct.new(:text)
906
- context.stub(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
907
- context.stub(:world).and_return('world')
908
- subject.should == "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!"
906
+ allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
907
+ allow(context).to receive(:world).and_return('world')
908
+ expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!"
909
+ end
910
+ end
911
+
912
+ describe 'each with @index in a nested block' do
913
+ let(:template) { "{{#each goodbyes}}{{#if @last}}{{@index}}. {{/if}}{{text}}! {{/each}}cruel {{world}}!" }
914
+
915
+ example 'the @index variable is used' do
916
+ g = Struct.new(:text)
917
+ allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
918
+ allow(context).to receive(:world).and_return('world')
919
+ expect(subject).to eq "goodbye! Goodbye! 2. GOODBYE! cruel world!"
920
+ end
921
+ end
922
+
923
+ describe 'each with @last' do
924
+ let(:template) { "{{#each goodbyes}}{{@index}}. {{text}}! {{#if @last}}last{{/if}}{{/each}} cruel {{world}}!" }
925
+
926
+ example 'the @last variable is used' do
927
+ g = Struct.new(:text)
928
+ allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
929
+ allow(context).to receive(:world).and_return('world')
930
+ expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE! last cruel world!"
931
+ end
932
+ end
933
+
934
+ describe 'each with @first' do
935
+ let(:template) { "{{#each goodbyes}}{{@index}}. {{text}} {{#if @first}}first{{/if}}! {{/each}}cruel {{world}}!" }
936
+
937
+ example 'the first variable is used' do
938
+ g = Struct.new(:text)
939
+ allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
940
+ allow(context).to receive(:world).and_return('world')
941
+ expect(subject).to eq "0. goodbye first! 1. Goodbye ! 2. GOODBYE ! cruel world!"
942
+ end
943
+ end
944
+
945
+ describe 'each with @root' do
946
+ let(:template) { "{{#each goodbyes}}{{@index}}. {{text}} cruel {{@root.place}}! {{/each}}" }
947
+
948
+ example 'the root variable is used' do
949
+ g = Struct.new(:text)
950
+ allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
951
+ allow(context).to receive(:place).and_return('world')
952
+ expect(subject).to eq "0. goodbye cruel world! 1. Goodbye cruel world! 2. GOODBYE cruel world! "
953
+ end
954
+ end
955
+
956
+ describe 'each with @root in a nested block' do
957
+ let(:template) { "{{#each goodbyes}}{{@index}}. {{text}}{{#if @last}} cruel {{@root.place}}{{/if}}! {{/each}}" }
958
+
959
+ example 'the root variable is used' do
960
+ g = Struct.new(:text)
961
+ allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
962
+ allow(context).to receive(:place).and_return('world')
963
+ expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE cruel world! "
964
+ end
965
+ end
966
+
967
+ describe 'each with @key' do
968
+ let(:template) { "{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!" }
969
+
970
+ example 'the @key variable is used' do
971
+ g = Struct.new(:text)
972
+ allow(context).to receive(:goodbyes).and_return({
973
+ one: g.new('goodbye'),
974
+ two: g.new('Goodbye'),
975
+ three: g.new('GOODBYE')
976
+ })
977
+ allow(context).to receive(:world).and_return('world')
978
+ expect(subject).to eq "one. goodbye! two. Goodbye! three. GOODBYE! cruel world!"
979
+ end
980
+ end
981
+
982
+ describe 'each with @key in a nested block' do
983
+ let(:template) { "{{#each goodbyes}}{{#if @last}}{{@key}}. {{/if}}{{text}}! {{/each}}cruel {{world}}!" }
984
+
985
+ example 'the @key variable is used' do
986
+ g = Struct.new(:text)
987
+ allow(context).to receive(:goodbyes).and_return({
988
+ one: g.new('goodbye'),
989
+ two: g.new('Goodbye'),
990
+ three: g.new('GOODBYE')
991
+ })
992
+ allow(context).to receive(:world).and_return('world')
993
+ expect(subject).to eq "goodbye! Goodbye! three. GOODBYE! cruel world!"
909
994
  end
910
995
  end
911
996
 
@@ -915,9 +1000,9 @@ describe FlavourSaver do
915
1000
  before { FS.logger = log }
916
1001
  after { FS.logger = nil }
917
1002
  example do
918
- context.stub(:blah).and_return('whee')
919
- log.should_receive(:debug).with('FlavourSaver: whee')
920
- subject.should == ''
1003
+ allow(context).to receive(:blah).and_return('whee')
1004
+ expect(log).to receive(:debug).with('FlavourSaver: whee')
1005
+ expect(subject).to eq ''
921
1006
  end
922
1007
  end
923
1008
  end