curlybars 1.2.1 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fbfe78e305b68cad9c83ab0deafe39a1814b519ede424de8459dfe8f096bee1
4
- data.tar.gz: 7fb5ee604e9379a73ef24cd607aea3a847656a3ecc6f3fddbedd0c4031b398fc
3
+ metadata.gz: 3c5f1fe84620e10957d38e663d3883158c00b6db25395c61e9628ddd3d19d110
4
+ data.tar.gz: 5eac82875ef4fca6a4c0aa728626615c643089ed6cc24de91232d793753f8f5b
5
5
  SHA512:
6
- metadata.gz: 1f3d779a0858270de68a2715f6badb08290cf977ad792ea019ee8d5b6f20ecc837371129d98a97f2a118df2edff352ec41d71023b4789b05321315fac5847526
7
- data.tar.gz: baeb86fd6563d5baca979bcc6cdd08f3a3a66b75bc29692fcbf366b7b3518725e2bd1fbdd6afa6b66567d95436f6d2d241c3d4c1cb81c6315a337df0aa9fc0aa
6
+ metadata.gz: 3697082fceb22d1d868d4de0fcf1054d8facc0e8dee7da0e58704bf34bb303a0cd287b460baa5d40ffcbf17ed7d0e3235643b7d855e57f821ed63223f1d737e3
7
+ data.tar.gz: dfba149b55705dbc9567a763dbc12b3514296a43ec576a683642f83f727d6d7ec4c49ffc514a4c2a9a4d1ec91740365dd144d2a87bde96d59b2632b8c24ed4df
@@ -1,27 +1,55 @@
1
1
  module Curlybars
2
2
  module MethodWhitelist
3
- def allow_methods(*methods, **methods_with_type)
4
- methods_with_type.each do |(method_name, type)|
5
- if type.is_a?(Array)
6
- if type.size != 1 || !type.first.respond_to?(:dependency_tree)
7
- raise "Invalid allowed method syntax for `#{method_name}`. Collections must be of one presenter class"
3
+ def allow_methods(*methods_without_type, **methods_with_type, &contextual_block)
4
+ methods_with_type_validator = lambda do |methods_to_validate|
5
+ methods_to_validate.each do |(method_name, type)|
6
+ if type.is_a?(Array)
7
+ if type.size != 1 || !type.first.respond_to?(:dependency_tree)
8
+ raise "Invalid allowed method syntax for `#{method_name}`. Collections must be of one presenter class"
9
+ end
8
10
  end
9
11
  end
10
12
  end
11
13
 
14
+ methods_with_type_validator.call(methods_with_type)
15
+
12
16
  define_method(:allowed_methods) do
13
- methods_list = methods + methods_with_type.keys
17
+ methods_list = methods_without_type + methods_with_type.keys
18
+
19
+ # Adds methods to the list of allowed methods
20
+ method_adder = lambda do |*more_methods, **more_methods_with_type|
21
+ methods_with_type_validator.call(more_methods_with_type)
22
+
23
+ methods_list += more_methods
24
+ methods_list += more_methods_with_type.keys
25
+ end
26
+
27
+ contextual_block&.call(self, method_adder)
28
+
14
29
  defined?(super) ? super() + methods_list : methods_list
15
30
  end
16
31
 
17
- define_singleton_method(:methods_schema) do |*args|
18
- schema = methods.each_with_object({}) do |method, memo|
32
+ define_singleton_method(:methods_schema) do |context = nil|
33
+ all_methods_without_type = methods_without_type
34
+ all_methods_with_type = methods_with_type
35
+
36
+ # Adds methods to the schema
37
+ schema_adder = lambda do |*more_methods_without_type, **more_methods_with_type|
38
+ methods_with_type_validator.call(more_methods_with_type)
39
+
40
+ all_methods_without_type += more_methods_without_type
41
+ all_methods_with_type = all_methods_with_type.merge(more_methods_with_type)
42
+ end
43
+
44
+ contextual_block&.call(context, schema_adder)
45
+
46
+ schema = all_methods_without_type.each_with_object({}) do |method, memo|
19
47
  memo[method] = nil
20
48
  end
21
49
 
22
- methods_with_type_resolved = methods_with_type.each_with_object({}) do |(method_name, type), memo|
50
+ methods_with_type_resolved = all_methods_with_type.each_with_object({}) do |(method_name, type), memo|
23
51
  memo[method_name] = if type.respond_to?(:call)
24
- type.call(*args)
52
+ type.call(context)
25
53
  else
26
54
  type
27
55
  end
@@ -30,26 +58,26 @@ module Curlybars
30
58
  schema.merge!(methods_with_type_resolved)
31
59
 
32
60
  # Inheritance
33
- schema.merge!(super(*args)) if defined?(super)
61
+ schema.merge!(super(context)) if defined?(super)
34
62
 
35
63
  # Included modules
36
64
  included_modules.each do |mod|
37
65
  next unless mod.respond_to?(:methods_schema)
38
- schema.merge!(mod.methods_schema(*args))
66
+ schema.merge!(mod.methods_schema(context))
39
67
  end
40
68
 
41
69
  schema
42
70
  end
43
71
 
44
- define_singleton_method(:dependency_tree) do |*args|
45
- methods_schema(*args).each_with_object({}) do |method_with_type, memo|
72
+ define_singleton_method(:dependency_tree) do |context = nil|
73
+ methods_schema(context).each_with_object({}) do |method_with_type, memo|
46
74
  method_name = method_with_type.first
47
75
  type = method_with_type.last
48
76
 
49
77
  memo[method_name] = if type.respond_to?(:dependency_tree)
50
- type.dependency_tree(*args)
78
+ type.dependency_tree(context)
51
79
  elsif type.is_a?(Array)
