flavour_saver 4.0.2 → 5.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +14 -0
  3. data/.standard.yml +1 -0
  4. data/CHANGELOG.md +57 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +48 -5
  7. data/README.md +153 -271
  8. data/flavour_saver.gemspec +17 -19
  9. data/lib/flavour_saver/error.rb +5 -0
  10. data/lib/flavour_saver/helpers.rb +19 -18
  11. data/lib/flavour_saver/lexer.rb +123 -50
  12. data/lib/flavour_saver/nodes.rb +107 -19
  13. data/lib/flavour_saver/parser.rb +339 -161
  14. data/lib/flavour_saver/partial.rb +4 -6
  15. data/lib/flavour_saver/rails_partial.rb +10 -4
  16. data/lib/flavour_saver/runtime.rb +76 -81
  17. data/lib/flavour_saver/template.rb +3 -5
  18. data/lib/flavour_saver/version.rb +1 -1
  19. data/lib/flavour_saver.rb +17 -17
  20. data/spec/acceptance/backtrack_spec.rb +9 -9
  21. data/spec/acceptance/comment_spec.rb +7 -7
  22. data/spec/acceptance/custom_block_helper_spec.rb +12 -12
  23. data/spec/acceptance/custom_helper_spec.rb +8 -8
  24. data/spec/acceptance/ensure_no_rce_spec.rb +64 -53
  25. data/spec/acceptance/handlebars_qunit_spec.rb +295 -297
  26. data/spec/acceptance/if_else_spec.rb +6 -6
  27. data/spec/acceptance/multi_level_with_spec.rb +10 -11
  28. data/spec/acceptance/nesting_depth_spec.rb +34 -0
  29. data/spec/acceptance/one_character_identifier_spec.rb +8 -8
  30. data/spec/acceptance/raw_block_spec.rb +7 -7
  31. data/spec/acceptance/sections_spec.rb +17 -14
  32. data/spec/acceptance/segment_literals_spec.rb +5 -5
  33. data/spec/acceptance/simple_expression_spec.rb +9 -9
  34. data/spec/acceptance/subexpression_spec.rb +18 -17
  35. data/spec/acceptance/unless_spec.rb +19 -6
  36. data/spec/lib/flavour_saver/lexer_spec.rb +103 -89
  37. data/spec/lib/flavour_saver/nodes_spec.rb +85 -0
  38. data/spec/lib/flavour_saver/parser_spec.rb +155 -95
  39. data/spec/lib/flavour_saver/runtime_spec.rb +94 -96
  40. data/spec/lib/flavour_saver/template_spec.rb +1 -2
  41. metadata +19 -48
@@ -2,10 +2,10 @@
2
2
  # to run against FlavourSaver. Yes, this is a more brittle way of
3
3
  # doing it.
4
4
 
5
- require 'active_support'
6
- ActiveSupport::SafeBuffer
5
+ require "active_support"
6
+ require "active_support/core_ext/string/output_safety"
7
7
 
8
- require 'flavour_saver'
8
+ require "flavour_saver"
9
9
 
10
10
  describe FlavourSaver do
11
11
  let(:context) { double(:context) }
@@ -18,85 +18,85 @@ describe FlavourSaver do
18
18
  describe "basic context" do
19
19
  before { FS.register_helper(:link_to) { "<a>#{context}</a>" } }
20
20
 
21
- describe 'most basic' do
21
+ describe "most basic" do
22
22
  let(:template) { "{{foo}}" }
23
23
 
24
24
  it 'returns "foo"' do
25
- allow(context).to receive(:foo).and_return('foo')
26
- expect(subject).to eq 'foo'
25
+ allow(context).to receive(:foo).and_return("foo")
26
+ expect(subject).to eq "foo"
27
27
  end
28
28
  end
29
29
 
30
- describe 'compiling with a basic context' do
30
+ describe "compiling with a basic context" do
31
31
  let(:template) { "Goodbye\n{{cruel}}\n{{world}}!" }
32
32
 
33
- it 'it works if all the required keys are provided' do
34
- expect(context).to receive(:cruel).and_return('cruel')
35
- expect(context).to receive(:world).and_return('world')
33
+ it "it works if all the required keys are provided" do
34
+ expect(context).to receive(:cruel).and_return("cruel")
35
+ expect(context).to receive(:world).and_return("world")
36
36
  expect(subject).to eq "Goodbye\ncruel\nworld!"
37
37
  end
38
38
  end
39
39
 
40
- describe 'comments' do
41
- let(:template) {"{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!"}
40
+ describe "comments" do
41
+ let(:template) { "{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!" }
42
42
 
43
- it 'comments are ignored' do
44
- expect(context).to receive(:cruel).and_return('cruel')
45
- expect(context).to receive(:world).and_return('world')
43
+ it "comments are ignored" do
44
+ expect(context).to receive(:cruel).and_return("cruel")
45
+ expect(context).to receive(:world).and_return("world")
46
46
  expect(subject).to eq "Goodbye\ncruel\nworld!"
47
47
  end
48
48
  end
49
49
 
50
- describe 'boolean' do
50
+ describe "boolean" do
51
51
  let(:template) { "{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!" }
52
52
 
53
- it 'booleans show the contents when true' do
53
+ it "booleans show the contents when true" do
54
54
  allow(context).to receive(:goodbye).and_return(true)
55
- allow(context).to receive(:world).and_return('world')
55
+ allow(context).to receive(:world).and_return("world")
56
56
  expect(subject).to eq "GOODBYE cruel world!"
57
57
  end
58
58
 
59
- it 'booleans do not show the contents when false' do
59
+ it "booleans do not show the contents when false" do
60
60
  allow(context).to receive(:goodbye).and_return(false)
61
- allow(context).to receive(:world).and_return('world')
61
+ allow(context).to receive(:world).and_return("world")
62
62
  expect(subject).to eq "cruel world!"
63
63
  end
64
64
  end
65
65
 
66
- describe 'zeros' do
67
- describe '{num1: 42, num2: 0}' do
68
- let (:template) { "num1: {{num1}}, num2: {{num2}}" }
66
+ describe "zeros" do
67
+ describe "{num1: 42, num2: 0}" do
68
+ let(:template) { "num1: {{num1}}, num2: {{num2}}" }
69
69
 
70
70
  it 'should compile to "num1: 42, num2: 0"' do
71
71
  allow(context).to receive(:num1).and_return(42)
72
72
  allow(context).to receive(:num2).and_return(0)
73
- expect(subject).to eq 'num1: 42, num2: 0'
73
+ expect(subject).to eq "num1: 42, num2: 0"
74
74
  end
75
75
  end
76
76
 
77
77
  describe 0 do
78
- let (:template) { 'num: {{.}}' }
78
+ let(:template) { "num: {{.}}" }
79
79
 
80
80
  it 'should compile to "num: 0"' do
81
- expect(FlavourSaver.evaluate(template,0)).to eq 'num: 0'
81
+ expect(FlavourSaver.evaluate(template, 0)).to eq "num: 0"
82
82
  end
83
83
  end
84
84
 
85
- describe '{num1: {num2: 0}}' do
86
- let(:template) { 'num: {{num1/num2}}' }
85
+ describe "{num1: {num2: 0}}" do
86
+ let(:template) { "num: {{num1/num2}}" }
87
87
 
88
88
  it 'should compile to "num: 0"' do
89
89
  allow(context).to receive_message_chain(:num1, :num2).and_return(0)
90
- expect(subject).to eq 'num: 0'
90
+ expect(subject).to eq "num: 0"
91
91
  end
92
92
  end
93
93
  end
94
94
 
