substation 0.0.10.beta2 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -3
- data/Changelog.md +99 -24
- data/Gemfile +8 -1
- data/Gemfile.devtools +37 -21
- data/Guardfile +1 -1
- data/README.md +118 -46
- data/TODO.md +1 -0
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/reek.yml +41 -16
- data/config/rubocop.yml +44 -0
- data/config/yardstick.yml +1 -1
- data/lib/substation.rb +41 -5
- data/lib/substation/chain.rb +73 -84
- data/lib/substation/chain/definition.rb +147 -0
- data/lib/substation/chain/dsl.rb +150 -112
- data/lib/substation/chain/dsl/config.rb +55 -0
- data/lib/substation/chain/dsl/module_builder.rb +84 -0
- data/lib/substation/dispatcher.rb +20 -229
- data/lib/substation/dsl/guard.rb +96 -0
- data/lib/substation/dsl/registry.rb +181 -0
- data/lib/substation/environment.rb +126 -23
- data/lib/substation/environment/dsl.rb +31 -12
- data/lib/substation/processor.rb +238 -7
- data/lib/substation/processor/builder.rb +26 -0
- data/lib/substation/processor/config.rb +24 -0
- data/lib/substation/processor/evaluator.rb +66 -42
- data/lib/substation/processor/evaluator/handler.rb +54 -0
- data/lib/substation/processor/evaluator/result.rb +24 -0
- data/lib/substation/processor/executor.rb +46 -0
- data/lib/substation/processor/nest.rb +40 -0
- data/lib/substation/processor/transformer.rb +46 -0
- data/lib/substation/processor/wrapper.rb +16 -5
- data/lib/substation/request.rb +29 -27
- data/lib/substation/response.rb +19 -34
- data/lib/substation/response/api.rb +37 -0
- data/lib/substation/response/exception.rb +20 -0
- data/lib/substation/response/exception/output.rb +59 -0
- data/lib/substation/response/failure.rb +11 -0
- data/lib/substation/response/success.rb +11 -0
- data/lib/substation/version.rb +3 -1
- data/spec/demo/core.rb +64 -0
- data/spec/demo/core/action.rb +49 -0
- data/spec/demo/core/action/create_person.rb +28 -0
- data/spec/demo/core/errors.rb +16 -0
- data/spec/demo/core/facade.rb +38 -0
- data/spec/demo/core/handler.rb +21 -0
- data/spec/demo/core/handler/acceptor.rb +47 -0
- data/spec/demo/core/handler/authenticator.rb +36 -0
- data/spec/demo/core/handler/authorizer.rb +38 -0
- data/spec/demo/core/input.rb +15 -0
- data/spec/demo/core/observers.rb +10 -0
- data/spec/demo/core/validator.rb +21 -0
- data/spec/demo/domain/actor.rb +29 -0
- data/spec/demo/domain/dto/person.rb +18 -0
- data/spec/demo/domain/environment.rb +55 -0
- data/spec/demo/domain/storage.rb +49 -0
- data/spec/demo/web.rb +26 -0
- data/spec/demo/web/errors.rb +9 -0
- data/spec/demo/web/facade.rb +60 -0
- data/spec/demo/web/handler/deserializer.rb +36 -0
- data/spec/demo/web/presenter.rb +38 -0
- data/spec/demo/web/presenter/person.rb +19 -0
- data/spec/demo/web/renderer.rb +45 -0
- data/spec/demo/web/sanitizer.rb +35 -0
- data/spec/demo/web/sanitizer/person.rb +20 -0
- data/spec/demo/web/views.rb +28 -0
- data/spec/integration/demo/core_spec.rb +97 -0
- data/spec/integration/demo/web_spec.rb +114 -0
- data/spec/shared/context/integration/demo.rb +33 -0
- data/spec/shared/context/unit/chain.rb +13 -0
- data/spec/shared/context/unit/processor.rb +58 -0
- data/spec/shared/context/unit/request.rb +8 -0
- data/spec/shared/examples/integration/demo.rb +35 -0
- data/spec/shared/examples/unit/processor.rb +72 -0
- data/spec/spec_helper.rb +52 -23
- data/spec/unit/substation/chain/definition_spec.rb +141 -0
- data/spec/unit/substation/chain/dsl/config/dsl_module_spec.rb +13 -0
- data/spec/unit/substation/chain/dsl/config/registry_spec.rb +13 -0
- data/spec/unit/substation/chain/dsl/config_spec.rb +18 -0
- data/spec/unit/substation/chain/dsl/module_builder_spec.rb +77 -0
- data/spec/unit/substation/chain/dsl_spec.rb +175 -0
- data/spec/unit/substation/chain_spec.rb +303 -0
- data/spec/unit/substation/dispatcher_spec.rb +68 -0
- data/spec/unit/substation/dsl/guard_spec.rb +72 -0
- data/spec/unit/substation/dsl/registry_spec.rb +181 -0
- data/spec/unit/substation/environment/dsl_spec.rb +156 -0
- data/spec/unit/substation/environment_spec.rb +259 -0
- data/spec/unit/substation/processor/builder_spec.rb +21 -0
- data/spec/unit/substation/processor/config_spec.rb +40 -0
- data/spec/unit/substation/processor/evaluator/handler_spec.rb +20 -0
- data/spec/unit/substation/processor/evaluator/pivot_spec.rb +42 -0
- data/spec/unit/substation/processor/evaluator/request_spec.rb +11 -0
- data/spec/unit/substation/processor/evaluator/result/failure_spec.rb +14 -0
- data/spec/unit/substation/processor/evaluator/result/success_spec.rb +14 -0
- data/spec/unit/substation/processor/evaluator/result_spec.rb +13 -0
- data/spec/unit/substation/processor/evaluator_spec.rb +18 -0
- data/spec/unit/substation/processor/executor/null_spec.rb +25 -0
- data/spec/unit/substation/processor/executor_spec.rb +32 -0
- data/spec/unit/substation/processor/fallible_spec.rb +24 -0
- data/spec/unit/substation/processor/incoming_spec.rb +17 -0
- data/spec/unit/substation/processor/nest/incoming_spec.rb +56 -0
- data/spec/unit/substation/processor/nest_spec.rb +6 -0
- data/spec/unit/substation/processor/outgoing_spec.rb +47 -0
- data/spec/unit/substation/processor/transformer/incoming_spec.rb +17 -0
- data/spec/unit/substation/processor/transformer/outgoing_spec.rb +17 -0
- data/spec/unit/substation/processor/wrapper/incoming_spec.rb +15 -0
- data/spec/unit/substation/processor/wrapper/outgoing_spec.rb +15 -0
- data/spec/unit/substation/processor/wrapper_spec.rb +24 -0
- data/spec/unit/substation/processor_spec.rb +68 -0
- data/spec/unit/substation/request_spec.rb +70 -0
- data/spec/unit/substation/response/api_spec.rb +22 -0
- data/spec/unit/substation/response/exception/output_spec.rb +46 -0
- data/spec/unit/substation/response/exception_spec.rb +25 -0
- data/spec/unit/substation/response/failure_spec.rb +25 -0
- data/spec/unit/substation/response/success_spec.rb +24 -0
- data/spec/unit/substation/response_spec.rb +73 -0
- data/substation.gemspec +7 -6
- metadata +157 -67
- checksums.yaml +0 -7
- data/TODO +0 -0
- data/lib/substation/observer.rb +0 -66
- data/lib/substation/processor/pivot.rb +0 -25
- data/lib/substation/utils.rb +0 -68
- data/spec/integration/substation/dispatcher/call_spec.rb +0 -260
- data/spec/unit/substation/chain/call_spec.rb +0 -63
- data/spec/unit/substation/chain/dsl/builder/class_methods/call_spec.rb +0 -19
- data/spec/unit/substation/chain/dsl/builder/dsl_spec.rb +0 -21
- data/spec/unit/substation/chain/dsl/builder/failure_chain_spec.rb +0 -30
- data/spec/unit/substation/chain/dsl/chain_spec.rb +0 -15
- data/spec/unit/substation/chain/dsl/class_methods/processors_spec.rb +0 -24
- data/spec/unit/substation/chain/dsl/initialize_spec.rb +0 -19
- data/spec/unit/substation/chain/dsl/processors_spec.rb +0 -42
- data/spec/unit/substation/chain/dsl/use_spec.rb +0 -14
- data/spec/unit/substation/chain/each_spec.rb +0 -46
- data/spec/unit/substation/chain/incoming/result_spec.rb +0 -21
- data/spec/unit/substation/chain/outgoing/call_spec.rb +0 -25
- data/spec/unit/substation/chain/outgoing/result_spec.rb +0 -21
- data/spec/unit/substation/dispatcher/action/call_spec.rb +0 -23
- data/spec/unit/substation/dispatcher/action/class_methods/coerce_spec.rb +0 -61
- data/spec/unit/substation/dispatcher/action_names_spec.rb +0 -14
- data/spec/unit/substation/dispatcher/call_spec.rb +0 -47
- data/spec/unit/substation/dispatcher/class_methods/coerce_spec.rb +0 -20
- data/spec/unit/substation/environment/chain_spec.rb +0 -50
- data/spec/unit/substation/environment/class_methods/build_spec.rb +0 -11
- data/spec/unit/substation/environment/dsl/class_methods/registry_spec.rb +0 -18
- data/spec/unit/substation/environment/dsl/register_spec.rb +0 -14
- data/spec/unit/substation/environment/dsl/registry_spec.rb +0 -19
- data/spec/unit/substation/observer/chain/call_spec.rb +0 -26
- data/spec/unit/substation/observer/class_methods/coerce_spec.rb +0 -33
- data/spec/unit/substation/observer/null/call_spec.rb +0 -12
- data/spec/unit/substation/processor/evaluator/call_spec.rb +0 -49
- data/spec/unit/substation/processor/pivot/call_spec.rb +0 -17
- data/spec/unit/substation/processor/wrapper/call_spec.rb +0 -20
- data/spec/unit/substation/request/env_spec.rb +0 -14
- data/spec/unit/substation/request/error_spec.rb +0 -15
- data/spec/unit/substation/request/input_spec.rb +0 -14
- data/spec/unit/substation/request/success_spec.rb +0 -15
- data/spec/unit/substation/response/env_spec.rb +0 -16
- data/spec/unit/substation/response/failure/success_predicate_spec.rb +0 -15
- data/spec/unit/substation/response/input_spec.rb +0 -16
- data/spec/unit/substation/response/output_spec.rb +0 -16
- data/spec/unit/substation/response/request_spec.rb +0 -16
- data/spec/unit/substation/response/success/success_predicate_spec.rb +0 -15
- data/spec/unit/substation/utils/class_methods/coerce_callable_spec.rb +0 -46
- data/spec/unit/substation/utils/class_methods/const_get_spec.rb +0 -46
- data/spec/unit/substation/utils/class_methods/symbolize_keys_spec.rb +0 -20
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,29 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rspec/its'
|
4
|
+
|
5
|
+
if ENV['COVERAGE'] == 'true'
|
6
|
+
require 'simplecov'
|
7
|
+
require 'coveralls'
|
2
8
|
|
3
|
-
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
10
|
+
SimpleCov::Formatter::HTMLFormatter,
|
11
|
+
Coveralls::SimpleCov::Formatter
|
12
|
+
]
|
13
|
+
|
14
|
+
SimpleCov.start do
|
15
|
+
command_name 'spec:unit'
|
16
|
+
add_filter 'config'
|
17
|
+
add_filter 'spec'
|
18
|
+
minimum_coverage 99.6
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'substation'
|
23
|
+
|
24
|
+
# MUST happen after ice_nine
|
25
|
+
# got required by substation
|
26
|
+
require 'devtools/spec_helper'
|
4
27
|
|
5
28
|
module Spec
|
6
29
|
|
@@ -28,13 +51,25 @@ module Spec
|
|
28
51
|
end
|
29
52
|
|
30
53
|
class Processor
|
31
|
-
include
|
54
|
+
include Substation::Processor::Incoming
|
55
|
+
|
56
|
+
attr_reader :name
|
57
|
+
|
58
|
+
def call(request)
|
59
|
+
request.success(execute(request))
|
60
|
+
end
|
32
61
|
end
|
33
62
|
|
34
63
|
class Presenter
|
35
64
|
include Concord.new(:data)
|
36
65
|
end
|
37
66
|
|
67
|
+
class Transformer
|
68
|
+
def self.call(response)
|
69
|
+
:transformed
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
38
73
|
module Handler
|
39
74
|
|
40
75
|
class Evaluator
|
@@ -76,32 +111,26 @@ module Spec
|
|
76
111
|
|
77
112
|
end
|
78
113
|
|
79
|
-
|
80
|
-
|
81
|
-
FAKE_PROCESSOR = Processor.new(FAKE_ENV, FAKE_HANDLER)
|
114
|
+
FAKE_ENV = Object.new
|
115
|
+
FAKE_HANDLER = Object.new
|
82
116
|
|
83
|
-
|
117
|
+
FAKE_CONFIG = Substation::Processor::Config.new(
|
118
|
+
Substation::Processor::Executor::NULL,
|
119
|
+
Substation::Chain::EMPTY,
|
120
|
+
Substation::EMPTY_ARRAY
|
121
|
+
)
|
84
122
|
|
85
|
-
|
86
|
-
require 'simplecov'
|
87
|
-
require 'coveralls'
|
123
|
+
FAKE_PROCESSOR = Processor.new(:test, FAKE_HANDLER, FAKE_CONFIG)
|
88
124
|
|
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
125
|
end
|
101
126
|
|
102
|
-
require 'substation'
|
103
|
-
|
104
127
|
include Substation
|
105
128
|
|
106
129
|
RSpec.configure do |config|
|
130
|
+
config.expect_with :rspec do |c|
|
131
|
+
c.syntax = :expect
|
132
|
+
end
|
133
|
+
config.mock_with :rspec do |c|
|
134
|
+
c.syntax = :expect
|
135
|
+
end
|
107
136
|
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Chain::Definition do
|
6
|
+
|
7
|
+
subject { described_class.new(nil, []) }
|
8
|
+
|
9
|
+
it { should be_kind_of(Enumerable) }
|
10
|
+
|
11
|
+
let(:object) { described_class.new(chain_name, processors) }
|
12
|
+
let(:chain_name) { double('chain_name') }
|
13
|
+
|
14
|
+
describe '#initialize' do
|
15
|
+
let(:chain_name) { 'chain name' }
|
16
|
+
let(:processors) { [Object.new, Object.new] }
|
17
|
+
|
18
|
+
it 'assigns the name' do
|
19
|
+
expect(object.name).to eq('chain name')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'has given processors' do
|
23
|
+
expect(object.each.count).to be(2)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#each' do
|
28
|
+
subject { object.each(&block) }
|
29
|
+
|
30
|
+
let(:processors) { [ processor ] }
|
31
|
+
let(:processor) { double('processor', :name => name) }
|
32
|
+
let(:name) { double('name') }
|
33
|
+
let(:block) { ->(_) { } }
|
34
|
+
|
35
|
+
it_should_behave_like 'an #each method'
|
36
|
+
|
37
|
+
it 'yields all processors' do
|
38
|
+
expect { |block| object.each(&block) }.to yield_successive_args(processor)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#<<' do
|
43
|
+
subject { object << processor }
|
44
|
+
|
45
|
+
let(:processor) { double('processor', :name => name) }
|
46
|
+
let(:name) { double('name') }
|
47
|
+
|
48
|
+
context 'when the given processor is not currently present in object' do
|
49
|
+
let(:processors) { [] }
|
50
|
+
|
51
|
+
it 'registers the processor' do
|
52
|
+
expect(subject.each).to include(processor)
|
53
|
+
end
|
54
|
+
|
55
|
+
it_behaves_like 'a command method'
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when the given processor is already present in object' do
|
59
|
+
let(:processors) { [processor] }
|
60
|
+
let(:msg) { Chain::Definition::DUPLICATE_PROCESSOR_MSG % [processor].inspect }
|
61
|
+
|
62
|
+
it 'raises DuplicateProcessorError' do
|
63
|
+
expect { subject }.to raise_error(DuplicateProcessorError, msg)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#prepend' do
|
69
|
+
subject { object.prepend(other) }
|
70
|
+
|
71
|
+
let(:object) { described_class.new(name, [processor_1]) }
|
72
|
+
let(:name) { double('chain_name') }
|
73
|
+
let(:processor_1) { double('processor_1', :name => name_1) }
|
74
|
+
let(:name_1) { double('name_1') }
|
75
|
+
let(:other_name) { double('other_chain_name') }
|
76
|
+
let(:other) { described_class.new(other_name, [processor_2]) }
|
77
|
+
let(:name_2) { double('name_2') }
|
78
|
+
|
79
|
+
context 'and the processors are disjoint' do
|
80
|
+
let(:processor_2) { double('processor_2', :name => name_2) }
|
81
|
+
|
82
|
+
it { should eql(described_class.new(name, [processor_2, processor_1])) }
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'and the processors contain duplicates' do
|
86
|
+
let(:processor_2) { processor_1 }
|
87
|
+
let(:msg) { Chain::Definition::DUPLICATE_PROCESSOR_MSG % [processor_2].inspect }
|
88
|
+
|
89
|
+
it 'raises DuplicateProcessorError' do
|
90
|
+
expect { subject }.to raise_error(DuplicateProcessorError, msg)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#replace_failure_chain' do
|
96
|
+
subject { object.replace_failure_chain(name, failure_chain) }
|
97
|
+
|
98
|
+
let(:processor) { double('processor', :name => name) }
|
99
|
+
let(:name) { double('name') }
|
100
|
+
let(:other_processor) { double('other_processor', :name => other_name) }
|
101
|
+
let(:other_name) { double('other_name') }
|
102
|
+
let(:failure_chain) { double('failure_chain') }
|
103
|
+
let(:replaced_processor) { double('replaced_processor') }
|
104
|
+
|
105
|
+
context 'when a processor is registered under the given name' do
|
106
|
+
before do
|
107
|
+
expect(processor).to receive(:with_failure_chain).with(failure_chain).and_return(replaced_processor)
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when one processor is registered under the given name' do
|
111
|
+
let(:processors) { [other_processor, processor] }
|
112
|
+
|
113
|
+
it 'replaces the processor with a new one' do
|
114
|
+
expect(subject.each).to include(replaced_processor)
|
115
|
+
end
|
116
|
+
|
117
|
+
it_behaves_like 'a command method'
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when more than one processor is registered under the given name' do
|
121
|
+
let(:processors) { [other_processor, processor, same_name_processor] }
|
122
|
+
let(:same_name_processor) { double('same_name_processor', :name => name) }
|
123
|
+
|
124
|
+
it 'replaces the first processor with a new one' do
|
125
|
+
expect(subject.each).to include(replaced_processor)
|
126
|
+
expect(subject.each).to include(same_name_processor)
|
127
|
+
end
|
128
|
+
|
129
|
+
it_behaves_like 'a command method'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when no processor is registered under the given name' do
|
134
|
+
let(:processors) { [] }
|
135
|
+
|
136
|
+
it 'raises an UnknownProcessorError' do
|
137
|
+
expect { subject }.to raise_error(UnknownProcessor, "No processor named #{name.inspect} is registered")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Chain::DSL::Config, '#dsl_module' do
|
6
|
+
subject { object.dsl_module }
|
7
|
+
|
8
|
+
let(:object) { described_class.new(registry, dsl_module) }
|
9
|
+
let(:registry) { double('registry') }
|
10
|
+
let(:dsl_module) { double('dsl_module') }
|
11
|
+
|
12
|
+
it { should be(dsl_module) }
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Chain::DSL::Config, '#registry' do
|
6
|
+
subject { object.registry }
|
7
|
+
|
8
|
+
let(:object) { described_class.new(registry, dsl_module) }
|
9
|
+
let(:registry) { double('registry') }
|
10
|
+
let(:dsl_module) { double('dsl_module') }
|
11
|
+
|
12
|
+
it { should be(registry) }
|
13
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Chain::DSL::Config, '.build' do
|
6
|
+
subject { described_class.build(registry) }
|
7
|
+
|
8
|
+
let(:registry) { double('registry') }
|
9
|
+
let(:dsl_module) { double('dsl_module') }
|
10
|
+
let(:config) { double('config') }
|
11
|
+
|
12
|
+
before do
|
13
|
+
expect(Chain::DSL::ModuleBuilder).to receive(:call).with(registry).and_return(dsl_module)
|
14
|
+
expect(described_class).to receive(:new).with(registry, dsl_module).and_return(config)
|
15
|
+
end
|
16
|
+
|
17
|
+
it { should eql(config) }
|
18
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Chain::DSL::ModuleBuilder do
|
6
|
+
describe '#dsl_module' do
|
7
|
+
subject { object.dsl_module }
|
8
|
+
|
9
|
+
let(:object) { described_class.new(registry) }
|
10
|
+
let(:registry) { { :test => processor_builder } }
|
11
|
+
let(:processor_builder) { double('processor_builder') }
|
12
|
+
let(:handler) { double('handler') }
|
13
|
+
let(:failure_chain) { double('failure_chain') }
|
14
|
+
let(:observers) { EMPTY_ARRAY }
|
15
|
+
|
16
|
+
let(:definition) { Chain::Definition.new(name, processors) }
|
17
|
+
let(:name) { double('chain_name') }
|
18
|
+
let(:processors) { [processor_1] }
|
19
|
+
let(:processor_1) { double('processor_1', :name => :processor_1) }
|
20
|
+
let(:processor_2) { double('processor_2', :name => :processor_2) }
|
21
|
+
|
22
|
+
before do
|
23
|
+
expect(processor_builder)
|
24
|
+
.to receive(:call)
|
25
|
+
.with(handler, failure_chain, observers)
|
26
|
+
.and_return(processor_2)
|
27
|
+
end
|
28
|
+
|
29
|
+
shared_examples_for 'Chain::DSL::ModuleBuilder#dsl_module' do
|
30
|
+
it 'compiles appropriate methods' do
|
31
|
+
config = Chain::DSL::Config.new(registry, subject)
|
32
|
+
dsl = Chain::DSL.new(config, definition)
|
33
|
+
|
34
|
+
dsl.test(*dsl_method_args)
|
35
|
+
|
36
|
+
expect(dsl.definition).to include(processor_1)
|
37
|
+
expect(dsl.definition).to include(processor_2)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when a failure_chain and observers are given' do
|
42
|
+
let(:dsl_method_args) { [handler, failure_chain, observers] }
|
43
|
+
|
44
|
+
it_behaves_like 'Chain::DSL::ModuleBuilder#dsl_module'
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when a failure_chain and no observers given' do
|
48
|
+
let(:dsl_method_args) { [handler, failure_chain] }
|
49
|
+
|
50
|
+
it_behaves_like 'Chain::DSL::ModuleBuilder#dsl_module'
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when no failure_chain and no observers are given' do
|
54
|
+
let(:dsl_method_args) { [handler] }
|
55
|
+
let(:failure_chain) { Chain::EMPTY }
|
56
|
+
|
57
|
+
it_behaves_like 'Chain::DSL::ModuleBuilder#dsl_module'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '.call' do
|
62
|
+
subject { described_class.call(registry) }
|
63
|
+
|
64
|
+
let(:registry) { { :test => processor_builder } }
|
65
|
+
let(:processor_builder) { double('processor_builder') }
|
66
|
+
|
67
|
+
let(:instance) { double('module_builder', :dsl_module => dsl_module) }
|
68
|
+
let(:dsl_module) { double('dsl_module') }
|
69
|
+
|
70
|
+
before do
|
71
|
+
expect(described_class).to receive(:new).with(registry).and_return(instance)
|
72
|
+
expect(instance).to receive(:dsl_module).and_return(dsl_module)
|
73
|
+
end
|
74
|
+
|
75
|
+
it { should be(dsl_module) }
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Chain::DSL do
|
6
|
+
describe '#name' do
|
7
|
+
subject { chain_dsl.name }
|
8
|
+
|
9
|
+
include_context 'Chain::DSL#initialize'
|
10
|
+
|
11
|
+
it { should eql(chain_name) }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#build' do
|
15
|
+
include_context 'Chain::DSL#initialize'
|
16
|
+
|
17
|
+
let(:failure_chain) { Chain::EMPTY }
|
18
|
+
let(:block) { ->(_) { test(Spec::FAKE_HANDLER) } }
|
19
|
+
let(:expected_definition) { Chain::Definition.new(new_chain_name, expected_processors) }
|
20
|
+
let(:expected) { Chain.new(expected_definition, failure_chain) }
|
21
|
+
|
22
|
+
let(:new_processors) { [new_processor] }
|
23
|
+
let(:new_processor) { double('new_processor', :name => :new_processor) }
|
24
|
+
|
25
|
+
let(:new_chain_name) { double('new_chain_name') }
|
26
|
+
|
27
|
+
shared_examples_for 'duplicate processors' do
|
28
|
+
let(:new_processor) { processor }
|
29
|
+
let(:msg) { Chain::Definition::DUPLICATE_PROCESSOR_MSG % [processor].inspect }
|
30
|
+
|
31
|
+
it 'should raise DuplicateProcessorError' do
|
32
|
+
expect { subject }.to raise_error(DuplicateProcessorError, msg)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
shared_examples_for 'disjoint processors' do
|
37
|
+
it { should eql(expected) }
|
38
|
+
|
39
|
+
it 'injects the proper registry' do
|
40
|
+
expect(chain_dsl.registry).to be(registry)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when a block is given' do
|
45
|
+
subject { chain_dsl.build(new_chain_name, new_processors, failure_chain, &block) }
|
46
|
+
|
47
|
+
context 'and all processors are disjoint' do
|
48
|
+
let(:expected_processors) { [processor, new_processor, Spec::FAKE_PROCESSOR] }
|
49
|
+
|
50
|
+
it_behaves_like 'disjoint processors'
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'and there are duplicate processors' do
|
54
|
+
it_behaves_like 'duplicate processors'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when no block is given' do
|
59
|
+
subject { chain_dsl.build(new_chain_name, new_processors, failure_chain) }
|
60
|
+
|
61
|
+
context 'and all processors are disjoint' do
|
62
|
+
let(:expected_processors) { [processor, new_processor] }
|
63
|
+
|
64
|
+
it_behaves_like 'disjoint processors'
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'and there are duplicate processors' do
|
68
|
+
it_behaves_like 'duplicate processors'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#chain' do
|
74
|
+
include_context 'Chain::DSL#initialize'
|
75
|
+
|
76
|
+
let(:other_processor) { double('other_processor', :name => :other_processor) }
|
77
|
+
let(:expected_definition) { Chain::Definition.new(chain_name, expected_processors) }
|
78
|
+
let(:expected) { described_class.build(registry, expected_definition) }
|
79
|
+
|
80
|
+
context 'when no block is given' do
|
81
|
+
subject { chain_dsl.chain([other_processor]) }
|
82
|
+
|
83
|
+
let(:expected_processors) { [processor, other_processor] }
|
84
|
+
|
85
|
+
it { should eql(expected) }
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when block is given' do
|
89
|
+
subject { chain_dsl.chain([other_processor], &block) }
|
90
|
+
|
91
|
+
let(:block) { ->(_) { test(Spec::FAKE_HANDLER) } }
|
92
|
+
|
93
|
+
let(:expected_processors) { [processor, other_processor, Spec::FAKE_PROCESSOR] }
|
94
|
+
|
95
|
+
it { should eql(expected) }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#nest' do
|
100
|
+
subject { object.nest(nested_name, chain_to_nest, executor) }
|
101
|
+
|
102
|
+
include_context 'Chain::DSL#initialize'
|
103
|
+
|
104
|
+
let(:object) { chain_dsl }
|
105
|
+
|
106
|
+
let(:chain_to_nest) { double('chain to nest') }
|
107
|
+
let(:nested_name) { double('nested name', :to_sym => 'neste name') }
|
108
|
+
let(:executor) { double }
|
109
|
+
|
110
|
+
let(:config) { Processor::Config.new(executor, EMPTY_ARRAY, EMPTY_ARRAY) }
|
111
|
+
let(:expected) { Processor::Nest::Incoming.new(nested_name, chain_to_nest, config) }
|
112
|
+
|
113
|
+
it { should eql(expected) }
|
114
|
+
|
115
|
+
it 'adds the chain to the definition' do
|
116
|
+
subject
|
117
|
+
expect(object.definition).to include(subject)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#definition' do
|
122
|
+
subject { object.definition }
|
123
|
+
|
124
|
+
include_context 'Chain::DSL#initialize'
|
125
|
+
|
126
|
+
let(:object) { chain_dsl }
|
127
|
+
|
128
|
+
it { should eql(definition) }
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#failure_chain' do
|
132
|
+
subject { object.failure_chain(name, failure_chain) }
|
133
|
+
|
134
|
+
let(:object) { described_class.new(config, definition) }
|
135
|
+
let(:config) { Chain::DSL::Config.new(registry, dsl_module) }
|
136
|
+
let(:registry) { double('registry') }
|
137
|
+
let(:dsl_module) { Module.new }
|
138
|
+
let(:definition) { double('definition', :name => double('chain_name')) }
|
139
|
+
let(:name) { double('name') }
|
140
|
+
let(:failure_chain) { double('failure_chain') }
|
141
|
+
|
142
|
+
before do
|
143
|
+
expect(definition).to receive(:replace_failure_chain).with(name, failure_chain)
|
144
|
+
end
|
145
|
+
|
146
|
+
it_behaves_like 'a command method'
|
147
|
+
end
|
148
|
+
|
149
|
+
describe '.build' do
|
150
|
+
|
151
|
+
let(:registry) { double('registry') }
|
152
|
+
let(:dsl) { double('dsl') }
|
153
|
+
let(:config) { double('config') }
|
154
|
+
let(:definition) { double('definition') }
|
155
|
+
|
156
|
+
before do
|
157
|
+
expect(Chain::DSL::Config).to receive(:build).with(registry).and_return(config)
|
158
|
+
expect(described_class).to receive(:new).with(config, definition).and_return(dsl)
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'when a definition is given' do
|
162
|
+
subject { described_class.build(registry, definition) }
|
163
|
+
|
164
|
+
it { should be(dsl) }
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'when no definition is given' do
|
168
|
+
subject { described_class.build(registry) }
|
169
|
+
|
170
|
+
let(:definition) { Chain::Definition::EMPTY }
|
171
|
+
|
172
|
+
it { should be(dsl) }
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|