curlybars 1.7.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 +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,426 +0,0 @@
1
- describe "{{(helper arg1 arg2 ... key=value ...)}}" do
2
- let(:global_helpers_providers) { [IntegrationTest::GlobalHelperProvider.new] }
3
-
4
- describe "#compile" do
5
- let(:presenter) { IntegrationTest::Presenter.new(double("view_context")) }
6
-
7
- it "can be an argument to helpers" do
8
- template = Curlybars.compile(<<-HBS)
9
- {{global_helper (global_helper 'argument' option='value') option='value'}}
10
- HBS
11
-
12
- expect(eval(template)).to resemble(<<-HTML)
13
- argument - option:value - option:value
14
- HTML
15
- end
16
-
17
- it "can be an argument to itself" do
18
- template = Curlybars.compile(<<-HBS)
19
- {{global_helper (global_helper (global_helper 'a' option='b') option='c') option='d'}}
20
- HBS
21
-
22
- expect(eval(template)).to resemble(<<-HTML)
23
- a - option:b - option:c - option:d
24
- HTML
25
- end
26
-
27
- it "can handle data objects as argument" do
28
- template = Curlybars.compile(<<-HBS)
29
- {{global_helper (extract user attribute='first_name') option='value'}}
30
- HBS
31
-
32
- expect(eval(template)).to resemble(<<-HTML)
33
- Libo - option:value
34
- HTML
35
- end
36
-
37
- it "can handle calls inside with" do
38
- template = Curlybars.compile(<<-HBS)
39
- {{#with article}}
40
- {{global_helper (extract author attribute='first_name') option='value'}}
41
- {{/with}}
42
- HBS
43
-
44
- expect(eval(template)).to resemble(<<-HTML)
45
- Nicolò - option:value
46
- HTML
47
- end
48
-
49
- it "does not accept subexpressions in the root" do
50
- expect do
51
- Curlybars.compile(<<-HBS)
52
- {{(join articles attribute='title' separator='-'}}
53
- HBS
54
- end.to raise_error(Curlybars::Error::Parse)
55
- end
56
-
57
- it "can be called within if expressions" do
58
- template = Curlybars.compile(<<-HBS)
59
- {{#if (calc 3 ">" 1)}}
60
- True
61
- {{/if}}
62
- HBS
63
-
64
- expect(eval(template)).to resemble(<<-HTML)
65
- True
66
- HTML
67
- end
68
-
69
- # Replication of Handlebars' subexpression specs for feature parity
70
- # https://github.com/handlebars-lang/handlebars.js/blob/1a08e1d0a7f500f2c1188cbd21750bb9180afcbb/spec/subexpressions.js
71
-
72
- it "arg-less helper" do
73
- template = Curlybars.compile(<<-HBS)
74
- {{foo (bar)}}!
75
- HBS
76
-
77
- expect(eval(template)).to resemble(<<-HTML)
78
- LOLLOL!
79
- HTML
80
- end
81
-
82
- context "with blog presenter" do
83
- let(:presenter) do
84
- IntegrationTest::BlogPresenter.new(
85
- lambda { |*args, options|
86
- val = args.first
87
- "val is #{val}"
88
- }
89
- )
90
- end
91
-
92
- it "helper w args" do
93
- template = Curlybars.compile(<<-HBS)
94
- {{blog (equal a b)}}
95
- HBS
96
-
97
- expect(eval(template)).to resemble(<<-HTML)
98
- val is true
99
- HTML
100
- end
101
-
102
- it "supports much nesting" do
103
- template = Curlybars.compile(<<-HBS)
104
- {{blog (equal (equal true true) true)}}
105
- HBS
106
-
107
- expect(eval(template)).to resemble(<<-HTML)
108
- val is true
109
- HTML
110
- end
111
-
112
- it "with hashes" do
113
- template = Curlybars.compile(<<-HBS)
114
- {{blog (equal (equal true true) true fun='yes')}}
115
- HBS
116
-
117
- expect(eval(template)).to resemble(<<-HTML)
118
- val is true
119
- HTML
120
- end
121
- end
122
-
123
- context "with a different blog presenter" do
124
- let(:presenter) do
125
- IntegrationTest::BlogPresenter.new(
126
- lambda { |*args, options|
127
- "val is #{options[:fun]}"
128
- }
129
- )
130
- end
131
-
132
- it "as hashes" do
133
- template = Curlybars.compile(<<-HBS)
134
- {{blog fun=(equal (blog fun=1) 'val is 1')}}
135
- HBS
136
-
137
- expect(eval(template)).to resemble(<<-HTML)
138
- val is true
139
- HTML
140
- end
141
- end
142
-
143
- context "with yet another blog presenter" do
144
- let(:presenter) do
145
- IntegrationTest::BlogPresenter.new(
146
- lambda { |*args, options|
147
- first, second, third = args
148
- "val is #{first}, #{second} and #{third}"
149
- }
150
- )
151
- end
152
-
153
- it "mixed paths and helpers" do
154
- template = Curlybars.compile(<<-HBS)
155
- {{blog baz.bat (equal a b) baz.bar}}
156
- HBS
157
-
158
- expect(eval(template)).to resemble(<<-HTML)
159
- val is bat!, true and bar!
160
- HTML
161
- end
162
- end
163
-
164
- describe "GH-800 : Complex subexpressions" do
165
- let(:presenter) do
166
- IntegrationTest::LetterPresenter.new(
167
- a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' }
168
- )
169
- end
170
-
171
- it "can handle complex subexpressions" do
172
- inputs = [
173
- "{{dash 'abc' (concat a b)}}",
174
- "{{dash d (concat a b)}}",
175
- "{{dash c.c (concat a b)}}",
176
- "{{dash (concat a b) c.c}}",
177
- "{{dash (concat a e.e) c.c}}"
178
- ]
179
-
180
- expected_results = [
181
- "abc-ab",
182
- "d-ab",
183
- "c-ab",
184
- "ab-c",
185
- "ae-c"
186
- ]
187
-
188
- aggregate_failures do
189
- inputs.each_with_index do |input, i|
190
- expect(eval(Curlybars.compile(input))).to resemble(expected_results[i])
191
- end
192
- end
193
- end
194
- end
195
-
196
- it "multiple subexpressions in a hash" do
197
- template = Curlybars.compile(<<-HBS)
198
- {{input aria-label=(t "Name") placeholder=(t "Example User")}}
199
- HBS
200
-
201
- expected_output = '<input aria-label="Name" placeholder="Example User" />'
202
- .gsub("<", "&lt;")
203
- .gsub(">", "&gt;")
204
- .gsub('"', "&quot;")
205
-
206
- expect(eval(template)).to resemble(expected_output)
207
- end
208
-
209
- context "with item show presenter" do
210
- let(:presenter) do
211
- IntegrationTest::ItemShowPresenter.new(field: "Name", placeholder: "Example User")
212
- end
213
-
214
- it "multiple subexpressions in a hash with context" do
215
- template = Curlybars.compile(<<-HBS)
216
- {{input aria-label=(t item.field) placeholder=(t item.placeholder)}}
217
- HBS
218
-
219
- expected_output = '<input aria-label="Name" placeholder="Example User" />'
220
- .gsub("<", "&lt;")
221
- .gsub(">", "&gt;")
222
- .gsub('"', "&quot;")
223
-
224
- expect(eval(template)).to resemble(expected_output)
225
- end
226
- end
227
- end
228
-
229
- describe "#validate" do
230
- before do
231
- allow(Curlybars.configuration).to receive(:global_helpers_provider_classes).and_return([IntegrationTest::GlobalHelperProvider])
232
- end
233
-
234
- it "without errors when global helper" do
235
- dependency_tree = {}
236
-
237
- source = <<-HBS
238
- {{#if (global_helper)}} ... {{/if}}
239
- HBS
240
-
241
- errors = Curlybars.validate(dependency_tree, source)
242
-
243
- expect(errors).to be_empty
244
- end
245
-
246
- it "with errors when invoking a leaf" do
247
- dependency_tree = { name: nil }
248
-
249
- source = <<-HBS
250
- {{#if (name)}} ... {{/if}}
251
- HBS
252
-
253
- errors = Curlybars.validate(dependency_tree, source)
254
-
255
- expect(errors).not_to be_empty
256
- end
257
-
258
- it "without errors if argument is a leaf" do
259
- dependency_tree = { helper: :helper, argument: nil }
260
-
261
- source = <<-HBS
262
- {{#if (helper argument)}} ... {{/if}}
263
- HBS
264
-
265
- errors = Curlybars.validate(dependency_tree, source)
266
-
267
- expect(errors).to be_empty
268
- end
269
-
270
- it "without errors if argument is a literal" do
271
- dependency_tree = { helper: :helper }
272
-
273
- source = <<-HBS
274
- {{#if (helper 'argument')}} ... {{/if}}
275
- HBS
276
-
277
- errors = Curlybars.validate(dependency_tree, source)
278
-
279
- expect(errors).to be_empty
280
- end
281
-
282
- it "without errors if argument is a variable" do
283
- dependency_tree = { helper: :helper }
284
-
285
- source = <<-HBS
286
- {{#if (helper @var)}} ... {{/if}}
287
- HBS
288
-
289
- errors = Curlybars.validate(dependency_tree, source)
290
-
291
- expect(errors).to be_empty
292
- end
293
-
294
- it "without errors if argument is another subexpression" do
295
- dependency_tree = { helper: :helper }
296
-
297
- source = <<-HBS
298
- {{#if (helper (helper option='argument'))}} ... {{/if}}
299
- HBS
300
-
301
- errors = Curlybars.validate(dependency_tree, source)
302
-
303
- expect(errors).to be_empty
304
- end
305
-
306
- it "without errors if option is a leaf" do
307
- dependency_tree = { helper: :helper, argument: nil }
308
-
309
- source = <<-HBS
310
- {{#if (helper option=argument)}} ... {{/if}}
311
- HBS
312
-
313
- errors = Curlybars.validate(dependency_tree, source)
314
-
315
- expect(errors).to be_empty
316
- end
317
-
318
- it "without errors if option is a literal" do
319
- dependency_tree = { helper: :helper }
320
-
321
- source = <<-HBS
322
- {{#if (helper option='argument')}} ... {{/if}}
323
- HBS
324
-
325
- errors = Curlybars.validate(dependency_tree, source)
326
-
327
- expect(errors).to be_empty
328
- end
329
-
330
- it "without errors if option is a variable" do
331
- dependency_tree = { helper: :helper }
332
-
333
- source = <<-HBS
334
- {{#if (helper option=@var)}} ... {{/if}}
335
- HBS
336
-
337
- errors = Curlybars.validate(dependency_tree, source)
338
-
339
- expect(errors).to be_empty
340
- end
341
-
342
- it "without errors if option is another subexpression" do
343
- dependency_tree = { helper: :helper }
344
-
345
- source = <<-HBS
346
- {{#if (helper option=(helper))}} ... {{/if}}
347
- HBS
348
-
349
- errors = Curlybars.validate(dependency_tree, source)
350
-
351
- expect(errors).to be_empty
352
- end
353
-
354
- it "with errors when helper does not exist" do
355
- dependency_tree = {}
356
-
357
- source = <<-HBS
358
- {{#if (helper)}} ... {{/if}}
359
- HBS
360
-
361
- errors = Curlybars.validate(dependency_tree, source)
362
-
363
- expect(errors).not_to be_empty
364
- end
365
-
366
- it "with errors when invoking a leaf with arguments" do
367
- dependency_tree = { name: nil }
368
-
369
- source = <<-HBS
370
- {{#if (name 'argument')}} ... {{/if}}
371
- HBS
372
-
373
- errors = Curlybars.validate(dependency_tree, source)
374
-
375
- expect(errors).not_to be_empty
376
- end
377
-
378
- it "with errors when invoking a leaf with options" do
379
- dependency_tree = { name: nil }
380
-
381
- source = <<-HBS
382
- {{#if (name option='value')}} ... {{/if}}
383
- HBS
384
-
385
- errors = Curlybars.validate(dependency_tree, source)
386
-
387
- expect(errors).not_to be_empty
388
- end
389
-
390
- it "with errors if argument is not a value" do
391
- dependency_tree = { helper: :helper }
392
-
393
- source = <<-HBS
394
- {{#if (helper not_a_value)}} ... {{/if}}
395
- HBS
396
-
397
- errors = Curlybars.validate(dependency_tree, source)
398
-
399
- expect(errors).not_to be_empty
400
- end
401
-
402
- it "with errors if option is not a value" do
403
- dependency_tree = { helper: :helper }
404
-
405
- source = <<-HBS
406
- {{#if (helper option=not_a_value)}} ... {{/if}}
407
- HBS
408
-
409
- errors = Curlybars.validate(dependency_tree, source)
410
-
411
- expect(errors).not_to be_empty
412
- end
413
-
414
- it "without errors when invoking a helper with the result of a subexpression" do
415
- dependency_tree = { join: :helper, uppercase: :helper, article: nil }
416
-
417
- source = <<-HBS
418
- {{join (uppercase article) attribute='title' separator='-'}}
419
- HBS
420
-
421
- errors = Curlybars.validate(dependency_tree, source)
422
-
423
- expect(errors).to be_empty
424
- end
425
- end
426
- end
@@ -1,84 +0,0 @@
1
- describe "template" do
2
- let(:global_helpers_providers) { [] }
3
-
4
- describe "#compile" do
5
- let(:post) { double("post") }
6
- let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
7
-
8
- it "raises an exception when contexts stack is too deep (>= 10)" do
9
- template = Curlybars.compile(hbs_with_depth(10))
10
-
11
- expect do
12
- eval(template)
13
- end.to raise_error(Curlybars::Error::Render)
14
- end
15
-
16
- it "raises an exception when contexts stack is not too deep (< 10)" do
17
- template = Curlybars.compile(hbs_with_depth(9))
18
-
19
- expect do
20
- eval(template)
21
- end.not_to raise_error
22
- end
23
-
24
- it "can be empty" do
25
- template = Curlybars.compile('')
26
-
27
- expect(eval(template)).to resemble("")
28
- end
29
-
30
- it "can contain a single curly" do
31
- template = Curlybars.compile('{')
32
-
33
- expect(eval(template)).to resemble(<<-HTML)
34
- {
35
- HTML
36
- end
37
-
38
- it "can contain a single backslash" do
39
- template = Curlybars.compile('\\')
40
-
41
- expect(eval(template)).to resemble(<<-HTML)
42
- \\
43
- HTML
44
- end
45
-
46
- private
47
-
48
- def hbs_with_depth(depth)
49
- hbs = "%s"
50
- depth.times { hbs %= "{{#with this}}%s{{/with}}" }
51
- hbs %= ''
52
- end
53
- end
54
-
55
- describe "#validate" do
56
- it "without errors" do
57
- dependency_tree = { presenter: { field: nil } }
58
-
59
- source = <<-HBS
60
- {{#with presenter}}
61
- {{field}}
62
- {{/with}}
63
- HBS
64
-
65
- errors = Curlybars.validate(dependency_tree, source)
66
-
67
- expect(errors).to be_empty
68
- end
69
-
70
- it "with errors" do
71
- dependency_tree = { presenter: { field: nil } }
72
-
73
- source = <<-HBS
74
- {{#with presenter}}
75
- {{unallowed}}
76
- {{/with}}
77
- HBS
78
-
79
- errors = Curlybars.validate(dependency_tree, source)
80
-
81
- expect(errors).not_to be_empty
82
- end
83
- end
84
- end
@@ -1,139 +0,0 @@
1
- describe "{{#unless}}...{{else}}...{{/unless}}" do
2
- let(:global_helpers_providers) { [] }
3
-
4
- describe "#compile" do
5
- let(:post) { double("post") }
6
- let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
7
-
8
- it "renders the unless_template" do
9
- allow(presenter).to receive(:allows_method?).with(:condition).and_return(true)
10
- allow(presenter).to receive(:condition).and_return(false)
11
-
12
- template = Curlybars.compile(<<-HBS)
13
- {{#unless condition}}
14
- unless_template
15
- {{else}}
16
- else_template
17
- {{/unless}}
18
- HBS
19
-
20
- expect(eval(template)).to resemble(<<-HTML)
21
- unless_template
22
- HTML
23
- end
24
-
25
- it "renders the else_template" do
26
- allow(presenter).to receive(:allows_method?).with(:condition).and_return(true)
27
- allow(presenter).to receive(:condition).and_return(true)
28
-
29
- template = Curlybars.compile(<<-HBS)
30
- {{#unless condition}}
31
- unless_template
32
- {{else}}
33
- else_template
34
- {{/unless}}
35
- HBS
36
-
37
- expect(eval(template)).to resemble(<<-HTML)
38
- else_template
39
- HTML
40
- end
41
-
42
- it "allows empty else_template" do
43
- allow(presenter).to receive(:allows_method?).with(:valid).and_return(true)
44
- allow(presenter).to receive(:valid).and_return(false)
45
-
46
- template = Curlybars.compile(<<-HBS)
47
- {{#unless valid}}
48
- unless_template
49
- {{else}}{{/unless}}
50
- HBS
51
-
52
- expect(eval(template)).to resemble(<<-HTML)
53
- unless_template
54
- HTML
55
- end
56
-
57
- it "allows empty unless_template" do
58
- allow(presenter).to receive(:allows_method?).with(:valid).and_return(true)
59
- allow(presenter).to receive(:valid).and_return(true)
60
-
61
- template = Curlybars.compile(<<-HBS)
62
- {{#unless valid}}{{else}}
63
- else_template
64
- {{/unless}}
65
- HBS
66
-
67
- expect(eval(template)).to resemble(<<-HTML)
68
- else_template
69
- HTML
70
- end
71
-
72
- it "allows empty unless_template and else_template" do
73
- allow(presenter).to receive(:allows_method?).with(:valid).and_return(true)
74
- allow(presenter).to receive(:valid).and_return(false)
75
-
76
- template = Curlybars.compile(<<-HBS)
77
- {{#unless valid}}{{else}}{{/unless}}
78
- HBS
79
-
80
- expect(eval(template)).to resemble("")
81
- end
82
- end
83
-
84
- describe "#validate" do
85
- it "validates with errors the condition" do
86
- dependency_tree = {}
87
-
88
- source = <<-HBS
89
- {{#unless condition}}{{else}}{{/unless}}
90
- HBS
91
-
92
- errors = Curlybars.validate(dependency_tree, source)
93
-
94
- expect(errors).not_to be_empty
95
- end
96
-
97
- it "validates without errors when using a helper in the condition" do
98
- dependency_tree = { helper: :helper }
99
-
100
- source = <<-HBS
101
- {{#unless helper}}{{/unless}}
102
- HBS
103
-
104
- errors = Curlybars.validate(dependency_tree, source)
105
-
106
- expect(errors).to be_empty
107
- end
108
-
109
- it "validates with errors the nested unless_template" do
110
- dependency_tree = { condition: nil }
111
-
112
- source = <<-HBS
113
- {{#unless condition}}
114
- {{unallowed_method}}
115
- {{else}}
116
- {{/unless}}
117
- HBS
118
-
119
- errors = Curlybars.validate(dependency_tree, source)
120
-
121
- expect(errors).not_to be_empty
122
- end
123
-
124
- it "validates with errors the nested else_template" do
125
- dependency_tree = { condition: nil }
126
-
127
- source = <<-HBS
128
- {{#unless condition}}
129
- {{else}}
130
- {{unallowed_method}}
131
- {{/unless}}
132
- HBS
133
-
134
- errors = Curlybars.validate(dependency_tree, source)
135
-
136
- expect(errors).not_to be_empty
137
- end
138
- end
139
- end