curlybars 1.7.0 → 1.9.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/curlybars/error/lex.rb +1 -1
  3. data/lib/curlybars/error/parse.rb +1 -1
  4. data/lib/curlybars/node/path.rb +11 -13
  5. data/lib/curlybars/presenter.rb +2 -2
  6. data/lib/curlybars/template_handler.rb +3 -11
  7. data/lib/curlybars/version.rb +1 -1
  8. metadata +17 -93
  9. data/spec/acceptance/application_layout_spec.rb +0 -60
  10. data/spec/acceptance/collection_blocks_spec.rb +0 -28
  11. data/spec/acceptance/global_helper_spec.rb +0 -25
  12. data/spec/curlybars/configuration_spec.rb +0 -57
  13. data/spec/curlybars/error/base_spec.rb +0 -41
  14. data/spec/curlybars/error/compile_spec.rb +0 -19
  15. data/spec/curlybars/error/lex_spec.rb +0 -25
  16. data/spec/curlybars/error/parse_spec.rb +0 -74
  17. data/spec/curlybars/error/render_spec.rb +0 -19
  18. data/spec/curlybars/error/validate_spec.rb +0 -19
  19. data/spec/curlybars/lexer_spec.rb +0 -490
  20. data/spec/curlybars/method_whitelist_spec.rb +0 -299
  21. data/spec/curlybars/processor/tilde_spec.rb +0 -60
  22. data/spec/curlybars/rendering_support_spec.rb +0 -421
  23. data/spec/curlybars/safe_buffer_spec.rb +0 -46
  24. data/spec/curlybars/template_handler_spec.rb +0 -225
  25. data/spec/integration/cache_spec.rb +0 -126
  26. data/spec/integration/comment_spec.rb +0 -60
  27. data/spec/integration/exception_spec.rb +0 -31
  28. data/spec/integration/node/block_helper_else_spec.rb +0 -420
  29. data/spec/integration/node/each_else_spec.rb +0 -408
  30. data/spec/integration/node/each_spec.rb +0 -289
  31. data/spec/integration/node/escape_spec.rb +0 -27
  32. data/spec/integration/node/helper_spec.rb +0 -186
  33. data/spec/integration/node/if_else_spec.rb +0 -170
  34. data/spec/integration/node/if_spec.rb +0 -153
  35. data/spec/integration/node/output_spec.rb +0 -66
  36. data/spec/integration/node/partial_spec.rb +0 -64
  37. data/spec/integration/node/path_spec.rb +0 -296
  38. data/spec/integration/node/root_spec.rb +0 -13
  39. data/spec/integration/node/sub_expression_spec.rb +0 -426
  40. data/spec/integration/node/template_spec.rb +0 -84
  41. data/spec/integration/node/unless_else_spec.rb +0 -139
  42. data/spec/integration/node/unless_spec.rb +0 -128
  43. data/spec/integration/node/with_spec.rb +0 -178
  44. data/spec/integration/processor/tilde_spec.rb +0 -38
  45. data/spec/integration/processors_spec.rb +0 -29
  46. data/spec/integration/visitor_spec.rb +0 -154
