curlybars 1.2.1 → 1.3.0

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