95
- describe 'newlines' do
95
+ describe "newlines" do
96
96
  describe '\n' do
97
97
  let(:template) { "Alan's\nTest" }
98
98
 
99
- it 'works' do
99
+ it "works" do
100
100
  expect(subject).to eq "Alan's\nTest"
101
101
  end
102
102
  end
@@ -104,22 +104,22 @@ describe FlavourSaver do
104
104
  describe '\r' do
105
105
  let(:template) { "Alan's\rTest" }
106
106
 
107
- it 'works' do
107
+ it "works" do
108
108
  expect(subject).to eq "Alan's\rTest"
109
109
  end
110
110
  end
111
111
  end
112
112
 
113
- describe 'esaping text' do
114
- describe 'apostrophes' do
115
- let(:template) {"Awesome's"}
113
+ describe "esaping text" do
114
+ describe "apostrophes" do
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
118
  expect(subject).to eq "Awesome's"
119
119
  end
120
120
  end
121
121
 
122
- describe 'backslashes' do
122
+ describe "backslashes" do
123
123
  let(:template) { "Awesome \\" }
124
124
 
125
125
  it "text is escaped so that the closing quote can't be ignored" do
@@ -127,7 +127,7 @@ describe FlavourSaver do
127
127
  end
128
128
  end
129
129
 
130
- describe 'more backslashes' do
130
+ describe "more backslashes" 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
@@ -135,16 +135,16 @@ describe FlavourSaver do
135
135
  end
136
136
  end
137
137
 
138
- describe 'helper output containing backslashes' do
138
+ describe "helper output containing backslashes" 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
- allow(context).to receive(:foo).and_return('\\')
142
+ allow(context).to receive(:foo).and_return("\\")
143
143
  expect(subject).to eq "Awesome \\"
144
144
  end
145
145
  end
146
146
 
147
- describe 'doubled quotes' do
147
+ describe "doubled quotes" do
148
148
  let(:template) { ' " " ' }
149
149
 
150
150
  it "double quotes never produce invalid javascript" do
@@ -153,8 +153,8 @@ describe FlavourSaver do
153
153
  end
154
154
  end
155
155
 
156
- describe 'escaping expressions' do
157
- describe 'expressions with 3 handlebars' do
156
+ describe "escaping expressions" do
157
+ describe "expressions with 3 handlebars" do
158
158
  let(:template) { "{{{awesome}}}" }
159
159
 
160
160
  it "shouldn't be escaped" do
@@ -163,7 +163,7 @@ describe FlavourSaver do
163
163
  end
164
164
  end
165
165
 
166
- describe 'expressions with {{& handlebars' do
166
+ describe "expressions with {{& handlebars" do
167
167
  let(:template) { "{{&awesome}}" }
168
168
 
169
169
  it "shouldn't be escaped" do
@@ -172,12 +172,12 @@ describe FlavourSaver do
172
172
  end
173
173
  end
174
174
 
175
- describe 'expressions' do
175
+ describe "expressions" do
176
176
  let(:template) { "{{awesome}}" }
177
177
 
178
178
  it "should be escaped" do
179
179
  allow(context).to receive(:awesome).and_return("&\"'`\\<>")
180
- if RUBY_VERSION >= '2.0.0'
180
+ if RUBY_VERSION >= "2.0.0"
181
181
  expect(subject).to eq "&amp;&quot;&#39;&#x60;\\&lt;&gt;"
182
182
  else
183
183
  expect(subject).to eq "&amp;&quot;&#x27;&#x60;\\&lt;&gt;"
@@ -185,7 +185,7 @@ describe FlavourSaver do
185
185
  end
186
186
  end
187
187
 
188
- describe 'ampersands' do
188
+ describe "ampersands" do
189
189
  let(:template) { "{{awesome}}" }
190
190
 
191
191
  it "should be escaped" do
@@ -204,7 +204,7 @@ describe FlavourSaver do
204
204
  end
205
205
  end
206
206
 
207
- describe 'functions' do
207
+ describe "functions" do
208
208
  let(:template) { "{{awesome}}" }
209
209
 
210
210
  it "are called and render their output" do
@@ -213,127 +213,127 @@ describe FlavourSaver do
213
213
  end
214
214
  end
215
215
 
216
- describe 'paths with hyphens' do
217
- describe '{{foo-bar}}' do
216
+ describe "paths with hyphens" do
217
+ describe "{{foo-bar}}" do
218
218
  let(:template) { "{{foo-bar}}" }
219
219
 
220
- it 'paths can contain hyphens (-)' do
221
- expect(context).to receive(:[]).with('foo-bar').and_return('baz')
222
- expect(subject).to eq 'baz'
220
+ it "paths can contain hyphens (-)" do
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
 
226
- describe '{{foo.foo-bar}}' do
226
+ describe "{{foo.foo-bar}}" do
227
227
  let(:template) { "{{foo.foo-bar}}" }
228
228
 
229
- it 'paths can contain hyphens (-)' do
230
- allow(context).to receive_message_chain(:foo, :[]).with('foo-bar').and_return(proc { 'baz' })
231
- expect(subject).to eq 'baz'
229
+ it "paths can contain hyphens (-)" do
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
 
235
- describe '{{foo/foo-bar}}' do
235
+ describe "{{foo/foo-bar}}" do
236
236
  let(:template) { "{{foo/foo-bar}}" }
237
237
 
238
- it 'paths can contain hyphens (-)' do
239
- allow(context).to receive_message_chain(:foo, :[]).with('foo-bar').and_return('baz')
240
- expect(subject).to eq 'baz'
238
+ it "paths can contain hyphens (-)" do
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
 
244
- describe 'nested paths' do
245
- let(:template) {"Goodbye {{alan/expression}} world!"}
244
+ describe "nested paths" do
245
+ let(:template) { "Goodbye {{alan/expression}} world!" }
246
246
 
247
- it 'access nested object' do
248
- allow(context).to receive_message_chain(:alan, :expression).and_return('beautiful')
249
- expect(subject).to eq 'Goodbye beautiful world!'
247
+ it "access nested object" do
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
 
253
- describe 'nested path with empty string value' do
254
- let(:template) {"Goodbye {{alan/expression}} world!"}
253
+ describe "nested path with empty string value" do
254
+ let(:template) { "Goodbye {{alan/expression}} world!" }
255
255
 
256
- it 'access nested object' do
257
- allow(context).to receive_message_chain(:alan, :expression).and_return('')
258
- expect(subject).to eq 'Goodbye world!'
256
+ it "access nested object" do
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
 
262
- describe 'literal paths' do
262
+ describe "literal paths" do
263
263
  let(:template) { "Goodbye {{[@alan]/expression}} world!" }
264
264
 
265
- it 'literal paths can be used' do
265
+ it "literal paths can be used" do
266
266
  alan = double(:alan)
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!'
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
 
273
- describe 'complex but empty paths' do
274
- let(:template) { '{{person/name}}' }
273
+ describe "complex but empty paths" do
274
+ let(:template) { "{{person/name}}" }
275
275
 
276
- it 'returns empty string from nested paths' do
277
- allow(context).to receive_message_chain(:person,:name).and_return('')
278
- expect(subject).to eq ''
276
+ it "returns empty string from nested paths" do
277
+ allow(context).to receive_message_chain(:person, :name).and_return("")
278
+ expect(subject).to eq ""
279
279
  end
280
280
 
281
- it 'returns empty string from nil objects' do
282
- allow(context).to receive_message_chain(:person,:name)
283
- expect(subject).to eq ''
281
+ it "returns empty string from nil objects" do
282
+ allow(context).to receive_message_chain(:person, :name)
283
+ expect(subject).to eq ""
284
284
  end
