light-service 0.8.1 → 0.8.2
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/README.md +10 -4
- data/RELEASES.md +6 -0
- data/lib/light-service/action.rb +3 -1
- data/lib/light-service/context.rb +22 -0
- data/lib/light-service/orchestrator.rb +26 -0
- data/lib/light-service/version.rb +1 -1
- data/light-service.gemspec +1 -1
- data/spec/acceptance/fail_spec.rb +24 -0
- data/spec/acceptance/orchestrator/context_failure_and_skipping_spec.rb +7 -7
- data/spec/acceptance/orchestrator/execute_spec.rb +17 -0
- data/spec/acceptance/orchestrator/iterate_spec.rb +17 -0
- data/spec/acceptance/orchestrator/reduce_if_spec.rb +19 -2
- data/spec/acceptance/orchestrator/reduce_until_spec.rb +20 -3
- data/spec/acceptance/orchestrator/with_callback_spec.rb +169 -0
- data/spec/context/inspect_spec.rb +57 -0
- data/spec/context_spec.rb +2 -2
- metadata +12 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65ef2c9c99bebb3e4b19a0fbfc63c893381fbfe4
|
4
|
+
data.tar.gz: 6962376a614207f0475112a1f21c1872876ec865
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ea257de8c459ecccbcb0d702c61c603f45c3d6bc50f2a829925ecbe2af4e1fbeb0eee277a9005c99a1f928087610ce02e8317b63e13e329f8b4c2328958b997
|
7
|
+
data.tar.gz: 768698a21f441add9d09ec47eed6cc8384b1babb232c1778a3abbdf0531ac8179eb3b47c75c16e07db77b2fe14870fd29e65cd022b45f9b458e02e8a92a9d77e
|
data/README.md
CHANGED
@@ -187,6 +187,9 @@ When something goes wrong in an action and you want to halt the chain, you need
|
|
187
187
|
The context's `fail!` method can take an optional message argument, this message might help describing what went wrong.
|
188
188
|
In case you need to return immediately from the point of failure, you have to do that by calling `next context`.
|
189
189
|
|
190
|
+
In case you want to fail the context and stop the execution of the executed block, use the `fail_and_return!('something went wront')` method.
|
191
|
+
This will immediately leave the block, you don't need to call `next context` to return from the block.
|
192
|
+
|
190
193
|
Here is an example:
|
191
194
|
```ruby
|
192
195
|
class SubmitsOrderAction
|
@@ -195,10 +198,10 @@ class SubmitsOrderAction
|
|
195
198
|
|
196
199
|
executed do |context|
|
197
200
|
unless context.order.submit_order_successful?
|
198
|
-
context.
|
199
|
-
next context
|
201
|
+
context.fail_and_return!("Failed to submit the order")
|
200
202
|
end
|
201
203
|
|
204
|
+
# This won't be executed
|
202
205
|
context.mailer.send_order_notification!
|
203
206
|
end
|
204
207
|
end
|
@@ -641,15 +644,16 @@ Orchestrators
|
|
641
644
|
|
642
645
|
You can mix organizers with actions in the orchestrator steps, but mixing other organizers with actions in an organizer is discouraged for the sake of simplicity.
|
643
646
|
|
644
|
-
The
|
647
|
+
The 6 different constructs an orchestrator can have:
|
645
648
|
|
646
649
|
1. `reduce`
|
647
650
|
2. `reduce_until`
|
648
651
|
3. `reduce_if`
|
649
652
|
4. `iterate`
|
650
653
|
5. `execute`
|
654
|
+
6. `with_callback`
|
651
655
|
|
652
|
-
The `reduce` method needs no
|
656
|
+
The `reduce` method needs no introduction, it behaves similarly to organizers' `reduce` method.
|
653
657
|
|
654
658
|
`reduce_until` behaves like a while loop in imperative languages, it iterates until the provided predicate in the lambda evaluates to true. Take a look at [this acceptance test](spec/acceptance/orchestrator/reduce_until_spec.rb) to see how it's used.
|
655
659
|
|
@@ -659,6 +663,8 @@ The `reduce` method needs no interaction, it behaves similarly to organizers' `r
|
|
659
663
|
|
660
664
|
To take advantage of another organizer or action, you might need to tweak the context a bit. Let's say you have a hash, and you need to iterate over its values in a series of action. To alter the context and have the values assigned into a variable, you need to create a new action with 1 line of code in it. That seems a lot of ceremony for a simple change. You can do that in a `execute` method like this `execute(->(ctx) { ctx[:some_values] = ctx.some_hash.values })`. [This test](spec/acceptance/orchestrator/execute_spec.rb) describes how you can use it.
|
661
665
|
|
666
|
+
Use `with_callback` when you want to execute actions with a deferred and controlled callback. It works similar to a Sax parser, I've used it for processing large files. The advantage of it is not having to keep large amount of data in memory. See [this acceptance test](spec/acceptance/orchestrator/with_callback_spec.rb) as a working example.
|
667
|
+
|
662
668
|
** Thanks to [@bwvoss](https://github.com/bwvoss) for writing most of the Orchestrators code, I only ported his changes to LS and submitted the PR.
|
663
669
|
|
664
670
|
## ContextFactory for Faster Action Testing
|
data/RELEASES.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
A brief list of new features and changes introduced with the specified version.
|
2
2
|
|
3
|
+
### 0.8.2
|
4
|
+
* A better way to [inspect](https://github.com/adomokos/light-service/pull/110) the context.
|
5
|
+
* [Short-circuiting](https://github.com/adomokos/light-service/pull/113) the Orchestrator methods.
|
6
|
+
* [Fail and return - with one call](https://github.com/adomokos/light-service/pull/115), no `and next` is needed.
|
7
|
+
* Adding [with_callback](https://github.com/adomokos/light-service/pull/116) to Orchestrators, allows us to process large data in smaller chunks.
|
8
|
+
|
3
9
|
### 0.8.1
|
4
10
|
* Renaming `skip_all!` to [skip_remaining!](https://github.com/adomokos/light-service/pull/103).
|
5
11
|
* Adding [ContextFactory](https://github.com/adomokos/light-service/pull/107) for easier testing.
|
data/lib/light-service/action.rb
CHANGED
@@ -87,6 +87,11 @@ module LightService
|
|
87
87
|
@outcome = Outcomes::FAILURE
|
88
88
|
end
|
89
89
|
|
90
|
+
def fail_and_return!(*args)
|
91
|
+
fail!(*args)
|
92
|
+
throw(:jump_when_failed, *args)
|
93
|
+
end
|
94
|
+
|
90
95
|
def fail_with_rollback!(message = nil, error_code = nil)
|
91
96
|
fail!(message, error_code)
|
92
97
|
raise FailWithRollbackError
|
@@ -138,6 +143,23 @@ module LightService
|
|
138
143
|
def fetch(key, default_or_block = nil)
|
139
144
|
self[key] ||= super(key, default_or_block)
|
140
145
|
end
|
146
|
+
|
147
|
+
def inspect
|
148
|
+
"#{self.class}(#{self}, " \
|
149
|
+
+ "success: #{success?}, " \
|
150
|
+
+ "message: #{check_nil(message)}, " \
|
151
|
+
+ "error_code: #{check_nil(error_code)}, " \
|
152
|
+
+ "skip_remaining: #{@skip_remaining}, " \
|
153
|
+
+ "aliases: #{@aliases}" \
|
154
|
+
+ ")"
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
def check_nil(value)
|
160
|
+
return 'nil' unless value
|
161
|
+
"'#{value}'"
|
162
|
+
end
|
141
163
|
end
|
142
164
|
# rubocop:enable ClassLength
|
143
165
|
end
|
@@ -24,6 +24,8 @@ module LightService
|
|
24
24
|
|
25
25
|
def reduce_until(condition_block, steps)
|
26
26
|
lambda do |ctx|
|
27
|
+
return ctx if ctx.stop_processing?
|
28
|
+
|
27
29
|
loop do
|
28
30
|
ctx = scoped_reduction(ctx, steps)
|
29
31
|
break if condition_block.call(ctx) || ctx.failure?
|
@@ -35,6 +37,8 @@ module LightService
|
|
35
37
|
|
36
38
|
def reduce_if(condition_block, steps)
|
37
39
|
lambda do |ctx|
|
40
|
+
return ctx if ctx.stop_processing?
|
41
|
+
|
38
42
|
ctx = scoped_reduction(ctx, steps) if condition_block.call(ctx)
|
39
43
|
ctx
|
40
44
|
end
|
@@ -42,6 +46,8 @@ module LightService
|
|
42
46
|
|
43
47
|
def execute(code_block)
|
44
48
|
lambda do |ctx|
|
49
|
+
return ctx if ctx.stop_processing?
|
50
|
+
|
45
51
|
ctx = code_block.call(ctx)
|
46
52
|
ctx
|
47
53
|
end
|
@@ -49,6 +55,8 @@ module LightService
|
|
49
55
|
|
50
56
|
def iterate(collection_key, steps)
|
51
57
|
lambda do |ctx|
|
58
|
+
return ctx if ctx.stop_processing?
|
59
|
+
|
52
60
|
collection = ctx[collection_key]
|
53
61
|
item_key = collection_key.to_s.singularize.to_sym
|
54
62
|
collection.each do |item|
|
@@ -60,6 +68,24 @@ module LightService
|
|
60
68
|
end
|
61
69
|
end
|
62
70
|
|
71
|
+
def with_callback(action, steps)
|
72
|
+
lambda do |ctx|
|
73
|
+
return ctx if ctx.stop_processing?
|
74
|
+
|
75
|
+
# This will only allow 2 level deep nesting of callbacks
|
76
|
+
previous_callback = ctx[:callback]
|
77
|
+
|
78
|
+
ctx[:callback] = lambda do |context|
|
79
|
+
reduce(steps, context)
|
80
|
+
end
|
81
|
+
|
82
|
+
ctx = action.execute(ctx)
|
83
|
+
ctx[:callback] = previous_callback
|
84
|
+
|
85
|
+
ctx
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
63
89
|
private
|
64
90
|
|
65
91
|
def scoped_reduction(ctx, steps)
|
data/light-service.gemspec
CHANGED
@@ -20,6 +20,6 @@ Gem::Specification.new do |gem|
|
|
20
20
|
|
21
21
|
gem.add_development_dependency("rspec", "~> 3.0")
|
22
22
|
gem.add_development_dependency("simplecov", "~> 0.14.1")
|
23
|
-
gem.add_development_dependency("rubocop", "
|
23
|
+
gem.add_development_dependency("rubocop", "0.46")
|
24
24
|
gem.add_development_dependency("pry", "~> 0.10")
|
25
25
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "fail! returns immediately from executed block" do
|
4
|
+
class FailAction
|
5
|
+
extend LightService::Action
|
6
|
+
promises :one, :two
|
7
|
+
|
8
|
+
executed do |ctx|
|
9
|
+
ctx.one = 1
|
10
|
+
# Have to set it in Context
|
11
|
+
ctx.two = nil
|
12
|
+
|
13
|
+
ctx.fail_and_return!('Something went wrong')
|
14
|
+
ctx.two = 2
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns immediately from executed block" do
|
19
|
+
result = FailAction.execute
|
20
|
+
|
21
|
+
expect(result).to be_failure
|
22
|
+
expect(result.two).to be_nil
|
23
|
+
end
|
24
|
+
end
|
@@ -14,11 +14,11 @@ describe LightService::Orchestrator do
|
|
14
14
|
|
15
15
|
def self.run_skip_after
|
16
16
|
with(:number => 1).reduce([
|
17
|
-
TestDoubles::
|
17
|
+
TestDoubles::AddOneAction,
|
18
18
|
reduce_until(->(ctx) { ctx.number == 3 }, [
|
19
|
-
TestDoubles::AddOneAction
|
20
|
-
TestDoubles::SkipAllAction
|
19
|
+
TestDoubles::AddOneAction
|
21
20
|
]),
|
21
|
+
TestDoubles::SkipAllAction,
|
22
22
|
TestDoubles::AddOneAction
|
23
23
|
])
|
24
24
|
end
|
@@ -33,18 +33,18 @@ describe LightService::Orchestrator do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
it '
|
36
|
+
it 'skips all the rest of the actions' do
|
37
37
|
result = TestSkipState.run_skip_before
|
38
38
|
|
39
39
|
expect(result).to be_success
|
40
|
-
expect(result
|
40
|
+
expect(result[:number]).to eq(1)
|
41
41
|
end
|
42
42
|
|
43
|
-
it '
|
43
|
+
it 'skips after an action in nested context' do
|
44
44
|
result = TestSkipState.run_skip_after
|
45
45
|
|
46
46
|
expect(result).to be_success
|
47
|
-
expect(result
|
47
|
+
expect(result[:number]).to eq(3)
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'respects failure across all nestings' do
|
@@ -19,6 +19,8 @@ describe LightService::Orchestrator do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
let(:empty_context) { LightService::Context.make }
|
23
|
+
|
22
24
|
it 'calls the lambda in the execute block using the context' do
|
23
25
|
result = TestExecute.run(:number => 0)
|
24
26
|
|
@@ -26,4 +28,19 @@ describe LightService::Orchestrator do
|
|
26
28
|
expect(result.number).to eq(3)
|
27
29
|
expect(result[:something]).to eq('hello')
|
28
30
|
end
|
31
|
+
|
32
|
+
it 'will not execute a failed context' do
|
33
|
+
empty_context.fail!('Something bad happened')
|
34
|
+
|
35
|
+
result = TestExecute.run(empty_context)
|
36
|
+
|
37
|
+
expect(result).to be_failure
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'does not execute over a skipped context' do
|
41
|
+
empty_context.skip_remaining!('No more needed')
|
42
|
+
|
43
|
+
result = TestExecute.run(empty_context)
|
44
|
+
expect(result).to be_success
|
45
|
+
end
|
29
46
|
end
|
@@ -20,6 +20,8 @@ describe LightService::Orchestrator do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
let(:empty_context) { LightService::Context.make }
|
24
|
+
|
23
25
|
it 'reduces each item of a collection and singularizes the collection key' do
|
24
26
|
result = TestIterate.run(:numbers => [1, 2, 3, 4])
|
25
27
|
|
@@ -33,4 +35,19 @@ describe LightService::Orchestrator do
|
|
33
35
|
expect(result).to be_success
|
34
36
|
expect(result.number).to eq(5)
|
35
37
|
end
|
38
|
+
|
39
|
+
it 'will not iterate over a failed context' do
|
40
|
+
empty_context.fail!('Something bad happened')
|
41
|
+
|
42
|
+
result = TestIterate.run(empty_context)
|
43
|
+
|
44
|
+
expect(result).to be_failure
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'does not iterate over a skipped context' do
|
48
|
+
empty_context.skip_remaining!('No more needed')
|
49
|
+
|
50
|
+
result = TestIterate.run(empty_context)
|
51
|
+
expect(result).to be_success
|
52
|
+
end
|
36
53
|
end
|
@@ -18,17 +18,34 @@ describe LightService::Orchestrator do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
let(:empty_context) { LightService::Context.make }
|
22
|
+
|
21
23
|
it 'reduces if the block evaluates to true' do
|
22
24
|
result = TestReduceIf.run(:number => 0)
|
23
25
|
|
24
26
|
expect(result).to be_success
|
25
|
-
expect(result
|
27
|
+
expect(result[:number]).to eq(2)
|
26
28
|
end
|
27
29
|
|
28
30
|
it 'does not reduce if the block evaluates to false' do
|
29
31
|
result = TestReduceIf.run(:number => 2)
|
30
32
|
|
31
33
|
expect(result).to be_success
|
32
|
-
expect(result
|
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.run(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.run(empty_context)
|
49
|
+
expect(result).to be_success
|
33
50
|
end
|
34
51
|
end
|
@@ -5,8 +5,8 @@ RSpec.describe LightService::Orchestrator do
|
|
5
5
|
class TestReduceUntil
|
6
6
|
extend LightService::Orchestrator
|
7
7
|
|
8
|
-
def self.run
|
9
|
-
with(
|
8
|
+
def self.run(context)
|
9
|
+
with(context).reduce(steps)
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.steps
|
@@ -17,10 +17,27 @@ RSpec.describe LightService::Orchestrator do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
let(:empty_context) { LightService::Context.make }
|
21
|
+
|
20
22
|
it 'reduces until the block evaluates to true' do
|
21
|
-
|
23
|
+
context = { :number => 1 }
|
24
|
+
result = TestReduceUntil.run(context)
|
22
25
|
|
23
26
|
expect(result).to be_success
|
24
27
|
expect(result.number).to eq(3)
|
25
28
|
end
|
29
|
+
|
30
|
+
it 'does not execute on failed context' do
|
31
|
+
empty_context.fail!('Something bad happened')
|
32
|
+
|
33
|
+
result = TestReduceUntil.run(empty_context)
|
34
|
+
expect(result).to be_failure
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does not execute a skipped context' do
|
38
|
+
empty_context.skip_remaining!('No more needed')
|
39
|
+
|
40
|
+
result = TestReduceUntil.run(empty_context)
|
41
|
+
expect(result).to be_success
|
42
|
+
end
|
26
43
|
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_doubles'
|
3
|
+
|
4
|
+
describe LightService::Orchestrator do
|
5
|
+
class TestWithCallback
|
6
|
+
extend LightService::Orchestrator
|
7
|
+
|
8
|
+
def self.run(context = {})
|
9
|
+
with(context).reduce(steps)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.steps
|
13
|
+
[
|
14
|
+
SetUpContextAction,
|
15
|
+
with_callback(IterateCollectionAction,
|
16
|
+
[IncrementCountAction,
|
17
|
+
AddToTotalAction])
|
18
|
+
]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class SetUpContextAction
|
23
|
+
extend LightService::Action
|
24
|
+
promises :numbers, :counter, :total
|
25
|
+
|
26
|
+
executed do |ctx|
|
27
|
+
ctx.numbers = [1, 2, 3]
|
28
|
+
ctx.counter = 0
|
29
|
+
ctx.total = 0
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class IterateCollectionAction
|
34
|
+
extend LightService::Action
|
35
|
+
expects :numbers, :callback
|
36
|
+
promises :number
|
37
|
+
|
38
|
+
executed do |ctx|
|
39
|
+
ctx.numbers.each do |number|
|
40
|
+
ctx.number = number
|
41
|
+
ctx.callback.call(ctx)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class IncrementCountAction
|
47
|
+
extend LightService::Action
|
48
|
+
expects :counter
|
49
|
+
|
50
|
+
executed do |ctx|
|
51
|
+
ctx.counter = ctx.counter + 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class AddToTotalAction
|
56
|
+
extend LightService::Action
|
57
|
+
expects :number, :total
|
58
|
+
|
59
|
+
executed do |ctx|
|
60
|
+
ctx.total += ctx.number
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'a simple case with a single callback' do
|
65
|
+
it 'calls the actions defined with callback' do
|
66
|
+
result = TestWithCallback.run
|
67
|
+
|
68
|
+
expect(result.counter).to eq(3)
|
69
|
+
expect(result.total).to eq(6)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'a more complex example with nested callbacks' do
|
74
|
+
class TestWithNestedCallback
|
75
|
+
extend LightService::Orchestrator
|
76
|
+
|
77
|
+
def self.run(context = {})
|
78
|
+
with(context).reduce(steps)
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.steps
|
82
|
+
[
|
83
|
+
SetUpNestedContextAction,
|
84
|
+
with_callback(IterateOuterCollectionAction,
|
85
|
+
[IncrementOuterCountAction,
|
86
|
+
with_callback(IterateCollectionAction,
|
87
|
+
[IncrementCountAction,
|
88
|
+
AddToTotalAction])])
|
89
|
+
]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class SetUpNestedContextAction
|
94
|
+
extend LightService::Action
|
95
|
+
promises :outer_numbers, :outer_counter,
|
96
|
+
:numbers, :counter, :total
|
97
|
+
|
98
|
+
executed do |ctx|
|
99
|
+
ctx.outer_numbers = [12, 17]
|
100
|
+
ctx.outer_counter = 0
|
101
|
+
ctx.numbers = [1, 2, 3]
|
102
|
+
ctx.counter = 0
|
103
|
+
ctx.total = 0
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class IterateOuterCollectionAction
|
108
|
+
extend LightService::Action
|
109
|
+
expects :outer_numbers, :callback
|
110
|
+
promises :outer_number
|
111
|
+
|
112
|
+
executed do |ctx|
|
113
|
+
ctx.outer_numbers.each do |outer_number|
|
114
|
+
ctx.outer_number = outer_number
|
115
|
+
ctx.callback.call(ctx)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class IncrementOuterCountAction
|
121
|
+
extend LightService::Action
|
122
|
+
expects :outer_counter
|
123
|
+
|
124
|
+
executed do |ctx|
|
125
|
+
ctx.outer_counter = ctx.outer_counter + 1
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'calls both the action and the nested callbacks' do
|
130
|
+
result = TestWithNestedCallback.run
|
131
|
+
|
132
|
+
expect(result.outer_counter).to eq(2)
|
133
|
+
# Counts and total are the duplicates of
|
134
|
+
# what you'll see in the simple spec,
|
135
|
+
# as the internal callback logic is called
|
136
|
+
# twice due to 2 items in the outer_numbers
|
137
|
+
# collection.
|
138
|
+
expect(result.counter).to eq(6)
|
139
|
+
expect(result.total).to eq(12)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe 'with failed or skipped context' do
|
144
|
+
class TestWithFailureCallback
|
145
|
+
extend LightService::Orchestrator
|
146
|
+
|
147
|
+
def self.run(context = {})
|
148
|
+
with(context).reduce(steps)
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.steps
|
152
|
+
[
|
153
|
+
SetUpContextAction,
|
154
|
+
with_callback(IterateCollectionAction,
|
155
|
+
[IncrementCountAction,
|
156
|
+
TestDoubles::FailureAction])
|
157
|
+
]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'will not process the routine' do
|
162
|
+
result = TestWithFailureCallback.run
|
163
|
+
|
164
|
+
expect(result).to be_failure
|
165
|
+
expect(result.counter).to eq(1)
|
166
|
+
expect(result.total).to eq(0)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_doubles'
|
3
|
+
|
4
|
+
RSpec.describe LightService::Context do
|
5
|
+
subject(:context) { LightService::Context.make }
|
6
|
+
|
7
|
+
describe 'to_s' do
|
8
|
+
it 'prints the context hash' do
|
9
|
+
expect(context.to_s).to eq('{}')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#inspect' do
|
14
|
+
it 'inspects the hash with all the fields' do
|
15
|
+
inspected_context =
|
16
|
+
'LightService::Context({}, ' \
|
17
|
+
+ 'success: true, ' \
|
18
|
+
+ 'message: \'\', ' \
|
19
|
+
+ 'error_code: nil, ' \
|
20
|
+
+ 'skip_remaining: false, ' \
|
21
|
+
+ 'aliases: {}' \
|
22
|
+
+ ')'
|
23
|
+
|
24
|
+
expect(context.inspect).to eq(inspected_context)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'prints the error message' do
|
28
|
+
context.fail!('There was an error')
|
29
|
+
|
30
|
+
inspected_context =
|
31
|
+
'LightService::Context({}, ' \
|
32
|
+
+ 'success: false, ' \
|
33
|
+
+ 'message: \'There was an error\', ' \
|
34
|
+
+ 'error_code: nil, ' \
|
35
|
+
+ 'skip_remaining: false, ' \
|
36
|
+
+ 'aliases: {}' \
|
37
|
+
+ ')'
|
38
|
+
|
39
|
+
expect(context.inspect).to eq(inspected_context)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'prints skip_remaining' do
|
43
|
+
context.skip_remaining!('No need to process')
|
44
|
+
|
45
|
+
inspected_context =
|
46
|
+
'LightService::Context({}, ' \
|
47
|
+
+ 'success: true, ' \
|
48
|
+
+ 'message: \'No need to process\', ' \
|
49
|
+
+ 'error_code: nil, ' \
|
50
|
+
+ 'skip_remaining: true, ' \
|
51
|
+
+ 'aliases: {}' \
|
52
|
+
+ ')'
|
53
|
+
|
54
|
+
expect(context.inspect).to eq(inspected_context)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/context_spec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: light-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Attila Domokos
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: rubocop
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
61
|
+
version: '0.46'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0.
|
68
|
+
version: '0.46'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- resources/skip_actions.png
|
127
127
|
- spec/acceptance/add_numbers_spec.rb
|
128
128
|
- spec/acceptance/around_each_spec.rb
|
129
|
+
- spec/acceptance/fail_spec.rb
|
129
130
|
- spec/acceptance/include_warning_spec.rb
|
130
131
|
- spec/acceptance/log_from_organizer_spec.rb
|
131
132
|
- spec/acceptance/message_localization_spec.rb
|
@@ -136,6 +137,7 @@ files:
|
|
136
137
|
- spec/acceptance/orchestrator/organizer_action_combination_spec.rb
|
137
138
|
- spec/acceptance/orchestrator/reduce_if_spec.rb
|
138
139
|
- spec/acceptance/orchestrator/reduce_until_spec.rb
|
140
|
+
- spec/acceptance/orchestrator/with_callback_spec.rb
|
139
141
|
- spec/acceptance/rollback_spec.rb
|
140
142
|
- spec/acceptance/skip_all_warning_spec.rb
|
141
143
|
- spec/acceptance/testing/context_factory_spec.rb
|
@@ -143,6 +145,7 @@ files:
|
|
143
145
|
- spec/action_expects_and_promises_spec.rb
|
144
146
|
- spec/action_promised_keys_spec.rb
|
145
147
|
- spec/action_spec.rb
|
148
|
+
- spec/context/inspect_spec.rb
|
146
149
|
- spec/context_spec.rb
|
147
150
|
- spec/localization_adapter_spec.rb
|
148
151
|
- spec/organizer/with_reducer_spec.rb
|
@@ -186,6 +189,7 @@ summary: A service skeleton with an emphasis on simplicity
|
|
186
189
|
test_files:
|
187
190
|
- spec/acceptance/add_numbers_spec.rb
|
188
191
|
- spec/acceptance/around_each_spec.rb
|
192
|
+
- spec/acceptance/fail_spec.rb
|
189
193
|
- spec/acceptance/include_warning_spec.rb
|
190
194
|
- spec/acceptance/log_from_organizer_spec.rb
|
191
195
|
- spec/acceptance/message_localization_spec.rb
|
@@ -196,6 +200,7 @@ test_files:
|
|
196
200
|
- spec/acceptance/orchestrator/organizer_action_combination_spec.rb
|
197
201
|
- spec/acceptance/orchestrator/reduce_if_spec.rb
|
198
202
|
- spec/acceptance/orchestrator/reduce_until_spec.rb
|
203
|
+
- spec/acceptance/orchestrator/with_callback_spec.rb
|
199
204
|
- spec/acceptance/rollback_spec.rb
|
200
205
|
- spec/acceptance/skip_all_warning_spec.rb
|
201
206
|
- spec/acceptance/testing/context_factory_spec.rb
|
@@ -203,6 +208,7 @@ test_files:
|
|
203
208
|
- spec/action_expects_and_promises_spec.rb
|
204
209
|
- spec/action_promised_keys_spec.rb
|
205
210
|
- spec/action_spec.rb
|
211
|
+
- spec/context/inspect_spec.rb
|
206
212
|
- spec/context_spec.rb
|
207
213
|
- spec/localization_adapter_spec.rb
|
208
214
|
- spec/organizer/with_reducer_spec.rb
|