curlybars 1.5.1 → 1.6.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/curlybars.rb +0 -1
  3. data/lib/curlybars/configuration.rb +1 -9
  4. data/lib/curlybars/error/base.rb +2 -0
  5. data/lib/curlybars/method_whitelist.rb +5 -2
  6. data/lib/curlybars/node/block_helper_else.rb +1 -0
  7. data/lib/curlybars/node/path.rb +6 -0
  8. data/lib/curlybars/processor/tilde.rb +3 -0
  9. data/lib/curlybars/rendering_support.rb +8 -0
  10. data/lib/curlybars/template_handler.rb +18 -6
  11. data/lib/curlybars/version.rb +1 -1
  12. data/spec/acceptance/application_layout_spec.rb +2 -2
  13. data/spec/acceptance/collection_blocks_spec.rb +1 -1
  14. data/spec/acceptance/global_helper_spec.rb +1 -1
  15. data/spec/curlybars/lexer_spec.rb +3 -2
  16. data/spec/curlybars/rendering_support_spec.rb +4 -9
  17. data/spec/curlybars/template_handler_spec.rb +33 -30
  18. data/spec/integration/cache_spec.rb +20 -18
  19. data/spec/integration/node/block_helper_else_spec.rb +0 -2
  20. data/spec/integration/node/each_else_spec.rb +0 -2
  21. data/spec/integration/node/each_spec.rb +0 -2
  22. data/spec/integration/node/helper_spec.rb +0 -2
  23. data/spec/integration/node/if_else_spec.rb +0 -2
  24. data/spec/integration/node/if_spec.rb +0 -2
  25. data/spec/integration/node/output_spec.rb +0 -2
  26. data/spec/integration/node/partial_spec.rb +0 -2
  27. data/spec/integration/node/path_spec.rb +0 -2
  28. data/spec/integration/node/root_spec.rb +0 -2
  29. data/spec/integration/node/sub_expression_spec.rb +0 -2
  30. data/spec/integration/node/template_spec.rb +0 -2
  31. data/spec/integration/node/unless_else_spec.rb +0 -2
  32. data/spec/integration/node/unless_spec.rb +0 -2
  33. data/spec/integration/node/with_spec.rb +0 -2
  34. data/spec/integration/processors_spec.rb +0 -1
  35. metadata +41 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 307c759c2acc1c33ab91a236aeb5042e6ecfee67581eef05f468c241a722e1f6
4
- data.tar.gz: 68b0a401f830e5985d0d6b657974f84c2afdda2d49e70c696e97641845d31a16
3
+ metadata.gz: 2be6d03409f5c575fb33c7ba4ed74117420fd22ddca8272005c5f23e459a0d8e
4
+ data.tar.gz: ad11b01849c9d28a70b2ae2260615665cc2dc3ca3c380b9dfbc2ab9c91bf1de3
5
5
  SHA512:
6
- metadata.gz: 7db835baca28f2c15af2fb1a582059bb8346d1de41f8d9ed72262ea7ef1e2ff2e8130091b4e1494858b366f050e1b2fe2cf1753afbd1a403c66058c37f8fa9ff
7
- data.tar.gz: 9a54e30bba2976a6c6f0ff4e6fef5f00075dc6186a9eb07c70a63ead7a96629a17897ce9ea9e09fad00049262a891eb88b1389873b629ca22f12c7b712686166
6
+ metadata.gz: ba6035a72fd5cf75120cc3adfc663192dae68d75132887b801bd29a53c4b655f6be09ed6b8e4a2ee497e708172c38db19258215b5f3b1a9b788371db20eeac3c
7
+ data.tar.gz: 83961d2f0ef03848c1ffb3feb9db859c866ff90e74d173f116b16c3af5ff4eac710e934cd7b3bb5039749f05169bd4f95e3f19fc208163f3333a6d66ba7261df
@@ -118,7 +118,6 @@ require 'curlybars/rendering_support'
118
118
  require 'curlybars/parser'
119
119
  require 'curlybars/position'
120
120
  require 'curlybars/lexer'
121
- require 'curlybars/parser'
122
121
  require 'curlybars/processor/token_factory'
123
122
  require 'curlybars/processor/tilde'
124
123
  require 'curlybars/error/lex'
@@ -16,15 +16,7 @@ module Curlybars
16
16
  end
17
17
 
18
18
  class Configuration
