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 +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
|