substation 0.0.9 → 0.0.10.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +0 -1
- data/Changelog.md +24 -82
- data/Gemfile.devtools +17 -24
- data/README.md +46 -116
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/mutant.yml +0 -1
- data/config/reek.yml +5 -10
- data/lib/substation.rb +3 -8
- data/lib/substation/chain.rb +64 -108
- data/lib/substation/chain/dsl.rb +30 -57
- data/lib/substation/dispatcher.rb +1 -3
- data/lib/substation/environment.rb +23 -9
- data/lib/substation/environment/dsl.rb +3 -4
- data/lib/substation/observer.rb +2 -4
- data/lib/substation/processor.rb +7 -106
- data/lib/substation/processor/evaluator.rb +42 -83
- data/lib/substation/processor/pivot.rb +25 -0
- data/lib/substation/processor/wrapper.rb +2 -4
- data/lib/substation/request.rb +1 -10
- data/lib/substation/response.rb +0 -11
- data/lib/substation/utils.rb +1 -3
- data/lib/substation/version.rb +1 -3
- data/spec/integration/substation/dispatcher/call_spec.rb +12 -12
- data/spec/spec_helper.rb +21 -30
- data/spec/unit/substation/chain/call_spec.rb +32 -202
- data/spec/unit/substation/chain/dsl/builder/class_methods/call_spec.rb +2 -2
- data/spec/unit/substation/chain/dsl/builder/dsl_spec.rb +6 -8
- data/spec/unit/substation/chain/dsl/builder/failure_chain_spec.rb +30 -0
- data/spec/unit/substation/chain/dsl/chain_spec.rb +2 -1
- data/spec/unit/substation/chain/dsl/class_methods/processors_spec.rb +24 -0
- data/spec/unit/substation/chain/dsl/initialize_spec.rb +19 -0
- data/spec/unit/substation/chain/dsl/processors_spec.rb +21 -9
- data/spec/unit/substation/chain/dsl/use_spec.rb +3 -2
- data/spec/unit/substation/chain/each_spec.rb +9 -5
- data/spec/unit/substation/chain/incoming/result_spec.rb +21 -0
- data/spec/unit/substation/chain/outgoing/call_spec.rb +25 -0
- data/spec/unit/substation/{processor → chain/outgoing}/result_spec.rb +5 -6
- data/spec/unit/substation/dispatcher/action/call_spec.rb +6 -7
- data/spec/unit/substation/dispatcher/action/class_methods/coerce_spec.rb +5 -7
- data/spec/unit/substation/dispatcher/action_names_spec.rb +1 -1
- data/spec/unit/substation/dispatcher/call_spec.rb +3 -3
- data/spec/unit/substation/dispatcher/class_methods/coerce_spec.rb +7 -7
- data/spec/unit/substation/environment/chain_spec.rb +32 -22
- data/spec/unit/substation/environment/class_methods/build_spec.rb +4 -11
- data/spec/unit/substation/environment/dsl/class_methods/registry_spec.rb +3 -5
- data/spec/unit/substation/environment/dsl/register_spec.rb +3 -8
- data/spec/unit/substation/environment/dsl/registry_spec.rb +3 -5
- data/spec/unit/substation/observer/chain/call_spec.rb +3 -5
- data/spec/unit/substation/observer/class_methods/coerce_spec.rb +2 -4
- data/spec/unit/substation/observer/null/call_spec.rb +1 -3
- data/spec/unit/substation/processor/evaluator/call_spec.rb +35 -21
- data/spec/unit/substation/processor/pivot/call_spec.rb +17 -0
- data/spec/unit/substation/processor/wrapper/call_spec.rb +7 -8
- data/spec/unit/substation/request/env_spec.rb +4 -5
- data/spec/unit/substation/request/error_spec.rb +4 -5
- data/spec/unit/substation/request/input_spec.rb +4 -5
- data/spec/unit/substation/request/success_spec.rb +4 -5
- data/spec/unit/substation/response/env_spec.rb +5 -6
- data/spec/unit/substation/response/failure/success_predicate_spec.rb +4 -5
- data/spec/unit/substation/response/input_spec.rb +5 -6
- data/spec/unit/substation/response/output_spec.rb +4 -5
- data/spec/unit/substation/response/request_spec.rb +5 -6
- data/spec/unit/substation/response/success/success_predicate_spec.rb +4 -5
- data/spec/unit/substation/utils/class_methods/coerce_callable_spec.rb +13 -15
- data/spec/unit/substation/utils/class_methods/const_get_spec.rb +6 -6
- data/spec/unit/substation/utils/class_methods/symbolize_keys_spec.rb +4 -4
- data/substation.gemspec +1 -1
- metadata +18 -45
- data/config/rubocop.yml +0 -35
- data/lib/substation/processor/transformer.rb +0 -26
- data/spec/unit/substation/chain/class_methods/failure_response_spec.rb +0 -16
- data/spec/unit/substation/chain/dsl/class_methods/build_spec.rb +0 -24
- data/spec/unit/substation/chain/dsl/failure_chain_spec.rb +0 -35
- data/spec/unit/substation/chain/failure_data/equalizer_spec.rb +0 -46
- data/spec/unit/substation/chain/failure_data/hash_spec.rb +0 -13
- data/spec/unit/substation/environment/equalizer_spec.rb +0 -25
- data/spec/unit/substation/processor/evaluator/class_methods/new_spec.rb +0 -9
- data/spec/unit/substation/processor/evaluator/data/call_spec.rb +0 -34
- data/spec/unit/substation/processor/evaluator/pivot/call_spec.rb +0 -34
- data/spec/unit/substation/processor/evaluator/request/call_spec.rb +0 -34
- data/spec/unit/substation/processor/fallible/name_spec.rb +0 -15
- data/spec/unit/substation/processor/fallible/with_failure_chain_spec.rb +0 -18
- data/spec/unit/substation/processor/incoming/result_spec.rb +0 -25
- data/spec/unit/substation/processor/outgoing/call_spec.rb +0 -28
- data/spec/unit/substation/processor/outgoing/name_spec.rb +0 -14
- data/spec/unit/substation/processor/outgoing/success_predicate_spec.rb +0 -15
- data/spec/unit/substation/processor/success_predicate_spec.rb +0 -22
- data/spec/unit/substation/processor/transformer/call_spec.rb +0 -21
- data/spec/unit/substation/request/name_spec.rb +0 -15
- data/spec/unit/substation/response/to_request_spec.rb +0 -19
data/lib/substation/request.rb
CHANGED
@@ -1,20 +1,11 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Substation
|
4
2
|
|
5
3
|
# Encapsulates the application environment and an input model instance
|
6
4
|
class Request
|
7
5
|
|
8
|
-
include Concord.new(:
|
6
|
+
include Concord.new(:env, :input)
|
9
7
|
include Adamantium::Flat
|
10
8
|
|
11
|
-
# The name of the request
|
12
|
-
#
|
13
|
-
# @return [Symbol]
|
14
|
-
#
|
15
|
-
# @api private
|
16
|
-
attr_reader :name
|
17
|
-
|
18
9
|
# The application environment
|
19
10
|
#
|
20
11
|
# @example
|
data/lib/substation/response.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Substation
|
4
2
|
|
5
3
|
# Base class for action responses
|
@@ -131,15 +129,6 @@ module Substation
|
|
131
129
|
# @api public
|
132
130
|
abstract_method :success?
|
133
131
|
|
134
|
-
# Return a {Request} instance built upon this response
|
135
|
-
#
|
136
|
-
# @return [Request]
|
137
|
-
#
|
138
|
-
# @api private
|
139
|
-
def to_request
|
140
|
-
Request.new(request.name, env, output)
|
141
|
-
end
|
142
|
-
|
143
132
|
# An errorneous {Response}
|
144
133
|
class Failure < self
|
145
134
|
|
data/lib/substation/utils.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Substation
|
4
2
|
|
5
3
|
# A collection of utility methods
|
@@ -14,7 +12,7 @@ module Substation
|
|
14
12
|
#
|
15
13
|
# @api private
|
16
14
|
def self.const_get(name)
|
17
|
-
list = name.to_s.split(
|
15
|
+
list = name.to_s.split("::")
|
18
16
|
list.shift if list.first.empty?
|
19
17
|
obj = Object
|
20
18
|
list.each do |const|
|
data/lib/substation/version.rb
CHANGED
@@ -181,8 +181,8 @@ module App
|
|
181
181
|
end # module Actions
|
182
182
|
|
183
183
|
module Observers
|
184
|
-
|
185
|
-
|
184
|
+
LogEvent = Proc.new { |response| response }
|
185
|
+
SendEmail = Proc.new { |response| response }
|
186
186
|
end
|
187
187
|
|
188
188
|
DB = Database.new({
|
@@ -198,8 +198,8 @@ module App
|
|
198
198
|
:create_person => {
|
199
199
|
:action => Actions::CreatePerson,
|
200
200
|
:observer => [
|
201
|
-
Observers::
|
202
|
-
Observers::
|
201
|
+
Observers::LogEvent,
|
202
|
+
Observers::SendEmail
|
203
203
|
]
|
204
204
|
}
|
205
205
|
}
|
@@ -213,11 +213,11 @@ end
|
|
213
213
|
|
214
214
|
describe App::APP, '#call' do
|
215
215
|
|
216
|
-
context
|
216
|
+
context "when dispatching an action" do
|
217
217
|
subject { object.call(action, input) }
|
218
218
|
|
219
219
|
let(:object) { described_class }
|
220
|
-
let(:request) { Substation::Request.new(
|
220
|
+
let(:request) { Substation::Request.new(env, input) }
|
221
221
|
let(:env) { App::Environment.new(storage) }
|
222
222
|
let(:storage) { App::Storage.new(App::DB) }
|
223
223
|
let(:response) { Substation::Response::Success.new(request, output) }
|
@@ -225,7 +225,7 @@ describe App::APP, '#call' do
|
|
225
225
|
let(:john) { App::Models::Person.new(:id => 1, :name => 'John') }
|
226
226
|
let(:jane) { App::Models::Person.new(:id => 2, :name => 'Jane') }
|
227
227
|
|
228
|
-
context
|
228
|
+
context "with no input data" do
|
229
229
|
let(:action) { :list_people }
|
230
230
|
let(:input) { nil }
|
231
231
|
let(:output) { [ john ] }
|
@@ -233,8 +233,8 @@ describe App::APP, '#call' do
|
|
233
233
|
it { should eql(response) }
|
234
234
|
end
|
235
235
|
|
236
|
-
context
|
237
|
-
context
|
236
|
+
context "with input data" do
|
237
|
+
context "and no observer" do
|
238
238
|
let(:action) { :load_person }
|
239
239
|
let(:input) { 1 }
|
240
240
|
let(:output) { john }
|
@@ -242,14 +242,14 @@ describe App::APP, '#call' do
|
|
242
242
|
it { should eq(response) }
|
243
243
|
end
|
244
244
|
|
245
|
-
context
|
245
|
+
context "and observers" do
|
246
246
|
let(:action) { :create_person }
|
247
247
|
let(:input) { jane }
|
248
248
|
let(:output) { [ john, jane ] }
|
249
249
|
|
250
250
|
before do
|
251
|
-
App::Observers::
|
252
|
-
App::Observers::
|
251
|
+
App::Observers::LogEvent.should_receive(:call).with(response).ordered
|
252
|
+
App::Observers::SendEmail.should_receive(:call).with(response).ordered
|
253
253
|
end
|
254
254
|
|
255
255
|
it { should eql(response) }
|
data/spec/spec_helper.rb
CHANGED
@@ -1,28 +1,7 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require 'devtools/spec_helper'
|
4
2
|
|
5
3
|
require 'concord' # makes spec setup easier
|
6
4
|
|
7
|
-
if ENV['COVERAGE'] == 'true'
|
8
|
-
require 'simplecov'
|
9
|
-
require 'coveralls'
|
10
|
-
|
11
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
12
|
-
SimpleCov::Formatter::HTMLFormatter,
|
13
|
-
Coveralls::SimpleCov::Formatter
|
14
|
-
]
|
15
|
-
|
16
|
-
SimpleCov.start do
|
17
|
-
command_name 'spec:unit'
|
18
|
-
add_filter 'config'
|
19
|
-
add_filter 'spec'
|
20
|
-
minimum_coverage 100
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
require 'substation'
|
25
|
-
|
26
5
|
module Spec
|
27
6
|
|
28
7
|
def self.response_data
|
@@ -49,20 +28,13 @@ module Spec
|
|
49
28
|
end
|
50
29
|
|
51
30
|
class Processor
|
52
|
-
include
|
53
|
-
attr_reader :name
|
31
|
+
include Concord::Public.new(:env, :handler)
|
54
32
|
end
|
55
33
|
|
56
34
|
class Presenter
|
57
35
|
include Concord.new(:data)
|
58
36
|
end
|
59
37
|
|
60
|
-
class Transformer
|
61
|
-
def self.call(response)
|
62
|
-
:transformed
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
38
|
module Handler
|
67
39
|
|
68
40
|
class Evaluator
|
@@ -106,10 +78,29 @@ module Spec
|
|
106
78
|
|
107
79
|
FAKE_HANDLER = Object.new
|
108
80
|
FAKE_ENV = Object.new
|
109
|
-
FAKE_PROCESSOR = Processor.new(
|
81
|
+
FAKE_PROCESSOR = Processor.new(FAKE_ENV, FAKE_HANDLER)
|
110
82
|
|
111
83
|
end
|
112
84
|
|
85
|
+
if ENV['COVERAGE'] == 'true'
|
86
|
+
require 'simplecov'
|
87
|
+
require 'coveralls'
|
88
|
+
|
89
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
90
|
+
SimpleCov::Formatter::HTMLFormatter,
|
91
|
+
Coveralls::SimpleCov::Formatter
|
92
|
+
]
|
93
|
+
|
94
|
+
SimpleCov.start do
|
95
|
+
command_name 'spec:unit'
|
96
|
+
add_filter 'config'
|
97
|
+
add_filter 'spec'
|
98
|
+
minimum_coverage 100
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
require 'substation'
|
103
|
+
|
113
104
|
include Substation
|
114
105
|
|
115
106
|
RSpec.configure do |config|
|
@@ -6,228 +6,58 @@ describe Chain, '#call' do
|
|
6
6
|
|
7
7
|
subject { object.call(request) }
|
8
8
|
|
9
|
-
let(:object)
|
10
|
-
let(:
|
11
|
-
let(:
|
12
|
-
let(:
|
13
|
-
let(:
|
14
|
-
|
15
|
-
let(:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
let(:processor_1_name) { mock }
|
21
|
-
let(:processor_2_name) { mock }
|
22
|
-
let(:processor_3_name) { mock }
|
23
|
-
|
24
|
-
context 'when all processors are successful' do
|
25
|
-
let(:processor_1) {
|
26
|
-
Class.new {
|
27
|
-
include Substation::Processor::Incoming
|
28
|
-
def call(request)
|
29
|
-
request.success(:success_1)
|
30
|
-
end
|
31
|
-
}.new(processor_1_name, handler, failure_chain)
|
32
|
-
}
|
33
|
-
|
34
|
-
let(:processor_2) {
|
35
|
-
Class.new {
|
36
|
-
include Substation::Processor::Pivot
|
37
|
-
def call(request)
|
38
|
-
request.success(:success_2)
|
39
|
-
end
|
40
|
-
}.new(processor_2_name, handler, failure_chain)
|
41
|
-
}
|
42
|
-
|
43
|
-
let(:processor_3) {
|
44
|
-
Class.new {
|
45
|
-
include Substation::Processor::Outgoing
|
46
|
-
def call(response)
|
47
|
-
respond_with(response, :success_3)
|
48
|
-
end
|
49
|
-
}.new(processor_3_name, handler)
|
50
|
-
}
|
51
|
-
|
52
|
-
let(:response) { Response::Success.new(current_request, :success_3) }
|
53
|
-
let(:current_request) { Request.new(name, env, :success_1) }
|
54
|
-
|
55
|
-
it { should eql(response) }
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'when an incoming processor is not successful' do
|
59
|
-
|
60
|
-
let(:processor_2) {
|
61
|
-
Class.new {
|
62
|
-
include Substation::Processor::Pivot
|
63
|
-
def call(request)
|
64
|
-
request.success(:success_1)
|
65
|
-
end
|
66
|
-
}.new(processor_2_name, handler, failure_chain)
|
67
|
-
}
|
68
|
-
|
69
|
-
let(:processor_3) {
|
70
|
-
Class.new {
|
71
|
-
include Substation::Processor::Outgoing
|
72
|
-
def call(response)
|
73
|
-
respond_with(response, :success_3)
|
74
|
-
end
|
75
|
-
}.new(processor_3_name, handler)
|
76
|
-
}
|
77
|
-
|
78
|
-
let(:response_class) { Response::Failure }
|
79
|
-
|
80
|
-
context 'because it returned a failure response' do
|
81
|
-
let(:processor_1) {
|
82
|
-
Class.new {
|
83
|
-
include Substation::Processor::Incoming
|
84
|
-
def call(request)
|
85
|
-
request.error(:error_1)
|
86
|
-
end
|
87
|
-
}.new(processor_1_name, handler, failure_chain)
|
88
|
-
}
|
89
|
-
|
90
|
-
let(:response) { Response::Failure.new(request, :error_1) }
|
91
|
-
|
92
|
-
it { should eql(response) }
|
93
|
-
end
|
94
|
-
|
95
|
-
context 'because it raised an uncaught exception' do
|
96
|
-
let(:processor_1) {
|
97
|
-
Class.new {
|
98
|
-
include Substation::Processor::Incoming
|
99
|
-
def call(request)
|
100
|
-
raise RuntimeError, 'exception_1'
|
101
|
-
end
|
102
|
-
}.new(processor_1_name, handler, failure_chain)
|
103
|
-
}
|
104
|
-
|
105
|
-
let(:response) { Response::Failure.new(request, data) }
|
106
|
-
let(:data) { Chain::FailureData.new(request, RuntimeError.new('exception_1')) }
|
107
|
-
|
108
|
-
it { should eql(response) }
|
109
|
-
|
110
|
-
it 'wraps the original exception instance' do
|
111
|
-
expect(subject.output.exception.message).to eql('exception_1')
|
9
|
+
let(:object) { described_class.new(handlers) }
|
10
|
+
let(:handlers) { [ handler_1, handler_2 ] }
|
11
|
+
let(:request) { Request.new(env, input) }
|
12
|
+
let(:env) { double }
|
13
|
+
let(:input) { double }
|
14
|
+
|
15
|
+
let(:handler_2) {
|
16
|
+
Class.new {
|
17
|
+
include Substation::Chain::Outgoing
|
18
|
+
def call(request)
|
19
|
+
request.success(request.input)
|
112
20
|
end
|
21
|
+
}.new
|
22
|
+
}
|
113
23
|
|
114
|
-
|
115
|
-
exception_chain.should_receive(:call).with(response)
|
116
|
-
subject
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
24
|
+
let(:response) { response_class.new(request, request.input) }
|
120
25
|
|
121
|
-
context
|
122
|
-
let(:
|
26
|
+
context "when all handlers are successful" do
|
27
|
+
let(:handler_1) {
|
123
28
|
Class.new {
|
124
|
-
include Substation::
|
29
|
+
include Substation::Chain::Incoming
|
125
30
|
def call(request)
|
126
|
-
request.success(
|
127
|
-
end
|
128
|
-
}.new(processor_1_name, handler, failure_chain)
|
129
|
-
}
|
130
|
-
|
131
|
-
let(:processor_3) {
|
132
|
-
Class.new {
|
133
|
-
include Substation::Processor::Outgoing
|
134
|
-
def call(response)
|
135
|
-
response
|
31
|
+
request.success(request.input)
|
136
32
|
end
|
137
|
-
}.new
|
33
|
+
}.new
|
138
34
|
}
|
139
35
|
|
140
|
-
let(:response_class) { Response::
|
141
|
-
|
142
|
-
context 'because it returned a failure response' do
|
143
|
-
let(:processor_2) {
|
144
|
-
Class.new {
|
145
|
-
include Substation::Processor::Pivot
|
146
|
-
def call(request)
|
147
|
-
request.error(:error_2)
|
148
|
-
end
|
149
|
-
}.new(processor_2_name, handler, failure_chain)
|
150
|
-
}
|
36
|
+
let(:response_class) { Response::Success }
|
151
37
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
it { should eql(response) }
|
38
|
+
before do
|
39
|
+
handler_2.should_receive(:call).with(request).and_return(response)
|
156
40
|
end
|
157
41
|
|
158
|
-
|
159
|
-
let(:processor_2) {
|
160
|
-
Class.new {
|
161
|
-
include Substation::Processor::Pivot
|
162
|
-
def call(request)
|
163
|
-
raise RuntimeError, 'exception_2'
|
164
|
-
end
|
165
|
-
}.new(processor_2_name, handler, failure_chain)
|
166
|
-
}
|
167
|
-
|
168
|
-
let(:response) { Response::Failure.new(request, data) }
|
169
|
-
let(:data) { Chain::FailureData.new(current_request, RuntimeError.new('exception_2')) }
|
170
|
-
let(:current_request) { Request.new(name, env, :success_1) }
|
171
|
-
|
172
|
-
it { should eql(response) }
|
173
|
-
|
174
|
-
it 'wraps the original exception instance' do
|
175
|
-
expect(subject.output.exception.message).to eql('exception_2')
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'calls the failure chain' do
|
179
|
-
exception_chain.should_receive(:call).with(response)
|
180
|
-
subject
|
181
|
-
end
|
182
|
-
end
|
42
|
+
it { should eql(response) }
|
183
43
|
end
|
184
44
|
|
185
|
-
context
|
186
|
-
let(:
|
45
|
+
context "when an intermediate handler is not successful" do
|
46
|
+
let(:handler_1) {
|
187
47
|
Class.new {
|
188
|
-
include Substation::
|
48
|
+
include Substation::Chain::Incoming
|
189
49
|
def call(request)
|
190
|
-
request.
|
191
|
-
end
|
192
|
-
}.new(processor_1_name, handler, failure_chain)
|
193
|
-
}
|
194
|
-
|
195
|
-
let(:processor_2) {
|
196
|
-
Class.new {
|
197
|
-
include Substation::Processor::Pivot
|
198
|
-
def call(response)
|
199
|
-
response.success(:success_2)
|
50
|
+
request.error(request.input)
|
200
51
|
end
|
201
|
-
}.new
|
52
|
+
}.new
|
202
53
|
}
|
203
54
|
|
204
55
|
let(:response_class) { Response::Failure }
|
205
56
|
|
206
|
-
|
207
|
-
|
208
|
-
Class.new {
|
209
|
-
include Substation::Processor::Outgoing
|
210
|
-
def call(response)
|
211
|
-
raise RuntimeError, 'exception_3'
|
212
|
-
end
|
213
|
-
}.new(processor_3_name, handler)
|
214
|
-
}
|
215
|
-
|
216
|
-
let(:response) { Response::Failure.new(request, data) }
|
217
|
-
let(:data) { Chain::FailureData.new(current_response, RuntimeError.new('exception_3')) }
|
218
|
-
let(:current_request) { Request.new(name, env, :success_1) }
|
219
|
-
let(:current_response) { Response::Success.new(current_request, :success_2) }
|
220
|
-
|
221
|
-
it { should eql(response) }
|
222
|
-
|
223
|
-
it 'wraps the original exception instance' do
|
224
|
-
expect(subject.output.exception.message).to eql('exception_3')
|
225
|
-
end
|
226
|
-
|
227
|
-
it 'calls the failure chain' do
|
228
|
-
exception_chain.should_receive(:call).with(response)
|
229
|
-
subject
|
230
|
-
end
|
57
|
+
before do
|
58
|
+
handler_2.should_not_receive(:call)
|
231
59
|
end
|
60
|
+
|
61
|
+
it { should eql(response) }
|
232
62
|
end
|
233
63
|
end
|