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 +4 -4
- data/lib/curlybars/method_whitelist.rb +44 -16
- data/lib/curlybars/version.rb +1 -1
- data/spec/curlybars/method_whitelist_spec.rb +119 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c5f1fe84620e10957d38e663d3883158c00b6db25395c61e9628ddd3d19d110
|
4
|
+
data.tar.gz: 5eac82875ef4fca6a4c0aa728626615c643089ed6cc24de91232d793753f8f5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(*
|
4
|
-
|
5
|
-
|
6
|
-
if type.
|
7
|
-
|
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 =
|
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
|
18
|
-
|
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 =
|
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(
|
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(
|
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(
|
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
|
45
|
-
methods_schema(
|
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(
|
78
|
+
type.dependency_tree(context)
|
51
79
|
elsif type.is_a?(Array)
|
52
|
-
[type.first.dependency_tree(
|
80
|
+
[type.first.dependency_tree(context)]
|
53
81
|
else
|
54
82
|
type
|
55
83
|
end
|
data/lib/curlybars/version.rb
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
describe Curlybars::MethodWhitelist do
|
2
|
-
let(:dummy_class)
|
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: -> {
|
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: {
|
222
|
+
expect(dummy_class.methods_schema(validation_context_class.new)).to eq(settings: { background_color: nil })
|
117
223
|
end
|
118
224
|
|
119
|
-
it "supports
|
120
|
-
dummy_class.class_eval
|
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(
|
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.
|
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-
|
16
|
+
date: 2019-12-17 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: actionpack
|