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,421 +0,0 @@
1
- # rubocop:disable RSpec/MultipleMemoizedHelpers
2
- describe Curlybars::RenderingSupport do
3
- let(:file_name) { '/app/views/template.hbs' }
4
- let(:presenter) { double(:presenter, allows_method?: true, meth: :value) }
5
- let(:contexts) { [presenter] }
6
- let(:variables) { [{}] }
7
- let(:rendering) { Curlybars::RenderingSupport.new(1.second, contexts, variables, file_name) }
8
- let(:position) do
9
- double(:position, file_name: 'template.hbs', line_number: 1, line_offset: 0)
10
- end
11
-
12
- describe "#check_timeout!" do
13
- it "skips checking if timeout is nil" do
14
- rendering = Curlybars::RenderingSupport.new(nil, contexts, variables, file_name)
15
-
16
- sleep 0.1.seconds
17
- expect { rendering.check_timeout! }.not_to raise_error
18
- end
19
-
20
- it "doesn't happen when rendering is < rendering_timeout" do
21
- rendering = Curlybars::RenderingSupport.new(10.seconds, contexts, variables, file_name)
22
- expect { rendering.check_timeout! }.not_to raise_error
23
- end
24
-
25
- it "happens and raises when rendering >= rendering_timeout" do
26
- rendering = Curlybars::RenderingSupport.new(0.01.seconds, contexts, variables, file_name)
27
-
28
- sleep 0.1.seconds
29
- expect { rendering.check_timeout! }.to raise_error(Curlybars::Error::Render)
30
- end
31
- end
32
-
33
- describe "#to_bool" do
34
- describe "returns true" do
35
- it "with `true`" do
36
- expect(rendering.to_bool(true)).to be_truthy
37
- end
38
-
39
- it "with `[:non_empty]`" do
40
- expect(rendering.to_bool([:non_empty])).to be_truthy
41
- end
42
-
43
- it "with `1`" do
44
- expect(rendering.to_bool(1)).to be_truthy
45
- end
46
- end
47
-
48
- describe "returns false" do
49
- it "with `false`" do
50
- expect(rendering.to_bool(false)).to be_falsey
51
- end
52
-
53
- it "with `[]`" do
54
- expect(rendering.to_bool([])).to be_falsey
55
- end
56
-
57
- it "with `{}`" do
58
- expect(rendering.to_bool({})).to be_falsey
59
- end
60
-
61
- it "with `0`" do
62
- expect(rendering.to_bool(0)).to be_falsey
63
- end
64
-
65
- it "with `nil`" do
66
- expect(rendering.to_bool(nil)).to be_falsey
67
- end
68
- end
69
- end
70
-
71
- describe "#path" do
72
- it "returns the method in the current context" do
73
- allow_all_methods(presenter)
74
- allow(presenter).to receive(:method).and_return(:method)
75
-
76
- expect(rendering.path('method', rendering.position(0, 1))).to eq :method
77
- end
78
-
79
- it "returns the sub presenter method in the current context" do
80
- sub = double(:sub_presenter)
81
- allow_all_methods(sub)
82
- allow(sub).to receive(:method).and_return(:method)
83
-
84
- allow_all_methods(presenter)
85
- allow(presenter).to receive(:sub) { sub }
86
-
87
- expect(rendering.path('sub.method', rendering.position(0, 1))).to eq :method
88
- end
89
-
90
- it "returns the length of a collection, when `lenght` is the last step" do
91
- allow_all_methods(presenter)
92
- single_element_presenter = double(:single_element_presenter)
93
- allow_all_methods(single_element_presenter)
94
- collection = [single_element_presenter]
95
- allow(presenter).to receive(:collection) { collection }
96
-
97
- returned_method = rendering.path('collection.length', rendering.position(0, 1))
98
- expect(returned_method.call).to eq collection.length
99
- end
100
-
101
- it "raises an exception when the method is not allowed" do
102
- disallow_all_methods(presenter)
103
- allow(presenter).to receive(:forbidden_method).and_return(:forbidden_method)
104
-
105
- expect do
106
- rendering.path('forbidden_method', rendering.position(0, 1))
107
- end.to raise_error(Curlybars::Error::Render)
108
- end
109
-
110
- it "exposes the unallowed method in the exception payload" do
111
- disallow_all_methods(presenter)
112
- allow(presenter).to receive(:forbidden_method).and_return(:forbidden_method)
113
-
114
- begin
115
- rendering.path('forbidden_method', rendering.position(0, 1))
116
- rescue Curlybars::Error::Render => e
117
- expect(e.metadata).to eq(meth: :forbidden_method)
118
- end
119
- end
120
-
121
- it "raises an exception when the context is not a presenter" do
122
- sub = double(:not_presenter)
123
- allow(presenter).to receive(:sub) { sub }
124
-
125
- expect do
126
- rendering.path('sub.method', rendering.position(0, 1))
127
- end.to raise_error(Curlybars::Error::Render)
128
- end
129
-
130
- it "refers to the second to last presenter in the stack when using `../`" do
131
- sub = double(:sub_presenter)
132
- allow_all_methods(sub)
133
- allow(sub).to receive(:method).and_return(:sub_method)
134
-
135
- allow_all_methods(presenter)
136
- allow(presenter).to receive(:method).and_return(:root_method)
137
-
138
- contexts.push(sub)
139
-
140
- expect(rendering.path('../method', rendering.position(0, 1))).to eq :root_method
141
- end
142
-
143
- it "refers to the third to last presenter in the stack when using `../../`" do
144
- sub_sub = double(:sub_presenter)
145
- allow_all_methods(sub_sub)
146
- allow(sub_sub).to receive(:method).and_return(:sub_sub_method)
147
-
148
- sub = double(:sub_presenter)
149
- allow_all_methods(sub)
150
- allow(sub).to receive(:method).and_return(:sub_method)
151
-
152
- allow_all_methods(presenter)
153
- allow(presenter).to receive(:method).and_return(:root_method)
154
-
155
- contexts.push(sub)
156
- contexts.push(sub_sub)
157
-
158
- expect(rendering.path('../../method', rendering.position(0, 1))).to eq :root_method
159
- end
160
-
161
- it "returns a method that returns nil, if nil is returned from any method in the chain (except the latter)" do
162
- allow_all_methods(presenter)
163
- allow(presenter).to receive(:returns_nil).and_return(nil)
164
-
165
- outcome = rendering.path('returns_nil.another_method', rendering.position(0, 1)).call
166
- expect(outcome).to be_nil
167
- end
168
-
169
- it "returns a method that returns nil, if `../`` goes too deep in the stack" do
170
- outcome = rendering.path('../too_deep', rendering.position(0, 1)).call
171
- expect(outcome).to be_nil
172
- end
173
-
174
- it "raises an exception if tha path is too deep (> 10)" do
175
- expect do
176
- rendering.path('a.b.c.d.e.f.g.h.i.l', rendering.position(0, 1))
177
- end.to raise_error(Curlybars::Error::Render)
178
- end
179
- end
180
-
181
- describe "#cached_call" do
182
- it "(cache miss) calls the method if not cached already" do
183
- meth = presenter.method(:meth)
184
- allow(meth).to receive(:call)
185
-
186
- rendering.cached_call(meth)
187
-
188
- expect(meth).to have_received(:call).once
189
- end
190
-
191
- it "(cache hit) avoids to call a method for more than one time" do
192
- meth = presenter.method(:meth)
193
- allow(meth).to receive(:call)
194
-
195
- rendering.cached_call(meth)
196
- rendering.cached_call(meth)
197
-
198
- expect(meth).to have_received(:call).once
199
- end
200
-
201
- it "the returned cached value is the same as the uncached one" do
202
- meth = presenter.method(:meth)
203
-
204
- first_outcome = rendering.cached_call(meth)
205
- second_outcome = rendering.cached_call(meth)
206
-
207
- expect(second_outcome).to eq first_outcome
208
- end
209
- end
210
-
211
- describe "#call" do
212
- let(:block) { -> {} }
213
-
214
- it "calls with no arguments a method with no parameters" do
215
- method = -> { :return }
216
- arguments = []
217
-
218
- output = rendering.call(method, "method", position, arguments, :options, &block)
219
- expect(output).to eq :return
220
- end
221
-
222
- it "calls with one argument a method with no parameters, discarding the parameter" do
223
- method = -> { :return }
224
- arguments = [:argument]
225
-
226
- output = rendering.call(method, "method", position, arguments, :options, &block)
227
- expect(output).to eq :return
228
- end
229
-
230
- it "calls a method with only one parameter can only receive the options" do
231
- method = ->(parameter) { parameter }
232
- arguments = []
233
-
234
- output = rendering.call(method, "method", position, arguments, :options, &block)
235
- expect(output).to eq :options
236
- end
237
-
238
- it "calls a method with only one parameter can only receive the options, even with some arguments" do
239
- method = ->(parameter) { parameter }
240
- arguments = [:argument]
241
-
242
- output = rendering.call(method, "method", position, arguments, :options, &block)
243
- expect(output).to eq :options
244
- end
245
-
246
- it "calls a method with two parameter can receive nil as first argument and the options" do
247
- method = ->(parameter, options) { [parameter, options] }
248
- arguments = []
249
-
250
- output = rendering.call(method, "method", position, arguments, :options, &block)
251
- expect(output).to eq [nil, :options]
252
- end
253
-
254
- it "calls a method with two parameter can receive an argument and the options" do
255
- method = ->(parameter, options) { [parameter, options] }
256
- arguments = [:argument]
257
-
258
- output = rendering.call(method, "method", position, arguments, :options, &block)
259
- expect(output).to eq [:argument, :options]
260
- end
261
-
262
- it "calls a method with three parameter can receive two arguments and the options" do
263
- method = ->(first, second, options) { [first, second, options] }
264
- arguments = [:first, :second]
265
-
266
- output = rendering.call(method, "method", position, arguments, :options, &block)
267
- expect(output).to eq [:first, :second, :options]
268
- end
269
-
270
- it "calls a method with three parameter can receive one argument, nil and the options" do
271
- method = ->(first, second, options) { [first, second, options] }
272
- arguments = [:first]
273
-
274
- output = rendering.call(method, "method", position, arguments, :options, &block)
275
- expect(output).to eq [:first, nil, :options]
276
- end
277
-
278
- it "calls a method with three parameter can receive nil, nil and the options" do
279
- method = ->(first, second, options) { [first, second, options] }
280
- arguments = []
281
-
282
- output = rendering.call(method, "method", position, arguments, :options, &block)
283
- expect(output).to eq [nil, nil, :options]
284
- end
285
-
286
- it "calls a method passing an array as argument" do
287
- method = ->(parameter, _) { parameter }
288
- array = [1, 2, 3]
289
- arguments = [array]
290
-
291
- output = rendering.call(method, "method", position, arguments, :options, &block)
292
- expect(output).to eq arguments.first
293
- end
294
-
295
- it "raises Curlybars::Error::Render if the helper has at least an optional parameter" do
296
- method = ->(one, two = :optional) {}
297
- arguments = [:arg1]
298
- options = { key: :value }
299
-
300
- expect do
301
- rendering.call(method, "method", position, arguments, options, &block)
302
- end.to raise_error(Curlybars::Error::Render)
303
- end
304
-
305
- it "raises Curlybars::Error::Render if the helper has at least a keyword parameter" do
306
- method = ->(keyword:) {}
307
- arguments = [:arg1]
308
- options = { key: :value }
309
-
310
- expect do
311
- rendering.call(method, "method", position, arguments, options, &block)
312
- end.to raise_error(Curlybars::Error::Render)
313
- end
314
-
315
- it "raises Curlybars::Error::Render if the helper has at least an optional keyword parameter" do
316
- method = ->(keyword: :optional) {}
317
- arguments = [:arg1]
318
- options = { key: :value }
319
-
320
- expect do
321
- rendering.call(method, "meth", position, arguments, options, &block)
322
- end.to raise_error(Curlybars::Error::Render)
323
- end
324
- end
325
-
326
- describe "#position" do
327
- it "returns a position with file_name" do
328
- position = rendering.position(0, 0)
329
- expect(position.file_name).to eq file_name
330
- end
331
-
332
- it "returns a position with line_number" do
333
- position = rendering.position(1, 0)
334
- expect(position.line_number).to eq 1
335
- end
336
-
337
- it "returns a position with line_offset" do
338
- position = rendering.position(0, 1)
339
- expect(position.line_offset).to eq 1
340
- end
341
- end
342
-
343
- describe "#check_context_is_hash_or_enum_of_presenters" do
344
- it "doesn't raise an exception when argument is an empty enumerable" do
345
- collection = []
346
- rendering.check_context_is_hash_or_enum_of_presenters(collection, 'path', position)
347
- end
348
-
349
- it "doesn't raise an exception when argument is an empty hash" do
350
- collection = {}
351
- rendering.check_context_is_hash_or_enum_of_presenters(collection, nil, position)
352
- end
353
-
354
- it "doesn't raise an exception when argument is an enumerable of presenters" do
355
- collection = [presenter]
356
- rendering.check_context_is_hash_or_enum_of_presenters(collection, 'path', position)
357
- end
358
-
359
- it "doesn't raise an exception when argument is a hash of presenters" do
360
- collection = { presenter: presenter }
361
- rendering.check_context_is_hash_or_enum_of_presenters(collection, 'path', position)
362
- end
363
-
364
- it "raises when it is not an hash or an enumerable" do
365
- expect do
366
- rendering.check_context_is_hash_or_enum_of_presenters(:not_a_presenter, 'path', position)
367
- end.to raise_error(Curlybars::Error::Render)
368
- end
369
-
370
- it "raises when it is not an hash or an enumerable of presenters" do
371
- expect do
372
- rendering.check_context_is_hash_or_enum_of_presenters([:not_a_presenter], 'path', position)
373
- end.to raise_error(Curlybars::Error::Render)
374
- end
375
- end
376
-
377
- describe "#check_context_is_presenter" do
378
- it "doesn't raise an exception when argument is a presenter" do
379
- rendering.check_context_is_presenter(presenter, 'path', position)
380
- end
381
-
382
- it "raises when it is not a presenter" do
383
- expect do
384
- rendering.check_context_is_presenter(:not_a_presenter, 'path', position)
385
- end.to raise_error(Curlybars::Error::Render)
386
- end
387
- end
388
-
389
- describe "#coerce_to_hash!" do
390
- let(:a_presenter) { double(:a_presenter, allows_method?: true, meth: :value) }
391
- let(:another_presenter) { double(:another_presenter, allows_method?: true, meth: :value) }
392
-
393
- it "leaves hashes intacted" do
394
- hash = { first: a_presenter }
395
- expect(rendering.coerce_to_hash!(hash, 'path', position)).to be hash
396
- end
397
-
398
- it "transform an Array to a Hash" do
399
- array = [a_presenter, another_presenter]
400
- expected_hash = { 0 => a_presenter, 1 => another_presenter }
401
- expect(rendering.coerce_to_hash!(array, 'path', position)).to eq expected_hash
402
- end
403
-
404
- it "raises when it is not a hash or an enumerable" do
405
- expect do
406
- rendering.coerce_to_hash!(:not_a_presenter, 'path', position)
407
- end.to raise_error(Curlybars::Error::Render)
408
- end
409
- end
410
-
411
- private
412
-
413
- def allow_all_methods(presenter)
414
- allow(presenter).to receive(:allows_method?).and_return(true)
415
- end
416
-
417
- def disallow_all_methods(presenter)
418
- allow(presenter).to receive(:allows_method?).and_return(false)
419
- end
420
- end
421
- # rubocop:enable RSpec/MultipleMemoizedHelpers
@@ -1,46 +0,0 @@
1
- describe Curlybars::SafeBuffer do
2
- let(:configuration) { double(:configuration) }
3
-
4
- before do
5
- allow(Curlybars).to receive(:configuration) { configuration }
6
- end
7
-
8
- describe '#is_a?' do
9
- it "is a String" do
10
- expect(Curlybars::SafeBuffer.new).to be_a(String)
11
- end
12
-
13
- it "is a ActiveSupport::SafeBuffer" do
14
- expect(Curlybars::SafeBuffer.new).to be_a(ActiveSupport::SafeBuffer)
15
- end
16
- end
17
-
18
- describe "#concat" do
19
- it "accepts when (buffer length + the existing output lenght) <= output_limit" do
20
- allow(configuration).to receive(:output_limit).and_return(10)
21
-
22
- buffer = Curlybars::SafeBuffer.new('*' * 5)
23
-
24
- expect do
25
- buffer.concat('*' * 5)
26
- end.not_to raise_error
27
- end
28
-
29
- it "raises when (buffer length + the existing output lenght) > output_limit" do
30
- allow(configuration).to receive(:output_limit).and_return(10)
31
- buffer = Curlybars::SafeBuffer.new('*' * 10)
32
-
33
- expect do
34
- buffer.concat('*')
35
- end.to raise_error(Curlybars::Error::Render)
36
- end
37
-
38
- it "raises when buffer length > output_limit" do
39
- allow(configuration).to receive(:output_limit).and_return(10)
40
-
41
- expect do
42
- Curlybars::SafeBuffer.new.concat('*' * 11)
43
- end.to raise_error(Curlybars::Error::Render)
44
- end
45
- end
46
- end
@@ -1,225 +0,0 @@
1
- describe Curlybars::TemplateHandler do
2
- let :presenter_class do
3
- Class.new do
4
- def initialize(context, options = {})
5
- @context = context
6
- @cache_key = options.fetch(:cache_key, nil)
7
- @cache_duration = options.fetch(:cache_duration, nil)
8
- @cache_options = options.fetch(:cache_options, {})
9
- end
10
-
11
- def setup!
12
- @context.content_for(:foo, "bar")
13
- end
14
-
15
- def foo
16
- "FOO"
17
- end
18
-
19
- def bar
20
- @context.bar
21
- end
22
-
23
- def cache_key
24
- @cache_key
25
- end
26
-
27
- def cache_duration
28
- @cache_duration
29
- end
30
-
31
- def cache_options
32
- @cache_options
33
- end
34
-
35
- def allows_method?(method)
36
- true
37
- end
38
- end
39
- end
40
-
41
- let :context_class do
42
- Class.new do
43
- attr_reader :output_buffer
44
- attr_reader :local_assigns, :assigns
45
-
46
- def initialize
47
- @cache = Hash.new
48
- @local_assigns = Hash.new
49
- @assigns = Hash.new
50
- @clock = 0
51
- end
52
-
53
- def reset!
54
- @output_buffer = ActiveSupport::SafeBuffer.new
55
- end
56
-
57
- def advance_clock(duration)
58
- @clock += duration
59
- end
60
-
61
- def content_for(key, value = nil)
62
- @contents ||= {}
63
- @contents[key] = value if value.present?
64
- @contents[key]
65
- end
66
-
67
- def cache(key, options = {})
68
- fragment, expired_at = @cache[key]
69
-
70
- if fragment.nil? || @clock >= expired_at
71
- old_buffer = @output_buffer
72
- @output_buffer = ActiveSupport::SafeBuffer.new
73
-
74
- yield
75
-
76
- fragment = @output_buffer.to_s
77
- duration = options[:expires_in] || Float::INFINITY
78
-
79
- @cache[key] = [fragment, @clock + duration]
80
-
81
- @output_buffer = old_buffer
82
- end
83
-
84
- safe_concat(fragment)
85
-
86
- nil
87
- end
88
-
89
- def safe_concat(str)
90
- @output_buffer.safe_concat(str)
91
- end
92
- end
93
- end
94
-
95
- let(:template) { double("template", virtual_path: "test", identifier: "test.hbs") }
96
- let(:context) { context_class.new }
97
-
98
- before do
99
- stub_const("TestPresenter", presenter_class)
100
- end
101
-
102
- it "strips the `# encoding: *` directive away from the template" do
103
- output = render(<<~TEMPLATE)
104
- # encoding: utf-8"
105
- first line
106
- TEMPLATE
107
- expect(output).to eq(<<~TEMPLATE)
108
-
109
- first line
110
- TEMPLATE
111
- end
112
-
113
- it "passes in the presenter context to the presenter class" do
114
- allow(context).to receive(:bar).and_return("BAR")
115
- output = render("{{bar}}")
116
- expect(output).to eq("BAR")
117
- end
118
-
119
- it "fails if there's no matching presenter class" do
120
- allow(template).to receive(:virtual_path).and_return("missing")
121
- expect { render(" FOO ") }.to raise_exception(Curlybars::Error::Presenter::NotFound)
122
- end
123
-
124
- it "allows calling public methods on the presenter" do
125
- output = render("{{foo}}")
126
- expect(output).to eq("FOO")
127
- end
128
-
129
- it "marks its output as HTML safe" do
130
- output = render("{{foo}}")
131
- expect(output).to be_html_safe
132
- end
133
-
134
- it "calls the #setup! method before rendering the view" do
135
- render("{{foo}}")
136
- expect(context.content_for(:foo)).to eq("bar")
137
- end
138
-
139
- describe "caching" do
140
- before do
141
- allow(context).to receive(:bar).and_return("BAR")
142
- end
143
-
144
- let(:output) { -> { render("{{bar}}") } }
145
-
146
- it "caches the result with the #cache_key from the presenter" do
147
- context.assigns[:cache_key] = "x"
148
- expect(output.call).to eq("BAR")
149
-
150
- allow(context).to receive(:bar).and_return("BAZ")
151
- expect(output.call).to eq("BAR")
152
-
153
- context.assigns[:cache_key] = "y"
154
- expect(output.call).to eq("BAZ")
155
- end
156
-
157
- it "doesn't cache when the cache key is nil" do
158
- context.assigns[:cache_key] = nil
159
- expect(output.call).to eq("BAR")
160
-
161
- allow(context).to receive(:bar).and_return("BAZ")
162
- expect(output.call).to eq("BAZ")
163
- end
164
-
165
- it "adds the presenter class' cache key to the instance's cache key" do
166
- # Make sure caching is enabled
167
- context.assigns[:cache_key] = "x"
168
-
169
- allow(presenter_class).to receive(:cache_key).and_return("foo")
170
-
171
- expect(output.call).to eq("BAR")
172
-
173
- allow(presenter_class).to receive(:cache_key).and_return("bar")
174
-
175
- allow(context).to receive(:bar).and_return("FOOBAR")
176
- expect(output.call).to eq("FOOBAR")
177
- end
178
-
179
- it "expires the cache keys after #cache_duration" do
180
- context.assigns[:cache_key] = "x"
181
- context.assigns[:cache_duration] = 42
182
-
183
- expect(output.call).to eq("BAR")
184
-
185
- allow(context).to receive(:bar).and_return("FOO")
186
-
187
- # Cached fragment has not yet expired.
188
- context.advance_clock(41)
189
- expect(output.call).to eq("BAR")
190
-
191
- # Now it has! Huzzah!
192
- context.advance_clock(1)
193
- expect(output.call).to eq("FOO")
194
- end
195
-
196
- it "passes #cache_options to the cache backend" do
197
- context.assigns[:cache_key] = "x"
198
- context.assigns[:cache_options] = { expires_in: 42 }
199
-
200
- expect(output.call).to eq("BAR")
201
-
202
- allow(context).to receive(:bar).and_return("FOO")
203
-
204
- # Cached fragment has not yet expired.
205
- context.advance_clock(41)
206
- expect(output.call).to eq("BAR")
207
-
208
- # Now it has! Huzzah!
209
- context.advance_clock(1)
210
- expect(output.call).to eq("FOO")
211
- end
212
- end
213
-
214
- def render(source)
215
- if ActionView::VERSION::MAJOR < 6
216
- allow(template).to receive(:source).and_return(source)
217
- code = Curlybars::TemplateHandler.call(template)
218
- else
219
- code = Curlybars::TemplateHandler.call(template, source)
220
- end
221
-
222
- context.reset!
223
- context.instance_eval(code)
224
- end
225
- end