19
- attr_accessor :presenters_namespace
20
- attr_accessor :nesting_limit
21
- attr_accessor :traversing_limit
22
- attr_accessor :output_limit
23
- attr_accessor :rendering_timeout
24
- attr_accessor :custom_processors
25
- attr_accessor :compiler_transformers
26
- attr_accessor :global_helpers_provider_classes
27
- attr_accessor :cache
19
+ attr_accessor :presenters_namespace, :nesting_limit, :traversing_limit, :output_limit, :rendering_timeout, :custom_processors, :compiler_transformers, :global_helpers_provider_classes, :cache
28
20
 
29
21
  def initialize
30
22
  @presenters_namespace = ''
@@ -8,8 +8,10 @@ module Curlybars
8
8
  @id = id
9
9
  @position = position
10
10
  @metadata = metadata
11
+
11
12
  return if position.nil?
12
13
  return if position.file_name.nil?
14
+
13
15
  location = "%s:%d:%d" % [position.file_name, position.line_number, position.line_offset]
14
16
  set_backtrace([location])
15
17
  end
@@ -1,5 +1,6 @@
1
1
  module Curlybars
2
2
  module MethodWhitelist
3
+ # rubocop:disable Style/SoleNestedConditional
3
4
  def allow_methods(*methods_without_type, **methods_with_type, &contextual_block)
4
5
  methods_with_type_validator = lambda do |methods_to_validate|
5
6
  methods_to_validate.each do |(method_name, type)|
@@ -49,8 +50,8 @@ module Curlybars
49
50
  memo[method] = nil
50
51
  end
51
52
 
52
- methods_with_type_resolved = all_methods_with_type.each_with_object({}) do |(method_name, type), memo|
53
- memo[method_name] = if type.respond_to?(:call)
53
+ methods_with_type_resolved = all_methods_with_type.transform_values do |type|
54
+ if type.respond_to?(:call)
54
55
  type.call(context)
55
56
  else
56
57
  type
@@ -65,6 +66,7 @@ module Curlybars
65
66
  # Included modules
66
67
  included_modules.each do |mod|
67
68
  next unless mod.respond_to?(:methods_schema)
69
+
68
70
  schema.merge!(mod.methods_schema(context))
69
71
  end
70
72
 
@@ -90,6 +92,7 @@ module Curlybars
90
92
  allowed_methods.include?(method)
91
93
  end
92
94
  end
95
+ # rubocop:enable Style/SoleNestedConditional
93
96
 
94
97
  def self.extended(base)
95
98
  # define a default of no method allowed
@@ -100,6 +100,7 @@ module Curlybars
100
100
 
101
101
  def check_open_and_close_elements(helper, helperclose, error_class)
102
102
  return unless helper.path != helperclose.path
103
+
103
104
  message = "block `#{helper.path}` cannot be closed by `#{helperclose.path}`"
104
105
  raise error_class.new('closing_tag_mismatch', message, helperclose.position)
105
106
  end
@@ -109,26 +109,32 @@ module Curlybars
109
109
  case check_type
110
110
  when :presenter
111
111
  return if presenter?(branches)
112
+
112
113
  message = "`#{path}` must resolve to a presenter"
113
114
  raise Curlybars::Error::Validate.new('not_a_presenter', message, position)
114
115
  when :presenter_collection
115
116
  return if presenter_collection?(branches)
117
+
116
118
  message = "`#{path}` must resolve to a collection of presenters"
117
119
  raise Curlybars::Error::Validate.new('not_a_presenter_collection', message, position)
118
120
  when :leaf
119
121
  return if leaf?(branches)
122
+
120
123
  message = "`#{path}` cannot resolve to a component"
121
124
  raise Curlybars::Error::Validate.new('not_a_leaf', message, position)
122
125
  when :partial
123
126
  return if partial?(branches)
127
+
124
128
  message = "`#{path}` cannot resolve to a partial"
125
129
  raise Curlybars::Error::Validate.new('not_a_partial', message, position)
126
130
  when :helper
127
131
  return if helper?(branches)
132
+
128
133
  message = "`#{path}` cannot resolve to a helper"
129
134
  raise Curlybars::Error::Validate.new('not_a_helper', message, position)
130
135
  when :not_helper
131
136
  return unless helper?(branches)
137
+
132
138
  message = "`#{path}` resolves to a helper"
133
139
  raise Curlybars::Error::Validate.new('is_a_helper', message, position)
134
140
  when :anything
@@ -10,10 +10,12 @@ module Curlybars
10
10
  when :TILDE_START
