curlybars 1.8.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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 +14 -90
  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