light-service 0.8.4 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -2
- data/README.md +149 -52
- data/RELEASES.md +6 -0
- data/gemfiles/activesupport_3.gemfile +1 -1
- data/gemfiles/activesupport_4.gemfile +1 -1
- data/gemfiles/activesupport_5.gemfile +1 -1
- data/lib/light-service.rb +7 -0
- data/lib/light-service/action.rb +22 -2
- data/lib/light-service/orchestrator.rb +21 -3
- data/lib/light-service/organizer.rb +42 -20
- data/lib/light-service/organizer/execute.rb +14 -0
- data/lib/light-service/organizer/iterate.rb +22 -0
- data/lib/light-service/organizer/reduce_if.rb +17 -0
- data/lib/light-service/organizer/reduce_until.rb +20 -0
- data/lib/light-service/organizer/scoped_reducable.rb +13 -0
- data/lib/light-service/organizer/verify_call_method_exists.rb +28 -0
- data/lib/light-service/organizer/with_callback.rb +26 -0
- data/lib/light-service/organizer/with_reducer.rb +14 -4
- data/lib/light-service/organizer/with_reducer_factory.rb +2 -0
- data/lib/light-service/version.rb +1 -1
- data/light-service.gemspec +2 -2
- data/resources/orchestrators_deprecated.svg +10 -0
- data/spec/acceptance/add_numbers_spec.rb +3 -3
- data/spec/acceptance/after_actions_spec.rb +67 -0
- data/spec/acceptance/before_actions_spec.rb +109 -0
- data/spec/acceptance/orchestrator/context_failure_and_skipping_spec.rb +12 -10
- data/spec/acceptance/orchestrator/execute_spec.rb +8 -6
- data/spec/acceptance/orchestrator/iterate_spec.rb +9 -7
- data/spec/acceptance/orchestrator/organizer_action_combination_spec.rb +13 -11
- data/spec/acceptance/orchestrator/reduce_if_spec.rb +9 -7
- data/spec/acceptance/orchestrator/reduce_until_spec.rb +7 -5
- data/spec/acceptance/orchestrator/with_callback_spec.rb +8 -6
- data/spec/acceptance/organizer/around_each_with_reduce_if_spec.rb +42 -0
- data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +65 -0
- data/spec/acceptance/organizer/execute_spec.rb +46 -0
- data/spec/acceptance/organizer/iterate_spec.rb +37 -0
- data/spec/acceptance/organizer/reduce_if_spec.rb +51 -0
- data/spec/acceptance/organizer/reduce_until_spec.rb +43 -0
- data/spec/acceptance/organizer/with_callback_spec.rb +110 -0
- data/spec/organizer/with_reducer_spec.rb +2 -7
- data/spec/sample/calculates_tax_spec.rb +1 -4
- data/spec/spec_helper.rb +12 -0
- data/spec/support.rb +9 -0
- data/spec/test_doubles.rb +84 -17
- metadata +34 -6
@@ -2,24 +2,26 @@ require 'spec_helper'
|
|
2
2
|
require 'test_doubles'
|
3
3
|
|
4
4
|
describe LightService::Orchestrator do
|
5
|
-
|
5
|
+
include_context 'expect orchestrator warning'
|
6
|
+
|
7
|
+
class OrchestratorTestSkipState
|
6
8
|
extend LightService::Orchestrator
|
7
9
|
def self.run_skip_before
|
8
10
|
with(:number => 1).reduce([
|
9
11
|
TestDoubles::SkipAllAction,
|
10
12
|
reduce_until(->(ctx) { ctx.number == 3 },
|
11
|
-
TestDoubles::
|
13
|
+
TestDoubles::AddsOneAction)
|
12
14
|
])
|
13
15
|
end
|
14
16
|
|
15
17
|
def self.run_skip_after
|
16
18
|
with(:number => 1).reduce([
|
17
|
-
TestDoubles::
|
19
|
+
TestDoubles::AddsOneAction,
|
18
20
|
reduce_until(->(ctx) { ctx.number == 3 }, [
|
19
|
-
TestDoubles::
|
21
|
+
TestDoubles::AddsOneAction
|
20
22
|
]),
|
21
23
|
TestDoubles::SkipAllAction,
|
22
|
-
TestDoubles::
|
24
|
+
TestDoubles::AddsOneAction
|
23
25
|
])
|
24
26
|
end
|
25
27
|
|
@@ -27,28 +29,28 @@ describe LightService::Orchestrator do
|
|
27
29
|
with(:number => 1).reduce([
|
28
30
|
TestDoubles::FailureAction,
|
29
31
|
reduce_until(->(ctx) { ctx[:number] == 3 },
|
30
|
-
TestDoubles::
|
31
|
-
TestDoubles::
|
32
|
+
TestDoubles::AddsOneAction),
|
33
|
+
TestDoubles::AddsOneAction
|
32
34
|
])
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
38
|
it 'skips all the rest of the actions' do
|
37
|
-
result =
|
39
|
+
result = OrchestratorTestSkipState.run_skip_before
|
38
40
|
|
39
41
|
expect(result).to be_success
|
40
42
|
expect(result[:number]).to eq(1)
|
41
43
|
end
|
42
44
|
|
43
45
|
it 'skips after an action in nested context' do
|
44
|
-
result =
|
46
|
+
result = OrchestratorTestSkipState.run_skip_after
|
45
47
|
|
46
48
|
expect(result).to be_success
|
47
49
|
expect(result[:number]).to eq(3)
|
48
50
|
end
|
49
51
|
|
50
52
|
it 'respects failure across all nestings' do
|
51
|
-
result =
|
53
|
+
result = OrchestratorTestSkipState.run_failure
|
52
54
|
|
53
55
|
expect(result).to be_failure
|
54
56
|
expect(result[:number]).to eq(1)
|
@@ -2,7 +2,9 @@ require 'spec_helper'
|
|
2
2
|
require 'test_doubles'
|
3
3
|
|
4
4
|
describe LightService::Orchestrator do
|
5
|
-
|
5
|
+
include_context 'expect orchestrator warning'
|
6
|
+
|
7
|
+
class OrchestratorTestExecute
|
6
8
|
extend LightService::Orchestrator
|
7
9
|
|
8
10
|
def self.run(context)
|
@@ -11,10 +13,10 @@ describe LightService::Orchestrator do
|
|
11
13
|
|
12
14
|
def self.steps
|
13
15
|
[
|
14
|
-
TestDoubles::
|
16
|
+
TestDoubles::AddsOneAction,
|
15
17
|
execute(->(ctx) { ctx.number += 1 }),
|
16
18
|
execute(->(ctx) { ctx[:something] = 'hello' }),
|
17
|
-
TestDoubles::
|
19
|
+
TestDoubles::AddsOneAction
|
18
20
|
]
|
19
21
|
end
|
20
22
|
end
|
@@ -22,7 +24,7 @@ describe LightService::Orchestrator do
|
|
22
24
|
let(:empty_context) { LightService::Context.make }
|
23
25
|
|
24
26
|
it 'calls the lambda in the execute block using the context' do
|
25
|
-
result =
|
27
|
+
result = OrchestratorTestExecute.run(:number => 0)
|
26
28
|
|
27
29
|
expect(result).to be_success
|
28
30
|
expect(result.number).to eq(3)
|
@@ -32,7 +34,7 @@ describe LightService::Orchestrator do
|
|
32
34
|
it 'will not execute a failed context' do
|
33
35
|
empty_context.fail!('Something bad happened')
|
34
36
|
|
35
|
-
result =
|
37
|
+
result = OrchestratorTestExecute.run(empty_context)
|
36
38
|
|
37
39
|
expect(result).to be_failure
|
38
40
|
end
|
@@ -40,7 +42,7 @@ describe LightService::Orchestrator do
|
|
40
42
|
it 'does not execute over a skipped context' do
|
41
43
|
empty_context.skip_remaining!('No more needed')
|
42
44
|
|
43
|
-
result =
|
45
|
+
result = OrchestratorTestExecute.run(empty_context)
|
44
46
|
expect(result).to be_success
|
45
47
|
end
|
46
48
|
end
|
@@ -2,20 +2,22 @@ require 'spec_helper'
|
|
2
2
|
require 'test_doubles'
|
3
3
|
|
4
4
|
describe LightService::Orchestrator do
|
5
|
-
|
5
|
+
include_context 'expect orchestrator warning'
|
6
|
+
|
7
|
+
class OrchestratorTestIterate
|
6
8
|
extend LightService::Orchestrator
|
7
9
|
|
8
10
|
def self.run(context)
|
9
11
|
with(context).reduce([
|
10
12
|
iterate(:numbers, [
|
11
|
-
TestDoubles::
|
13
|
+
TestDoubles::AddsOneAction
|
12
14
|
])
|
13
15
|
])
|
14
16
|
end
|
15
17
|
|
16
18
|
def self.run_single(context)
|
17
19
|
with(context).reduce([
|
18
|
-
iterate(:numbers, TestDoubles::
|
20
|
+
iterate(:numbers, TestDoubles::AddsOneAction)
|
19
21
|
])
|
20
22
|
end
|
21
23
|
end
|
@@ -23,14 +25,14 @@ describe LightService::Orchestrator do
|
|
23
25
|
let(:empty_context) { LightService::Context.make }
|
24
26
|
|
25
27
|
it 'reduces each item of a collection and singularizes the collection key' do
|
26
|
-
result =
|
28
|
+
result = OrchestratorTestIterate.run(:numbers => [1, 2, 3, 4])
|
27
29
|
|
28
30
|
expect(result).to be_success
|
29
31
|
expect(result.number).to eq(5)
|
30
32
|
end
|
31
33
|
|
32
34
|
it 'accepts a single action or organizer' do
|
33
|
-
result =
|
35
|
+
result = OrchestratorTestIterate.run_single(:numbers => [1, 2, 3, 4])
|
34
36
|
|
35
37
|
expect(result).to be_success
|
36
38
|
expect(result.number).to eq(5)
|
@@ -39,7 +41,7 @@ describe LightService::Orchestrator do
|
|
39
41
|
it 'will not iterate over a failed context' do
|
40
42
|
empty_context.fail!('Something bad happened')
|
41
43
|
|
42
|
-
result =
|
44
|
+
result = OrchestratorTestIterate.run(empty_context)
|
43
45
|
|
44
46
|
expect(result).to be_failure
|
45
47
|
end
|
@@ -47,7 +49,7 @@ describe LightService::Orchestrator do
|
|
47
49
|
it 'does not iterate over a skipped context' do
|
48
50
|
empty_context.skip_remaining!('No more needed')
|
49
51
|
|
50
|
-
result =
|
52
|
+
result = OrchestratorTestIterate.run(empty_context)
|
51
53
|
expect(result).to be_success
|
52
54
|
end
|
53
55
|
end
|
@@ -2,7 +2,9 @@ require 'spec_helper'
|
|
2
2
|
require 'test_doubles'
|
3
3
|
|
4
4
|
describe LightService::Orchestrator do
|
5
|
-
|
5
|
+
include_context 'expect orchestrator warning'
|
6
|
+
|
7
|
+
class OrchestratorTestReduce
|
6
8
|
extend LightService::Orchestrator
|
7
9
|
|
8
10
|
def self.run(context, steps)
|
@@ -11,21 +13,21 @@ describe LightService::Orchestrator do
|
|
11
13
|
end
|
12
14
|
|
13
15
|
it 'responds to both actions and organizers' do
|
14
|
-
result =
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
result = OrchestratorTestReduce.run({ :number => 0 }, [
|
17
|
+
TestDoubles::AddTwoOrganizer,
|
18
|
+
TestDoubles::AddsOneAction
|
19
|
+
])
|
18
20
|
|
19
21
|
expect(result).to be_success
|
20
22
|
expect(result.number).to eq(3)
|
21
23
|
end
|
22
24
|
|
23
25
|
it 'fails fast by skipping proceeding actions/organizers after failure' do
|
24
|
-
result =
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
result = OrchestratorTestReduce.run({ :number => 0 }, [
|
27
|
+
TestDoubles::AddTwoOrganizer,
|
28
|
+
TestDoubles::FailureAction,
|
29
|
+
TestDoubles::AddsOneAction
|
30
|
+
])
|
29
31
|
|
30
32
|
expect(result).not_to be_success
|
31
33
|
expect(result.number).to eq(2)
|
@@ -33,7 +35,7 @@ describe LightService::Orchestrator do
|
|
33
35
|
|
34
36
|
it 'does not allow anything but actions and organizers' do
|
35
37
|
expect do
|
36
|
-
|
38
|
+
OrchestratorTestReduce.run({}, [double])
|
37
39
|
end.to raise_error(RuntimeError)
|
38
40
|
end
|
39
41
|
end
|
@@ -2,7 +2,9 @@ require 'spec_helper'
|
|
2
2
|
require 'test_doubles'
|
3
3
|
|
4
4
|
describe LightService::Orchestrator do
|
5
|
-
|
5
|
+
include_context 'expect orchestrator warning'
|
6
|
+
|
7
|
+
class OrchestratorTestReduceIf
|
6
8
|
extend LightService::Orchestrator
|
7
9
|
|
8
10
|
def self.run(context)
|
@@ -11,9 +13,9 @@ describe LightService::Orchestrator do
|
|
11
13
|
|
12
14
|
def self.steps
|
13
15
|
[
|
14
|
-
TestDoubles::
|
16
|
+
TestDoubles::AddsOneAction,
|
15
17
|
reduce_if(->(ctx) { ctx.number == 1 },
|
16
|
-
TestDoubles::
|
18
|
+
TestDoubles::AddsOneAction)
|
17
19
|
]
|
18
20
|
end
|
19
21
|
end
|
@@ -21,14 +23,14 @@ describe LightService::Orchestrator do
|
|
21
23
|
let(:empty_context) { LightService::Context.make }
|
22
24
|
|
23
25
|
it 'reduces if the block evaluates to true' do
|
24
|
-
result =
|
26
|
+
result = OrchestratorTestReduceIf.run(:number => 0)
|
25
27
|
|
26
28
|
expect(result).to be_success
|
27
29
|
expect(result[:number]).to eq(2)
|
28
30
|
end
|
29
31
|
|
30
32
|
it 'does not reduce if the block evaluates to false' do
|
31
|
-
result =
|
33
|
+
result = OrchestratorTestReduceIf.run(:number => 2)
|
32
34
|
|
33
35
|
expect(result).to be_success
|
34
36
|
expect(result[:number]).to eq(3)
|
@@ -37,7 +39,7 @@ describe LightService::Orchestrator do
|
|
37
39
|
it 'will not reduce over a failed context' do
|
38
40
|
empty_context.fail!('Something bad happened')
|
39
41
|
|
40
|
-
result =
|
42
|
+
result = OrchestratorTestReduceIf.run(empty_context)
|
41
43
|
|
42
44
|
expect(result).to be_failure
|
43
45
|
end
|
@@ -45,7 +47,7 @@ describe LightService::Orchestrator do
|
|
45
47
|
it 'does not reduce over a skipped context' do
|
46
48
|
empty_context.skip_remaining!('No more needed')
|
47
49
|
|
48
|
-
result =
|
50
|
+
result = OrchestratorTestReduceIf.run(empty_context)
|
49
51
|
expect(result).to be_success
|
50
52
|
end
|
51
53
|
end
|
@@ -2,7 +2,9 @@ require 'spec_helper'
|
|
2
2
|
require 'test_doubles'
|
3
3
|
|
4
4
|
RSpec.describe LightService::Orchestrator do
|
5
|
-
|
5
|
+
include_context 'expect orchestrator warning'
|
6
|
+
|
7
|
+
class OrchestratorTestReduceUntil
|
6
8
|
extend LightService::Orchestrator
|
7
9
|
|
8
10
|
def self.run(context)
|
@@ -12,7 +14,7 @@ RSpec.describe LightService::Orchestrator do
|
|
12
14
|
def self.steps
|
13
15
|
[
|
14
16
|
reduce_until(->(ctx) { ctx.number == 3 },
|
15
|
-
TestDoubles::
|
17
|
+
TestDoubles::AddsOneAction)
|
16
18
|
]
|
17
19
|
end
|
18
20
|
end
|
@@ -21,7 +23,7 @@ RSpec.describe LightService::Orchestrator do
|
|
21
23
|
|
22
24
|
it 'reduces until the block evaluates to true' do
|
23
25
|
context = { :number => 1 }
|
24
|
-
result =
|
26
|
+
result = OrchestratorTestReduceUntil.run(context)
|
25
27
|
|
26
28
|
expect(result).to be_success
|
27
29
|
expect(result.number).to eq(3)
|
@@ -30,14 +32,14 @@ RSpec.describe LightService::Orchestrator do
|
|
30
32
|
it 'does not execute on failed context' do
|
31
33
|
empty_context.fail!('Something bad happened')
|
32
34
|
|
33
|
-
result =
|
35
|
+
result = OrchestratorTestReduceUntil.run(empty_context)
|
34
36
|
expect(result).to be_failure
|
35
37
|
end
|
36
38
|
|
37
39
|
it 'does not execute a skipped context' do
|
38
40
|
empty_context.skip_remaining!('No more needed')
|
39
41
|
|
40
|
-
result =
|
42
|
+
result = OrchestratorTestReduceUntil.run(empty_context)
|
41
43
|
expect(result).to be_success
|
42
44
|
end
|
43
45
|
end
|
@@ -2,7 +2,9 @@ require 'spec_helper'
|
|
2
2
|
require 'test_doubles'
|
3
3
|
|
4
4
|
describe LightService::Orchestrator do
|
5
|
-
|
5
|
+
include_context 'expect orchestrator warning'
|
6
|
+
|
7
|
+
class OrchestratorTestWithCallback
|
6
8
|
extend LightService::Orchestrator
|
7
9
|
|
8
10
|
def self.run(context = {})
|
@@ -63,7 +65,7 @@ describe LightService::Orchestrator do
|
|
63
65
|
|
64
66
|
describe 'a simple case with a single callback' do
|
65
67
|
it 'calls the actions defined with callback' do
|
66
|
-
result =
|
68
|
+
result = OrchestratorTestWithCallback.run
|
67
69
|
|
68
70
|
expect(result.counter).to eq(3)
|
69
71
|
expect(result.total).to eq(6)
|
@@ -71,7 +73,7 @@ describe LightService::Orchestrator do
|
|
71
73
|
end
|
72
74
|
|
73
75
|
describe 'a more complex example with nested callbacks' do
|
74
|
-
class
|
76
|
+
class OrchestratorTestWithNextedCallback
|
75
77
|
extend LightService::Orchestrator
|
76
78
|
|
77
79
|
def self.run(context = {})
|
@@ -127,7 +129,7 @@ describe LightService::Orchestrator do
|
|
127
129
|
end
|
128
130
|
|
129
131
|
it 'calls both the action and the nested callbacks' do
|
130
|
-
result =
|
132
|
+
result = OrchestratorTestWithNextedCallback.run
|
131
133
|
|
132
134
|
expect(result.outer_counter).to eq(2)
|
133
135
|
# Counts and total are the duplicates of
|
@@ -141,7 +143,7 @@ describe LightService::Orchestrator do
|
|
141
143
|
end
|
142
144
|
|
143
145
|
describe 'with failed or skipped context' do
|
144
|
-
class
|
146
|
+
class OrchestratorTestWithFailureCallback
|
145
147
|
extend LightService::Orchestrator
|
146
148
|
|
147
149
|
def self.run(context = {})
|
@@ -159,7 +161,7 @@ describe LightService::Orchestrator do
|
|
159
161
|
end
|
160
162
|
|
161
163
|
it 'will not process the routine' do
|
162
|
-
result =
|
164
|
+
result = OrchestratorTestWithFailureCallback.run
|
163
165
|
|
164
166
|
expect(result).to be_failure
|
165
167
|
expect(result.counter).to eq(1)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_doubles'
|
3
|
+
|
4
|
+
RSpec.describe LightService::Organizer do
|
5
|
+
class TestReduceIfWithAroundEach
|
6
|
+
extend LightService::Organizer
|
7
|
+
|
8
|
+
def self.call(context)
|
9
|
+
with(context)
|
10
|
+
.around_each(TestDoubles::AroundEachLoggerHandler)
|
11
|
+
.reduce(actions)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.actions
|
15
|
+
[
|
16
|
+
TestDoubles::AddsOneAction,
|
17
|
+
reduce_if(->(ctx) { ctx.number == 1 },
|
18
|
+
TestDoubles::AddsOneAction)
|
19
|
+
]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can be used to log data' do
|
24
|
+
result =
|
25
|
+
TestReduceIfWithAroundEach
|
26
|
+
.call(:number => 0,
|
27
|
+
:logger => TestDoubles::TestLogger.new)
|
28
|
+
|
29
|
+
expect(result.fetch(:number)).to eq(2)
|
30
|
+
expect(result[:logger].logs).to eq(
|
31
|
+
[{
|
32
|
+
:action => TestDoubles::AddsOneAction,
|
33
|
+
:before => 0,
|
34
|
+
:after => 1
|
35
|
+
}, {
|
36
|
+
:action => TestDoubles::AddsOneAction,
|
37
|
+
:before => 1,
|
38
|
+
:after => 2
|
39
|
+
}]
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_doubles'
|
3
|
+
|
4
|
+
RSpec.describe LightService::Organizer do
|
5
|
+
class TestSkipBefore
|
6
|
+
extend LightService::Organizer
|
7
|
+
def self.call
|
8
|
+
with(:number => 1)
|
9
|
+
.reduce([
|
10
|
+
TestDoubles::SkipAllAction,
|
11
|
+
reduce_until(->(ctx) { ctx.number == 3 },
|
12
|
+
TestDoubles::AddsOneAction)
|
13
|
+
])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class TestSkipAfter
|
18
|
+
extend LightService::Organizer
|
19
|
+
def self.call
|
20
|
+
with(:number => 1)
|
21
|
+
.reduce([
|
22
|
+
TestDoubles::AddsOneAction,
|
23
|
+
reduce_until(->(ctx) { ctx.number == 3 }, [
|
24
|
+
TestDoubles::AddsOneAction
|
25
|
+
]),
|
26
|
+
TestDoubles::SkipAllAction,
|
27
|
+
TestDoubles::AddsOneAction
|
28
|
+
])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class TestContextFailure
|
33
|
+
extend LightService::Organizer
|
34
|
+
def self.call
|
35
|
+
with(:number => 1)
|
36
|
+
.reduce([
|
37
|
+
TestDoubles::FailureAction,
|
38
|
+
reduce_until(->(ctx) { ctx[:number] == 3 },
|
39
|
+
TestDoubles::AddsOneAction),
|
40
|
+
TestDoubles::AddsOneAction
|
41
|
+
])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'skips all the rest of the actions' do
|
46
|
+
result = TestSkipBefore.call
|
47
|
+
|
48
|
+
expect(result).to be_success
|
49
|
+
expect(result[:number]).to eq(1)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'skips after an action in nested context' do
|
53
|
+
result = TestSkipAfter.call
|
54
|
+
|
55
|
+
expect(result).to be_success
|
56
|
+
expect(result[:number]).to eq(3)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'respects failure across all nestings' do
|
60
|
+
result = TestContextFailure.call
|
61
|
+
|
62
|
+
expect(result).to be_failure
|
63
|
+
expect(result[:number]).to eq(1)
|
64
|
+
end
|
65
|
+
end
|