11
11
  tokens[index] = create_token(:START, token.value, token.position)
12
12
  next if index == 0
13
+
13
14
  strip_token_if_text(tokens, index - 1, :rstrip)
14
15
  when :TILDE_END
15
16
  tokens[index] = create_token(:END, token.value, token.position)
16
17
  next if index == (tokens.length - 1)
18
+
17
19
  strip_token_if_text(tokens, index + 1, :lstrip)
18
20
  end
19
21
  end
@@ -22,6 +24,7 @@ module Curlybars
22
24
  def strip_token_if_text(tokens, index, strip_method)
23
25
  token = tokens[index]
24
26
  return if token.type != :TEXT
27
+
25
28
  stripped_value = token.value.public_send(strip_method)
26
29
  tokens[index] = create_token(token.type, stripped_value, token.position)
27
30
  end
@@ -23,12 +23,14 @@ module Curlybars
23
23
  def check_timeout!
24
24
  return unless timeout.present?
25
25
  return unless (Time.now - start_time) > timeout
26
+
26
27
  message = "Rendering took too long (> #{timeout} seconds)"
27
28
  raise ::Curlybars::Error::Render.new('timeout', message, nil)
28
29
  end
29
30
 
30
31
  def check_context_is_presenter(context, path, position)
31
32
  return if presenter?(context)
33
+
32
34
  message = "`#{path}` is not a context type object"
33
35
  raise Curlybars::Error::Render.new('context_is_not_a_presenter', message, position)
34
36
  end
@@ -83,9 +85,11 @@ module Curlybars
83
85
  resolved = chain.inject(base_context) do |context, meth|
84
86
  next context if meth == 'this'
85
87
  next context.count if meth == 'length' && presenter_collection?(context)
88
+
86
89
  raise_if_not_traversable(context, meth, position)
87
90
  outcome = instrument(context.method(meth)) { context.public_send(meth) }
88
91
  return -> {} if outcome.nil?
92
+
89
93
  outcome
90
94
  end
91
95
 
@@ -101,6 +105,7 @@ module Curlybars
101
105
 
102
106
  def cached_call(meth)
103
107
  return cached_calls[meth] if cached_calls.key? meth
108
+
104
109
  instrument(meth) { cached_calls[meth] = meth.call(*arguments_for_signature(meth, [], {})) }
105
110
  end
106
111
 
@@ -202,6 +207,7 @@ module Curlybars
202
207
 
203
208
  def check_context_allows_method(context, meth, position)
204
209
  return if context.allows_method?(meth.to_sym)
210
+
205
211
  message = "`#{meth}` is not available - "
206
212
  message += "add `allow_methods :#{meth}` to #{context.class} to allow this path"
207
213
  raise Curlybars::Error::Render.new('unallowed_path', message, position, meth: meth.to_sym)
@@ -209,12 +215,14 @@ module Curlybars
209
215
 
210
216
  def check_context_has_method(context, meth, position)
211
217
  return if context.respond_to?(meth.to_sym)
218
+
212
219
  message = "`#{meth}` is not available in #{context.class}"
213
220
  raise Curlybars::Error::Render.new('unallowed_path', message, position)
214
221
  end
215
222
 
216
223
  def check_traverse_not_too_deep(traverse, position)
217
224
  return unless traverse.count('.') > Curlybars.configuration.traversing_limit
225
+
218
226
  message = "`#{traverse}` too deep"
219
227
  raise Curlybars::Error::Render.new('traverse_too_deep', message, position)
220
228
  end
@@ -13,9 +13,17 @@ module Curlybars
13
13
  # template - The ActionView::Template template that should be compiled.
14
14
  #
15
15
  # Returns a String containing the Ruby code representing the template.
16
- def call(template)
17
- instrument(template) do
18
- compile(template)
16
+ if ActionView::VERSION::MAJOR < 6
17
+ def call(template)
18
+ instrument(template) do
19
+ compile_for_actionview5(template)
20
+ end
21
+ end
22
+ else
23
+ def call(template, source)
24
+ instrument(template) do
25
+ compile(template, source)
26
+ end
19
27
  end
20
28
  end
21
29
 
@@ -43,9 +51,13 @@ module Curlybars
43
51
 
44
52
  private
45
53
 
46
- def compile(template)
54
+ def compile_for_actionview5(template)
55
+ compile(template, template.source)
56
+ end
57
+
58
+ def compile(template, source)
47
59
  # Template is empty, so there's no need to initialize a presenter.