285
285
  end
286
286
 
287
287
  describe '"this" keyword' do
288
- describe 'in a block' do
288
+ describe "in a block" do
289
289
  let(:template) { "{{#goodbyes}}{{this}}{{/goodbyes}}" }
290
290
 
291
- it 'evaluates to the current context' do
291
+ it "evaluates to the current context" do
292
292
  allow(context).to receive(:goodbyes).and_return(["goodbye", "Goodbye", "GOODBYE"])
293
293
  expect(subject).to eq "goodbyeGoodbyeGOODBYE"
294
294
  end
295
295
  end
296
296
 
297
- describe 'in a block in a path' do
297
+ describe "in a block in a path" do
298
298
  let(:template) { "{{#hellos}}{{this/text}}{{/hellos}}" }
299
299
 
300
- it 'evaluates in more complex paths' do
300
+ it "evaluates in more complex paths" do
301
301
  hellos = []
302
302
  hellos << double(:hello)
303
- expect(hellos[0]).to receive(:text).and_return('hello')
303
+ expect(hellos[0]).to receive(:text).and_return("hello")
304
304
  hellos << double(:Hello)
305
- expect(hellos[1]).to receive(:text).and_return('Hello')
305
+ expect(hellos[1]).to receive(:text).and_return("Hello")
306
306
  hellos << double(:HELLO)
307
- expect(hellos[2]).to receive(:text).and_return('HELLO')
307
+ expect(hellos[2]).to receive(:text).and_return("HELLO")
308
308
  allow(context).to receive(:hellos).and_return(hellos)
309
309
  expect(subject).to eq "helloHelloHELLO"
310
310
  end
311
311
  end
312
312
  end
313
313
 
314
- describe 'this keyword in helpers' do
314
+ describe "this keyword in helpers" do
315
315
  before { FS.register_helper(:foo) { |value| "bar #{value}" } }
316
316
 
317
- describe 'this keyword in arguments' do
317
+ describe "this keyword in arguments" do
318
318
  let(:template) { "{{#goodbyes}}{{foo this}}{{/goodbyes}}" }
319
319
 
320
- it 'evaluates to current context' do
320
+ it "evaluates to current context" do
321
321
  allow(context).to receive(:goodbyes).and_return(["goodbye", "Goodbye", "GOODBYE"])
322
322
  expect(subject).to eq "bar goodbyebar Goodbyebar GOODBYE"
323
323
  end
324
324
  end
325
325
 
326
- describe 'this keyword in object path arguments' do
326
+ describe "this keyword in object path arguments" do
327
327
  let(:template) { "{{#hellos}}{{foo this/text}}{{/hellos}}" }
328
328
 
329
- it 'evaluates to current context' do
329
+ it "evaluates to current context" do
330
330
  hellos = []
331
331
  hellos << double(:hello)
332
- expect(hellos[0]).to receive(:text).and_return('hello')
332
+ expect(hellos[0]).to receive(:text).and_return("hello")
333
333
  hellos << double(:Hello)
334
- expect(hellos[1]).to receive(:text).and_return('Hello')
334
+ expect(hellos[1]).to receive(:text).and_return("Hello")
335
335
  hellos << double(:HELLO)
336
- expect(hellos[2]).to receive(:text).and_return('HELLO')
336
+ expect(hellos[2]).to receive(:text).and_return("HELLO")
337
337
  allow(context).to receive(:hellos).and_return(hellos)
338
338
  expect(subject).to eq "bar hellobar Hellobar HELLO"
339
339
  end
@@ -342,208 +342,208 @@ describe FlavourSaver do
342
342
  end
343
343
  end
344
344
 
345
- describe 'Inverted sections' do
345
+ describe "Inverted sections" do
346
346
  let(:template) { "{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}" }
347
347
 
348
- describe 'with unset value' do
349
- it 'renders' do
348
+ describe "with unset value" do
349
+ it "renders" do
350
350
  allow(context).to receive(:goodbyes)
351
- expect(subject).to eq 'Right On!'
351
+ expect(subject).to eq "Right On!"
352
352
  end
353
353
  end
354
354
 
355
- describe 'with false value' do
356
- it 'renders' do
355
+ describe "with false value" do
356
+ it "renders" do
357
357
  allow(context).to receive(:goodbyes).and_return(false)
358
- expect(subject).to eq 'Right On!'
358
+ expect(subject).to eq "Right On!"
359
359
  end
360
360
  end
361
361
 
362
- describe 'with an empty set' do
363
- it 'renders' do
362
+ describe "with an empty set" do
363
+ it "renders" do
364
364
  allow(context).to receive(:goodbyes).and_return([])
365
- expect(subject).to eq 'Right On!'
365
+ expect(subject).to eq "Right On!"
366
366
  end
367
367
  end
368
368
  end
369
369
 
370
- describe 'Blocks' do
370
+ describe "Blocks" do
371
371
  let(:template) { "{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!" }
372
372
 
373
- it 'arrays iterate the contents with non-empty' do
373
+ it "arrays iterate the contents with non-empty" do
374
374
  goodbyes = []
375
375
  goodbyes << double(:goodbye)
376
- expect(goodbyes[0]).to receive(:text).and_return('goodbye')
376
+ expect(goodbyes[0]).to receive(:text).and_return("goodbye")
377
377
  goodbyes << double(:Goodbye)
378
- expect(goodbyes[1]).to receive(:text).and_return('Goodbye')
378
+ expect(goodbyes[1]).to receive(:text).and_return("Goodbye")
379
379
  goodbyes << double(:GOODBYE)
380
- expect(goodbyes[2]).to receive(:text).and_return('GOODBYE')
380
+ expect(goodbyes[2]).to receive(:text).and_return("GOODBYE")
381
381
  allow(context).to receive(:goodbyes).and_return(goodbyes)
382
- allow(context).to receive(:world).and_return('world')
382
+ allow(context).to receive(:world).and_return("world")
383
383
  expect(subject).to eq "goodbye! Goodbye! GOODBYE! cruel world!"
384
384
  end
385
385
 
386
- it 'ignores the contents when the array is empty' do
386
+ it "ignores the contents when the array is empty" do
387
387
  allow(context).to receive(:goodbyes).and_return([])
388
- allow(context).to receive(:world).and_return('world')
388
+ allow(context).to receive(:world).and_return("world")
389
389
  expect(subject).to eq "cruel world!"
390
390
  end
391
391
 
392
- describe 'array with @index' do
393
- let(:template) {"{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!"}
392
+ describe "array with @index" do
393
+ let(:template) { "{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!" }
394
394
 
395
- it 'the @index variable is used' do
395
+ it "the @index variable is used" do
396
396
  goodbyes = []
397
397
  goodbyes << double(:goodbye)
398
- expect(goodbyes[0]).to receive(:text).and_return('goodbye')
398
+ expect(goodbyes[0]).to receive(:text).and_return("goodbye")
399
399
  goodbyes << double(:Goodbye)
400
- expect(goodbyes[1]).to receive(:text).and_return('Goodbye')
400
+ expect(goodbyes[1]).to receive(:text).and_return("Goodbye")
401
401
  goodbyes << double(:GOODBYE)
402
- expect(goodbyes[2]).to receive(:text).and_return('GOODBYE')
402
+ expect(goodbyes[2]).to receive(:text).and_return("GOODBYE")
403
403
  allow(context).to receive(:goodbyes).and_return(goodbyes)
404
- allow(context).to receive(:world).and_return('world')
404
+ allow(context).to receive(:world).and_return("world")
405
405
  expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!"
406
406
  end
407
407
  end
