meddleware 0.1.0 → 0.2.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/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
|