48
- return %("") if template.source.empty?
60
+ return %("") if source.empty?
49
61
 
50
62
  path = template.virtual_path
51
63
  presenter_class = Curlybars::Presenter.presenter_for_path(path)
@@ -55,7 +67,7 @@ module Curlybars
55
67
  # For security reason, we strip the encoding directive in order to avoid
56
68
  # potential issues when rendering the template in another character
57
69
  # encoding.
58
- safe_source = template.source.gsub(/\A#{ActionView::ENCODING_FLAG}/, '')
70
+ safe_source = source.gsub(/\A#{ActionView::ENCODING_FLAG}/, '')
59
71
 
60
72
  source = Curlybars.compile(safe_source, template.identifier)
61
73
 
@@ -1,3 +1,3 @@
1
1
  module Curlybars
2
- VERSION = '1.5.1'.freeze
2
+ VERSION = '1.6.0'.freeze
3
3
  end
@@ -2,7 +2,7 @@ describe "Using Curlybars for the application layout", type: :request do
2
2
  example "A simple layout view in Curlybars" do
3
3
  get '/'
4
4
 
5
- expect(body).to eq(<<-HTML.strip_heredoc)
5
+ expect(body).to eq(<<~HTML)
6
6
  <html>
7
7
  <head>
8
8
  <title>Dummy app</title>
@@ -31,7 +31,7 @@ describe "Using Curlybars for the application layout", type: :request do
31
31
  example "A simple layout view in Curlybars with html safe logic" do
32
32
  get '/articles/1'
33
33
 
34
- expect(body).to eq(<<-HTML.strip_heredoc)
34
+ expect(body).to eq(<<~HTML)
35
35
  <html>
36
36
  <head>
37
37
  <title>Dummy app</title>
@@ -8,7 +8,7 @@ describe "Collection blocks", type: :request do
8
8
  example "Rendering collections" do
9
9
  get '/categories'
10
10
 
11
- expect(body).to eq(<<-HTML.strip_heredoc)
11
+ expect(body).to eq(<<~HTML)
12
12
  <html>
13
13
  <head>
14
14
  <title>Dummy app</title>
@@ -9,7 +9,7 @@ describe "Collection blocks", type: :request do
9
9
  example "Render a global helper" do
10
10
  get '/welcome'
11
11
 
12
- expect(body).to eq(<<-HTML.strip_heredoc)
12
+ expect(body).to eq(<<~HTML)
13
13
  <html>
14
14
  <head>
15
15
  <title>Dummy app</title>
@@ -37,6 +37,7 @@ describe Curlybars::Lexer do
37
37
  it "is resilient to whitespaces" do
38
38
  expect(lex('{{! }}')).to produce []
39
39
  end
40
+
40
41
  it "is resilient to newlines" do
41
42
  expect(lex("{{!\n}}")).to produce []
42
43
  end
@@ -202,7 +203,7 @@ describe Curlybars::Lexer do
202
203
  end
203
204
  end
204
205
 
205
- # rubocop:disable Layout/AlignArray
206
+ # rubocop:disable Layout/ArrayAlignment
206
207
  describe "{{#if path}}...{{else}}...{{/if}}" do
207
208
  it "is lexed" do
208
209
  expect(lex('{{#if path}} text {{else}} text {{/if}}')).to produce(
@@ -320,7 +321,7 @@ describe Curlybars::Lexer do
320
321
  )
321
322
  end
322
323
  end
323
- # rubocop:enable Layout/AlignArray
324
+ # rubocop:enable Layout/ArrayAlignment
324
325
 
325
326
  describe "{{#with path}}...{{/with}}" do
326
327
  it "is lexed" do
@@ -1,3 +1,4 @@
1
+ # rubocop:disable RSpec/MultipleMemoizedHelpers
1
2
  describe Curlybars::RenderingSupport do
2
3
  let(:file_name) { '/app/views/template.hbs' }
3
4
  let(:presenter) { double(:presenter, allows_method?: true, meth: :value) }
@@ -7,7 +8,6 @@ describe Curlybars::RenderingSupport do
7
8
  let(:position) do
8
9
  double(:position, file_name: 'template.hbs', line_number: 1, line_offset: 0)
9
10
  end
10
- let(:block) { -> {} }
11
11
 
12
12
  describe "#check_timeout!" do
13
13
  it "skips checking if timeout is nil" do
@@ -179,14 +179,6 @@ describe Curlybars::RenderingSupport do
179
179
  end
180
180
 
181
181
  describe "#cached_call" do
182
- before do
183
- class APresenter
184
- def meth
185
- :value
186
- end
187
- end
188
- end
189
-
190
182
  it "(cache miss) calls the method if not cached already" do
191
183
  meth = presenter.method(:meth)
192
184
  allow(meth).to receive(:call)
@@ -217,6 +209,8 @@ describe Curlybars::RenderingSupport do
217
209
  end
218
210
 
219
211
  describe "#call" do
212
+ let(:block) { -> {} }
213
+
220
214
  it "calls with no arguments a method with no parameters" do
221
215
  method = -> { :return }
222
216
  arguments = []
@@ -424,3 +418,4 @@ describe Curlybars::RenderingSupport do
424
418
  allow(presenter).to receive(:allows_method?).and_return(false)
425
419
  end
426
420
  end
421
+ # rubocop:enable RSpec/MultipleMemoizedHelpers
@@ -100,13 +100,11 @@ describe Curlybars::TemplateHandler do
100
100
  end
101
101
 
102
102
  it "strips the `# encoding: *` directive away from the template" do
103
- allow(template).to receive(:source) do
104
- <<-TEMPLATE.strip_heredoc
105
- # encoding: utf-8"
106
- first line
107
- TEMPLATE
108
- end
109
- expect(output).to eq(<<-TEMPLATE.strip_heredoc)
103
+ output = render(<<~TEMPLATE)
104
+ # encoding: utf-8"
105
+ first line
106
+ TEMPLATE
107
+ expect(output).to eq(<<~TEMPLATE)
110
108
 
111
109
  first line
112
110
  TEMPLATE
@@ -114,55 +112,54 @@ describe Curlybars::TemplateHandler do
114
112
 
115
113
  it "passes in the presenter context to the presenter class" do
116
114
  allow(context).to receive(:bar).and_return("BAR")
117
- allow(template).to receive(:source).and_return("{{bar}}")
115
+ output = render("{{bar}}")
118
116
  expect(output).to eq("BAR")
119
117
  end
120
118
 
121
119
  it "fails if there's no matching presenter class" do
122
120
  allow(template).to receive(:virtual_path).and_return("missing")
123
- allow(template).to receive(:source).and_return(" FOO ")
124
- expect { output }.to raise_exception(Curlybars::Error::Presenter::NotFound)
121
+ expect { render(" FOO ") }.to raise_exception(Curlybars::Error::Presenter::NotFound)
125
122
  end
126
123
 
127
124
  it "allows calling public methods on the presenter" do
128
- allow(template).to receive(:source).and_return("{{foo}}")
125
+ output = render("{{foo}}")
129
126
  expect(output).to eq("FOO")
130
127
  end
131
128
 
132
129
  it "marks its output as HTML safe" do
133
- allow(template).to receive(:source).and_return("{{foo}}")
130
+ output = render("{{foo}}")
134
131
  expect(output).to be_html_safe
135
132
  end
136
133
 
137
134
  it "calls the #setup! method before rendering the view" do
138
- allow(template).to receive(:source).and_return("{{foo}}")
139
- output
135
+ render("{{foo}}")
140
136
  expect(context.content_for(:foo)).to eq("bar")
141
137
  end
142
138
 
143
139
  describe "caching" do
144
140
  before do
145
- allow(template).to receive(:source).and_return("{{bar}}")
146
141
  allow(context).to receive(:bar).and_return("BAR")
147
142
  end
148
143
 
144
+ let(:output) { -> { render("{{bar}}") } }
145
+
149
146
  it "caches the result with the #cache_key from the presenter" do
150
147
  context.assigns[:cache_key] = "x"
151
- expect(output).to eq("BAR")
148
+ expect(output.call).to eq("BAR")
152
149
 
153
150
  allow(context).to receive(:bar).and_return("BAZ")
154
- expect(output).to eq("BAR")
151
+ expect(output.call).to eq("BAR")
155
152
 
156
153
  context.assigns[:cache_key] = "y"
157
- expect(output).to eq("BAZ")
154
+ expect(output.call).to eq("BAZ")
158
155
  end
159
156
 
160
157
  it "doesn't cache when the cache key is nil" do
161
158
  context.assigns[:cache_key] = nil
162
- expect(output).to eq("BAR")
159
+ expect(output.call).to eq("BAR")
163
160
 
164
161
  allow(context).to receive(:bar).and_return("BAZ")
165
- expect(output).to eq("BAZ")
162
+ expect(output.call).to eq("BAZ")
166
163
  end
167
164
 
168
165
  it "adds the presenter class' cache key to the instance's cache key" do
@@ -171,51 +168,57 @@ describe Curlybars::TemplateHandler do
171
168
 
172
169
  allow(presenter_class).to receive(:cache_key).and_return("foo")
173
170
 
174
- expect(output).to eq("BAR")
171
+ expect(output.call).to eq("BAR")
175
172
 
176
173
  allow(presenter_class).to receive(:cache_key).and_return("bar")
177
174
 
178
175
  allow(context).to receive(:bar).and_return("FOOBAR")
179
- expect(output).to eq("FOOBAR")
176
+ expect(output.call).to eq("FOOBAR")
180
177
  end
181
178
 
182
179
  it "expires the cache keys after #cache_duration" do
183
180
  context.assigns[:cache_key] = "x"
184
181
  context.assigns[:cache_duration] = 42
185
182
 
186
- expect(output).to eq("BAR")
183
+ expect(output.call).to eq("BAR")
187
184
 
188
185
  allow(context).to receive(:bar).and_return("FOO")
189
186
 
190
187
  # Cached fragment has not yet expired.
191
188
  context.advance_clock(41)
192
- expect(output).to eq("BAR")
189
+ expect(output.call).to eq("BAR")
193
190
 
194
191
  # Now it has! Huzzah!
195
192
  context.advance_clock(1)
196
- expect(output).to eq("FOO")
193
+ expect(output.call).to eq("FOO")
197
194
  end
198
195
 
199
196
  it "passes #cache_options to the cache backend" do
200
197
  context.assigns[:cache_key] = "x"
201
198
  context.assigns[:cache_options] = { expires_in: 42 }
202
199
 
203
- expect(output).to eq("BAR")
200
+ expect(output.call).to eq("BAR")
204
201
 
205
202
  allow(context).to receive(:bar).and_return("FOO")
206
203
 
207
204
  # Cached fragment has not yet expired.
208
205
  context.advance_clock(41)
209
- expect(output).to eq("BAR")
206
+ expect(output.call).to eq("BAR")
210
207
 
211
208
  # Now it has! Huzzah!
212
209
  context.advance_clock(1)
213
- expect(output).to eq("FOO")
210
+ expect(output.call).to eq("FOO")
214
211
  end
215
212
  end
216
213
 
217
- def output
218
- code = Curlybars::TemplateHandler.call(template)
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
+
219
222
  context.reset!
220
223
  context.instance_eval(code)
221
224
  end
@@ -1,29 +1,31 @@
1
1
  describe "caching" do
2
- class DummyCache
3
- attr_reader :reads, :hits
4
-
5
- def initialize
6
- @store = {}
7
- @reads = 0
8
- @hits = 0
9
- end
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
10
11
 
11
- def fetch(key)
12
- @reads += 1
13
- if @store.key?(key)
14
- @hits += 1
15
- @store[key]
16
- else
17
- value = yield
18
- @store[key] = value
19
- value
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
20
22
  end
21
23
  end
22
24
  end
23
25
 
24
26
  let(:global_helpers_providers) { [] }
25
27
  let(:presenter) { IntegrationTest::Presenter.new(double("view_context")) }
26
- let(:cache) { DummyCache.new }
28
+ let(:cache) { dummy_cache.new }
27
29
 
28
30
  before do
29
31
  Curlybars.configure do |config|
@@ -230,8 +230,6 @@ describe "{{#helper arg1 arg2 ... key=value ...}}...<{{else}}>...{{/helper}}" do
230
230
  end
231
231
 
232
232
  describe "#validate" do
233
- let(:presenter_class) { double(:presenter_class) }
234
-
235
233
  it "without errors when global helper" do
236
234
  allow(Curlybars.configuration).to receive(:global_helpers_provider_classes).and_return([IntegrationTest::GlobalHelperProvider])
237
235
 
@@ -151,8 +151,6 @@ describe "{{#each collection}}...{{else}}...{{/each}}" do
151
151
  end
152
152
 
153
153
  describe "#validate" do
154
- let(:presenter_class) { double(:presenter_class) }
155
-
156
154
  it "without errors" do
157
155
  dependency_tree = { a_presenter_collection: [{}] }
158
156
 
@@ -238,8 +238,6 @@ describe "{{#each collection}}...{{/each}}" do
238
238
  end
239
239
 
240
240
  describe "#validate" do
241
- let(:presenter_class) { double(:presenter_class) }
242
-
243
241
  it "without errors" do
244
242
  dependency_tree = { a_presenter_collection: [{}] }
245
243
 
@@ -121,8 +121,6 @@ describe "{{helper context key=value}}" do
121
121
  end
122
122
 
123
123
  describe "#validate" do
124
- let(:presenter_class) { double(:presenter_class) }
125
-
126
124
  it "with errors" do
127
125
  dependency_tree = {}
128
126
 
@@ -82,8 +82,6 @@ describe "{{#if}}...{{else}}...{{/if}}" do
82
82
  end
83
83
 
84
84
  describe "#validate" do
85
- let(:presenter_class) { double(:presenter_class) }
86
-
87
85
  it "validates without errors the literal condition" do
88
86
  dependency_tree = {}
89
87
 
@@ -112,8 +112,6 @@ describe "{{#if}}...{{/if}}" do
112
112
  end
113
113
 
114
114
  describe "#validate" do
115
- let(:presenter_class) { double(:presenter_class) }
116
-
117
115
  it "validates with errors the condition" do
118
116
  dependency_tree = {}
119
117
 
@@ -51,8 +51,6 @@ describe '{{value}}' do
51
51
  end
52
52
 
53
53
  describe "#validate" do
54
- let(:presenter_class) { double(:presenter_class) }
55
-
56
54
  it "validates the path with errors" do
57
55
  dependency_tree = {}
58
56
 
@@ -25,8 +25,6 @@ describe "{{> partial}}" do
25
25
  end
26
26
 
27
27
  describe "#validate" do
28
- let(:presenter_class) { double(:presenter_class) }
29
-
30
28
  it "validates the path with errors" do
31
29
  dependency_tree = {}
32
30
 
@@ -123,8 +123,6 @@ describe "{{path}}" do
123
123
  end
124
124
 
125
125
  describe "#validate" do
126
- let(:presenter_class) { double(:presenter_class) }
127
-
128
126
  it "without errors" do
129
127
  dependency_tree = { sub_context: {}, outer_field: nil }
130
128
 
@@ -1,7 +1,5 @@
1
1
  describe "root" do
2
2
  describe "#validate" do
3
- let(:presenter_class) { double(:presenter_class) }
4
-
5
3
  it "without errors if template is empty" do
6
4
  dependency_tree = {}
7
5
 
@@ -227,8 +227,6 @@ describe "{{(helper arg1 arg2 ... key=value ...)}}" do
227
227
  end
228
228
 
229
229
  describe "#validate" do
230
- let(:presenter_class) { double(:presenter_class) }
231
-
232
230
  before do
233
231
  allow(Curlybars.configuration).to receive(:global_helpers_provider_classes).and_return([IntegrationTest::GlobalHelperProvider])
234
232
  end
@@ -53,8 +53,6 @@ describe "template" do
53
53
  end
54
54
 
55
55
  describe "#validate" do
56
- let(:presenter_class) { double(:presenter_class) }
57
-
58
56
  it "without errors" do
59
57
  dependency_tree = { presenter: { field: nil } }
60
58
 
@@ -82,8 +82,6 @@ describe "{{#unless}}...{{else}}...{{/unless}}" do
82
82
  end
83
83
 
84
84
  describe "#validate" do
85
- let(:presenter_class) { double(:presenter_class) }
86
-
87
85
  it "validates with errors the condition" do
88
86
  dependency_tree = {}
89
87
 
@@ -99,8 +99,6 @@ describe "{{#unless}}...{{/unless}}" do
99
99
  end
100
100
 
101
101
  describe "#validate" do
102
- let(:presenter_class) { double(:presenter_class) }
103
-
104
102
  it "validates with errors the condition" do
105
103
  dependency_tree = {}
106
104
 
@@ -75,8 +75,6 @@ describe "{{#with presenter}}...{{/with}}" do
75
75
  end
76
76
 
77
77
  describe "#validate" do
78
- let(:presenter_class) { double(:presenter_class) }
79
-
80
78
  it "without errors" do
81
79
  dependency_tree = { a_presenter: {} }
82
80
 
@@ -1,6 +1,5 @@
1
1
  describe "processors" do
2
2
  let(:presenter) { double(:presenter, dependency_tree: { curlybars: nil }) }
3
- let(:global_helpers_providers) { [] }
4
3
  let(:processor) { double(:processor) }
5
4
 
6
5
  before do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curlybars
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Libo Cannici
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2020-11-02 00:00:00.000000000 Z
17
+ date: 2021-01-05 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: actionpack
@@ -25,7 +25,7 @@ dependencies:
25
25
  version: '4.2'
26
26
  - - "<"
27
27
  - !ruby/object:Gem::Version
28
- version: '6.0'
28
+ version: '6.2'
29
29
  type: :runtime
30
30
  prerelease: false
31
31
  version_requirements: !ruby/object:Gem::Requirement
@@ -35,7 +35,7 @@ dependencies:
35
35
  version: '4.2'
36
36
  - - "<"
37
37
  - !ruby/object:Gem::Version
38
- version: '6.0'
38
+ version: '6.2'
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: activesupport
41
41
  requirement: !ruby/object:Gem::Requirement
@@ -45,7 +45,7 @@ dependencies:
45
45
  version: '4.2'
46
46
  - - "<"
47
47
  - !ruby/object:Gem::Version
48
- version: '6.0'
48
+ version: '6.2'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
@@ -55,7 +55,7 @@ dependencies:
55
55
  version: '4.2'
56
56
  - - "<"
57
57
  - !ruby/object:Gem::Version
58
- version: '6.0'
58
+ version: '6.2'
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: ffi
61
61
  requirement: !ruby/object:Gem::Requirement
@@ -121,7 +121,7 @@ dependencies:
121
121
  version: '4.2'
122
122
  - - "<"
123
123
  - !ruby/object:Gem::Version
124
- version: '6.0'
124
+ version: '6.2'
125
125
  type: :development
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
@@ -131,7 +131,7 @@ dependencies:
131
131
  version: '4.2'
132
132
  - - "<"
133
133
  - !ruby/object:Gem::Version
134
- version: '6.0'
134
+ version: '6.2'
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: rake
137
137
  requirement: !ruby/object:Gem::Requirement
@@ -166,28 +166,56 @@ dependencies:
166
166
  requirements:
167
167
  - - "~>"
168
168
  - !ruby/object:Gem::Version
169
- version: 0.58.2
169
+ version: 1.6.0
170
170
  type: :development
171
171
  prerelease: false
172
172
  version_requirements: !ruby/object:Gem::Requirement
173
173
  requirements:
174
174
  - - "~>"
175
175
  - !ruby/object:Gem::Version
176
- version: 0.58.2
176
+ version: 1.6.0
177
+ - !ruby/object:Gem::Dependency
178
+ name: rubocop-performance
179
+ requirement: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - "~>"
182
+ - !ruby/object:Gem::Version
183
+ version: 1.9.0
184
+ type: :development
185
+ prerelease: false
186
+ version_requirements: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - "~>"
189
+ - !ruby/object:Gem::Version
190
+ version: 1.9.0
191
+ - !ruby/object:Gem::Dependency
192
+ name: rubocop-rake
193
+ requirement: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - "~>"
196
+ - !ruby/object:Gem::Version
197
+ version: 0.5.0
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - "~>"
203
+ - !ruby/object:Gem::Version
204
+ version: 0.5.0
177
205
  - !ruby/object:Gem::Dependency
178
206
  name: rubocop-rspec
179
207
  requirement: !ruby/object:Gem::Requirement
180
208
  requirements:
181
209
  - - "~>"
182
210
  - !ruby/object:Gem::Version
183
- version: 1.28.0
211
+ version: 2.1.0
184
212
  type: :development
185
213
  prerelease: false
186
214
  version_requirements: !ruby/object:Gem::Requirement
187
215
  requirements:
188
216
  - - "~>"
189
217
  - !ruby/object:Gem::Version
190
- version: 1.28.0
218
+ version: 2.1.0
191
219
  description: |-
192
220
  A view layer for your Rails apps that separates structure and logic, using Handlebars templates.
193
221
  Strongly inspired by Curly Template gem by Daniel Schierbeck.
@@ -288,7 +316,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
288
316
  requirements:
289
317
  - - ">="
290
318
  - !ruby/object:Gem::Version
291
- version: '0'
319
+ version: '2.4'
292
320
  required_rubygems_version: !ruby/object:Gem::Requirement
293
321
  requirements:
294
322
  - - ">="