408
408
 
409
- describe 'array with numeric dereference' do
410
- let(:template) {"{{goodbyes.0.text}} cruel {{world}}!"}
409
+ describe "array with numeric dereference" do
410
+ let(:template) { "{{goodbyes.0.text}} cruel {{world}}!" }
411
411
 
412
- it 'properly inserts the referenced element' do
412
+ it "properly inserts the referenced element" do
413
413
  goodbyes = []
414
414
  goodbyes << double(:goodbye)
415
- expect(goodbyes[0]).to receive(:text).and_return('goodbye')
415
+ expect(goodbyes[0]).to receive(:text).and_return("goodbye")
416
416
 
417
417
  allow(context).to receive(:goodbyes).and_return(goodbyes)
418
- allow(context).to receive(:world).and_return('world')
418
+ allow(context).to receive(:world).and_return("world")
419
419
 
420
420
  expect(subject).to eq "goodbye cruel world!"
421
421
  end
422
422
  end
423
423
 
424
- describe 'empty block' do
424
+ describe "empty block" do
425
425
  let(:template) { "{{#goodbyes}}{{/goodbyes}}cruel {{world}}!" }
426
426
 
427
- it 'arrays iterate the contents with non-empty' do
427
+ it "arrays iterate the contents with non-empty" do
428
428
  goodbyes = []
429
429
  goodbyes << double(:goodbye)
430
- allow(goodbyes[0]).to receive(:text).and_return('goodbye')
430
+ allow(goodbyes[0]).to receive(:text).and_return("goodbye")
431
431
  goodbyes << double(:Goodbye)
432
- allow(goodbyes[1]).to receive(:text).and_return('Goodbye')
432
+ allow(goodbyes[1]).to receive(:text).and_return("Goodbye")
433
433
  goodbyes << double(:GOODBYE)
434
- allow(goodbyes[2]).to receive(:text).and_return('GOODBYE')
434
+ allow(goodbyes[2]).to receive(:text).and_return("GOODBYE")
435
435
  allow(context).to receive(:goodbyes).and_return(goodbyes)
436
- allow(context).to receive(:world).and_return('world')
436
+ allow(context).to receive(:world).and_return("world")
437
437
  expect(subject).to eq "cruel world!"
438
438
  end
439
439
 
440
- it 'ignores the contents when the array is empty' do
440
+ it "ignores the contents when the array is empty" do
441
441
  allow(context).to receive(:goodbyes).and_return([])
442
- allow(context).to receive(:world).and_return('world')
442
+ allow(context).to receive(:world).and_return("world")
443
443
  expect(subject).to eq "cruel world!"
444
444
  end
445
445
  end
446
446
 
447
- describe 'nested iteration'
447
+ describe "nested iteration"
448
448
 
449
- describe 'block with complex lookup' do
450
- let(:template) {"{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}"}
449
+ describe "block with complex lookup" do
450
+ let(:template) { "{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}" }
451
451
 
452
- it 'templates can access variables in contexts up the stack with relative path syntax' do
453
- allow(context).to receive(:name).and_return('Alan')
452
+ it "templates can access variables in contexts up the stack with relative path syntax" do
453
+ allow(context).to receive(:name).and_return("Alan")
454
454
  goodbyes = []
455
455
  goodbyes << double(:goodbye)
456
- expect(goodbyes[0]).to receive(:text).and_return('goodbye')
456
+ expect(goodbyes[0]).to receive(:text).and_return("goodbye")
457
457
  goodbyes << double(:Goodbye)
458
- expect(goodbyes[1]).to receive(:text).and_return('Goodbye')
458
+ expect(goodbyes[1]).to receive(:text).and_return("Goodbye")
459
459
  goodbyes << double(:GOODBYE)
460
- expect(goodbyes[2]).to receive(:text).and_return('GOODBYE')
460
+ expect(goodbyes[2]).to receive(:text).and_return("GOODBYE")
461
461
  allow(context).to receive(:goodbyes).and_return(goodbyes)
462
462
  expect(subject).to eq "goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! "
463
463
  end
464
464
  end
465
465
 
466
- describe 'helper with complex lookup' do
467
- let(:template) {"{{#goodbyes}}{{{link ../prefix}}}{{/goodbyes}}"}
466
+ describe "helper with complex lookup" do
467
+ let(:template) { "{{#goodbyes}}{{{link ../prefix}}}{{/goodbyes}}" }
468
468
  before do
469
469
  FS.register_helper(:link) do |prefix|
470
470
  "<a href='#{prefix}/#{url}'>#{text}</a>"
471
471
  end
472
472
  end
473
473
 
474
- it 'renders correctly' do
475
- allow(context).to receive(:prefix).and_return('/root')
474
+ it "renders correctly" do
475
+ allow(context).to receive(:prefix).and_return("/root")
476
476
  goodbyes = []
477
477
  goodbyes << double(:Goodbye)
478
- expect(goodbyes[0]).to receive(:text).and_return('Goodbye')
479
- expect(goodbyes[0]).to receive(:url).and_return('goodbye')
478
+ expect(goodbyes[0]).to receive(:text).and_return("Goodbye")
479
+ expect(goodbyes[0]).to receive(:url).and_return("goodbye")
480
480
  allow(context).to receive(:goodbyes).and_return(goodbyes)
481
481
  expect(subject).to eq "<a href='/root/goodbye'>Goodbye</a>"
482
482
  end
483
483
  end
484
484
 
485
- describe 'helper with complex lookup expression' do
485
+ describe "helper with complex lookup expression" do
486
486
  let(:template) { "{{#goodbyes}}{{../name}}{{/goodbyes}}" }
487
487
  before do
488
488
  FS.register_helper(:goodbyes) do |&b|
489
489
  ["Goodbye", "goodbye", "GOODBYE"].map do |bye|
490
490
  "#{bye} #{b.call.contents}! "
491
- end.join('')
491
+ end.join("")
492
492
  end
493
493
  end
494
494
 
495
- it 'renders correctly' do
496
- allow(context).to receive(:name).and_return('Alan')
495
+ it "renders correctly" do
496
+ allow(context).to receive(:name).and_return("Alan")
497
497
  expect(subject).to eq "Goodbye Alan! goodbye Alan! GOODBYE Alan! "
498
498
  end
499
499
  end
500
500
 
501
- describe 'helper with complex lookup and nested template' do
501
+ describe "helper with complex lookup and nested template" do
502
502
  let(:template) { "{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}" }
503
503
  before do
504
- FS.register_helper(:link) do |prefix,&b|
504
+ FS.register_helper(:link) do |prefix, &b|
505
505
  "<a href='#{prefix}/#{url}'>#{b.call.contents}</a>"
506
506
  end
507
507
  end
508
508
 
509
- it 'renders correctly' do
510
- allow(context).to receive(:prefix).and_return('/root')
509
+ it "renders correctly" do
510
+ allow(context).to receive(:prefix).and_return("/root")
511
511
  goodbye = double(:goodbye)
512
- allow(goodbye).to receive(:text).and_return('Goodbye')
513
- allow(goodbye).to receive(:url).and_return('goodbye')
512
+ allow(goodbye).to receive(:text).and_return("Goodbye")
513
+ allow(goodbye).to receive(:url).and_return("goodbye")
514
514
  allow(context).to receive(:goodbyes).and_return([goodbye])
515
515
  expect(subject).to eq "<a href='/root/goodbye'>Goodbye</a>"
516
516
  end
517
517
  end
518
518
 
519
- describe 'block with deep nested complex lookup' do
519
+ describe "block with deep nested complex lookup" do
520
520
  let(:template) { "{{#outer}}Goodbye {{#inner}}cruel {{../../omg}}{{/inner}}{{/outer}}" }
