interactor-strict 1.0.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.
@@ -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