|
1 | 1 | shared_examples :lint do |
2 | 2 | let(:interactor) { Class.new.send(:include, described_class) } |
3 | 3 |
|
| 4 | + let(:context_double) do |
| 5 | + double(:double, failure?: false, called!: nil, rollback!: nil) |
| 6 | + end |
| 7 | + |
| 8 | + let(:failed_context_double) do |
| 9 | + double(:failed_context_double, failure?: true, called!: nil, rollback!: nil) |
| 10 | + end |
| 11 | + |
4 | 12 | describe ".call" do |
5 | 13 | let(:context) { double(:context) } |
6 | 14 | let(:instance) { double(:instance, context: context) } |
|
66 | 74 | let(:instance) { interactor.new } |
67 | 75 |
|
68 | 76 | it "runs the interactor" do |
69 | | - expect(instance).to receive(:run!).once.with(no_args) |
| 77 | + expect(instance).to receive(:call).once.with(no_args) |
70 | 78 |
|
71 | 79 | instance.run |
72 | 80 | end |
73 | 81 |
|
74 | | - it "rescues failure" do |
75 | | - expect(instance).to receive(:run!).and_raise(Interactor::Failure) |
76 | | - |
| 82 | + it "catches :early_return" do |
| 83 | + allow(instance).to receive(:call).and_throw(:early_return) |
77 | 84 | expect { |
78 | 85 | instance.run |
79 | | - }.not_to raise_error |
| 86 | + }.not_to throw_symbol |
80 | 87 | end |
81 | 88 |
|
82 | | - it "raises other errors" do |
83 | | - expect(instance).to receive(:run!).and_raise("foo") |
| 89 | + context "when error is raised inside #call" do |
| 90 | + it "propagates it and rollbacks context" do |
| 91 | + allow(instance).to receive(:context) { context_double } |
| 92 | + allow(instance).to receive(:call).and_raise("foo") |
84 | 93 |
|
85 | | - expect { |
| 94 | + expect(instance.context).to receive(:rollback!) |
| 95 | + expect { |
| 96 | + instance.run |
| 97 | + }.to raise_error("foo") |
| 98 | + end |
| 99 | + end |
| 100 | + |
| 101 | + context "on call failure" do |
| 102 | + before do |
| 103 | + allow(instance).to receive(:context) { failed_context_double } |
| 104 | + end |
| 105 | + |
| 106 | + it "doesn't raise Failure" do |
| 107 | + expect { |
| 108 | + instance.run |
| 109 | + }.not_to raise_error |
| 110 | + end |
| 111 | + |
| 112 | + it "rollbacks context on error" do |
| 113 | + expect(instance.context).to receive(:rollback!) |
86 | 114 | instance.run |
87 | | - }.to raise_error("foo") |
| 115 | + end |
88 | 116 | end |
89 | 117 | end |
90 | 118 |
|
91 | 119 | describe "#run!" do |
92 | 120 | let(:instance) { interactor.new } |
93 | 121 |
|
94 | 122 | it "calls the interactor" do |
95 | | - expect(instance).to receive(:call).once.with(no_args) |
| 123 | + expect(instance).to receive(:run).once.with(no_args) |
96 | 124 |
|
97 | 125 | instance.run! |
98 | 126 | end |
99 | 127 |
|
100 | | - it "raises failure" do |
101 | | - expect(instance).to receive(:run!).and_raise(Interactor::Failure) |
102 | | - |
103 | | - expect { |
104 | | - instance.run! |
105 | | - }.to raise_error(Interactor::Failure) |
106 | | - end |
107 | | - |
108 | | - it "raises other errors" do |
109 | | - expect(instance).to receive(:run!).and_raise("foo") |
| 128 | + it "propagates errors" do |
| 129 | + expect(instance).to receive(:run).and_raise("foo") |
110 | 130 |
|
111 | 131 | expect { |
112 | 132 | instance.run |
113 | 133 | }.to raise_error("foo") |
114 | 134 | end |
| 135 | + |
| 136 | + context "on failure" do |
| 137 | + before do |
| 138 | + allow(instance).to receive(:context) { failed_context_double } |
| 139 | + end |
| 140 | + |
| 141 | + it "raises Interactor::Failure" do |
| 142 | + expect { |
| 143 | + instance.run! |
| 144 | + }.to raise_error(Interactor::Failure) |
| 145 | + end |
| 146 | + |
| 147 | + it "makes context available from the error" do |
| 148 | + begin |
| 149 | + instance.run! |
| 150 | + rescue Interactor::Failure => error |
| 151 | + expect(error.context).to be(instance.context) |
| 152 | + end |
| 153 | + end |
| 154 | + end |
115 | 155 | end |
116 | 156 |
|
117 | 157 | describe "#call" do |
|
0 commit comments