521
521
 
522
522
  example do
523
523
  goodbye = double(:goodbye)
524
- allow(goodbye).to receive(:text).and_return('goodbye')
524
+ allow(goodbye).to receive(:text).and_return("goodbye")
525
525
  inner = double(:inner)
526
526
  allow(inner).to receive(:inner).and_return([goodbye])
527
- allow(context).to receive(:omg).and_return('OMG!')
527
+ allow(context).to receive(:omg).and_return("OMG!")
528
528
  allow(context).to receive(:outer).and_return([inner])
529
529
  expect(subject).to eq "Goodbye cruel OMG!"
530
530
  end
531
531
  end
532
532
 
533
- describe 'block helper' do
533
+ describe "block helper" do
534
534
  let(:template) { "{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!" }
535
535
  before do
536
536
  FS.register_helper(:goodbyes) do |&block|
537
- block.call.contents Struct.new(:text).new('GOODBYE')
537
+ block.call.contents Struct.new(:text).new("GOODBYE")
538
538
  end
539
539
  end
540
540
 
541
541
  example do
542
- allow(context).to receive(:world).and_return('world')
542
+ allow(context).to receive(:world).and_return("world")
543
543
  end
544
544
  end
545
545
 
546
- describe 'block helper staying in the same context' do
546
+ describe "block helper staying in the same context" do
547
547
  let(:template) { "{{#form}}<p>{{name}}</p>{{/form}}" }
548
548
  before do
549
549
  FS.register_helper(:form) do |&block|
@@ -552,12 +552,12 @@ describe FlavourSaver do
552
552
  end
553
553
 
554
554
  example do
555
- allow(context).to receive(:name).and_return('Yehuda')
555
+ allow(context).to receive(:name).and_return("Yehuda")
556
556
  expect(subject).to eq "<form><p>Yehuda</p></form>"
557
557
  end
558
558
  end
559
559
 
560
- describe 'block helper should have context in this' do
560
+ describe "block helper should have context in this" do
561
561
  let(:template) { "<ul>{{#people}}<li>{{#link}}{{name}}{{/link}}</li>{{/people}}</ul>" }
562
562
  before do
563
563
  FS.register_helper(:link) do |&block|
@@ -566,64 +566,64 @@ describe FlavourSaver do
566
566
  end
567
567
  example do
568
568
  person = Struct.new(:name, :id)
569
- allow(context).to receive(:people).and_return([person.new('Alan', 1), person.new('Yehuda', 2)])
569
+ allow(context).to receive(:people).and_return([person.new("Alan", 1), person.new("Yehuda", 2)])
570
570
  expect(subject).to eq "<ul><li><a href=\"/people/1\">Alan</a></li><li><a href=\"/people/2\">Yehuda</a></li></ul>"
571
571
  end
572
572
  end
573
573
 
574
- describe 'block helper for undefined value' do
574
+ describe "block helper for undefined value" do
575
575
  let(:template) { "{{#empty}}shoulnd't render{{/empty}}" }
576
576
  example do
577
577
  expect { subject }.to raise_exception(FlavourSaver::UnknownHelperException)
578
578
  end
579
579
  end
580
580
 
581
- describe 'block helper passing a new context' do
581
+ describe "block helper passing a new context" do
582
582
  let(:template) { "{{#form yehuda}}<p>{{name}}</p>{{/form}}" }
583
583
  before do
584
- FS.register_helper(:form) do |whom,&block|
584
+ FS.register_helper(:form) do |whom, &block|
585
585
  "<form>#{block.call.contents whom}</form>"
586
586
  end
587
587
  end
588
588
  example do
589
- allow(context).to receive_message_chain(:yehuda,:name).and_return('Yehuda')
589
+ allow(context).to receive_message_chain(:yehuda, :name).and_return("Yehuda")
590
590
  expect(subject).to eq "<form><p>Yehuda</p></form>"
591
591
  end
592
592
  end
593
593
 
594
- describe 'block helper passing a complex path context' do
594
+ describe "block helper passing a complex path context" do
595
595
  let(:template) { "{{#form yehuda/cat}}<p>{{name}}</p>{{/form}}" }
596
596
  before do
597
- FS.register_helper(:form) do |context,&block|
597
+ FS.register_helper(:form) do |context, &block|
598
598
  "<form>#{block.call.contents context}</form>"
599
599
  end
600
600
  end
601
601
  example do
602
602
  yehuda = double(:yehuda)
603
- allow(yehuda).to receive(:name).and_return('Yehuda')
604
- allow(yehuda).to receive_message_chain(:cat,:name).and_return('Harold')
603
+ allow(yehuda).to receive(:name).and_return("Yehuda")
604
+ allow(yehuda).to receive_message_chain(:cat, :name).and_return("Harold")
605
605
  allow(context).to receive(:yehuda).and_return(yehuda)
606
606
  expect(subject).to eq "<form><p>Harold</p></form>"
607
607
  end
608
608
  end
609
609
 
610
- describe 'nested block helpers' do
610
+ describe "nested block helpers" do
611
611
  let(:template) { "{{#form yehuda}}<p>{{name}}</p>{{#link}}Hello{{/link}}{{/form}}" }
612
612
  before do
613
613
  FS.register_helper(:link) do |&block|
614
614
  "<a href='#{name}'>#{block.call.contents}</a>"
615
615
  end
616
- FS.register_helper(:form) do |context,&block|
616
+ FS.register_helper(:form) do |context, &block|
617
617
  "<form>#{block.call.contents context}</form>"
618
618
  end
619
619
  end
620
620
  example do
621
- allow(context).to receive_message_chain(:yehuda,:name).and_return('Yehuda')
621
+ allow(context).to receive_message_chain(:yehuda, :name).and_return("Yehuda")
622
622
  expect(subject).to eq "<form><p>Yehuda</p><a href='Yehuda'>Hello</a></form>"
623
623
  end
624
624
  end
625
625
 
626
- describe 'block inverted sections' do
626
+ describe "block inverted sections" do
627
627
  let(:template) { "{{#people}}{{name}}{{^}}{{none}}{{/people}}" }
628
628
  example do
629
629
  allow(context).to receive(:none).and_return("No people")
@@ -632,22 +632,22 @@ describe FlavourSaver do
632
632
  end
633
633
  end
634
634
 
635
- describe 'block inverted sections with empty arrays' do
635
+ describe "block inverted sections with empty arrays" do
636
636
  let(:template) { "{{#people}}{{name}}{{^}}{{none}}{{/people}}" }
637
637
  example do
638
- allow(context).to receive(:none).and_return('No people')
638
+ allow(context).to receive(:none).and_return("No people")
639
639
  allow(context).to receive(:people).and_return([])
640
640
  expect(subject).to eq "No people"
641
641
  end
642
642
  end
643
643
 
644
- describe 'block helpers with inverted sections' do
645
- let (:template) { "{{#list people}}{{name}}{{^}}<em>Nobody's here</em>{{/list}}" }
644
+ describe "block helpers with inverted sections" do
645
+ let(:template) { "{{#list people}}{{name}}{{^}}<em>Nobody's here</em>{{/list}}" }
646
646
  before do
647
- FS.register_helper(:list) do |context,&block|
647
+ FS.register_helper(:list) do |context, &block|
648
648
  if context.any?
649
649
  "<ul>" +
650
- context.map { |e| "<li>#{block.call.contents e}</li>" }.join('') +
650
+ context.map { |e| "<li>#{block.call.contents e}</li>" }.join("") +
651
651
  "</ul>"
