meddleware 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/meddleware/v2_5.rb +143 -0
- data/lib/meddleware/version.rb +1 -1
- data/lib/meddleware.rb +71 -37
- data/spec/build_meddleware_spec.rb +100 -5
- data/spec/call_meddleware_spec.rb +30 -23
- data/spec/{examples_spec.rb → readme/full_example_spec.rb} +16 -5
- data/spec/readme/usage_spec.rb +47 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bfe09bf6e8d403864543e0c74fea482608b78f31c83b32a6cca71ad1d8a3973
|
4
|
+
data.tar.gz: 93c888f10763f70779e9a834249e475f6eab18db3f2eacf9bd1442cb87f155d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abaee8a6faafe5ed08d04d9a5166efedbf3e9cc51de2fc3bd1608ba57496e38676860b18bc44ab4a8dfc4030709fc287c84cfaa5001be7a391be7f5f09f4b736
|
7
|
+
data.tar.gz: 5222b652ae8a45723d4b20798d4c852d7b8a0e24a1449531c0c8fc96a3c3fa3a265e4bbe8bec3e81f1958a77112fd189f8a75b9bce2f66f3c4c8e5ae8770dac3
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# backwards compatible functionality for Ruby 2.5
|
2
|
+
|
3
|
+
class Meddleware
|
4
|
+
module V2_5
|
5
|
+
def use(*klass_and_args, &block)
|
6
|
+
entry = create_entry(klass_and_args, block)
|
7
|
+
remove(entry[0])
|
8
|
+
stack << entry
|
9
|
+
self
|
10
|
+
end
|
11
|
+
alias append use
|
12
|
+
|
13
|
+
def prepend(*klass_and_args, &block)
|
14
|
+
entry = create_entry(klass_and_args, block)
|
15
|
+
remove(entry[0])
|
16
|
+
stack.insert(0, entry)
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def after(after_klass, *klass_and_args, &block)
|
21
|
+
entry = create_entry(klass_and_args, block)
|
22
|
+
remove(entry[0])
|
23
|
+
|
24
|
+
i = if after_klass.is_a? Array
|
25
|
+
after_klass.map {|x| index(x) }.compact.max
|
26
|
+
else
|
27
|
+
index(after_klass)
|
28
|
+
end
|
29
|
+
i ||= count - 1 # last element
|
30
|
+
|
31
|
+
stack.insert(i + 1, entry)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def before(before_klass, *klass_and_args, &block)
|
36
|
+
entry = create_entry(klass_and_args, block)
|
37
|
+
remove(entry[0])
|
38
|
+
|
39
|
+
i = if before_klass.is_a? Array
|
40
|
+
before_klass.map {|x| index(x) }.compact.min
|
41
|
+
else
|
42
|
+
index(before_klass)
|
43
|
+
end
|
44
|
+
i ||= 0 # first element
|
45
|
+
|
46
|
+
stack.insert(i, entry)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def replace(old_klass, *klass_and_args, &block)
|
51
|
+
entry = create_entry(klass_and_args, block)
|
52
|
+
remove(entry[0])
|
53
|
+
|
54
|
+
i = index(old_klass)
|
55
|
+
|
56
|
+
unless i
|
57
|
+
raise RuntimeError, "middleware not present: #{old_klass}"
|
58
|
+
end
|
59
|
+
|
60
|
+
stack[i] = entry
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def call(*args)
|
65
|
+
chain = build_chain
|
66
|
+
default_args = args
|
67
|
+
|
68
|
+
traverse = proc do |*args|
|
69
|
+
if args.empty?
|
70
|
+
args = default_args
|
71
|
+
else
|
72
|
+
default_args = args
|
73
|
+
end
|
74
|
+
|
75
|
+
if chain.empty?
|
76
|
+
yield(*args) if block_given?
|
77
|
+
else
|
78
|
+
middleware = chain.shift
|
79
|
+
|
80
|
+
if middleware.is_a?(Proc) && !middleware.lambda?
|
81
|
+
middleware.call(*args)
|
82
|
+
|
83
|
+
# implicit yield
|
84
|
+
traverse.call(*args)
|
85
|
+
else
|
86
|
+
middleware.call(*args, &traverse)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
traverse.call(*args)
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def create_entry(klass_and_args, block)
|
97
|
+
klass, *args = klass_and_args
|
98
|
+
|
99
|
+
if [ klass, block ].compact.count == 0
|
100
|
+
raise ArgumentError, 'either a middleware or block must be provided'
|
101
|
+
end
|
102
|
+
|
103
|
+
if klass
|
104
|
+
# validate
|
105
|
+
if klass.is_a? Class
|
106
|
+
unless klass.method_defined?(:call)
|
107
|
+
raise ArgumentError, "middleware must implement `.call`: #{klass}"
|
108
|
+
end
|
109
|
+
else
|
110
|
+
unless klass.respond_to?(:call)
|
111
|
+
raise ArgumentError, "middleware must respond to `.call`: #{klass}"
|
112
|
+
end
|
113
|
+
|
114
|
+
unless block.nil?
|
115
|
+
raise ArgumentError, 'can not supply middleware instance and block'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
[ klass, args, block ].compact
|
120
|
+
else
|
121
|
+
[ block ]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def build_chain
|
126
|
+
# build the middleware stack
|
127
|
+
stack.map do |klass, args, block|
|
128
|
+
if klass.is_a? Class
|
129
|
+
klass.new(*args, &block)
|
130
|
+
else
|
131
|
+
if args.nil? || args.empty?
|
132
|
+
klass
|
133
|
+
else
|
134
|
+
# curry args
|
135
|
+
->(*more_args, &block) do
|
136
|
+
klass.call(*args, *more_args, &block)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/meddleware/version.rb
CHANGED
data/lib/meddleware.rb
CHANGED
@@ -5,44 +5,64 @@ class Meddleware
|
|
5
5
|
instance_eval(&block) if block_given?
|
6
6
|
end
|
7
7
|
|
8
|
-
def use(*
|
9
|
-
entry = create_entry(
|
8
|
+
def use(*args, **kwargs, &block)
|
9
|
+
entry = create_entry(args, kwargs, block)
|
10
|
+
remove(entry[0])
|
10
11
|
stack << entry
|
11
12
|
self
|
12
13
|
end
|
13
14
|
alias append use
|
14
15
|
|
15
|
-
def prepend(*
|
16
|
-
entry = create_entry(
|
16
|
+
def prepend(*args, **kwargs, &block)
|
17
|
+
entry = create_entry(args, kwargs, block)
|
18
|
+
remove(entry[0])
|
17
19
|
stack.insert(0, entry)
|
18
20
|
self
|
19
21
|
end
|
20
22
|
|
21
|
-
def after(after_klass, *
|
22
|
-
entry = create_entry(
|
23
|
-
|
23
|
+
def after(after_klass, *args, **kwargs, &block)
|
24
|
+
entry = create_entry(args, kwargs, block)
|
25
|
+
remove(entry[0])
|
26
|
+
|
27
|
+
i = if after_klass.is_a? Array
|
28
|
+
after_klass.map {|x| index(x) }.compact.max
|
29
|
+
else
|
30
|
+
index(after_klass)
|
31
|
+
end
|
32
|
+
i ||= count - 1 # last element
|
33
|
+
|
24
34
|
stack.insert(i + 1, entry)
|
25
35
|
self
|
26
36
|
end
|
27
37
|
|
28
|
-
def before(before_klass, *
|
29
|
-
entry = create_entry(
|
30
|
-
|
38
|
+
def before(before_klass, *args, **kwargs, &block)
|
39
|
+
entry = create_entry(args, kwargs, block)
|
40
|
+
remove(entry[0])
|
41
|
+
|
42
|
+
i = if before_klass.is_a? Array
|
43
|
+
before_klass.map {|x| index(x) }.compact.min
|
44
|
+
else
|
45
|
+
index(before_klass)
|
46
|
+
end
|
47
|
+
i ||= 0 # first element
|
48
|
+
|
31
49
|
stack.insert(i, entry)
|
32
50
|
self
|
33
51
|
end
|
34
52
|
|
35
|
-
def include?(klass)
|
36
|
-
|
53
|
+
def include?(*klass)
|
54
|
+
klass.all? {|x| index(x) }
|
37
55
|
end
|
38
56
|
|
39
|
-
def remove(klass)
|
40
|
-
stack.reject! { |entry| entry[0]
|
57
|
+
def remove(*klass)
|
58
|
+
stack.reject! { |entry| klass.include?(entry[0]) }
|
41
59
|
self
|
42
60
|
end
|
43
61
|
|
44
|
-
def replace(old_klass, *
|
45
|
-
entry = create_entry(
|
62
|
+
def replace(old_klass, *args, **kwargs, &block)
|
63
|
+
entry = create_entry(args, kwargs, block)
|
64
|
+
remove(entry[0])
|
65
|
+
|
46
66
|
i = index(old_klass)
|
47
67
|
|
48
68
|
unless i
|
@@ -66,37 +86,41 @@ class Meddleware
|
|
66
86
|
stack.empty?
|
67
87
|
end
|
68
88
|
|
69
|
-
def call(*args)
|
89
|
+
def call(*args, **kwargs)
|
70
90
|
chain = build_chain
|
71
91
|
default_args = args
|
92
|
+
default_kwargs = kwargs
|
72
93
|
|
73
|
-
traverse = proc do |*args|
|
74
|
-
if args.empty?
|
94
|
+
traverse = proc do |*args, **kwargs|
|
95
|
+
if args.empty? && kwargs.empty?
|
75
96
|
args = default_args
|
97
|
+
kwargs = default_kwargs
|
76
98
|
else
|
77
99
|
default_args = args
|
100
|
+
default_kwargs = kwargs
|
78
101
|
end
|
79
102
|
|
80
103
|
if chain.empty?
|
81
|
-
yield(*args) if block_given?
|
104
|
+
yield(*args, **kwargs) if block_given?
|
82
105
|
else
|
83
106
|
middleware = chain.shift
|
84
107
|
|
85
108
|
if middleware.is_a?(Proc) && !middleware.lambda?
|
86
|
-
middleware.call(*args)
|
109
|
+
middleware.call(*args, **kwargs)
|
87
110
|
|
88
111
|
# implicit yield
|
89
|
-
traverse.call(*args)
|
112
|
+
traverse.call(*args, **kwargs)
|
90
113
|
else
|
91
|
-
middleware.call(*args, &traverse)
|
114
|
+
middleware.call(*args, **kwargs, &traverse)
|
92
115
|
end
|
93
116
|
end
|
94
117
|
end
|
95
|
-
|
118
|
+
|
119
|
+
traverse.call(*args, **kwargs)
|
96
120
|
end
|
97
121
|
|
98
122
|
|
99
|
-
|
123
|
+
protected
|
100
124
|
|
101
125
|
def stack
|
102
126
|
@stack ||= []
|
@@ -106,16 +130,13 @@ class Meddleware
|
|
106
130
|
stack.index {|entry| entry[0] == klass }
|
107
131
|
end
|
108
132
|
|
109
|
-
def create_entry(
|
110
|
-
klass, *args =
|
133
|
+
def create_entry(args, kwargs, block)
|
134
|
+
klass, *args = args
|
111
135
|
|
112
|
-
if [ klass, block ].compact.
|
136
|
+
if [ klass, block ].compact.empty?
|
113
137
|
raise ArgumentError, 'either a middleware or block must be provided'
|
114
138
|
end
|
115
139
|
|
116
|
-
# dedup
|
117
|
-
remove(klass || block)
|
118
|
-
|
119
140
|
if klass
|
120
141
|
# validate
|
121
142
|
if klass.is_a? Class
|
@@ -132,7 +153,7 @@ class Meddleware
|
|
132
153
|
end
|
133
154
|
end
|
134
155
|
|
135
|
-
[ klass, args, block ]
|
156
|
+
[ klass, args, kwargs, block ].compact
|
136
157
|
else
|
137
158
|
[ block ]
|
138
159
|
end
|
@@ -140,19 +161,32 @@ class Meddleware
|
|
140
161
|
|
141
162
|
def build_chain
|
142
163
|
# build the middleware stack
|
143
|
-
stack.map do |klass, args, block|
|
164
|
+
stack.map do |klass, args, kwargs, block|
|
144
165
|
if klass.is_a? Class
|
145
|
-
klass.new(*args, &block)
|
166
|
+
klass.new(*args, **kwargs, &block)
|
146
167
|
else
|
147
|
-
if args.nil?
|
168
|
+
if args.nil? && kwargs.nil?
|
169
|
+
# middleware is a block
|
170
|
+
klass
|
171
|
+
elsif args.empty? && kwargs.empty?
|
172
|
+
# nothing to curry, just pass through middleware instance
|
148
173
|
klass
|
149
174
|
else
|
150
175
|
# curry args
|
151
|
-
->(*more_args, &block) do
|
152
|
-
klass.call(
|
176
|
+
->(*more_args, **more_kwargs, &block) do
|
177
|
+
klass.call(
|
178
|
+
*(args + more_args),
|
179
|
+
**kwargs.merge(more_kwargs),
|
180
|
+
&block
|
181
|
+
)
|
153
182
|
end
|
154
183
|
end
|
155
184
|
end
|
156
185
|
end
|
157
186
|
end
|
187
|
+
|
188
|
+
if RUBY_VERSION < '3'
|
189
|
+
require 'meddleware/v2_5'
|
190
|
+
prepend Meddleware::V2_5
|
191
|
+
end
|
158
192
|
end
|
@@ -200,6 +200,33 @@ describe Meddleware do
|
|
200
200
|
subject.after nil, C
|
201
201
|
expect(stack).to eq [ A, C ]
|
202
202
|
end
|
203
|
+
|
204
|
+
context 'when target is an array' do
|
205
|
+
before do
|
206
|
+
subject.use A
|
207
|
+
subject.use B
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'inserts after the last target' do
|
211
|
+
subject.after [ A, B ], C
|
212
|
+
expect(stack).to eq [ A, B, C ]
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'ignores missing targets' do
|
216
|
+
subject.after [ A, Meddler ], C
|
217
|
+
expect(stack).to eq [ A, C, B ]
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'handles nil targets' do
|
221
|
+
subject.after [ nil, A ], C
|
222
|
+
expect(stack).to eq [ A, C, B ]
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'handles an empty array' do
|
226
|
+
subject.after [], C
|
227
|
+
expect(stack).to eq [ A, B, C ]
|
228
|
+
end
|
229
|
+
end
|
203
230
|
end
|
204
231
|
|
205
232
|
describe '#before' do
|
@@ -231,6 +258,33 @@ describe Meddleware do
|
|
231
258
|
subject.before nil, C
|
232
259
|
expect(stack).to eq [ C, A ]
|
233
260
|
end
|
261
|
+
|
262
|
+
context 'when target is an array' do
|
263
|
+
before do
|
264
|
+
subject.use A
|
265
|
+
subject.use B
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'inserts before the first target' do
|
269
|
+
subject.before [ A, B ], C
|
270
|
+
expect(stack).to eq [ C, A, B ]
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'ignores missing targets' do
|
274
|
+
subject.before [ B, Meddler ], C
|
275
|
+
expect(stack).to eq [ A, C, B ]
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'handles nil targets' do
|
279
|
+
subject.before [ nil, B ], C
|
280
|
+
expect(stack).to eq [ A, C, B ]
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'handles an empty array' do
|
284
|
+
subject.before [], C
|
285
|
+
expect(stack).to eq [ C, A, B ]
|
286
|
+
end
|
287
|
+
end
|
234
288
|
end
|
235
289
|
|
236
290
|
describe '#empty?' do
|
@@ -277,11 +331,35 @@ describe Meddleware do
|
|
277
331
|
end
|
278
332
|
|
279
333
|
describe '#include?' do
|
280
|
-
|
281
|
-
expect(subject.include?(A)).to be false
|
282
|
-
|
334
|
+
before do
|
283
335
|
subject.use A
|
284
|
-
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'finds existing middleware' do
|
339
|
+
is_expected.to include A
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'handles missing middleware' do
|
343
|
+
is_expected.not_to include B
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'handles nil' do
|
347
|
+
is_expected.not_to include nil
|
348
|
+
end
|
349
|
+
|
350
|
+
context 'with multiple targets' do
|
351
|
+
it 'requires all targets to exist' do
|
352
|
+
expect(subject.include?(A, B)).to be false
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'works when all targets exist' do
|
356
|
+
subject.use B
|
357
|
+
expect(subject.include?(A, B)).to be true
|
358
|
+
end
|
359
|
+
|
360
|
+
it 'handles nil' do
|
361
|
+
expect(subject.include?(A, nil)).to be false
|
362
|
+
end
|
285
363
|
end
|
286
364
|
end
|
287
365
|
|
@@ -311,6 +389,23 @@ describe Meddleware do
|
|
311
389
|
subject.remove(nil)
|
312
390
|
expect(stack).to eq [ A, B, C ]
|
313
391
|
end
|
392
|
+
|
393
|
+
context 'with multiple targets' do
|
394
|
+
it 'removes multiple middleware' do
|
395
|
+
subject.remove(A, B)
|
396
|
+
expect(stack).to eq [ C ]
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'handles redundancy' do
|
400
|
+
subject.remove(A, A)
|
401
|
+
expect(stack).to eq [ B, C ]
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'handles nil' do
|
405
|
+
subject.remove(A, nil)
|
406
|
+
expect(stack).to eq [ B, C ]
|
407
|
+
end
|
408
|
+
end
|
314
409
|
end
|
315
410
|
|
316
411
|
describe '#replace' do
|
@@ -378,7 +473,7 @@ describe Meddleware do
|
|
378
473
|
it 'is a private method' do
|
379
474
|
expect {
|
380
475
|
subject.index
|
381
|
-
}.to raise_error(NoMethodError
|
476
|
+
}.to raise_error(NoMethodError)
|
382
477
|
end
|
383
478
|
end
|
384
479
|
end
|
@@ -2,6 +2,7 @@ describe 'Meddleware#call' do
|
|
2
2
|
subject { Meddleware.new }
|
3
3
|
|
4
4
|
let(:middleware) { Meddler.new }
|
5
|
+
ruby3 = RUBY_VERSION >= '3'
|
5
6
|
|
6
7
|
it 'works with no block, no stack' do
|
7
8
|
expect(subject.call).to be nil
|
@@ -18,8 +19,9 @@ describe 'Meddleware#call' do
|
|
18
19
|
end
|
19
20
|
|
20
21
|
it 'passes args through to block' do
|
21
|
-
subject.call(:abc, x: :yz) do |*args|
|
22
|
-
expect(args).to eq [ :abc
|
22
|
+
subject.call(:abc, x: :yz) do |*args, **kwargs|
|
23
|
+
expect(args).to eq [ :abc ]
|
24
|
+
expect(kwargs).to eq x: :yz
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
@@ -56,10 +58,10 @@ describe 'Meddleware#call' do
|
|
56
58
|
subject.call {}
|
57
59
|
end
|
58
60
|
|
59
|
-
it 'calls middleware with args and block' do
|
60
|
-
expect(middleware).to receive(:call) do |a, b
|
61
|
+
it 'calls middleware with args, kwargs, and block' do
|
62
|
+
expect(middleware).to receive(:call) do |a, b:, &block|
|
61
63
|
expect(a).to be :a
|
62
|
-
expect(b).to eq(
|
64
|
+
expect(b).to eq(:c)
|
63
65
|
expect(block).to be_a Proc
|
64
66
|
end
|
65
67
|
|
@@ -80,8 +82,9 @@ describe 'Meddleware#call' do
|
|
80
82
|
end
|
81
83
|
|
82
84
|
it 'implicitly passes along original arguments' do
|
83
|
-
subject.call(:abc) do |
|
84
|
-
expect(
|
85
|
+
subject.call(:abc, x: :yz) do |*args, **kwargs|
|
86
|
+
expect(args).to eq [ :abc ]
|
87
|
+
expect(kwargs).to eq x: :yz
|
85
88
|
end
|
86
89
|
end
|
87
90
|
end
|
@@ -89,21 +92,23 @@ describe 'Meddleware#call' do
|
|
89
92
|
context 'when middleware calls block with explicit arguments' do
|
90
93
|
it 'can add arguments' do
|
91
94
|
expect(middleware).to receive(:call) do |&block|
|
92
|
-
block.call(:abc)
|
95
|
+
block.call(:abc, x: :yz)
|
93
96
|
end
|
94
97
|
|
95
|
-
subject.call do |
|
96
|
-
expect(
|
98
|
+
subject.call do |*args, **kwargs|
|
99
|
+
expect(args).to eq [ :abc ]
|
100
|
+
expect(kwargs).to eq x: :yz
|
97
101
|
end
|
98
102
|
end
|
99
103
|
|
100
104
|
it 'can override the arguments passed on' do
|
101
105
|
expect(middleware).to receive(:call) do |&block|
|
102
|
-
block.call(:abc)
|
106
|
+
block.call(:abc, x: :z)
|
103
107
|
end
|
104
108
|
|
105
|
-
subject.call(123) do |
|
106
|
-
expect(
|
109
|
+
subject.call(123, x: :y) do |*args, **kwargs|
|
110
|
+
expect(args).to eq [ :abc ]
|
111
|
+
expect(kwargs).to eq x: :z
|
107
112
|
end
|
108
113
|
end
|
109
114
|
|
@@ -112,9 +117,9 @@ describe 'Meddleware#call' do
|
|
112
117
|
block.call(nil)
|
113
118
|
end
|
114
119
|
|
115
|
-
subject.call(:abc, :
|
116
|
-
expect(
|
117
|
-
expect(
|
120
|
+
subject.call(:abc, x: :yz) do |arg, **kwargs|
|
121
|
+
expect(arg).to be nil
|
122
|
+
expect(kwargs).to be_empty
|
118
123
|
end
|
119
124
|
end
|
120
125
|
end
|
@@ -158,23 +163,25 @@ describe 'Meddleware#call' do
|
|
158
163
|
|
159
164
|
context 'with a middleware instance and arguments' do
|
160
165
|
before do
|
161
|
-
subject.use middleware, :abc
|
166
|
+
subject.use middleware, :abc, x: :yz
|
162
167
|
end
|
163
168
|
|
164
169
|
it 'curries the arguments' do
|
165
|
-
expect(middleware).to receive(:call) do |*args, &block|
|
166
|
-
expect(args).to eq
|
170
|
+
expect(middleware).to receive(:call) do |*args, **kwargs, &block|
|
171
|
+
expect(args).to eq [ :abc ]
|
172
|
+
expect(kwargs).to eq x: :yz
|
167
173
|
end
|
168
174
|
|
169
175
|
subject.call
|
170
176
|
end
|
171
177
|
|
172
|
-
it 'curries and appends extra arguments' do
|
173
|
-
expect(middleware).to receive(:call) do |*args, &block|
|
174
|
-
expect(args).to eq
|
178
|
+
it 'curries and appends extra arguments', if: ruby3 do
|
179
|
+
expect(middleware).to receive(:call) do |*args, **kwargs, &block|
|
180
|
+
expect(args).to eq [ :abc, :def ]
|
181
|
+
expect(kwargs).to eq x: :yz, y: :z
|
175
182
|
end
|
176
183
|
|
177
|
-
subject.call(:
|
184
|
+
subject.call(:def, y: :z)
|
178
185
|
end
|
179
186
|
|
180
187
|
it 'curries and appends, without yielding implicitly' do
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module MyList
|
2
|
+
# generate an array from 1 to n
|
3
|
+
|
2
4
|
extend self
|
3
5
|
|
4
6
|
def middleware(&block)
|
@@ -8,18 +10,24 @@ module MyList
|
|
8
10
|
end
|
9
11
|
|
10
12
|
def generate(n)
|
11
|
-
|
13
|
+
# invoke middleware chain
|
14
|
+
middleware.call(n) do |n|
|
15
|
+
# do the actual work of generating your results
|
16
|
+
(1..n).to_a
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
14
20
|
|
15
21
|
class OneExtra
|
16
22
|
def call(n)
|
23
|
+
# adds one to the argument being passed in
|
17
24
|
yield(n + 1)
|
18
25
|
end
|
19
26
|
end
|
20
27
|
|
21
28
|
class Doubler
|
22
29
|
def call(*)
|
30
|
+
# modifies the results by doubles each value
|
23
31
|
yield.map {|x| x * 2 }
|
24
32
|
end
|
25
33
|
end
|
@@ -37,13 +45,16 @@ describe MyList do
|
|
37
45
|
end
|
38
46
|
end
|
39
47
|
|
48
|
+
after { MyList.middleware.clear }
|
49
|
+
|
40
50
|
it 'calls middleware chain and generates a list' do
|
41
|
-
res =
|
51
|
+
res = MyList.generate(2)
|
52
|
+
expect(res).to eq [ 2, 4, 6 ]
|
53
|
+
end
|
42
54
|
|
55
|
+
it 'logs to stdout' do
|
43
56
|
expect {
|
44
|
-
|
57
|
+
MyList.generate(2)
|
45
58
|
}.to output("n starts as 2\nn ends as 3\n").to_stdout
|
46
|
-
|
47
|
-
expect(res).to eq [ 2, 4, 6 ]
|
48
59
|
end
|
49
60
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'meddleware'
|
2
|
+
|
3
|
+
# lib/mywidget.rb
|
4
|
+
class MyWidget
|
5
|
+
def self.middleware(&block)
|
6
|
+
(@middleware ||= Meddleware.new).tap do
|
7
|
+
@middleware.instance_eval(&block) if block_given?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def do_the_thing
|
12
|
+
# invoke middleware chain
|
13
|
+
MyWidget.middleware.call do
|
14
|
+
# do your thing
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
MyMiddleware = proc {}
|
20
|
+
|
21
|
+
# config/initializers/mywidget.rb
|
22
|
+
MyWidget.middleware do
|
23
|
+
# add a logger
|
24
|
+
use { puts "before the thing" }
|
25
|
+
|
26
|
+
# add another middleware
|
27
|
+
use MyMiddleware
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# use it from whereever
|
32
|
+
# MyWidget.new.do_the_thing
|
33
|
+
|
34
|
+
|
35
|
+
describe MyWidget do
|
36
|
+
it 'adds middleware to the framework' do
|
37
|
+
expect(MyWidget.middleware).to include(MyMiddleware)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'calls each middleware' do
|
41
|
+
expect(MyMiddleware).to receive(:call)
|
42
|
+
|
43
|
+
expect {
|
44
|
+
MyWidget.new.do_the_thing
|
45
|
+
}.to output("before the thing\n").to_stdout
|
46
|
+
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meddleware
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Pepper
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -87,11 +87,13 @@ extensions: []
|
|
87
87
|
extra_rdoc_files: []
|
88
88
|
files:
|
89
89
|
- lib/meddleware.rb
|
90
|
+
- lib/meddleware/v2_5.rb
|
90
91
|
- lib/meddleware/version.rb
|
91
92
|
- spec/build_meddleware_spec.rb
|
92
93
|
- spec/call_meddleware_chain_spec.rb
|
93
94
|
- spec/call_meddleware_spec.rb
|
94
|
-
- spec/
|
95
|
+
- spec/readme/full_example_spec.rb
|
96
|
+
- spec/readme/usage_spec.rb
|
95
97
|
homepage: https://github.com/dpep/meddleware_rb
|
96
98
|
licenses:
|
97
99
|
- MIT
|
@@ -104,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
106
|
requirements:
|
105
107
|
- - ">="
|
106
108
|
- !ruby/object:Gem::Version
|
107
|
-
version: '
|
109
|
+
version: '2.5'
|
108
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
111
|
requirements:
|
110
112
|
- - ">="
|
@@ -117,6 +119,7 @@ specification_version: 4
|
|
117
119
|
summary: Meddleware
|
118
120
|
test_files:
|
119
121
|
- spec/call_meddleware_spec.rb
|
122
|
+
- spec/readme/usage_spec.rb
|
123
|
+
- spec/readme/full_example_spec.rb
|
120
124
|
- spec/call_meddleware_chain_spec.rb
|
121
125
|
- spec/build_meddleware_spec.rb
|
122
|
-
- spec/examples_spec.rb
|