@@ -1,126 +0,0 @@
1
- describe "caching" do
2
- let(:dummy_cache) do
3
- Class.new do
4
- attr_reader :reads, :hits
5
-
6
- def initialize
7
- @store = {}
8
- @reads = 0
9
- @hits = 0
10
- end
11
-
12
- def fetch(key)
13
- @reads += 1
14
- if @store.key?(key)
15
- @hits += 1
16
- @store[key]
17
- else
18
- value = yield
19
- @store[key] = value
20
- value
21
- end
22
- end
23
- end
24
- end
25
-
26
- let(:global_helpers_providers) { [] }
27
- let(:presenter) { IntegrationTest::Presenter.new(double("view_context")) }
28
- let(:cache) { dummy_cache.new }
29
-
30
- before do
31
- Curlybars.configure do |config|
32
- config.cache = cache.method(:fetch)
33
- end
34
- end
35
-
36
- after do
37
- Curlybars.reset
38
- end
39
-
40
- describe "{{#each}}" do
41
- it "invokes cache if presenter responds to #cache_key" do
42
- template = Curlybars.compile(<<-HBS)
43
- {{#each array_of_users}}{{/each}}
44
- HBS
45
-
46
- eval(template)
47
-
48
- expect(cache.reads).to eq(1)
49
- expect(cache.hits).to eq(0)
50
- end
51
-
52
- it "reuses cached values" do
53
- template = Curlybars.compile(<<-HBS)
54
- {{#each array_of_users}}
55
- a
56
- {{/each}}
57
-
58
- {{#each array_of_users}}
59
- a
60
- {{/each}}
61
- HBS
62
-
63
- eval(template)
64
-
65
- expect(cache.reads).to eq(2)
66
- expect(cache.hits).to eq(1)
67
- end
68
-
69
- it "generates unique cache keys per template" do
70
- template = Curlybars.compile(<<-HBS)
71
- {{#each array_of_users}}
72
- a
73
- {{/each}}
74
-
75
- {{#each array_of_users}}
76
- b
77
- {{/each}}
78
- HBS
79
-
80
- eval(template)
81
-
82
- expect(cache.reads).to eq(2)
83
- expect(cache.hits).to eq(0)
84
- end
85
-
86
- it "produces correct output from cached presenters" do
87
- template = Curlybars.compile(<<-HBS)
88
- {{#each array_of_users}}
89
- - {{first_name}}
90
- {{/each}}
91
- HBS
92
-
93
- expect(eval(template)).to resemble(<<-HTML)
94
- - Libo
95
- HTML
96
- end
97
-
98
- it "works for empty templates" do
99
- template = Curlybars.compile(<<-HBS)
100
- before
101
- {{#each array_of_users}}{{/each}}
102
- {{#each array_of_users}}{{/each}}
103
- after
104
- HBS
105
-
106
- expect(eval(template)).to resemble(<<-HTML)
107
- before
108
- after
109
- HTML
110
- end
111
-
112
- it "leaves variables and contexts in correct state after a cache hit" do
113
- template = Curlybars.compile(<<-HBS)
114
- {{#each array_of_users}}a{{/each}}
115
- {{#each array_of_users}}a{{/each}}
116
- {{context}}
117
- HBS
118
-
119
- expect(eval(template)).to resemble(<<-HTML)
120
- a
121
- a
122
- root_context
123
- HTML
124
- end
125
- end
126
- end
@@ -1,60 +0,0 @@
1
- describe "{{!-- --}} and {{! }}" do
2
- let(:post) { double("post") }
3
- let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
4
- let(:global_helpers_providers) { [] }
5
-
6
- it "ignores one line comment" do
7
- template = Curlybars.compile(<<-HBS)
8
- before{{! This is a comment }}after
9
- HBS
10
-
11
- expect(eval(template)).to resemble(<<-HTML)
12
- before after
13
- HTML
14
- end
15
-
16
- it "ignores multi line comment" do
17
- template = Curlybars.compile(<<-HBS)
18
- before
19
- {{! 2 lines
20
- lines }}
21
- after
22
- HBS
23
-
24
- expect(eval(template)).to resemble(<<-HTML)
25
- before after
26
- HTML
27
- end
28
-
29
- it "ignores multi lines with curly inside comment" do
30
- template = Curlybars.compile(<<-HBS)
31
- before
32
- {{!
33
- And another one
34
- in
35
- 3 lines
36
- }
37
- }}
38
- after
39
- HBS
40
-
41
- expect(eval(template)).to resemble(<<-HTML)
42
- before after
43
- HTML
44
- end
45
-
46
- it "ignores multi line comment with {{!-- --}}" do
47
- template = Curlybars.compile(<<-HBS)
48
- before
49
- {{!--
50
- And this is the {{ test }} other style
51
- }}
52
- --}}
53
- after
54
- HBS
55
-
56
- expect(eval(template)).to resemble(<<-HTML)
57
- before after
58
- HTML
59
- end
60
- end
@@ -1,31 +0,0 @@
1
- describe "Exception reporting" do
2
- let(:post) { double("post") }
3
- let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
4
- let(:global_helpers_providers) { [] }
5
-
6
- it "Throw Curlybars::Error::Lex in case of a lex error occurs" do
7
- expect do
8
- Curlybars.compile('{{{')
9
- end.to raise_error(Curlybars::Error::Lex)
10
- end
11
-
12
- it "Throw Curlybars::Error::Parse in case of a lex error occurs" do
13
- expect do
14
- Curlybars.compile('{{#with "notallowed"}} ... {{/with}}')
15
- end.to raise_error(Curlybars::Error::Parse)
16
- end
17
-
18
- it "Throw Curlybars::Error::Compile in case of a lex error occurs" do
19
- expect do
20
- Curlybars.compile('{{#form new_comment_form}} ... {{/different_closing}}')
21
- end.to raise_error(Curlybars::Error::Compile)
22
- end
23
-
24
- it "Throw Curlybars::Error::Render in case of a rendering error occurs" do
25
- compiled = Curlybars.compile('{{#form not_allowed_path}} ... {{/form}}')
26
-
27
- expect do
28
- eval(compiled)
29
- end.to raise_error(Curlybars::Error::Render)
30
- end
31
- end
@@ -1,420 +0,0 @@
1
- describe "{{#helper arg1 arg2 ... key=value ...}}...<{{else}}>...{{/helper}}" do
2
- let(:global_helpers_providers) { [IntegrationTest::GlobalHelperProvider.new] }
3
-
4
- describe "#compile" do
5
- let(:post) { double("post") }
6
- let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
7
-
8
- it "can be a global helper" do
9
- template = Curlybars.compile(<<-HBS)
10
- {{global_helper 'argument' option='value'}}
11
- HBS
12
-
13
- expect(eval(template)).to resemble(<<-HTML)
14
- argument - option:value
15
- HTML
16
- end
17
-
18
- it "accepts no arguments at all" do
19
- template = Curlybars.compile(<<-HBS)
20
- {{#just_yield}}
21
- template
22
- {{/just_yield}}
23
- HBS
24
-
25
- expect(eval(template)).to resemble(<<-HTML)
26
- template
27
- HTML
28
- end
29
-
30
- it "passes two arguments" do
31
- template = Curlybars.compile(<<-HBS)
32
- {{#print_args_and_options 'first' 'second'}}
33
- {{/print_args_and_options}}
34
- HBS
35
-
36
- expect(eval(template)).to resemble(<<-HTML)
37
- first, second, key=
38
- HTML
39
- end
40
-
41
- it "passes two arguments and options" do
42
- template = Curlybars.compile(<<-HBS)
43
- {{#print_args_and_options 'first' 'second' key='value'}}
44
- {{/print_args_and_options}}
45
- HBS
46
-
47
- expect(eval(template)).to resemble(<<-HTML)
48
- first, second, key=value
49
- HTML
50
- end
51
-
52
- it "renders the inverse block" do
53
- template = Curlybars.compile(<<-HBS)
54
- {{#render_inverse}}
55
- fn
56
- {{else}}
57
- inverse
58
- {{/render_inverse}}
59
- HBS
60
-
61
- expect(eval(template)).to resemble(<<-HTML)
62
- inverse
63
- HTML
64
- end
65
-
66
- it "renders the fn block" do
67
- template = Curlybars.compile(<<-HBS)
68
- {{#render_fn}}
69
- fn
70
- {{else}}
71
- inverse
72
- {{/render_fn}}
73
- HBS
74
-
75
- expect(eval(template)).to resemble(<<-HTML)
76
- fn
77
- HTML
78
- end
79
-
80
- it "block helpers can access the current context" do
81
- template = Curlybars.compile(<<-HBS)
82
- {{#print_current_context}} {{/print_current_context}}
83
- HBS
84
-
85
- expect(eval(template)).to resemble(<<-HTML)
86
- root_context
87
- HTML
88
- end
89
-
90
- it "renders a block helper without options" do
91
- template = Curlybars.compile(<<-HBS)
92
- {{#beautify}}
93
- template
94
- {{/beautify}}
95
- HBS
96
-
97
- expect(eval(template)).to resemble(<<-HTML)
98
- bold template italic
99
- HTML
100
- end
101
-
102
- it "renders a block helper with custom variables" do
103
- template = Curlybars.compile(<<-HBS)
104
- {{#yield_custom_variable}}
105
- {{!--
106
- `@custom1` and `@custom2` are variables yielded
107
- by the block helper implementation.
108
- --}}
109
-
110
- {{@custom1}} {{@custom2}}
111
- {{/yield_custom_variable}}
112
- HBS
113
-
114
- expect(eval(template)).to resemble(<<-HTML)
115
- custom variable1
116
- custom variable2
117
- HTML
118
- end
119
-
120
- it "renders a block helper with custom variables that can be used in conditionals" do
121
- template = Curlybars.compile(<<-HBS)
122
- {{#yield_custom_variable}}
123
- {{!--
124
- `@cond` is a boolean variable yielded
125
- by the block helper implementation.
126
- --}}
127
-
128
- {{#if @cond}}
129
- Cond is true
130
- {{/if}}
131
- {{/yield_custom_variable}}
132
- HBS
133
-
134
- expect(eval(template)).to resemble(<<-HTML)
135
- Cond is true
136
- HTML
137
- end
138
-
139
- it "renders a block helper with custom variables that can be seen by nested contexts" do
140
- template = Curlybars.compile(<<-HBS)
141
- {{#yield_custom_variable}}
142
- {{!--
143
- `@custom1` and `@custom2` are variables yielded
144
- by the block helper implementation.
145
- --}}
146
- {{#with this}}
147
- {{@custom1}} {{@custom2}}
148
- {{/with}}
149
- {{/yield_custom_variable}}
150
- HBS
151
-
152
- expect(eval(template)).to resemble(<<-HTML)
153
- custom variable1
154
- custom variable2
155
- HTML
156
- end
157
-
158
- it "renders a block helper with options and presenter" do
159
- template = Curlybars.compile(<<-HBS)
160
- {{#form new_comment_form class="red" foo="bar"}}
161
- {{new_comment_form.button_label}}
162
- {{/form}}
163
- HBS
164
-
165
- expect(eval(template)).to resemble(<<-HTML)
166
- beauty class:red foo:bar submit
167
- HTML
168
- end
169
-
170
- it "allow empty template" do
171
- template = Curlybars.compile(<<-HBS)
172
- {{#form new_comment_form class="red" foo="bar"}}{{/form}}
173
- HBS
174
-
175
- expect(eval(template)).to resemble(<<-HTML)
176
- beauty class:red foo:bar
177
- HTML
178
- end
179
-
180
- it "renders correctly a return type of integer" do
181
- template = Curlybars.compile(<<-HBS)
182
- {{#integer new_comment_form}} text {{/integer}}
183
- HBS
184
-
185
- expect(eval(template)).to resemble(<<-HTML)
186
- 0
187
- HTML
188
- end
189
-
190
- it "renders correctly a return type of boolean" do
191
- template = Curlybars.compile(<<-HBS)
192
- {{#boolean new_comment_form}} text {{/boolean}}
193
- HBS
194
-
195
- expect(eval(template)).to resemble(<<-HTML)
196
- true
197
- HTML
198
- end
199
-
200
- it "accepts a nil context" do
201
- template = Curlybars.compile(<<-HBS)
202
- {{#this_method_yields return_nil}}
203
- {{/this_method_yields}}
204
- HBS
205
-
206
- expect(eval(template)).to resemble("")
207
- end
208
-
209
- it "yield tolerated nil as pushed context" do
210
- template = Curlybars.compile(<<-HBS)
211
- {{#this_method_yields return_nil}}
212
- text
213
- {{/this_method_yields}}
214
- HBS
215
-
216
- expect(eval(template)).to resemble(<<-HTML)
217
- text
218
- HTML
219
- end
220
-
221
- it "raises an exception if the context is not a presenter-like object" do
222
- template = Curlybars.compile(<<-HBS)
223
- {{#boolean post}} text {{/boolean}}
224
- HBS
225
-
226
- expect do
227
- eval(template)
228
- end.to raise_error(Curlybars::Error::Render)
229
- end
230
- end
231
-
232
- describe "#validate" do
233
- it "without errors when global helper" do
234
- allow(Curlybars.configuration).to receive(:global_helpers_provider_classes).and_return([IntegrationTest::GlobalHelperProvider])
235
-
236
- dependency_tree = {}
237
-
238
- source = <<-HBS
239
- {{global_helper}}
240
- HBS
241
-
242
- errors = Curlybars.validate(dependency_tree, source)
243
-
244
- expect(errors).to be_empty
245
- end
246
-
247
- it "without errors when invoking a leaf" do
248
- dependency_tree = { name: nil }
249
-
250
- source = <<-HBS
251
- {{name}}
252
- HBS
253
-
254
- errors = Curlybars.validate(dependency_tree, source)
255
-
256
- expect(errors).to be_empty
257
- end
258
-
259
- it "without errors if argument is a leaf" do
260
- dependency_tree = { block_helper: :helper, argument: nil }
261
-
262
- source = <<-HBS
263
- {{#block_helper argument}} ... {{/block_helper}}
264
- HBS
265
-
266
- errors = Curlybars.validate(dependency_tree, source)
267
-
268
- expect(errors).to be_empty
269
- end
270
-
271
- it "without errors if argument is a literal" do
272
- dependency_tree = { block_helper: :helper }
273
-
274
- source = <<-HBS
275
- {{#block_helper 'argument'}} ... {{/block_helper}}
276
- HBS
277
-
278
- errors = Curlybars.validate(dependency_tree, source)
279
-
280
- expect(errors).to be_empty
281
- end
282
-
283
- it "without errors if argument is a variable" do
284
- dependency_tree = { block_helper: :helper }
285
-
286
- source = <<-HBS
287
- {{#block_helper @var}} ... {{/block_helper}}
288
- HBS
289
-
290
- errors = Curlybars.validate(dependency_tree, source)
291
-
292
- expect(errors).to be_empty
293
- end
294
-
295
- it "without errors if option is a leaf" do
296
- dependency_tree = { block_helper: :helper, argument: nil }
297
-
298
- source = <<-HBS
299
- {{#block_helper option=argument}} ... {{/block_helper}}
300
- HBS
301
-
302
- errors = Curlybars.validate(dependency_tree, source)
303
-
304
- expect(errors).to be_empty
305
- end
306
-
307
- it "without errors if option is a literal" do
308
- dependency_tree = { block_helper: :helper }
309
-
310
- source = <<-HBS
311
- {{#block_helper option='argument'}} ... {{/block_helper}}
312
- HBS
313
-
314
- errors = Curlybars.validate(dependency_tree, source)
315
-
316
- expect(errors).to be_empty
317
- end
318
-
319
- it "without errors if option is a variable" do
320
- dependency_tree = { block_helper: :helper }
321
-
322
- source = <<-HBS
323
- {{#block_helper option=@var}} ... {{/block_helper}}
324
- HBS
325
-
326
- errors = Curlybars.validate(dependency_tree, source)
327
-
328
- expect(errors).to be_empty
329
- end
330
-
331
- it "without errors in block_helper" do
332
- dependency_tree = { block_helper: :helper, context: nil }
333
-
334
- source = <<-HBS
335
- {{#block_helper context}} ... {{/block_helper}}
336
- HBS
337
-
338
- errors = Curlybars.validate(dependency_tree, source)
339
-
340
- expect(errors).to be_empty
341
- end
342
-
343
- it "with errors when invoking a leaf with arguments" do
344
- dependency_tree = { name: nil }
345
-
346
- source = <<-HBS
347
- {{name 'argument'}}
348
- HBS
349
-
350
- errors = Curlybars.validate(dependency_tree, source)
351
-
352
- expect(errors).not_to be_empty
353
- end
354
-
355
- it "with errors when invoking a leaf with options" do
356
- dependency_tree = { name: nil }
357
-
358
- source = <<-HBS
359
- {{name option='value'}}
360
- HBS
361
-
362
- errors = Curlybars.validate(dependency_tree, source)
363
-
364
- expect(errors).not_to be_empty
365
- end
366
-
367
- it "with errors if argument is not a value" do
368
- dependency_tree = { block_helper: :helper, not_a_value: {} }
369
-
370
- source = <<-HBS
371
- {{#block_helper not_a_value}} ... {{/block_helper}}
372
- HBS
373
-
374
- errors = Curlybars.validate(dependency_tree, source)
375
-
376
- expect(errors).not_to be_empty
377
- end
378
-
379
- it "with errors if option is not a value" do
380
- dependency_tree = { block_helper: :helper, not_a_value: {} }
381
-
382
- source = <<-HBS
383
- {{#block_helper option=not_a_value}} ... {{/block_helper}}
384
- HBS
385
-
386
- errors = Curlybars.validate(dependency_tree, source)
387
-
388
- expect(errors).not_to be_empty
389
- end
390
-
391
- it "with errors in fn block" do
392
- dependency_tree = { context: {}, block_helper: :helper }
393
-
394
- source = <<-HBS
395
- {{#block_helper context}}
396
- {{invalid}}
397
- {{/block_helper}}
398
- HBS
399
-
400
- errors = Curlybars.validate(dependency_tree, source)
401
-
402
- expect(errors).not_to be_empty
403
- end
404
-
405
- it "with errors in inverse block" do
406
- dependency_tree = { context: {}, block_helper: :helper }
407
-
408
- source = <<-HBS
409
- {{#block_helper context}}
410
- {{else}}
411
- {{invalid}}
412
- {{/block_helper}}
413
- HBS
414
-
415
- errors = Curlybars.validate(dependency_tree, source)
416
-
417
- expect(errors).not_to be_empty
418
- end
419
- end
420
- end