652
652
  else
653
653
  "<p>#{block.call.inverse}</p>"
@@ -655,23 +655,23 @@ describe FlavourSaver do
655
655
  end
656
656
  end
657
657
 
658
- example 'an inverse wrapper is passed in as a new context' do
658
+ example "an inverse wrapper is passed in as a new context" do
659
659
  person = Struct.new(:name)
660
- allow(context).to receive(:people).and_return([person.new('Alan'),person.new('Yehuda')])
660
+ allow(context).to receive(:people).and_return([person.new("Alan"), person.new("Yehuda")])
661
661
  expect(subject).to eq "<ul><li>Alan</li><li>Yehuda</li></ul>"
662
662
  end
663
663
 
664
- example 'an inverse wrapper can optionally be called' do
664
+ example "an inverse wrapper can optionally be called" do
665
665
  allow(context).to receive(:people).and_return([])
666
666
  expect(subject).to eq "<p><em>Nobody's here</em></p>"
667
667
  end
668
668
 
669
- describe 'the context of an inverse is the parent of the block' do
669
+ describe "the context of an inverse is the parent of the block" do
670
670
  let(:template) { "{{#list people}}Hello{{^}}{{message}}{{/list}}" }
671
671
  example do
672
672
  allow(context).to receive(:people).and_return([])
673
673
  allow(context).to receive(:message).and_return("Nobody's here")
674
- if RUBY_VERSION >= '2.0.0'
674
+ if RUBY_VERSION >= "2.0.0"
675
675
  expect(subject).to eq "<p>Nobody&#39;s here</p>"
676
676
  else
677
677
  expect(subject).to eq "<p>Nobody&#x27;s here</p>"
@@ -681,51 +681,51 @@ describe FlavourSaver do
681
681
  end
682
682
  end
683
683
 
684
- describe 'partials' do
684
+ describe "partials" do
685
685
  let(:template) { "Dudes: {{#dudes}}{{> dude}}{{/dudes}}" }
686
686
  before do
687
687
  FS.register_partial(:dude, "{{name}} ({{url}}) ")
688
688
  end
689
689
  example do
690
690
  person = Struct.new(:name, :url)
