functional-light-service 0.5.4 → 6.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.
- checksums.yaml +4 -4
- data/.github/workflows/project-build.yml +35 -11
- data/.rubocop.yml +101 -160
- data/AUDIT-functional-light-service.md +352 -0
- data/CHANGELOG.md +38 -0
- data/README.md +54 -2
- data/audit/bench.rb +99 -0
- data/audit/verify_findings.rb +172 -0
- data/functional-light-service.gemspec +15 -21
- data/lib/functional-light-service/action.rb +97 -101
- data/lib/functional-light-service/configuration.rb +26 -24
- data/lib/functional-light-service/context/key_verifier.rb +124 -118
- data/lib/functional-light-service/context.rb +63 -20
- data/lib/functional-light-service/deprecations.rb +26 -0
- data/lib/functional-light-service/errors.rb +8 -6
- data/lib/functional-light-service/functional/enum.rb +286 -250
- data/lib/functional-light-service/functional/maybe.rb +21 -15
- data/lib/functional-light-service/functional/monad.rb +77 -66
- data/lib/functional-light-service/functional/null.rb +88 -74
- data/lib/functional-light-service/functional/option.rb +100 -97
- data/lib/functional-light-service/functional/result.rb +129 -116
- data/lib/functional-light-service/localization_adapter.rb +48 -47
- data/lib/functional-light-service/organizer/execute.rb +16 -14
- data/lib/functional-light-service/organizer/iterate.rb +30 -25
- data/lib/functional-light-service/organizer/reduce_if.rb +19 -17
- data/lib/functional-light-service/organizer/reduce_until.rb +22 -20
- data/lib/functional-light-service/organizer/scoped_reducable.rb +15 -13
- data/lib/functional-light-service/organizer/with_callback.rb +28 -26
- data/lib/functional-light-service/organizer/with_reducer.rb +81 -77
- data/lib/functional-light-service/organizer/with_reducer_factory.rb +20 -18
- data/lib/functional-light-service/organizer/with_reducer_log_decorator.rb +110 -108
- data/lib/functional-light-service/organizer.rb +114 -114
- data/lib/functional-light-service/testing/context_factory.rb +48 -42
- data/lib/functional-light-service/testing.rb +3 -1
- data/lib/functional-light-service/version.rb +5 -3
- data/lib/functional-light-service.rb +30 -28
- data/spec/acceptance/after_actions_spec.rb +87 -71
- data/spec/acceptance/before_actions_spec.rb +115 -98
- data/spec/acceptance/custom_log_from_organizer_spec.rb +61 -60
- data/spec/acceptance/deprecation_warnings_spec.rb +82 -0
- data/spec/acceptance/fail_spec.rb +52 -50
- data/spec/acceptance/message_localization_spec.rb +119 -118
- data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +68 -65
- data/spec/acceptance/organizer/reduce_if_spec.rb +89 -89
- data/spec/acceptance/organizer/with_callback_spec.rb +113 -110
- data/spec/acceptance/{not_having_call_method_warning_spec.rb → organizer_entry_point_spec.rb} +10 -7
- data/spec/acceptance/rollback_spec.rb +183 -132
- data/spec/action_expects_and_promises_spec.rb +97 -93
- data/spec/action_promised_keys_spec.rb +126 -122
- data/spec/context_spec.rb +289 -197
- data/spec/examples/controller_spec.rb +63 -63
- data/spec/examples/validate_address_spec.rb +38 -37
- data/spec/lib/deterministic/currify_spec.rb +90 -88
- data/spec/lib/deterministic/null_spec.rb +6 -1
- data/spec/lib/deterministic/option_spec.rb +140 -137
- data/spec/lib/deterministic/result/result_map_spec.rb +155 -154
- data/spec/lib/deterministic/result/result_shared.rb +3 -2
- data/spec/lib/deterministic/result_spec.rb +2 -2
- data/spec/lib/edge_cases_spec.rb +156 -0
- data/spec/lib/enum_spec.rb +1 -1
- data/spec/lib/native_pattern_matching_spec.rb +74 -0
- data/spec/organizer_spec.rb +115 -114
- data/spec/readme_spec.rb +45 -47
- data/spec/sample/calculates_order_tax_action_spec.rb +16 -16
- data/spec/sample/calculates_tax_spec.rb +1 -1
- data/spec/sample/looks_up_tax_percentage_action_spec.rb +55 -55
- data/spec/sample/tax/calculates_order_tax_action.rb +10 -9
- data/spec/sample/tax/looks_up_tax_percentage_action.rb +28 -27
- data/spec/sample/tax/provides_free_shipping_action.rb +11 -10
- data/spec/spec_helper.rb +6 -0
- data/spec/test_doubles.rb +628 -599
- data/spec/testing/context_factory_spec.rb +21 -0
- metadata +45 -161
- data/lib/functional-light-service/organizer/verify_call_method_exists.rb +0 -29
- data/spec/acceptance/include_warning_spec.rb +0 -29
|
@@ -1,65 +1,68 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
RSpec.describe FunctionalLightService::Organizer do
|
|
5
|
-
class TestSkipBefore
|
|
6
|
-
extend FunctionalLightService::Organizer
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
TestDoubles::
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'test_doubles'
|
|
3
|
+
|
|
4
|
+
RSpec.describe FunctionalLightService::Organizer do
|
|
5
|
+
class TestSkipBefore
|
|
6
|
+
extend FunctionalLightService::Organizer
|
|
7
|
+
|
|
8
|
+
def self.call
|
|
9
|
+
with(:number => 1)
|
|
10
|
+
.reduce([
|
|
11
|
+
TestDoubles::SkipAllAction,
|
|
12
|
+
reduce_until(->(ctx) { ctx.number == 3 },
|
|
13
|
+
TestDoubles::AddsOneAction)
|
|
14
|
+
])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class TestSkipAfter
|
|
19
|
+
extend FunctionalLightService::Organizer
|
|
20
|
+
|
|
21
|
+
def self.call
|
|
22
|
+
with(:number => 1)
|
|
23
|
+
.reduce([
|
|
24
|
+
TestDoubles::AddsOneAction,
|
|
25
|
+
reduce_until(->(ctx) { ctx.number == 3 }, [
|
|
26
|
+
TestDoubles::AddsOneAction
|
|
27
|
+
]),
|
|
28
|
+
TestDoubles::SkipAllAction,
|
|
29
|
+
TestDoubles::AddsOneAction
|
|
30
|
+
])
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class TestContextFailure
|
|
35
|
+
extend FunctionalLightService::Organizer
|
|
36
|
+
|
|
37
|
+
def self.call
|
|
38
|
+
with(:number => 1)
|
|
39
|
+
.reduce([
|
|
40
|
+
TestDoubles::FailureAction,
|
|
41
|
+
reduce_until(->(ctx) { ctx[:number] == 3 },
|
|
42
|
+
TestDoubles::AddsOneAction),
|
|
43
|
+
TestDoubles::AddsOneAction
|
|
44
|
+
])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'skips all the rest of the actions' do
|
|
49
|
+
result = TestSkipBefore.call
|
|
50
|
+
|
|
51
|
+
expect(result).to be_success
|
|
52
|
+
expect(result[:number]).to eq(1)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'skips after an action in nested context' do
|
|
56
|
+
result = TestSkipAfter.call
|
|
57
|
+
|
|
58
|
+
expect(result).to be_success
|
|
59
|
+
expect(result[:number]).to eq(3)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'respects failure across all nestings' do
|
|
63
|
+
result = TestContextFailure.call
|
|
64
|
+
|
|
65
|
+
expect(result).to be_failure
|
|
66
|
+
expect(result[:number]).to eq(1)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
RSpec.describe FunctionalLightService::Organizer do
|
|
5
|
-
class TestReduceIf
|
|
6
|
-
extend FunctionalLightService::Organizer
|
|
7
|
-
|
|
8
|
-
def self.call(context)
|
|
9
|
-
with(context).reduce(actions)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def self.actions
|
|
13
|
-
[
|
|
14
|
-
TestDoubles::AddsOneAction,
|
|
15
|
-
reduce_if(->(ctx) { ctx.number == 1 },
|
|
16
|
-
TestDoubles::AddsOneAction)
|
|
17
|
-
]
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
let(:empty_context) { FunctionalLightService::Context.make }
|
|
22
|
-
|
|
23
|
-
it 'reduces if the block evaluates to true' do
|
|
24
|
-
result = TestReduceIf.call(:number => 0)
|
|
25
|
-
|
|
26
|
-
expect(result).to be_success
|
|
27
|
-
expect(result[:number]).to eq(2)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it 'does not reduce if the block evaluates to false' do
|
|
31
|
-
result = TestReduceIf.call(:number => 2)
|
|
32
|
-
|
|
33
|
-
expect(result).to be_success
|
|
34
|
-
expect(result[:number]).to eq(3)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'will not reduce over a failed context' do
|
|
38
|
-
empty_context.fail!('Something bad happened')
|
|
39
|
-
|
|
40
|
-
result = TestReduceIf.call(empty_context)
|
|
41
|
-
|
|
42
|
-
expect(result).to be_failure
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it 'does not reduce over a skipped context' do
|
|
46
|
-
empty_context.skip_remaining!('No more needed')
|
|
47
|
-
|
|
48
|
-
result = TestReduceIf.call(empty_context)
|
|
49
|
-
expect(result).to be_success
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "knows that it's being conditionally reduced from within an organizer" do
|
|
53
|
-
result = TestReduceIf.call(:number => 2)
|
|
54
|
-
|
|
55
|
-
expect(result.organized_by).to eq TestReduceIf
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it 'skips actions within in its own scope' do
|
|
59
|
-
org = Class.new do
|
|
60
|
-
extend FunctionalLightService::Organizer
|
|
61
|
-
|
|
62
|
-
def self.call
|
|
63
|
-
reduce(actions)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def self.actions
|
|
67
|
-
[
|
|
68
|
-
reduce_if(
|
|
69
|
-
->(c) { !c.nil? },
|
|
70
|
-
[
|
|
71
|
-
execute(->(c) { c[:first_reduce_if] = true }),
|
|
72
|
-
execute(->(c) { c.skip_remaining! }),
|
|
73
|
-
execute(->(c) { c[:second_reduce_if] = true })
|
|
74
|
-
]
|
|
75
|
-
),
|
|
76
|
-
execute(->(c) { c[:last_outside] = true })
|
|
77
|
-
]
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
result = org.call
|
|
82
|
-
|
|
83
|
-
aggregate_failures do
|
|
84
|
-
expect(result[:first_reduce_if]).to be true
|
|
85
|
-
expect(result[:second_reduce_if]).to be_nil
|
|
86
|
-
expect(result[:last_outside]).to be true
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'test_doubles'
|
|
3
|
+
|
|
4
|
+
RSpec.describe FunctionalLightService::Organizer do
|
|
5
|
+
class TestReduceIf
|
|
6
|
+
extend FunctionalLightService::Organizer
|
|
7
|
+
|
|
8
|
+
def self.call(context)
|
|
9
|
+
with(context).reduce(actions)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.actions
|
|
13
|
+
[
|
|
14
|
+
TestDoubles::AddsOneAction,
|
|
15
|
+
reduce_if(->(ctx) { ctx.number == 1 },
|
|
16
|
+
TestDoubles::AddsOneAction)
|
|
17
|
+
]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
let(:empty_context) { FunctionalLightService::Context.make }
|
|
22
|
+
|
|
23
|
+
it 'reduces if the block evaluates to true' do
|
|
24
|
+
result = TestReduceIf.call(:number => 0)
|
|
25
|
+
|
|
26
|
+
expect(result).to be_success
|
|
27
|
+
expect(result[:number]).to eq(2)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'does not reduce if the block evaluates to false' do
|
|
31
|
+
result = TestReduceIf.call(:number => 2)
|
|
32
|
+
|
|
33
|
+
expect(result).to be_success
|
|
34
|
+
expect(result[:number]).to eq(3)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'will not reduce over a failed context' do
|
|
38
|
+
empty_context.fail!('Something bad happened')
|
|
39
|
+
|
|
40
|
+
result = TestReduceIf.call(empty_context)
|
|
41
|
+
|
|
42
|
+
expect(result).to be_failure
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'does not reduce over a skipped context' do
|
|
46
|
+
empty_context.skip_remaining!('No more needed')
|
|
47
|
+
|
|
48
|
+
result = TestReduceIf.call(empty_context)
|
|
49
|
+
expect(result).to be_success
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "knows that it's being conditionally reduced from within an organizer" do
|
|
53
|
+
result = TestReduceIf.call(:number => 2)
|
|
54
|
+
|
|
55
|
+
expect(result.organized_by).to eq TestReduceIf
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'skips actions within in its own scope' do
|
|
59
|
+
org = Class.new do
|
|
60
|
+
extend FunctionalLightService::Organizer
|
|
61
|
+
|
|
62
|
+
def self.call
|
|
63
|
+
reduce(actions)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.actions
|
|
67
|
+
[
|
|
68
|
+
reduce_if(
|
|
69
|
+
->(c) { !c.nil? },
|
|
70
|
+
[
|
|
71
|
+
execute(->(c) { c[:first_reduce_if] = true }),
|
|
72
|
+
execute(->(c) { c.skip_remaining! }), # rubocop:disable Style/SymbolProc
|
|
73
|
+
execute(->(c) { c[:second_reduce_if] = true })
|
|
74
|
+
]
|
|
75
|
+
),
|
|
76
|
+
execute(->(c) { c[:last_outside] = true })
|
|
77
|
+
]
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
result = org.call
|
|
82
|
+
|
|
83
|
+
aggregate_failures do
|
|
84
|
+
expect(result[:first_reduce_if]).to be true
|
|
85
|
+
expect(result[:second_reduce_if]).to be_nil
|
|
86
|
+
expect(result[:last_outside]).to be true
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -1,110 +1,113 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
RSpec.describe FunctionalLightService::Organizer do
|
|
5
|
-
describe 'a simple case with a single callback' do
|
|
6
|
-
it 'calls the actions defined with callback' do
|
|
7
|
-
result = TestDoubles::TestWithCallback.call
|
|
8
|
-
|
|
9
|
-
expect(result.counter).to eq(3)
|
|
10
|
-
expect(result.total).to eq(6)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
describe 'a more complex example with nested callbacks' do
|
|
15
|
-
class TestWithNestedCallback
|
|
16
|
-
extend FunctionalLightService::Organizer
|
|
17
|
-
|
|
18
|
-
def self.call(context = {})
|
|
19
|
-
with(context).reduce(actions)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def self.actions
|
|
23
|
-
[
|
|
24
|
-
SetUpNestedContextAction,
|
|
25
|
-
with_callback(IterateOuterCollectionAction,
|
|
26
|
-
[IncrementOuterCountAction,
|
|
27
|
-
with_callback(TestDoubles::IterateCollectionAction,
|
|
28
|
-
[TestDoubles::IncrementCountAction,
|
|
29
|
-
TestDoubles::AddToTotalAction])])
|
|
30
|
-
]
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
class SetUpNestedContextAction
|
|
35
|
-
extend FunctionalLightService::Action
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
ctx.
|
|
42
|
-
ctx.
|
|
43
|
-
ctx.
|
|
44
|
-
ctx.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'test_doubles'
|
|
3
|
+
|
|
4
|
+
RSpec.describe FunctionalLightService::Organizer do
|
|
5
|
+
describe 'a simple case with a single callback' do
|
|
6
|
+
it 'calls the actions defined with callback' do
|
|
7
|
+
result = TestDoubles::TestWithCallback.call
|
|
8
|
+
|
|
9
|
+
expect(result.counter).to eq(3)
|
|
10
|
+
expect(result.total).to eq(6)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe 'a more complex example with nested callbacks' do
|
|
15
|
+
class TestWithNestedCallback
|
|
16
|
+
extend FunctionalLightService::Organizer
|
|
17
|
+
|
|
18
|
+
def self.call(context = {})
|
|
19
|
+
with(context).reduce(actions)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.actions
|
|
23
|
+
[
|
|
24
|
+
SetUpNestedContextAction,
|
|
25
|
+
with_callback(IterateOuterCollectionAction,
|
|
26
|
+
[IncrementOuterCountAction,
|
|
27
|
+
with_callback(TestDoubles::IterateCollectionAction,
|
|
28
|
+
[TestDoubles::IncrementCountAction,
|
|
29
|
+
TestDoubles::AddToTotalAction])])
|
|
30
|
+
]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class SetUpNestedContextAction
|
|
35
|
+
extend FunctionalLightService::Action
|
|
36
|
+
|
|
37
|
+
promises :outer_numbers, :outer_counter,
|
|
38
|
+
:numbers, :counter, :total
|
|
39
|
+
|
|
40
|
+
executed do |ctx|
|
|
41
|
+
ctx.outer_numbers = [12, 17]
|
|
42
|
+
ctx.outer_counter = 0
|
|
43
|
+
ctx.numbers = [1, 2, 3]
|
|
44
|
+
ctx.counter = 0
|
|
45
|
+
ctx.total = 0
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class IterateOuterCollectionAction
|
|
50
|
+
extend FunctionalLightService::Action
|
|
51
|
+
|
|
52
|
+
expects :outer_numbers, :callback
|
|
53
|
+
promises :outer_number
|
|
54
|
+
|
|
55
|
+
executed do |ctx|
|
|
56
|
+
ctx.outer_numbers.each do |outer_number|
|
|
57
|
+
ctx.outer_number = outer_number
|
|
58
|
+
ctx.callback.call(ctx)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class IncrementOuterCountAction
|
|
64
|
+
extend FunctionalLightService::Action
|
|
65
|
+
|
|
66
|
+
expects :outer_counter
|
|
67
|
+
|
|
68
|
+
executed do |ctx|
|
|
69
|
+
ctx.outer_counter = ctx.outer_counter + 1
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'calls both the action and the nested callbacks' do
|
|
74
|
+
result = TestWithNestedCallback.call
|
|
75
|
+
|
|
76
|
+
expect(result.outer_counter).to eq(2)
|
|
77
|
+
# Counts and total are the duplicates of
|
|
78
|
+
# what you'll see in the simple spec,
|
|
79
|
+
# as the internal callback logic is called
|
|
80
|
+
# twice due to 2 items in the outer_numbers
|
|
81
|
+
# collection.
|
|
82
|
+
expect(result.counter).to eq(6)
|
|
83
|
+
expect(result.total).to eq(12)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe 'with failed or skipped context' do
|
|
88
|
+
class TestWithFailureCallback
|
|
89
|
+
extend FunctionalLightService::Organizer
|
|
90
|
+
|
|
91
|
+
def self.call(context = {})
|
|
92
|
+
with(context).reduce(actions)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def self.actions
|
|
96
|
+
[
|
|
97
|
+
TestDoubles::SetUpContextAction,
|
|
98
|
+
with_callback(TestDoubles::IterateCollectionAction,
|
|
99
|
+
[TestDoubles::IncrementCountAction,
|
|
100
|
+
TestDoubles::FailureAction])
|
|
101
|
+
]
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'will not process the routine' do
|
|
106
|
+
result = TestWithFailureCallback.call
|
|
107
|
+
|
|
108
|
+
expect(result).to be_failure
|
|
109
|
+
expect(result.counter).to eq(1)
|
|
110
|
+
expect(result.total).to eq(0)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
data/spec/acceptance/{not_having_call_method_warning_spec.rb → organizer_entry_point_spec.rb}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'test_doubles'
|
|
3
3
|
|
|
4
|
-
describe "Organizer
|
|
5
|
-
context "when the organizer
|
|
6
|
-
it "
|
|
4
|
+
describe "Organizer entry point" do
|
|
5
|
+
context "when the organizer entry method is not named `call`" do
|
|
6
|
+
it "works without emitting any warning" do
|
|
7
7
|
class OrganizerWithoutCallMethod
|
|
8
8
|
extend FunctionalLightService::Organizer
|
|
9
9
|
|
|
@@ -11,14 +11,16 @@ describe "Organizer should invoke with/reduce from a call method" do
|
|
|
11
11
|
reduce([])
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
|
|
15
|
+
result = nil
|
|
16
|
+
expect { result = OrganizerWithoutCallMethod.do_something }
|
|
17
|
+
.not_to output.to_stdout
|
|
18
|
+
expect(result).to be_a_kind_of(FunctionalLightService::Context)
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
context "when the organizer has the `call` method" do
|
|
21
|
-
it "
|
|
23
|
+
it "works without emitting any warning" do
|
|
22
24
|
class OrganizerWithCallMethod
|
|
23
25
|
extend FunctionalLightService::Organizer
|
|
24
26
|
|
|
@@ -26,6 +28,7 @@ describe "Organizer should invoke with/reduce from a call method" do
|
|
|
26
28
|
reduce([])
|
|
27
29
|
end
|
|
28
30
|
end
|
|
31
|
+
|
|
29
32
|
expect(OrganizerWithCallMethod.call).to be_a_kind_of(FunctionalLightService::Context)
|
|
30
33
|
end
|
|
31
34
|
end
|