meddleware 0.2.0 → 0.4.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.
@@ -1,479 +0,0 @@
1
- A = Class.new(Meddler)
2
- B = Class.new(Meddler)
3
- C = Class.new(Meddler)
4
-
5
-
6
- describe Meddleware do
7
- subject { described_class.new }
8
-
9
- def stack
10
- subject.send(:build_chain).map &:class
11
- end
12
-
13
- shared_examples 'a middleware adder method' do |name|
14
- let(:function) do
15
- subject.method(name).yield_self do |fn|
16
- if fn.arity < -1
17
- # needs prefix arg, eg. :before/:after
18
- proc {|*args, &block| fn.call(nil, *args, &block) }
19
- else
20
- fn
21
- end
22
- end
23
- end
24
-
25
- it 'adds middleware to the stack' do
26
- function.call(A)
27
- expect(stack).to eq [ A ]
28
- end
29
-
30
- it 'does not add duplicates' do
31
- 3.times { function.call(A) }
32
- expect(stack).to eq [ A ]
33
- end
34
-
35
- it 'returns self' do
36
- expect(function.call(A)).to be subject
37
- end
38
-
39
- it 'is idempotent' do
40
- subject.use A
41
- function.call(B)
42
- res = stack
43
-
44
- function.call(B)
45
- expect(stack).to eq res
46
- end
47
-
48
- context 'with arguments' do
49
- after { subject.send :build_chain }
50
-
51
- it 'accepts an argument' do
52
- expect(A).to receive(:new).with(:abc)
53
- function.call(A, :abc)
54
- end
55
-
56
- it 'accepts multiple arguments' do
57
- expect(A).to receive(:new).with(:abc, :xyz)
58
- function.call(A, :abc, :xyz)
59
- end
60
-
61
- it 'accepts kwargs' do
62
- expect(A).to receive(:new).with(a: 1, b: 2)
63
- function.call(A, a: 1, b: 2)
64
- end
65
-
66
- it 'works with all forms of kwargs' do
67
- expect(A).to receive(:new).with(a: 1, b: 2)
68
- function.call(A, { a: 1, b: 2 })
69
-
70
- expect(B).to receive(:new).with({ a: 1, b: 2 })
71
- function.call(B, { a: 1, b: 2 })
72
-
73
- expect(C).to receive(:new).with({ a: 1, b: 2 })
74
- function.call(C, a: 1, b: 2)
75
- end
76
-
77
- it 'works with both args and kwargs' do
78
- expect(A).to receive(:new).with(:abc, a: 1, b: 2)
79
- function.call(A, :abc, a: 1, b: 2)
80
- end
81
- end
82
-
83
- context 'when middleware is an instance' do
84
- it 'adds middleware to the stack' do
85
- function.call(A.new)
86
- expect(stack).to eq [ A ]
87
- end
88
-
89
- it 'will add multiple instances of the same class' do
90
- function.call(A.new)
91
- function.call(A.new)
92
- expect(stack).to eq [ A, A ]
93
- end
94
- end
95
-
96
- context 'when middleware is a block' do
97
- it 'accepts procs' do
98
- function.call(Proc.new {})
99
- expect(stack).to eq [ Proc ]
100
- end
101
-
102
- it 'accepts lambdas' do
103
- function.call(-> {})
104
- expect(stack).to eq [ Proc ]
105
- end
106
-
107
- it 'accepts inline blocks' do
108
- function.call {}
109
- expect(stack).to eq [ Proc ]
110
- end
111
- end
112
-
113
- context 'when middleware is invalid' do
114
- it 'rejects classes that do not implement `.call`' do
115
- expect {
116
- function.call(Class.new)
117
- }.to raise_error(ArgumentError)
118
- end
119
-
120
- it 'rejects instances that do not respond to `.call`' do
121
- expect {
122
- function.call(123)
123
- }.to raise_error(ArgumentError)
124
- end
125
-
126
- it 'fails when both instance and block are passed' do
127
- expect {
128
- function.call(A.new) {}
129
- }.to raise_error(ArgumentError)
130
- end
131
-
132
- it 'rejects nil' do
133
- expect {
134
- function.call(nil)
135
- }.to raise_error(ArgumentError)
136
- end
137
- end
138
- end
139
-
140
- describe '#use' do
141
- it_behaves_like 'a middleware adder method', :use
142
-
143
- it 'appends middleware in order' do
144
- subject.use A
145
- subject.use B
146
- expect(stack).to eq [ A, B ]
147
- end
148
-
149
- it 'reorders duplicates' do
150
- subject.use A
151
- subject.use B
152
- subject.use A
153
- expect(stack).to eq [ B, A ]
154
- end
155
- end
156
-
157
- describe '#prepend' do
158
- it_behaves_like 'a middleware adder method', :prepend
159
-
160
- it 'prepends middleware in order' do
161
- subject.prepend A
162
- subject.prepend B
163
- expect(stack).to eq [ B, A ]
164
- end
165
-
166
- it 'reorders duplicates' do
167
- subject.prepend A
168
- subject.prepend B
169
- subject.prepend A
170
- expect(stack).to eq [ A, B ]
171
- end
172
- end
173
-
174
- describe '#after' do
175
- it_behaves_like 'a middleware adder method', :after
176
-
177
- it 'adds middleware where specified' do
178
- subject.use A
179
- subject.use B
180
- subject.after A, C
181
- expect(stack).to eq [ A, C, B ]
182
- end
183
-
184
- it 'maintans order for duplicates' do
185
- subject.use A
186
- subject.use B
187
- subject.after A, C
188
- subject.after A, C
189
- expect(stack).to eq [ A, C, B ]
190
- end
191
-
192
- it 'works when target is missing' do
193
- subject.use A
194
- subject.after B, C
195
- expect(stack).to eq [ A, C ]
196
- end
197
-
198
- it 'works when target is nil' do
199
- subject.use A
200
- subject.after nil, C
201
- expect(stack).to eq [ A, C ]
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
230
- end
231
-
232
- describe '#before' do
233
- it_behaves_like 'a middleware adder method', :before
234
-
235
- it 'adds middleware where specified' do
236
- subject.use A
237
- subject.use B
238
- subject.before B, C
239
- expect(stack).to eq [ A, C, B ]
240
- end
241
-
242
- it 'maintans order for duplicates' do
243
- subject.use A
244
- subject.use B
245
- subject.before B, C
246
- subject.before B, C
247
- expect(stack).to eq [ A, C, B ]
248
- end
249
-
250
- it 'works when target is missing' do
251
- subject.use A
252
- subject.before B, C
253
- expect(stack).to eq [ C, A ]
254
- end
255
-
256
- it 'works when target is nil' do
257
- subject.use A
258
- subject.before nil, C
259
- expect(stack).to eq [ C, A ]
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
288
- end
289
-
290
- describe '#empty?' do
291
- it 'works with empty middleware' do
292
- expect(subject).to be_empty
293
- expect(subject.empty?).to be true
294
- expect(stack.empty?).to be true
295
- end
296
-
297
- it 'works with middleware' do
298
- subject.use A
299
- expect(subject).not_to be_empty
300
- expect(subject.empty?).to be false
301
- expect(stack.empty?).to be false
302
- end
303
- end
304
-
305
- describe '#clear' do
306
- it 'works' do
307
- subject.use A
308
- subject.clear
309
- expect(subject).to be_empty
310
- end
311
-
312
- it 'works with an empty stack' do
313
- subject.clear
314
- expect(subject).to be_empty
315
- end
316
- end
317
-
318
- describe '#count' do
319
- it 'works' do
320
- expect(subject.count).to be 0
321
-
322
- subject.use A
323
- expect(subject.count).to be 1
324
-
325
- subject.use B
326
- expect(subject.count).to be 2
327
-
328
- subject.remove B
329
- expect(subject.count).to be 1
330
- end
331
- end
332
-
333
- describe '#include?' do
334
- before do
335
- subject.use A
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
363
- end
364
- end
365
-
366
- describe '#remove' do
367
- before do
368
- subject.use A
369
- subject.use B
370
- subject.use C
371
- expect(stack).to eq [ A, B, C ]
372
- end
373
-
374
- it 'removes middleware' do
375
- subject.remove(B)
376
- expect(stack).to eq [ A, C ]
377
- subject.remove(A)
378
- expect(stack).to eq [ C ]
379
- subject.remove(C)
380
- expect(subject).to be_empty
381
- end
382
-
383
- it 'is idempotent' do
384
- 3.times { subject.remove(A) }
385
- expect(stack).to eq [ B, C ]
386
- end
387
-
388
- it 'works with nil' do
389
- subject.remove(nil)
390
- expect(stack).to eq [ A, B, C ]
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
409
- end
410
-
411
- describe '#replace' do
412
- before do
413
- subject.use A
414
- subject.use B
415
-
416
- expect(stack).to eq [ A, B ]
417
- end
418
-
419
- it 'replaces middleware' do
420
- subject.replace(A, C)
421
- expect(stack).to eq [ C, B ]
422
- end
423
-
424
- it 'works with middleware instances' do
425
- instance = A.new
426
- subject.replace(A, instance)
427
-
428
- expect(subject).to include instance
429
- expect(subject).not_to include A
430
-
431
- subject.replace(instance, B)
432
- expect(stack).to eq [ B ]
433
- end
434
-
435
- it 'fails when target middleware is missing' do
436
- expect {
437
- subject.replace(C, C)
438
- }.to raise_error(RuntimeError)
439
- end
440
-
441
- it 'fails when middleware is invalid' do
442
- expect {
443
- subject.replace(A, nil)
444
- }.to raise_error(ArgumentError)
445
- end
446
- end
447
-
448
- describe '.new' do
449
- it 'supports block mode' do
450
- instance = described_class.new do
451
- use A
452
- prepend B
453
- end
454
-
455
- expect(instance).to include A
456
- expect(instance).to include B
457
- end
458
- end
459
-
460
- describe '#index' do
461
- before do
462
- subject.use A
463
- subject.use B
464
- end
465
-
466
- it do
467
- expect(subject.send(:index, A)).to be 0
468
- expect(subject.send(:index, B)).to be 1
469
- expect(subject.send(:index, C)).to be nil
470
- expect(subject.send(:index, nil)).to be nil
471
- end
472
-
473
- it 'is a private method' do
474
- expect {
475
- subject.index
476
- }.to raise_error(NoMethodError)
477
- end
478
- end
479
- end
@@ -1,74 +0,0 @@
1
- describe 'Meddleware#call' do
2
- subject { Meddleware.new }
3
-
4
- let(:middleware_one) { Meddler.new }
5
- let(:middleware_two) { Meddler.new }
6
-
7
- before do
8
- subject.use middleware_one
9
- subject.use middleware_two
10
- end
11
-
12
- it 'calls the whole chain' do
13
- expect(middleware_one).to receive(:call).and_yield
14
- expect(middleware_two).to receive(:call).and_yield
15
-
16
- expect {|b| subject.call(&b) }.to yield_control
17
- end
18
-
19
- it 'stops propagation if a middleware does not yield' do
20
- expect(middleware_one).to receive(:call).and_yield
21
- expect(middleware_two).to receive(:call)
22
-
23
- expect {|b| subject.call(&b) }.not_to yield_control
24
- end
25
-
26
- it 'recurses' do
27
- order = []
28
-
29
- expect(middleware_one).to receive(:call) do |&block|
30
- order << 1
31
- block.call
32
- order << 5
33
- end
34
-
35
- expect(middleware_two).to receive(:call) do |&block|
36
- order << 2
37
- block.call
38
- order << 4
39
- end
40
-
41
- subject.call { order << 3 }
42
- expect(order).to eq((1..5).to_a)
43
- end
44
-
45
- context 'when arguments are altered' do
46
- before do
47
- expect(middleware_one).to receive(:call) do |x, &block|
48
- block.call(x * 2)
49
- end
50
- end
51
-
52
- it 'propagates them' do
53
- expect(middleware_two).to receive(:call) do |x, &block|
54
- expect(x).to be 2
55
- block.call(x * 3)
56
- end
57
-
58
- subject.call(1) do |x|
59
- expect(x).to be 6
60
- end
61
- end
62
-
63
- it 'propagates them as default arguments' do
64
- expect(middleware_two).to receive(:call) do |x, &block|
65
- expect(x).to be 2
66
- block.call
67
- end
68
-
69
- subject.call(1) do |x|
70
- expect(x).to be 2
71
- end
72
- end
73
- end
74
- end