691
- allow(context).to receive(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
691
+ allow(context).to receive(:dudes).and_return([person.new("Yehuda", "http://yehuda"), person.new("Alan", "http://alan")])
692
692
  expect(subject).to eq "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
693
693
  end
694
694
  end
695
695
 
696
- describe 'partials with context' do
697
- let(:template) {"Dudes: {{>dude dudes}}"}
696
+ describe "partials with context" do
697
+ let(:template) { "Dudes: {{>dude dudes}}" }
698
698
  before do
699
699
  FS.register_partial(:dude, "{{#this}}{{name}} ({{url}}) {{/this}}")
700
700
  end
701
701
  example "Partials can be passed a context" do
702
702
  person = Struct.new(:name, :url)
703
- allow(context).to receive(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
703
+ allow(context).to receive(:dudes).and_return([person.new("Yehuda", "http://yehuda"), person.new("Alan", "http://alan")])
704
704
  expect(subject).to eq "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
705
705
  end
706
706
  end
707
707
 
708
- describe 'partial in a partial' do
709
- let(:template) {"Dudes: {{#dudes}}{{>dude}}{{/dudes}}"}
708
+ describe "partial in a partial" do
709
+ let(:template) { "Dudes: {{#dudes}}{{>dude}}{{/dudes}}" }
710
710
  before do
711
711
  FS.register_partial(:dude, "{{name}} {{>url}} ")
712
712
  FS.register_partial(:url, "<a href='{{url}}'>{{url}}</a>")
713
713
  end
714
714
  example "Partials can be passed a context" do
715
715
  person = Struct.new(:name, :url)
716
- allow(context).to receive(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
716
+ allow(context).to receive(:dudes).and_return([person.new("Yehuda", "http://yehuda"), person.new("Alan", "http://alan")])
717
717
  expect(subject).to eq "Dudes: Yehuda <a href='http://yehuda'>http://yehuda</a> Alan <a href='http://alan'>http://alan</a> "
718
718
  end
719
719
  end
720
720
 
721
- describe 'rendering undefined partial throws an exception' do
721
+ describe "rendering undefined partial throws an exception" do
722
722
  let(:template) { "{{> whatever}}" }
723
723
  example do
724
724
  expect { subject }.to raise_error(FS::UnknownPartialException)
725
725
  end
726
726
  end
727
727
 
728
- describe 'rendering a function partial' do
728
+ describe "rendering a function partial" do
729
729
  let(:template) { "Dudes: {{#dudes}}{{> dude}}{{/dudes}}" }
730
730
  before do
731
731
  FS.register_partial(:dude) do |context|
@@ -734,53 +734,52 @@ describe FlavourSaver do
734
734
  end
735
735
  example do
736
736
  person = Struct.new(:name, :url)
737
- allow(context).to receive(:dudes).and_return([person.new('Yehuda', 'http://yehuda'), person.new('Alan', 'http://alan')])
737
+ allow(context).to receive(:dudes).and_return([person.new("Yehuda", "http://yehuda"), person.new("Alan", "http://alan")])
738
738
  expect(subject).to eq "Dudes: Yehuda (http://yehuda) Alan (http://alan) "
739
739
  end
740
740
  end
741
741
 
742
- describe 'a partial preceding a selector' do
742
+ describe "a partial preceding a selector" do
743
743
  let(:template) { "Dudes: {{>dude}} {{another_dude}}" }
744
744
  before do
745
745
  FS.register_partial(:dude, "{{name}}")
746
746
  end
747
747
  example do
748
- allow(context).to receive(:name).and_return('Jeepers')
749
- allow(context).to receive(:another_dude).and_return('Creepers')
748
+ allow(context).to receive(:name).and_return("Jeepers")
749
+ allow(context).to receive(:another_dude).and_return("Creepers")
750
750
  expect(subject).to eq "Dudes: Jeepers Creepers"
751
751
  end
752
752
  end
753
753
 
754
- describe 'partials with literal paths' do
754
+ describe "partials with literal paths" do
755
755
  let(:template) { "Dudes: {{> [dude]}}" }
756
756
  before do
757
757
  FS.register_partial(:dude, "{{name}}")
758
758
  end
759
759
  example do
760
- allow(context).to receive(:name).and_return('Jeepers')
761
- allow(context).to receive(:another_dude).and_return('Creepers')
760
+ allow(context).to receive(:name).and_return("Jeepers")
761
+ allow(context).to receive(:another_dude).and_return("Creepers")
762
762
  expect(subject).to eq "Dudes: Jeepers"
763
763
  end
764
764
  end
765
765
 
766
- describe 'partials with string paths' do
766
+ describe "partials with string paths" do
767
767
  let(:template) { "Dudes: {{> \"dude/man\"}}" }
768
768
  before do
769
769
  FS.register_partial("dude/man", "{{name}}")
770
770
  end
771
771
  example do
772
- allow(context).to receive(:name).and_return('Jeepers')
773
- allow(context).to receive(:another_dude).and_return('Creepers')
772
+ allow(context).to receive(:name).and_return("Jeepers")
773
+ allow(context).to receive(:another_dude).and_return("Creepers")
774
774
  expect(subject).to eq "Dudes: Jeepers"
775
775
  end
776
776
  end
777
777
 
778
- describe 'string literal parameters' do
779
-
780
- describe 'simple literals work' do
778
+ describe "string literal parameters" do
779
+ describe "simple literals work" do
781
780
  let(:template) { "Message: {{hello \"world\" 12 true false}}" }
782
781
  before do
783
- FS.register_helper(:hello) do |param,times,bool1,bool2|
782
+ FS.register_helper(:hello) do |param, times, bool1, bool2|
784
783
  times = "NaN" unless times.is_a? Integer
785
784
  bool1 = "NaB" unless bool1 == true
786
785
  bool2 = "NaB" unless bool2 == false
@@ -792,14 +791,14 @@ describe FlavourSaver do
792
791
  end
793
792
  end
794
793
 
795
- describe 'using a quote in the middle of a parameter raises an error' do
794
+ describe "using a quote in the middle of a parameter raises an error" do
796
795
  let(:template) { "Message: {{hello wo\"rld\"}}" }
797
796
  example do
798
- expect { subject }.to raise_error(RLTK::NotInLanguage)
797
+ expect { subject }.to raise_error(FlavourSaver::Parser::NotInLanguage)
799
798
  end
800
799
  end
801
800
 
802
- describe 'escaping a string is possible' do
801
+ describe "escaping a string is possible" do
803
802
  let(:template) { 'Message: {{{hello "\"world\""}}}' }
804
803
  before do
805
804
  FS.register_helper(:hello) do |param|
@@ -811,7 +810,7 @@ describe FlavourSaver do
811
810
  end
812
811
  end
813
812
 
814
- describe 'string work with ticks' do
813
+ describe "string work with ticks" do
815
814
  let(:template) { 'Message: {{{hello "Alan\'s world"}}}' }
816
815
  before do
817
816
  FS.register_helper(:hello) do |param|
@@ -822,202 +821,201 @@ describe FlavourSaver do
822
821
  expect(subject).to eq "Message: Hello Alan's world"
823
822
  end
824
823
  end
825
-
826
824
  end
827
825
 
828
- describe 'multi-params' do
829
- describe 'simple multi-params work' do
826
+ describe "multi-params" do
827
+ describe "simple multi-params work" do
830
828
  let(:template) { "Message: {{goodbye cruel world}}" }
831
- before { FS.register_helper(:goodbye) { |cruel,world| "Goodbye #{cruel} #{world}" } }
829
+ before { FS.register_helper(:goodbye) { |cruel, world| "Goodbye #{cruel} #{world}" } }
832
830
  example do
833
- allow(context).to receive(:cruel).and_return('cruel')
834
- allow(context).to receive(:world).and_return('world')
831
+ allow(context).to receive(:cruel).and_return("cruel")
832
+ allow(context).to receive(:world).and_return("world")
835
833
  expect(subject).to eq "Message: Goodbye cruel world"
836
834
  end
837
835
  end
838
836
 
839
- describe 'block multi-params' do
837
+ describe "block multi-params" do
840
838
  let(:template) { "Message: {{#goodbye cruel world}}{{greeting}} {{adj}} {{noun}}{{/goodbye}}" }
841
- before { FS.register_helper(:goodbye) { |adj,noun,&b| b.call.contents Struct.new(:greeting,:adj,:noun).new('Goodbye', adj, noun) } }
839
+ before { FS.register_helper(:goodbye) { |adj, noun, &b| b.call.contents Struct.new(:greeting, :adj, :noun).new("Goodbye", adj, noun) } }
842
840
  example do
843
- allow(context).to receive(:cruel).and_return('cruel')
844
- allow(context).to receive(:world).and_return('world')
841
+ allow(context).to receive(:cruel).and_return("cruel")
842
+ allow(context).to receive(:world).and_return("world")
845
843
  expect(subject).to eq "Message: Goodbye cruel world"
846
844
  end
847
845
  end
848
846
  end
849
847
 
850
- describe 'built-in helpers' do
851
- describe 'with' do
848
+ describe "built-in helpers" do
849
+ describe "with" do
852
850
  let(:template) { "{{#with person}}{{first}} {{last}}{{/with}}" }
853
851
  example do
854
- allow(context).to receive(:person).and_return(Struct.new(:first,:last).new('Alan','Johnson'))
855
- expect(subject).to eq 'Alan Johnson'
852
+ allow(context).to receive(:person).and_return(Struct.new(:first, :last).new("Alan", "Johnson"))
853
+ expect(subject).to eq "Alan Johnson"
856
854
  end
857
855
  end
858
856
 
859
- describe 'if' do
857
+ describe "if" do
860
858
  let(:template) { "{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!" }
861
859
 
862
- example 'if with boolean argument shows the contents when true' do
860
+ example "if with boolean argument shows the contents when true" do
863
861
  allow(context).to receive(:goodbye).and_return(true)
864
- allow(context).to receive(:world).and_return('world')
862
+ allow(context).to receive(:world).and_return("world")
865
863
  expect(subject).to eq "GOODBYE cruel world!"
866
864
  end
867
865
 
868
- example 'if with string argument shows the contents with true' do
869
- allow(context).to receive(:goodbye).and_return('dummy')
870
- allow(context).to receive(:world).and_return('world')
866
+ example "if with string argument shows the contents with true" do
867
+ allow(context).to receive(:goodbye).and_return("dummy")
868
+ allow(context).to receive(:world).and_return("world")
871
869
  expect(subject).to eq "GOODBYE cruel world!"
872
870
  end
873
871
 
874
- example 'if with boolean argument does not show the contents when false' do
872
+ example "if with boolean argument does not show the contents when false" do
875
873
  allow(context).to receive(:goodbye).and_return(false)
876
- allow(context).to receive(:world).and_return('world')
874
+ allow(context).to receive(:world).and_return("world")
877
875
  expect(subject).to eq "cruel world!"
878
876
  end
879
877
 
880
- example 'if with undefined does not show the contents' do
878
+ example "if with undefined does not show the contents" do
881
879
  allow(context).to receive(:goodbye)
882
- allow(context).to receive(:world).and_return('world')
880
+ allow(context).to receive(:world).and_return("world")
883
881
  expect(subject).to eq "cruel world!"
884
882
  end
885
883
 
886
- example 'if with non-empty array shows the contents' do
887
- allow(context).to receive(:goodbye).and_return(['foo'])
888
- allow(context).to receive(:world).and_return('world')
884
+ example "if with non-empty array shows the contents" do
885
+ allow(context).to receive(:goodbye).and_return(["foo"])
886
+ allow(context).to receive(:world).and_return("world")
889
887
  expect(subject).to eq "GOODBYE cruel world!"
890
888
  end
891
889
 
892
- example 'if with empty array does not show the contents' do
890
+ example "if with empty array does not show the contents" do
893
891
  allow(context).to receive(:goodbye).and_return([])
894
- allow(context).to receive(:world).and_return('world')
892
+ allow(context).to receive(:world).and_return("world")
895
893
  expect(subject).to eq "cruel world!"
896
894
  end
897
895
  end
898
896
 
899
- describe '#each' do
897
+ describe "#each" do
900
898
  let(:template) { "{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!" }
901
899
 
902
- example 'each with array iterates over the contents with non-empty' do
900
+ example "each with array iterates over the contents with non-empty" do
903
901
  g = Struct.new(:text)
904
- allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
905
- allow(context).to receive(:world).and_return('world')
902
+ allow(context).to receive(:goodbyes).and_return([g.new("goodbye"), g.new("Goodbye"), g.new("GOODBYE")])
903
+ allow(context).to receive(:world).and_return("world")
906
904
  expect(subject).to eq "goodbye! Goodbye! GOODBYE! cruel world!"
907
905
  end
908
906
 
909
- example 'each with array ignores the contents when empty' do
907
+ example "each with array ignores the contents when empty" do
910
908
  allow(context).to receive(:goodbyes).and_return([])
911
- allow(context).to receive(:world).and_return('world')
909
+ allow(context).to receive(:world).and_return("world")
912
910
  expect(subject).to eq "cruel world!"
913
911
  end
914
912
  end
915
913
 
916
- describe 'each with @index' do
914
+ describe "each with @index" do
917
915
  let(:template) { "{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!" }
918
916
 
919
- example 'the @index variable is used' do
917
+ example "the @index variable is used" do
920
918
  g = Struct.new(:text)
921
- allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
922
- allow(context).to receive(:world).and_return('world')
919
+ allow(context).to receive(:goodbyes).and_return([g.new("goodbye"), g.new("Goodbye"), g.new("GOODBYE")])
920
+ allow(context).to receive(:world).and_return("world")
923
921
  expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!"
924
922
  end
925
923
  end
926
924
 
927
- describe 'each with @index in a nested block' do
925
+ describe "each with @index in a nested block" do
928
926
  let(:template) { "{{#each goodbyes}}{{#if @last}}{{@index}}. {{/if}}{{text}}! {{/each}}cruel {{world}}!" }
929
927
 
930
- example 'the @index variable is used' do
928
+ example "the @index variable is used" do
931
929
  g = Struct.new(:text)
932
- allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
933
- allow(context).to receive(:world).and_return('world')
930
+ allow(context).to receive(:goodbyes).and_return([g.new("goodbye"), g.new("Goodbye"), g.new("GOODBYE")])
931
+ allow(context).to receive(:world).and_return("world")
934
932
  expect(subject).to eq "goodbye! Goodbye! 2. GOODBYE! cruel world!"
935
933
  end
936
934
  end
937
935
 
938
- describe 'each with @last' do
936
+ describe "each with @last" do
939
937
  let(:template) { "{{#each goodbyes}}{{@index}}. {{text}}! {{#if @last}}last{{/if}}{{/each}} cruel {{world}}!" }
940
938
 
941
- example 'the @last variable is used' do
939
+ example "the @last variable is used" do
942
940
  g = Struct.new(:text)
943
- allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
944
- allow(context).to receive(:world).and_return('world')
941
+ allow(context).to receive(:goodbyes).and_return([g.new("goodbye"), g.new("Goodbye"), g.new("GOODBYE")])
942
+ allow(context).to receive(:world).and_return("world")
945
943
  expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE! last cruel world!"
946
944
  end
947
945
  end
948
946
 
949
- describe 'each with @first' do
947
+ describe "each with @first" do
950
948
  let(:template) { "{{#each goodbyes}}{{@index}}. {{text}} {{#if @first}}first{{/if}}! {{/each}}cruel {{world}}!" }
951
949
 
952
- example 'the first variable is used' do
950
+ example "the first variable is used" do
953
951
  g = Struct.new(:text)
954
- allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
955
- allow(context).to receive(:world).and_return('world')
952
+ allow(context).to receive(:goodbyes).and_return([g.new("goodbye"), g.new("Goodbye"), g.new("GOODBYE")])
953
+ allow(context).to receive(:world).and_return("world")
956
954
  expect(subject).to eq "0. goodbye first! 1. Goodbye ! 2. GOODBYE ! cruel world!"
957
955
  end
958
956
  end
959
957
 
960
- describe 'each with @root' do
958
+ describe "each with @root" do
961
959
  let(:template) { "{{#each goodbyes}}{{@index}}. {{text}} cruel {{@root.place}}! {{/each}}" }
962
960
 
963
- example 'the root variable is used' do
961
+ example "the root variable is used" do
964
962
  g = Struct.new(:text)
965
- allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
966
- allow(context).to receive(:place).and_return('world')
963
+ allow(context).to receive(:goodbyes).and_return([g.new("goodbye"), g.new("Goodbye"), g.new("GOODBYE")])
964
+ allow(context).to receive(:place).and_return("world")
967
965
  expect(subject).to eq "0. goodbye cruel world! 1. Goodbye cruel world! 2. GOODBYE cruel world! "
968
966
  end
969
967
  end
970
968
 
971
- describe 'each with @root in a nested block' do
969
+ describe "each with @root in a nested block" do
972
970
  let(:template) { "{{#each goodbyes}}{{@index}}. {{text}}{{#if @last}} cruel {{@root.place}}{{/if}}! {{/each}}" }
973
971
 
974
- example 'the root variable is used' do
972
+ example "the root variable is used" do
975
973
  g = Struct.new(:text)
976
- allow(context).to receive(:goodbyes).and_return([g.new('goodbye'), g.new('Goodbye'), g.new('GOODBYE')])
977
- allow(context).to receive(:place).and_return('world')
974
+ allow(context).to receive(:goodbyes).and_return([g.new("goodbye"), g.new("Goodbye"), g.new("GOODBYE")])
975
+ allow(context).to receive(:place).and_return("world")
978
976
  expect(subject).to eq "0. goodbye! 1. Goodbye! 2. GOODBYE cruel world! "
979
977
  end
980
978
  end
981
979
 
982
- describe 'each with @key' do
980
+ describe "each with @key" do
983
981
  let(:template) { "{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!" }
984
982
 
985
- example 'the @key variable is used' do
983
+ example "the @key variable is used" do
986
984
  g = Struct.new(:text)
987
985
  allow(context).to receive(:goodbyes).and_return({
988
- one: g.new('goodbye'),
989
- two: g.new('Goodbye'),
990
- three: g.new('GOODBYE')
986
+ one: g.new("goodbye"),
987
+ two: g.new("Goodbye"),
988
+ three: g.new("GOODBYE")
991
989
  })
992
- allow(context).to receive(:world).and_return('world')
990
+ allow(context).to receive(:world).and_return("world")
993
991
  expect(subject).to eq "one. goodbye! two. Goodbye! three. GOODBYE! cruel world!"
994
992
  end
995
993
  end
996
994
 
997
- describe 'each with @key in a nested block' do
995
+ describe "each with @key in a nested block" do
998
996
  let(:template) { "{{#each goodbyes}}{{#if @last}}{{@key}}. {{/if}}{{text}}! {{/each}}cruel {{world}}!" }
999
997
 
1000
- example 'the @key variable is used' do
998
+ example "the @key variable is used" do
1001
999
  g = Struct.new(:text)
1002
1000
  allow(context).to receive(:goodbyes).and_return({
1003
- one: g.new('goodbye'),
1004
- two: g.new('Goodbye'),
1005
- three: g.new('GOODBYE')
1001
+ one: g.new("goodbye"),
1002
+ two: g.new("Goodbye"),
1003
+ three: g.new("GOODBYE")
1006
1004
  })
1007
- allow(context).to receive(:world).and_return('world')
1005
+ allow(context).to receive(:world).and_return("world")
1008
1006
  expect(subject).to eq "goodbye! Goodbye! three. GOODBYE! cruel world!"
1009
1007
  end
1010
1008
  end
1011
1009
 
1012
- describe 'log' do
1010
+ describe "log" do
1013
1011
  let(:template) { "{{log blah}}" }
1014
1012
  let(:log) { double(:log) }
1015
1013
  before { FS.logger = log }
1016
- after { FS.logger = nil }
1014
+ after { FS.logger = nil }
1017
1015
  example do
1018
- allow(context).to receive(:blah).and_return('whee')
1019
- expect(log).to receive(:debug).with('FlavourSaver: whee')
1020
- expect(subject).to eq ''
1016
+ allow(context).to receive(:blah).and_return("whee")
1017
+ expect(log).to receive(:debug).with("FlavourSaver: whee")
1018
+ expect(subject).to eq ""
1021
1019
  end
1022
1020
  end
1023
1021
  end