interactor-strict 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1777 @@
1
+ describe "Integration" do
2
+ def build_interactor(&block)
3
+ interactor = Class.new.send(:include, Interactor)
4
+ interactor.class_eval(&block) if block
5
+ interactor
6
+ end
7
+
8
+ def build_organizer(options = {}, &block)
9
+ organizer = Class.new.send(:include, Interactor::Organizer)
10
+ organizer.organize(options[:organize]) if options[:organize]
11
+ organizer.class_eval(&block) if block
12
+ organizer
13
+ end
14
+
15
+ # organizer
16
+ # ├─ organizer2
17
+ # │ ├─ interactor2a
18
+ # │ ├─ interactor2b
19
+ # │ └─ interactor2c
20
+ # ├─ interactor3
21
+ # ├─ organizer4
22
+ # │ ├─ interactor4a
23
+ # │ ├─ interactor4b
24
+ # │ └─ interactor4c
25
+ # └─ interactor5
26
+
27
+ let(:organizer) {
28
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
29
+ around do |interactor|
30
+ context.steps << :around_before
31
+ interactor.call
32
+ context.steps << :around_after
33
+ end
34
+
35
+ before do
36
+ context.steps << :before
37
+ end
38
+
39
+ after do
40
+ context.steps << :after
41
+ end
42
+ end
43
+ }
44
+
45
+ let(:organizer2) {
46
+ build_organizer(organize: [interactor2a, interactor2b, interactor2c]) do
47
+ around do |interactor|
48
+ context.steps << :around_before2
49
+ interactor.call
50
+ context.steps << :around_after2
51
+ end
52
+
53
+ before do
54
+ context.steps << :before2
55
+ end
56
+
57
+ after do
58
+ context.steps << :after2
59
+ end
60
+ end
61
+ }
62
+
63
+ let(:interactor2a) {
64
+ build_interactor do
65
+ around do |interactor|
66
+ context.steps << :around_before2a
67
+ interactor.call
68
+ context.steps << :around_after2a
69
+ end
70
+
71
+ before do
72
+ context.steps << :before2a
73
+ end
74
+
75
+ after do
76
+ context.steps << :after2a
77
+ end
78
+
79
+ def call
80
+ context.steps << :call2a
81
+ end
82
+
83
+ def rollback
84
+ context.steps << :rollback2a
85
+ end
86
+ end
87
+ }
88
+
89
+ let(:interactor2b) {
90
+ build_interactor do
91
+ around do |interactor|
92
+ context.steps << :around_before2b
93
+ interactor.call
94
+ context.steps << :around_after2b
95
+ end
96
+
97
+ before do
98
+ context.steps << :before2b
99
+ end
100
+
101
+ after do
102
+ context.steps << :after2b
103
+ end
104
+
105
+ def call
106
+ context.steps << :call2b
107
+ end
108
+
109
+ def rollback
110
+ context.steps << :rollback2b
111
+ end
112
+ end
113
+ }
114
+
115
+ let(:interactor2c) {
116
+ build_interactor do
117
+ around do |interactor|
118
+ context.steps << :around_before2c
119
+ interactor.call
120
+ context.steps << :around_after2c
121
+ end
122
+
123
+ before do
124
+ context.steps << :before2c
125
+ end
126
+
127
+ after do
128
+ context.steps << :after2c
129
+ end
130
+
131
+ def call
132
+ context.steps << :call2c
133
+ end
134
+
135
+ def rollback
136
+ context.steps << :rollback2c
137
+ end
138
+ end
139
+ }
140
+
141
+ let(:interactor3) {
142
+ build_interactor do
143
+ around do |interactor|
144
+ context.steps << :around_before3
145
+ interactor.call
146
+ context.steps << :around_after3
147
+ end
148
+
149
+ before do
150
+ context.steps << :before3
151
+ end
152
+
153
+ after do
154
+ context.steps << :after3
155
+ end
156
+
157
+ def call
158
+ context.steps << :call3
159
+ end
160
+
161
+ def rollback
162
+ context.steps << :rollback3
163
+ end
164
+ end
165
+ }
166
+
167
+ let(:organizer4) {
168
+ build_organizer(organize: [interactor4a, interactor4b, interactor4c]) do
169
+ around do |interactor|
170
+ context.steps << :around_before4
171
+ interactor.call
172
+ context.steps << :around_after4
173
+ end
174
+
175
+ before do
176
+ context.steps << :before4
177
+ end
178
+
179
+ after do
180
+ context.steps << :after4
181
+ end
182
+ end
183
+ }
184
+
185
+ let(:interactor4a) {
186
+ build_interactor do
187
+ around do |interactor|
188
+ context.steps << :around_before4a
189
+ interactor.call
190
+ context.steps << :around_after4a
191
+ end
192
+
193
+ before do
194
+ context.steps << :before4a
195
+ end
196
+
197
+ after do
198
+ context.steps << :after4a
199
+ end
200
+
201
+ def call
202
+ context.steps << :call4a
203
+ end
204
+
205
+ def rollback
206
+ context.steps << :rollback4a
207
+ end
208
+ end
209
+ }
210
+
211
+ let(:interactor4b) {
212
+ build_interactor do
213
+ around do |interactor|
214
+ context.steps << :around_before4b
215
+ interactor.call
216
+ context.steps << :around_after4b
217
+ end
218
+
219
+ before do
220
+ context.steps << :before4b
221
+ end
222
+
223
+ after do
224
+ context.steps << :after4b
225
+ end
226
+
227
+ def call
228
+ context.steps << :call4b
229
+ end
230
+
231
+ def rollback
232
+ context.steps << :rollback4b
233
+ end
234
+ end
235
+ }
236
+
237
+ let(:interactor4c) {
238
+ build_interactor do
239
+ around do |interactor|
240
+ context.steps << :around_before4c
241
+ interactor.call
242
+ context.steps << :around_after4c
243
+ end
244
+
245
+ before do
246
+ context.steps << :before4c
247
+ end
248
+
249
+ after do
250
+ context.steps << :after4c
251
+ end
252
+
253
+ def call
254
+ context.steps << :call4c
255
+ end
256
+
257
+ def rollback
258
+ context.steps << :rollback4c
259
+ end
260
+ end
261
+ }
262
+
263
+ let(:interactor5) {
264
+ build_interactor do
265
+ around do |interactor|
266
+ context.steps << :around_before5
267
+ interactor.call
268
+ context.steps << :around_after5
269
+ end
270
+
271
+ before do
272
+ context.steps << :before5
273
+ end
274
+
275
+ after do
276
+ context.steps << :after5
277
+ end
278
+
279
+ def call
280
+ context.steps << :call5
281
+ end
282
+
283
+ def rollback
284
+ context.steps << :rollback5
285
+ end
286
+ end
287
+ }
288
+
289
+ let(:context) { Interactor::Context.new(steps: []) }
290
+
291
+ context "when successful" do
292
+ it "calls and runs hooks in the proper sequence" do
293
+ expect {
294
+ organizer.call(context)
295
+ }.to change {
296
+ context.steps
297
+ }.from([]).to([
298
+ :around_before, :before,
299
+ :around_before2, :before2,
300
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
301
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
302
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
303
+ :after2, :around_after2,
304
+ :around_before3, :before3, :call3, :after3, :around_after3,
305
+ :around_before4, :before4,
306
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
307
+ :around_before4b, :before4b, :call4b, :after4b, :around_after4b,
308
+ :around_before4c, :before4c, :call4c, :after4c, :around_after4c,
309
+ :after4, :around_after4,
310
+ :around_before5, :before5, :call5, :after5, :around_after5,
311
+ :after, :around_after
312
+ ])
313
+ end
314
+ end
315
+
316
+ context "when an around hook fails early" do
317
+ let(:organizer) {
318
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
319
+ around do |interactor|
320
+ context.fail!
321
+ context.steps << :around_before
322
+ interactor.call
323
+ context.steps << :around_after
324
+ end
325
+
326
+ before do
327
+ context.fail!
328
+ context.steps << :before
329
+ end
330
+
331
+ after do
332
+ context.steps << :after
333
+ end
334
+ end
335
+ }
336
+
337
+ it "aborts" do
338
+ expect {
339
+ organizer.call(context)
340
+ }.not_to change {
341
+ context.steps
342
+ }
343
+ end
344
+ end
345
+
346
+ context "when an around hook errors early" do
347
+ let(:organizer) {
348
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
349
+ around do |interactor|
350
+ raise "foo"
351
+ end
352
+
353
+ before do
354
+ context.fail!
355
+ context.steps << :before
356
+ end
357
+
358
+ after do
359
+ context.steps << :after
360
+ end
361
+ end
362
+ }
363
+
364
+ it "aborts" do
365
+ expect {
366
+ begin
367
+ organizer.call(context)
368
+ rescue
369
+ nil
370
+ end
371
+ }.not_to change {
372
+ context.steps
373
+ }
374
+ end
375
+
376
+ it "raises the error" do
377
+ expect {
378
+ organizer.call(context)
379
+ }.to raise_error("foo")
380
+ end
381
+ end
382
+
383
+ context "when a before hook fails" do
384
+ let(:organizer) {
385
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
386
+ around do |interactor|
387
+ context.steps << :around_before
388
+ interactor.call
389
+ context.steps << :around_after
390
+ end
391
+
392
+ before do
393
+ context.fail!
394
+ context.steps << :before
395
+ end
396
+
397
+ after do
398
+ context.steps << :after
399
+ end
400
+ end
401
+ }
402
+
403
+ it "aborts" do
404
+ expect {
405
+ organizer.call(context)
406
+ }.to change {
407
+ context.steps
408
+ }.from([]).to([
409
+ :around_before
410
+ ])
411
+ end
412
+ end
413
+
414
+ context "when a before hook errors" do
415
+ let(:organizer) {
416
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
417
+ around do |interactor|
418
+ context.steps << :around_before
419
+ interactor.call
420
+ context.steps << :around_after
421
+ end
422
+
423
+ before do
424
+ raise "foo"
425
+ end
426
+
427
+ after do
428
+ context.steps << :after
429
+ end
430
+ end
431
+ }
432
+
433
+ it "aborts" do
434
+ expect {
435
+ begin
436
+ organizer.call(context)
437
+ rescue
438
+ nil
439
+ end
440
+ }.to change {
441
+ context.steps
442
+ }.from([]).to([
443
+ :around_before
444
+ ])
445
+ end
446
+
447
+ it "raises the error" do
448
+ expect {
449
+ organizer.call(context)
450
+ }.to raise_error("foo")
451
+ end
452
+ end
453
+
454
+ context "when an after hook fails" do
455
+ let(:organizer) {
456
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
457
+ around do |interactor|
458
+ context.steps << :around_before
459
+ interactor.call
460
+ context.steps << :around_after
461
+ end
462
+
463
+ before do
464
+ context.steps << :before
465
+ end
466
+
467
+ after do
468
+ context.fail!
469
+ context.steps << :after
470
+ end
471
+ end
472
+ }
473
+
474
+ it "rolls back successfully called interactors and the failed interactor" do
475
+ expect {
476
+ organizer.call(context)
477
+ }.to change {
478
+ context.steps
479
+ }.from([]).to([
480
+ :around_before, :before,
481
+ :around_before2, :before2,
482
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
483
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
484
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
485
+ :after2, :around_after2,
486
+ :around_before3, :before3, :call3, :after3, :around_after3,
487
+ :around_before4, :before4,
488
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
489
+ :around_before4b, :before4b, :call4b, :after4b, :around_after4b,
490
+ :around_before4c, :before4c, :call4c, :after4c, :around_after4c,
491
+ :after4, :around_after4,
492
+ :around_before5, :before5, :call5, :after5, :around_after5,
493
+ :rollback5,
494
+ :rollback4c,
495
+ :rollback4b,
496
+ :rollback4a,
497
+ :rollback3,
498
+ :rollback2c,
499
+ :rollback2b,
500
+ :rollback2a
501
+ ])
502
+ end
503
+ end
504
+
505
+ context "when an after hook errors" do
506
+ let(:organizer) {
507
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
508
+ around do |interactor|
509
+ context.steps << :around_before
510
+ interactor.call
511
+ context.steps << :around_after
512
+ end
513
+
514
+ before do
515
+ context.steps << :before
516
+ end
517
+
518
+ after do
519
+ raise "foo"
520
+ end
521
+ end
522
+ }
523
+
524
+ it "rolls back successfully called interactors and the failed interactor" do
525
+ expect {
526
+ begin
527
+ organizer.call(context)
528
+ rescue
529
+ nil
530
+ end
531
+ }.to change {
532
+ context.steps
533
+ }.from([]).to([
534
+ :around_before, :before,
535
+ :around_before2, :before2,
536
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
537
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
538
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
539
+ :after2, :around_after2,
540
+ :around_before3, :before3, :call3, :after3, :around_after3,
541
+ :around_before4, :before4,
542
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
543
+ :around_before4b, :before4b, :call4b, :after4b, :around_after4b,
544
+ :around_before4c, :before4c, :call4c, :after4c, :around_after4c,
545
+ :after4, :around_after4,
546
+ :around_before5, :before5, :call5, :after5, :around_after5,
547
+ :rollback5,
548
+ :rollback4c,
549
+ :rollback4b,
550
+ :rollback4a,
551
+ :rollback3,
552
+ :rollback2c,
553
+ :rollback2b,
554
+ :rollback2a
555
+ ])
556
+ end
557
+
558
+ it "raises the error" do
559
+ expect {
560
+ organizer.call(context)
561
+ }.to raise_error("foo")
562
+ end
563
+ end
564
+
565
+ context "when an around hook fails late" do
566
+ let(:organizer) {
567
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
568
+ around do |interactor|
569
+ context.steps << :around_before
570
+ interactor.call
571
+ context.fail!
572
+ context.steps << :around_after
573
+ end
574
+
575
+ before do
576
+ context.steps << :before
577
+ end
578
+
579
+ after do
580
+ context.steps << :after
581
+ end
582
+ end
583
+ }
584
+
585
+ it "rolls back successfully called interactors and the failed interactor" do
586
+ expect {
587
+ organizer.call(context)
588
+ }.to change {
589
+ context.steps
590
+ }.from([]).to([
591
+ :around_before, :before,
592
+ :around_before2, :before2,
593
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
594
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
595
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
596
+ :after2, :around_after2,
597
+ :around_before3, :before3, :call3, :after3, :around_after3,
598
+ :around_before4, :before4,
599
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
600
+ :around_before4b, :before4b, :call4b, :after4b, :around_after4b,
601
+ :around_before4c, :before4c, :call4c, :after4c, :around_after4c,
602
+ :after4, :around_after4,
603
+ :around_before5, :before5, :call5, :after5, :around_after5,
604
+ :after,
605
+ :rollback5,
606
+ :rollback4c,
607
+ :rollback4b,
608
+ :rollback4a,
609
+ :rollback3,
610
+ :rollback2c,
611
+ :rollback2b,
612
+ :rollback2a
613
+ ])
614
+ end
615
+ end
616
+
617
+ context "when an around hook errors late" do
618
+ let(:organizer) {
619
+ build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do
620
+ around do |interactor|
621
+ context.steps << :around_before
622
+ interactor.call
623
+ raise "foo"
624
+ end
625
+
626
+ before do
627
+ context.steps << :before
628
+ end
629
+
630
+ after do
631
+ context.steps << :after
632
+ end
633
+ end
634
+ }
635
+
636
+ it "rolls back successfully called interactors and the failed interactor" do
637
+ expect {
638
+ begin
639
+ organizer.call(context)
640
+ rescue
641
+ nil
642
+ end
643
+ }.to change {
644
+ context.steps
645
+ }.from([]).to([
646
+ :around_before, :before,
647
+ :around_before2, :before2,
648
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
649
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
650
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
651
+ :after2, :around_after2,
652
+ :around_before3, :before3, :call3, :after3, :around_after3,
653
+ :around_before4, :before4,
654
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
655
+ :around_before4b, :before4b, :call4b, :after4b, :around_after4b,
656
+ :around_before4c, :before4c, :call4c, :after4c, :around_after4c,
657
+ :after4, :around_after4,
658
+ :around_before5, :before5, :call5, :after5, :around_after5,
659
+ :after,
660
+ :rollback5,
661
+ :rollback4c,
662
+ :rollback4b,
663
+ :rollback4a,
664
+ :rollback3,
665
+ :rollback2c,
666
+ :rollback2b,
667
+ :rollback2a
668
+ ])
669
+ end
670
+
671
+ it "raises the error" do
672
+ expect {
673
+ organizer.call(context)
674
+ }.to raise_error("foo")
675
+ end
676
+ end
677
+
678
+ context "when a nested around hook fails early" do
679
+ let(:interactor3) {
680
+ build_interactor do
681
+ around do |interactor|
682
+ context.fail!
683
+ context.steps << :around_before3
684
+ interactor.call
685
+ context.steps << :around_after3
686
+ end
687
+
688
+ before do
689
+ context.steps << :before3
690
+ end
691
+
692
+ after do
693
+ context.steps << :after3
694
+ end
695
+
696
+ def call
697
+ context.steps << :call3
698
+ end
699
+
700
+ def rollback
701
+ context.steps << :rollback3
702
+ end
703
+ end
704
+ }
705
+
706
+ it "rolls back successfully called interactors" do
707
+ expect {
708
+ organizer.call(context)
709
+ }.to change {
710
+ context.steps
711
+ }.from([]).to([
712
+ :around_before, :before,
713
+ :around_before2, :before2,
714
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
715
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
716
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
717
+ :after2, :around_after2,
718
+ :rollback2c,
719
+ :rollback2b,
720
+ :rollback2a
721
+ ])
722
+ end
723
+ end
724
+
725
+ context "when a nested around hook errors early" do
726
+ let(:interactor3) {
727
+ build_interactor do
728
+ around do |interactor|
729
+ raise "foo"
730
+ end
731
+
732
+ before do
733
+ context.steps << :before3
734
+ end
735
+
736
+ after do
737
+ context.steps << :after3
738
+ end
739
+
740
+ def call
741
+ context.steps << :call3
742
+ end
743
+
744
+ def rollback
745
+ context.steps << :rollback3
746
+ end
747
+ end
748
+ }
749
+
750
+ it "rolls back successfully called interactors" do
751
+ expect {
752
+ begin
753
+ organizer.call(context)
754
+ rescue
755
+ nil
756
+ end
757
+ }.to change {
758
+ context.steps
759
+ }.from([]).to([
760
+ :around_before, :before,
761
+ :around_before2, :before2,
762
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
763
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
764
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
765
+ :after2, :around_after2,
766
+ :rollback2c,
767
+ :rollback2b,
768
+ :rollback2a
769
+ ])
770
+ end
771
+
772
+ it "raises the error" do
773
+ expect {
774
+ organizer.call(context)
775
+ }.to raise_error("foo")
776
+ end
777
+ end
778
+
779
+ context "when a nested before hook fails" do
780
+ let(:interactor3) {
781
+ build_interactor do
782
+ around do |interactor|
783
+ context.steps << :around_before3
784
+ interactor.call
785
+ context.steps << :around_after3
786
+ end
787
+
788
+ before do
789
+ context.fail!
790
+ context.steps << :before3
791
+ end
792
+
793
+ after do
794
+ context.steps << :after3
795
+ end
796
+
797
+ def call
798
+ context.steps << :call3
799
+ end
800
+
801
+ def rollback
802
+ context.steps << :rollback3
803
+ end
804
+ end
805
+ }
806
+
807
+ it "rolls back successfully called interactors" do
808
+ expect {
809
+ organizer.call(context)
810
+ }.to change {
811
+ context.steps
812
+ }.from([]).to([
813
+ :around_before, :before,
814
+ :around_before2, :before2,
815
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
816
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
817
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
818
+ :after2, :around_after2,
819
+ :around_before3,
820
+ :rollback2c,
821
+ :rollback2b,
822
+ :rollback2a
823
+ ])
824
+ end
825
+ end
826
+
827
+ context "when a nested before hook errors" do
828
+ let(:interactor3) {
829
+ build_interactor do
830
+ around do |interactor|
831
+ context.steps << :around_before3
832
+ interactor.call
833
+ context.steps << :around_after3
834
+ end
835
+
836
+ before do
837
+ raise "foo"
838
+ end
839
+
840
+ after do
841
+ context.steps << :after3
842
+ end
843
+
844
+ def call
845
+ context.steps << :call3
846
+ end
847
+
848
+ def rollback
849
+ context.steps << :rollback3
850
+ end
851
+ end
852
+ }
853
+
854
+ it "rolls back successfully called interactors" do
855
+ expect {
856
+ begin
857
+ organizer.call(context)
858
+ rescue
859
+ nil
860
+ end
861
+ }.to change {
862
+ context.steps
863
+ }.from([]).to([
864
+ :around_before, :before,
865
+ :around_before2, :before2,
866
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
867
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
868
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
869
+ :after2, :around_after2,
870
+ :around_before3,
871
+ :rollback2c,
872
+ :rollback2b,
873
+ :rollback2a
874
+ ])
875
+ end
876
+
877
+ it "raises the error" do
878
+ expect {
879
+ organizer.call(context)
880
+ }.to raise_error("foo")
881
+ end
882
+ end
883
+
884
+ context "when a nested call fails" do
885
+ let(:interactor3) {
886
+ build_interactor do
887
+ around do |interactor|
888
+ context.steps << :around_before3
889
+ interactor.call
890
+ context.steps << :around_after3
891
+ end
892
+
893
+ before do
894
+ context.steps << :before3
895
+ end
896
+
897
+ after do
898
+ context.steps << :after3
899
+ end
900
+
901
+ def call
902
+ context.fail!
903
+ context.steps << :call3
904
+ end
905
+
906
+ def rollback
907
+ context.steps << :rollback3
908
+ end
909
+ end
910
+ }
911
+
912
+ it "rolls back successfully called interactors" do
913
+ expect {
914
+ organizer.call(context)
915
+ }.to change {
916
+ context.steps
917
+ }.from([]).to([
918
+ :around_before, :before,
919
+ :around_before2, :before2,
920
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
921
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
922
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
923
+ :after2, :around_after2,
924
+ :around_before3, :before3,
925
+ :rollback2c,
926
+ :rollback2b,
927
+ :rollback2a
928
+ ])
929
+ end
930
+ end
931
+
932
+ context "when a nested call errors" do
933
+ let(:interactor3) {
934
+ build_interactor do
935
+ around do |interactor|
936
+ context.steps << :around_before3
937
+ interactor.call
938
+ context.steps << :around_after3
939
+ end
940
+
941
+ before do
942
+ context.steps << :before3
943
+ end
944
+
945
+ after do
946
+ context.steps << :after3
947
+ end
948
+
949
+ def call
950
+ raise "foo"
951
+ end
952
+
953
+ def rollback
954
+ context.steps << :rollback3
955
+ end
956
+ end
957
+ }
958
+
959
+ it "rolls back successfully called interactors" do
960
+ expect {
961
+ begin
962
+ organizer.call(context)
963
+ rescue
964
+ nil
965
+ end
966
+ }.to change {
967
+ context.steps
968
+ }.from([]).to([
969
+ :around_before, :before,
970
+ :around_before2, :before2,
971
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
972
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
973
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
974
+ :after2, :around_after2,
975
+ :around_before3, :before3,
976
+ :rollback2c,
977
+ :rollback2b,
978
+ :rollback2a
979
+ ])
980
+ end
981
+
982
+ it "raises the error" do
983
+ expect {
984
+ organizer.call(context)
985
+ }.to raise_error("foo")
986
+ end
987
+ end
988
+
989
+ context "when a nested after hook fails" do
990
+ let(:interactor3) {
991
+ build_interactor do
992
+ around do |interactor|
993
+ context.steps << :around_before3
994
+ interactor.call
995
+ context.steps << :around_after3
996
+ end
997
+
998
+ before do
999
+ context.steps << :before3
1000
+ end
1001
+
1002
+ after do
1003
+ context.fail!
1004
+ context.steps << :after3
1005
+ end
1006
+
1007
+ def call
1008
+ context.steps << :call3
1009
+ end
1010
+
1011
+ def rollback
1012
+ context.steps << :rollback3
1013
+ end
1014
+ end
1015
+ }
1016
+
1017
+ it "rolls back successfully called interactors and the failed interactor" do
1018
+ expect {
1019
+ organizer.call(context)
1020
+ }.to change {
1021
+ context.steps
1022
+ }.from([]).to([
1023
+ :around_before, :before,
1024
+ :around_before2, :before2,
1025
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1026
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1027
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1028
+ :after2, :around_after2,
1029
+ :around_before3, :before3, :call3,
1030
+ :rollback3,
1031
+ :rollback2c,
1032
+ :rollback2b,
1033
+ :rollback2a
1034
+ ])
1035
+ end
1036
+ end
1037
+
1038
+ context "when a nested after hook errors" do
1039
+ let(:interactor3) {
1040
+ build_interactor do
1041
+ around do |interactor|
1042
+ context.steps << :around_before3
1043
+ interactor.call
1044
+ context.steps << :around_after3
1045
+ end
1046
+
1047
+ before do
1048
+ context.steps << :before3
1049
+ end
1050
+
1051
+ after do
1052
+ raise "foo"
1053
+ end
1054
+
1055
+ def call
1056
+ context.steps << :call3
1057
+ end
1058
+
1059
+ def rollback
1060
+ context.steps << :rollback3
1061
+ end
1062
+ end
1063
+ }
1064
+
1065
+ it "rolls back successfully called interactors and the failed interactor" do
1066
+ expect {
1067
+ begin
1068
+ organizer.call(context)
1069
+ rescue
1070
+ nil
1071
+ end
1072
+ }.to change {
1073
+ context.steps
1074
+ }.from([]).to([
1075
+ :around_before, :before,
1076
+ :around_before2, :before2,
1077
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1078
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1079
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1080
+ :after2, :around_after2,
1081
+ :around_before3, :before3, :call3,
1082
+ :rollback3,
1083
+ :rollback2c,
1084
+ :rollback2b,
1085
+ :rollback2a
1086
+ ])
1087
+ end
1088
+
1089
+ it "raises the error" do
1090
+ expect {
1091
+ organizer.call(context)
1092
+ }.to raise_error("foo")
1093
+ end
1094
+ end
1095
+
1096
+ context "when a nested around hook fails late" do
1097
+ let(:interactor3) {
1098
+ build_interactor do
1099
+ around do |interactor|
1100
+ context.steps << :around_before3
1101
+ interactor.call
1102
+ context.fail!
1103
+ context.steps << :around_after3
1104
+ end
1105
+
1106
+ before do
1107
+ context.steps << :before3
1108
+ end
1109
+
1110
+ after do
1111
+ context.steps << :after3
1112
+ end
1113
+
1114
+ def call
1115
+ context.steps << :call3
1116
+ end
1117
+
1118
+ def rollback
1119
+ context.steps << :rollback3
1120
+ end
1121
+ end
1122
+ }
1123
+
1124
+ it "rolls back successfully called interactors and the failed interactor" do
1125
+ expect {
1126
+ organizer.call(context)
1127
+ }.to change {
1128
+ context.steps
1129
+ }.from([]).to([
1130
+ :around_before, :before,
1131
+ :around_before2, :before2,
1132
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1133
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1134
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1135
+ :after2, :around_after2,
1136
+ :around_before3, :before3, :call3, :after3,
1137
+ :rollback3,
1138
+ :rollback2c,
1139
+ :rollback2b,
1140
+ :rollback2a
1141
+ ])
1142
+ end
1143
+ end
1144
+
1145
+ context "when a nested around hook errors late" do
1146
+ let(:interactor3) {
1147
+ build_interactor do
1148
+ around do |interactor|
1149
+ context.steps << :around_before3
1150
+ interactor.call
1151
+ raise "foo"
1152
+ end
1153
+
1154
+ before do
1155
+ context.steps << :before3
1156
+ end
1157
+
1158
+ after do
1159
+ context.steps << :after3
1160
+ end
1161
+
1162
+ def call
1163
+ context.steps << :call3
1164
+ end
1165
+
1166
+ def rollback
1167
+ context.steps << :rollback3
1168
+ end
1169
+ end
1170
+ }
1171
+
1172
+ it "rolls back successfully called interactors and the failed interactor" do
1173
+ expect {
1174
+ begin
1175
+ organizer.call(context)
1176
+ rescue
1177
+ nil
1178
+ end
1179
+ }.to change {
1180
+ context.steps
1181
+ }.from([]).to([
1182
+ :around_before, :before,
1183
+ :around_before2, :before2,
1184
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1185
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1186
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1187
+ :after2, :around_after2,
1188
+ :around_before3, :before3, :call3, :after3,
1189
+ :rollback3,
1190
+ :rollback2c,
1191
+ :rollback2b,
1192
+ :rollback2a
1193
+ ])
1194
+ end
1195
+
1196
+ it "raises the error" do
1197
+ expect {
1198
+ organizer.call(context)
1199
+ }.to raise_error("foo")
1200
+ end
1201
+ end
1202
+
1203
+ context "when a deeply nested around hook fails early" do
1204
+ let(:interactor4b) {
1205
+ build_interactor do
1206
+ around do |interactor|
1207
+ context.fail!
1208
+ context.steps << :around_before4b
1209
+ interactor.call
1210
+ context.steps << :around_after4b
1211
+ end
1212
+
1213
+ before do
1214
+ context.steps << :before4b
1215
+ end
1216
+
1217
+ after do
1218
+ context.steps << :after4b
1219
+ end
1220
+
1221
+ def call
1222
+ context.steps << :call4b
1223
+ end
1224
+
1225
+ def rollback
1226
+ context.steps << :rollback4b
1227
+ end
1228
+ end
1229
+ }
1230
+
1231
+ it "rolls back successfully called interactors" do
1232
+ expect {
1233
+ organizer.call(context)
1234
+ }.to change {
1235
+ context.steps
1236
+ }.from([]).to([
1237
+ :around_before, :before,
1238
+ :around_before2, :before2,
1239
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1240
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1241
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1242
+ :after2, :around_after2,
1243
+ :around_before3, :before3, :call3, :after3, :around_after3,
1244
+ :around_before4, :before4,
1245
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1246
+ :rollback4a,
1247
+ :rollback3,
1248
+ :rollback2c,
1249
+ :rollback2b,
1250
+ :rollback2a
1251
+ ])
1252
+ end
1253
+ end
1254
+
1255
+ context "when a deeply nested around hook errors early" do
1256
+ let(:interactor4b) {
1257
+ build_interactor do
1258
+ around do |interactor|
1259
+ raise "foo"
1260
+ end
1261
+
1262
+ before do
1263
+ context.steps << :before4b
1264
+ end
1265
+
1266
+ after do
1267
+ context.steps << :after4b
1268
+ end
1269
+
1270
+ def call
1271
+ context.steps << :call4b
1272
+ end
1273
+
1274
+ def rollback
1275
+ context.steps << :rollback4b
1276
+ end
1277
+ end
1278
+ }
1279
+
1280
+ it "rolls back successfully called interactors" do
1281
+ expect {
1282
+ begin
1283
+ organizer.call(context)
1284
+ rescue
1285
+ nil
1286
+ end
1287
+ }.to change {
1288
+ context.steps
1289
+ }.from([]).to([
1290
+ :around_before, :before,
1291
+ :around_before2, :before2,
1292
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1293
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1294
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1295
+ :after2, :around_after2,
1296
+ :around_before3, :before3, :call3, :after3, :around_after3,
1297
+ :around_before4, :before4,
1298
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1299
+ :rollback4a,
1300
+ :rollback3,
1301
+ :rollback2c,
1302
+ :rollback2b,
1303
+ :rollback2a
1304
+ ])
1305
+ end
1306
+
1307
+ it "raises the error" do
1308
+ expect {
1309
+ organizer.call(context)
1310
+ }.to raise_error("foo")
1311
+ end
1312
+ end
1313
+
1314
+ context "when a deeply nested before hook fails" do
1315
+ let(:interactor4b) {
1316
+ build_interactor do
1317
+ around do |interactor|
1318
+ context.steps << :around_before4b
1319
+ interactor.call
1320
+ context.steps << :around_after4b
1321
+ end
1322
+
1323
+ before do
1324
+ context.fail!
1325
+ context.steps << :before4b
1326
+ end
1327
+
1328
+ after do
1329
+ context.steps << :after4b
1330
+ end
1331
+
1332
+ def call
1333
+ context.steps << :call4b
1334
+ end
1335
+
1336
+ def rollback
1337
+ context.steps << :rollback4b
1338
+ end
1339
+ end
1340
+ }
1341
+
1342
+ it "rolls back successfully called interactors" do
1343
+ expect {
1344
+ organizer.call(context)
1345
+ }.to change {
1346
+ context.steps
1347
+ }.from([]).to([
1348
+ :around_before, :before,
1349
+ :around_before2, :before2,
1350
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1351
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1352
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1353
+ :after2, :around_after2,
1354
+ :around_before3, :before3, :call3, :after3, :around_after3,
1355
+ :around_before4, :before4,
1356
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1357
+ :around_before4b,
1358
+ :rollback4a,
1359
+ :rollback3,
1360
+ :rollback2c,
1361
+ :rollback2b,
1362
+ :rollback2a
1363
+ ])
1364
+ end
1365
+ end
1366
+
1367
+ context "when a deeply nested before hook errors" do
1368
+ let(:interactor4b) {
1369
+ build_interactor do
1370
+ around do |interactor|
1371
+ context.steps << :around_before4b
1372
+ interactor.call
1373
+ context.steps << :around_after4b
1374
+ end
1375
+
1376
+ before do
1377
+ raise "foo"
1378
+ end
1379
+
1380
+ after do
1381
+ context.steps << :after4b
1382
+ end
1383
+
1384
+ def call
1385
+ context.steps << :call4b
1386
+ end
1387
+
1388
+ def rollback
1389
+ context.steps << :rollback4b
1390
+ end
1391
+ end
1392
+ }
1393
+
1394
+ it "rolls back successfully called interactors" do
1395
+ expect {
1396
+ begin
1397
+ organizer.call(context)
1398
+ rescue
1399
+ nil
1400
+ end
1401
+ }.to change {
1402
+ context.steps
1403
+ }.from([]).to([
1404
+ :around_before, :before,
1405
+ :around_before2, :before2,
1406
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1407
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1408
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1409
+ :after2, :around_after2,
1410
+ :around_before3, :before3, :call3, :after3, :around_after3,
1411
+ :around_before4, :before4,
1412
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1413
+ :around_before4b,
1414
+ :rollback4a,
1415
+ :rollback3,
1416
+ :rollback2c,
1417
+ :rollback2b,
1418
+ :rollback2a
1419
+ ])
1420
+ end
1421
+
1422
+ it "raises the error" do
1423
+ expect {
1424
+ organizer.call(context)
1425
+ }.to raise_error("foo")
1426
+ end
1427
+ end
1428
+
1429
+ context "when a deeply nested call fails" do
1430
+ let(:interactor4b) {
1431
+ build_interactor do
1432
+ around do |interactor|
1433
+ context.steps << :around_before4b
1434
+ interactor.call
1435
+ context.steps << :around_after4b
1436
+ end
1437
+
1438
+ before do
1439
+ context.steps << :before4b
1440
+ end
1441
+
1442
+ after do
1443
+ context.steps << :after4b
1444
+ end
1445
+
1446
+ def call
1447
+ context.fail!
1448
+ context.steps << :call4b
1449
+ end
1450
+
1451
+ def rollback
1452
+ context.steps << :rollback4b
1453
+ end
1454
+ end
1455
+ }
1456
+
1457
+ it "rolls back successfully called interactors" do
1458
+ expect {
1459
+ organizer.call(context)
1460
+ }.to change {
1461
+ context.steps
1462
+ }.from([]).to([
1463
+ :around_before, :before,
1464
+ :around_before2, :before2,
1465
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1466
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1467
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1468
+ :after2, :around_after2,
1469
+ :around_before3, :before3, :call3, :after3, :around_after3,
1470
+ :around_before4, :before4,
1471
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1472
+ :around_before4b, :before4b,
1473
+ :rollback4a,
1474
+ :rollback3,
1475
+ :rollback2c,
1476
+ :rollback2b,
1477
+ :rollback2a
1478
+ ])
1479
+ end
1480
+ end
1481
+
1482
+ context "when a deeply nested call errors" do
1483
+ let(:interactor4b) {
1484
+ build_interactor do
1485
+ around do |interactor|
1486
+ context.steps << :around_before4b
1487
+ interactor.call
1488
+ context.steps << :around_after4b
1489
+ end
1490
+
1491
+ before do
1492
+ context.steps << :before4b
1493
+ end
1494
+
1495
+ after do
1496
+ context.steps << :after4b
1497
+ end
1498
+
1499
+ def call
1500
+ raise "foo"
1501
+ end
1502
+
1503
+ def rollback
1504
+ context.steps << :rollback4b
1505
+ end
1506
+ end
1507
+ }
1508
+
1509
+ it "rolls back successfully called interactors" do
1510
+ expect {
1511
+ begin
1512
+ organizer.call(context)
1513
+ rescue
1514
+ nil
1515
+ end
1516
+ }.to change {
1517
+ context.steps
1518
+ }.from([]).to([
1519
+ :around_before, :before,
1520
+ :around_before2, :before2,
1521
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1522
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1523
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1524
+ :after2, :around_after2,
1525
+ :around_before3, :before3, :call3, :after3, :around_after3,
1526
+ :around_before4, :before4,
1527
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1528
+ :around_before4b, :before4b,
1529
+ :rollback4a,
1530
+ :rollback3,
1531
+ :rollback2c,
1532
+ :rollback2b,
1533
+ :rollback2a
1534
+ ])
1535
+ end
1536
+
1537
+ it "raises the error" do
1538
+ expect {
1539
+ organizer.call(context)
1540
+ }.to raise_error("foo")
1541
+ end
1542
+ end
1543
+
1544
+ context "when a deeply nested after hook fails" do
1545
+ let(:interactor4b) {
1546
+ build_interactor do
1547
+ around do |interactor|
1548
+ context.steps << :around_before4b
1549
+ interactor.call
1550
+ context.steps << :around_after4b
1551
+ end
1552
+
1553
+ before do
1554
+ context.steps << :before4b
1555
+ end
1556
+
1557
+ after do
1558
+ context.fail!
1559
+ context.steps << :after4b
1560
+ end
1561
+
1562
+ def call
1563
+ context.steps << :call4b
1564
+ end
1565
+
1566
+ def rollback
1567
+ context.steps << :rollback4b
1568
+ end
1569
+ end
1570
+ }
1571
+
1572
+ it "rolls back successfully called interactors and the failed interactor" do
1573
+ expect {
1574
+ organizer.call(context)
1575
+ }.to change {
1576
+ context.steps
1577
+ }.from([]).to([
1578
+ :around_before, :before,
1579
+ :around_before2, :before2,
1580
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1581
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1582
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1583
+ :after2, :around_after2,
1584
+ :around_before3, :before3, :call3, :after3, :around_after3,
1585
+ :around_before4, :before4,
1586
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1587
+ :around_before4b, :before4b, :call4b,
1588
+ :rollback4b,
1589
+ :rollback4a,
1590
+ :rollback3,
1591
+ :rollback2c,
1592
+ :rollback2b,
1593
+ :rollback2a
1594
+ ])
1595
+ end
1596
+ end
1597
+
1598
+ context "when a deeply nested after hook errors" do
1599
+ let(:interactor4b) {
1600
+ build_interactor do
1601
+ around do |interactor|
1602
+ context.steps << :around_before4b
1603
+ interactor.call
1604
+ context.steps << :around_after4b
1605
+ end
1606
+
1607
+ before do
1608
+ context.steps << :before4b
1609
+ end
1610
+
1611
+ after do
1612
+ raise "foo"
1613
+ end
1614
+
1615
+ def call
1616
+ context.steps << :call4b
1617
+ end
1618
+
1619
+ def rollback
1620
+ context.steps << :rollback4b
1621
+ end
1622
+ end
1623
+ }
1624
+
1625
+ it "rolls back successfully called interactors and the failed interactor" do
1626
+ expect {
1627
+ begin
1628
+ organizer.call(context)
1629
+ rescue
1630
+ nil
1631
+ end
1632
+ }.to change {
1633
+ context.steps
1634
+ }.from([]).to([
1635
+ :around_before, :before,
1636
+ :around_before2, :before2,
1637
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1638
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1639
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1640
+ :after2, :around_after2,
1641
+ :around_before3, :before3, :call3, :after3, :around_after3,
1642
+ :around_before4, :before4,
1643
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1644
+ :around_before4b, :before4b, :call4b,
1645
+ :rollback4b,
1646
+ :rollback4a,
1647
+ :rollback3,
1648
+ :rollback2c,
1649
+ :rollback2b,
1650
+ :rollback2a
1651
+ ])
1652
+ end
1653
+
1654
+ it "raises the error" do
1655
+ expect {
1656
+ organizer.call(context)
1657
+ }.to raise_error("foo")
1658
+ end
1659
+ end
1660
+
1661
+ context "when a deeply nested around hook fails late" do
1662
+ let(:interactor4b) {
1663
+ build_interactor do
1664
+ around do |interactor|
1665
+ context.steps << :around_before4b
1666
+ interactor.call
1667
+ context.fail!
1668
+ context.steps << :around_after4b
1669
+ end
1670
+
1671
+ before do
1672
+ context.steps << :before4b
1673
+ end
1674
+
1675
+ after do
1676
+ context.steps << :after4b
1677
+ end
1678
+
1679
+ def call
1680
+ context.steps << :call4b
1681
+ end
1682
+
1683
+ def rollback
1684
+ context.steps << :rollback4b
1685
+ end
1686
+ end
1687
+ }
1688
+
1689
+ it "rolls back successfully called interactors and the failed interactor" do
1690
+ expect {
1691
+ organizer.call(context)
1692
+ }.to change {
1693
+ context.steps
1694
+ }.from([]).to([
1695
+ :around_before, :before,
1696
+ :around_before2, :before2,
1697
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1698
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1699
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1700
+ :after2, :around_after2,
1701
+ :around_before3, :before3, :call3, :after3, :around_after3,
1702
+ :around_before4, :before4,
1703
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1704
+ :around_before4b, :before4b, :call4b, :after4b,
1705
+ :rollback4b,
1706
+ :rollback4a,
1707
+ :rollback3,
1708
+ :rollback2c,
1709
+ :rollback2b,
1710
+ :rollback2a
1711
+ ])
1712
+ end
1713
+ end
1714
+
1715
+ context "when a deeply nested around hook errors late" do
1716
+ let(:interactor4b) {
1717
+ build_interactor do
1718
+ around do |interactor|
1719
+ context.steps << :around_before4b
1720
+ interactor.call
1721
+ raise "foo"
1722
+ end
1723
+
1724
+ before do
1725
+ context.steps << :before4b
1726
+ end
1727
+
1728
+ after do
1729
+ context.steps << :after4b
1730
+ end
1731
+
1732
+ def call
1733
+ context.steps << :call4b
1734
+ end
1735
+
1736
+ def rollback
1737
+ context.steps << :rollback4b
1738
+ end
1739
+ end
1740
+ }
1741
+
1742
+ it "rolls back successfully called interactors and the failed interactor" do
1743
+ expect {
1744
+ begin
1745
+ organizer.call(context)
1746
+ rescue
1747
+ nil
1748
+ end
1749
+ }.to change {
1750
+ context.steps
1751
+ }.from([]).to([
1752
+ :around_before, :before,
1753
+ :around_before2, :before2,
1754
+ :around_before2a, :before2a, :call2a, :after2a, :around_after2a,
1755
+ :around_before2b, :before2b, :call2b, :after2b, :around_after2b,
1756
+ :around_before2c, :before2c, :call2c, :after2c, :around_after2c,
1757
+ :after2, :around_after2,
1758
+ :around_before3, :before3, :call3, :after3, :around_after3,
1759
+ :around_before4, :before4,
1760
+ :around_before4a, :before4a, :call4a, :after4a, :around_after4a,
1761
+ :around_before4b, :before4b, :call4b, :after4b,
1762
+ :rollback4b,
1763
+ :rollback4a,
1764
+ :rollback3,
1765
+ :rollback2c,
1766
+ :rollback2b,
1767
+ :rollback2a
1768
+ ])
1769
+ end
1770
+
1771
+ it "raises the error" do
1772
+ expect {
1773
+ organizer.call(context)
1774
+ }.to raise_error("foo")
1775
+ end
1776
+ end
1777
+ end