52
- [type.first.dependency_tree(*args)]
80
+ [type.first.dependency_tree(context)]
53
81
  else
54
82
  type
55
83
  end
@@ -1,3 +1,3 @@
1
1
  module Curlybars
2
- VERSION = '1.2.1'.freeze
2
+ VERSION = '1.3.0'.freeze
3
3
  end
@@ -1,5 +1,30 @@
1
1
  describe Curlybars::MethodWhitelist do
2
- let(:dummy_class) { Class.new { extend Curlybars::MethodWhitelist } }
2
+ let(:dummy_class) do
3
+ Class.new do
4
+ extend Curlybars::MethodWhitelist
5
+
6
+ # A method available in the context
7
+ def foo?
8
+ true
9
+ end
10
+
11
+ def qux?
12
+ false
13
+ end
14
+ end
15
+ end
16
+
17
+ let(:validation_context_class) do
18
+ Class.new do
19
+ def foo?
20
+ true
21
+ end
22
+
23
+ def qux?
24
+ false
25
+ end
26
+ end
27
+ end
3
28
 
4
29
  describe "#allowed_methods" do
5
30
  it "returns an empty array as default" do
@@ -21,6 +46,25 @@ describe Curlybars::MethodWhitelist do
21
46
  expect(dummy_class.new.allowed_methods).to eq([:cook, :link, :article])
22
47
  end
23
48
 
49
+ it "supports adding more methods for validation" do
50
+ dummy_class.class_eval do
51
+ allow_methods do |context, allow_method|
52
+ if context.foo?
53
+ allow_method.call(:bar)
54
+ end
55
+
56
+ if context.qux?
57
+ allow_method.call(:quux)
58
+ end
59
+ end
60
+ end
61
+
62
+ aggregate_failures "test both allowed_methods and allows_method?" do
63
+ expect(dummy_class.new.allowed_methods).to eq([:bar])
64
+ expect(dummy_class.new.allows_method?(:bar)).to eq(true)
65
+ end
66
+ end
67
+
24
68
  it "raises when collection is not of presenters" do
25
69
  expect do
26
70
  dummy_class.class_eval { allow_methods :cook, links: ["foobar"] }
@@ -79,6 +123,68 @@ describe Curlybars::MethodWhitelist do
79
123
  wave: nil
80
124
  )
81
125
  end
126
+
127
+ context "with context dependent methods" do
128
+ let(:base_presenter) do
129
+ stub_const("LinkPresenter", Class.new)
130
+
131
+ Class.new do
132
+ extend Curlybars::MethodWhitelist
133
+ allow_methods :cook, link: LinkPresenter do |context, allow_method|
134
+ if context.foo?
135
+ allow_method.call(:bar)
136
+ end
137
+ end
138
+
139
+ def foo?
140
+ true
141
+ end
142
+ end
143
+ end
144
+
145
+ let(:helpers) do
146
+ Module.new do
147
+ extend Curlybars::MethodWhitelist
148
+ allow_methods :form do |context, allow_method|
149
+ if context.foo?
150
+ allow_method.call(foo_bar: :helper)
151
+ end
152
+ end
153
+
154
+ def foo?
155
+ true
156
+ end
157
+ end
158
+ end
159
+
160
+ let(:post_presenter) do
161
+ Class.new(base_presenter) do
162
+ extend Curlybars::MethodWhitelist
163
+ include Helpers
164
+ allow_methods :wave
165
+ end
166
+ end
167
+
168
+ before do
169
+ stub_const("Helpers", helpers)
170
+ end
171
+
172
+ it "allows context methods from inheritance and composition" do
173
+ expect(post_presenter.new.allowed_methods).to eq([:cook, :link, :bar, :form, :foo_bar, :wave])
174
+ end
175
+
176
+ it "returns a dependency_tree with inheritance and composition with context" do
177
+ expect(post_presenter.dependency_tree(validation_context_class.new)).
178
+ to eq(
179
+ cook: nil,
180
+ link: LinkPresenter,
181
+ form: nil,
182
+ wave: nil,
183
+ bar: nil,
184
+ foo_bar: :helper
185
+ )
186
+ end
187
+ end
82
188
  end
83
189
 
84
190
  describe ".methods_schema" do
@@ -110,16 +216,22 @@ describe Curlybars::MethodWhitelist do
110
216
  expect(dummy_class.methods_schema).to eq(links: [LinkPresenter])
111
217
  end
112
218
 
113
- it "supports procs in schema" do
114
- dummy_class.class_eval { allow_methods settings: -> { { color_1: nil } } }
219
+ it "supports procs with context in schema" do
220
+ dummy_class.class_eval { allow_methods settings: ->(context) { context.foo? ? Hash[:background_color, nil] : nil } }
115
221
 
116
- expect(dummy_class.methods_schema).to eq(settings: { color_1: nil })
222
+ expect(dummy_class.methods_schema(validation_context_class.new)).to eq(settings: { background_color: nil })
117
223
  end
118
224
 
119
- it "supports procs with arguments in schema" do
120
- dummy_class.class_eval { allow_methods settings: ->(name) { Hash[name, nil] } }
225
+ it "supports context methods" do
226
+ dummy_class.class_eval do
227
+ allow_methods do |context, allow_method|
228
+ if context.foo?
229
+ allow_method.call(:bar)
230
+ end
231
+ end
232
+ end
121
233
 
122
- expect(dummy_class.methods_schema(:background_color)).to eq(settings: { background_color: nil })
234
+ expect(dummy_class.methods_schema(validation_context_class.new)).to eq(bar: nil)
123
235
  end
124
236
  end
125
237
 
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.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Libo Cannici
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2019-11-14 00:00:00.000000000 Z
16
+ date: 2019-12-17 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: actionpack