light-service 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -5
- data/README.md +62 -8
- data/RELEASES.md +7 -0
- data/lib/light-service/context.rb +17 -7
- data/lib/light-service/orchestrator.rb +2 -2
- data/lib/light-service/organizer/with_reducer_log_decorator.rb +13 -13
- data/lib/light-service/testing.rb +1 -0
- data/lib/light-service/testing/context_factory.rb +43 -0
- data/lib/light-service/version.rb +1 -1
- data/light-service.gemspec +1 -1
- data/spec/acceptance/include_warning_spec.rb +0 -1
- data/spec/acceptance/skip_all_warning_spec.rb +20 -0
- data/spec/acceptance/testing/context_factory_spec.rb +33 -0
- data/spec/action_spec.rb +2 -2
- data/spec/context_spec.rb +6 -6
- data/spec/sample/calculates_tax_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/test_doubles.rb +9 -4
- data/spec/testing/context_factory_spec.rb +40 -0
- metadata +13 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd24b40af28ef32897e621b863de7499a4c34038
|
4
|
+
data.tar.gz: 9ad9f2f66757c15d6d43197ba8e4537eef8df788
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56d906cf2ad3d3e3ba7cdcdcf606120fa3421a0e8b552b0af958bebff23038b5a1bdf3769f2f1e529c57f1fad09a8236e2a1d68374b841983cf7faa506e47669
|
7
|
+
data.tar.gz: 68361c87eb7dd8a731cd28f14bf3e8d71012f5f23106b15f4c18a4402bfd78fd273132ebdef4fe80770ffa938833b825066fe0a244dfcb1d864917193b07b05c
|
data/.travis.yml
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
3
|
rvm:
|
4
|
-
- 2.
|
5
|
-
- 2.1.2
|
4
|
+
- 2.1.8
|
6
5
|
- 2.2.2
|
7
|
-
- 2.3.
|
6
|
+
- 2.3.3
|
7
|
+
- 2.4.0
|
8
8
|
|
9
9
|
before_install:
|
10
10
|
- 'echo ''gem: --no-ri --no-rdoc'' > ~/.gemrc'
|
11
11
|
- gem install bundler
|
12
|
+
- bundle update simplecov
|
12
13
|
- bundle install --path vendor/bundle
|
13
14
|
|
14
15
|
# uncomment this line if your project needs to run something other than `rake`:
|
@@ -23,7 +24,7 @@ gemfile:
|
|
23
24
|
|
24
25
|
matrix:
|
25
26
|
exclude:
|
26
|
-
- rvm: 2.
|
27
|
+
- rvm: 2.1.8
|
27
28
|
gemfile: gemfiles/activesupport_5.gemfile
|
28
|
-
- rvm: 2.
|
29
|
+
- rvm: 2.2.2
|
29
30
|
gemfile: gemfiles/activesupport_5.gemfile
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
![LightService](resources/light-service.png)
|
1
|
+
![LightService](https://raw.githubusercontent.com/adomokos/light-service/master/resources/light-service.png)
|
2
2
|
|
3
3
|
[![Gem Version](https://img.shields.io/gem/v/light-service.svg)](https://rubygems.org/gems/light-service)
|
4
4
|
[![Build Status](https://secure.travis-ci.org/adomokos/light-service.png)](http://travis-ci.org/adomokos/light-service)
|
@@ -62,7 +62,7 @@ and executes them one-by-one. Then you need to create the actions with one metho
|
|
62
62
|
|
63
63
|
This is how the organizer and actions interact with each other:
|
64
64
|
|
65
|
-
![LightService](resources/organizer_and_actions.png)
|
65
|
+
![LightService](https://raw.githubusercontent.com/adomokos/light-service/master/resources/organizer_and_actions.png)
|
66
66
|
|
67
67
|
```ruby
|
68
68
|
class CalculatesTax
|
@@ -158,6 +158,7 @@ simple and elegant Rails code where I told the story of how LightService was ext
|
|
158
158
|
* [Action Rollback](#action-rollback)
|
159
159
|
* [Localizing Messages](#localizing-messages)
|
160
160
|
* [Orchestrators](#orchestrators)
|
161
|
+
* [ContextFactory for Faster Action Testing](#contextfactory-for-faster-action-testing)
|
161
162
|
|
162
163
|
## Stopping the Series of Actions
|
163
164
|
When nothing unexpected happens during the organizer's call, the returned `context` will be successful. Here is how you can check for this:
|
@@ -202,12 +203,12 @@ class SubmitsOrderAction
|
|
202
203
|
end
|
203
204
|
end
|
204
205
|
```
|
205
|
-
![
|
206
|
+
![fail-actions](https://raw.githubusercontent.com/adomokos/light-service/master/resources/fail_actions.png)
|
206
207
|
|
207
208
|
In the example above the organizer called 4 actions. The first 2 actions got executed successfully. The 3rd had a failure, that pushed the context into a failure state and the 4th action was skipped.
|
208
209
|
|
209
210
|
### Skipping the rest of the actions
|
210
|
-
You can skip the rest of the actions by calling `context.
|
211
|
+
You can skip the rest of the actions by calling `context.skip_remaining!`. This behaves very similarly to the above-mentioned `fail!` mechanism, except this will not push the context into a failure state.
|
211
212
|
A good use case for this is executing the first couple of action and based on a check you might not need to execute the rest.
|
212
213
|
Here is an example of how you do it:
|
213
214
|
```ruby
|
@@ -217,12 +218,12 @@ class ChecksOrderStatusAction
|
|
217
218
|
|
218
219
|
executed do |context|
|
219
220
|
if context.order.send_notification?
|
220
|
-
context.
|
221
|
+
context.skip_remaining!("Everything is good, no need to execute the rest of the actions")
|
221
222
|
end
|
222
223
|
end
|
223
224
|
end
|
224
225
|
```
|
225
|
-
![
|
226
|
+
![skip-actions](https://raw.githubusercontent.com/adomokos/light-service/master/resources/skip_actions.png)
|
226
227
|
|
227
228
|
In the example above the organizer called 4 actions. The first 2 actions got executed successfully. The 3rd decided to skip the rest, the 4th action was not invoked. The context was successful.
|
228
229
|
|
@@ -652,14 +653,67 @@ The `reduce` method needs no interaction, it behaves similarly to organizers' `r
|
|
652
653
|
|
653
654
|
`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.
|
654
655
|
|
655
|
-
`reduce_if` will reduce the included organizers and/or actions if the predicate in the
|
656
|
+
`reduce_if` will reduce the included organizers and/or actions if the predicate in the lambda evaluates to true. [This acceptance test](spec/acceptance/orchestrator/reduce_if_spec.rb) describes this functionality.
|
656
657
|
|
657
658
|
`iterate` gives your iteration logic, the symbol you define there has to be in the context as a key. For example. to iterate over items you will use `iterate(:items)` in your steps, the context needs to have `items` as a key, otherwise it will fail. The orchestrator will singularize the collection name and will put the actual item into the context under that name. Remaining with the example above, each element will be accessible by the name `item` for the actions in the `iterate` steps. [This acceptance test](spec/acceptance/orchestrator/iterate_spec.rb) should provide you with an example.
|
658
659
|
|
659
|
-
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
|
660
|
+
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.
|
660
661
|
|
661
662
|
** 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.
|
662
663
|
|
664
|
+
## ContextFactory for Faster Action Testing
|
665
|
+
|
666
|
+
As the complexity of your workflow increases, you will find yourself spending more and more time creating a context (LightService::Context it is) for your action tests. Some of this code can be reused by clever factories, but still, you are using a context that is artificial, and can be different from what the previous actions produced. This is especially true, when you use LightService in ETLs, where you start out with initial data and your actions are mutating its state.
|
667
|
+
|
668
|
+
Here is an example:
|
669
|
+
|
670
|
+
```ruby
|
671
|
+
class SomeOrganizer
|
672
|
+
extend LightService::Organizer
|
673
|
+
|
674
|
+
def self.call(ctx)
|
675
|
+
with(ctx).reduce(actions)
|
676
|
+
end
|
677
|
+
|
678
|
+
def self.actions
|
679
|
+
[
|
680
|
+
ETL::ParsesPayloadAction,
|
681
|
+
ETL::BuildsEnititiesAction,
|
682
|
+
ETL::SetsUpMappingsAction,
|
683
|
+
ETL::SavesEntitiesAction,
|
684
|
+
ETL::SendsNotificationAction
|
685
|
+
]
|
686
|
+
end
|
687
|
+
end
|
688
|
+
```
|
689
|
+
|
690
|
+
You should test your workflow from the outside, invoking the organizer’s `call` method and verify that the data was properly created or updated in your data store. However, sometimes you need to zoom into one action, and setting up the context to test it is tedious work. This is where `ContextFactory` can be helpful.
|
691
|
+
|
692
|
+
In order to test the third action `ETL::SetsUpMappingAction`, you have to have several entities in the context. Depending on the logic you need to write code for, this could be a lot of work. However, by using the `ContextFactory` in your spec, you could easily have a prepared context that’s ready for testing:
|
693
|
+
|
694
|
+
```ruby
|
695
|
+
require 'spec_helper'
|
696
|
+
require 'light-service/testing'
|
697
|
+
|
698
|
+
RSpec.describe ETL::SetsUpMappingsAction do
|
699
|
+
let(:context) do
|
700
|
+
LightService::Testing::ContextFactory
|
701
|
+
.make_from(SomeOrganizer)
|
702
|
+
.for(described_class)
|
703
|
+
.with(:payload => File.read(‘spec/data/payload.json’)
|
704
|
+
end
|
705
|
+
|
706
|
+
it ‘works like it should’ do
|
707
|
+
result = described_class.execute(context)
|
708
|
+
expect(result).to be_success
|
709
|
+
end
|
710
|
+
end
|
711
|
+
```
|
712
|
+
|
713
|
+
This context then can be passed to the action under test, freeing you up from the 20 lines of factory or fixture calls to create a context for your specs.
|
714
|
+
|
715
|
+
In case your organizer has more logic in its `call` method, you could create your own test organizer in your specs like you can see it in this [acceptance test](spec/acceptance/testing/context_factory_spec.rb#L4-L11). This is reusable in all your action tests.
|
716
|
+
|
663
717
|
## Requirements
|
664
718
|
|
665
719
|
This gem requires ruby 2.x
|
data/RELEASES.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
A brief list of new features and changes introduced with the specified version.
|
2
2
|
|
3
|
+
### 0.8.1
|
4
|
+
* Renaming `skip_all!` to [skip_remaining!](https://github.com/adomokos/light-service/pull/103).
|
5
|
+
* Adding [ContextFactory](https://github.com/adomokos/light-service/pull/107) for easier testing.
|
6
|
+
|
7
|
+
### 0.8.0
|
8
|
+
* Adding [orchestrators](https://github.com/adomokos/light-service/pull/99).
|
9
|
+
|
3
10
|
### 0.7.0
|
4
11
|
* Organizers should have a public method [call](https://github.com/adomokos/light-service/pull/98) in preparation of orchestrators.
|
5
12
|
|
@@ -6,6 +6,7 @@ module LightService
|
|
6
6
|
FAILURE = 1
|
7
7
|
end
|
8
8
|
|
9
|
+
# rubocop:disable ClassLength
|
9
10
|
class Context < Hash
|
10
11
|
attr_accessor :message, :error_code, :current_action
|
11
12
|
|
@@ -16,7 +17,7 @@ module LightService
|
|
16
17
|
@outcome = outcome
|
17
18
|
@message = message
|
18
19
|
@error_code = error_code
|
19
|
-
@
|
20
|
+
@skip_remaining = false
|
20
21
|
context.to_hash.each { |k, v| self[k] = v }
|
21
22
|
self
|
22
23
|
end
|
@@ -45,13 +46,13 @@ module LightService
|
|
45
46
|
success? == false
|
46
47
|
end
|
47
48
|
|
48
|
-
def
|
49
|
-
@
|
49
|
+
def skip_remaining?
|
50
|
+
@skip_remaining
|
50
51
|
end
|
51
52
|
|
52
|
-
def
|
53
|
+
def reset_skip_remaining!
|
53
54
|
@message = nil
|
54
|
-
@
|
55
|
+
@skip_remaining = false
|
55
56
|
end
|
56
57
|
|
57
58
|
def outcome
|
@@ -92,12 +93,20 @@ module LightService
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def skip_all!(message = nil)
|
96
|
+
warning_msg = "Using skip_all! has been deprecated, " \
|
97
|
+
"please use `skip_remaining!` instead."
|
98
|
+
ActiveSupport::Deprecation.warn(warning_msg)
|
99
|
+
|
100
|
+
skip_remaining!(message)
|
101
|
+
end
|
102
|
+
|
103
|
+
def skip_remaining!(message = nil)
|
95
104
|
@message = message
|
96
|
-
@
|
105
|
+
@skip_remaining = true
|
97
106
|
end
|
98
107
|
|
99
108
|
def stop_processing?
|
100
|
-
failure? ||
|
109
|
+
failure? || skip_remaining?
|
101
110
|
end
|
102
111
|
|
103
112
|
def define_accessor_methods_for_keys(keys)
|
@@ -130,4 +139,5 @@ module LightService
|
|
130
139
|
self[key] ||= super(key, default_or_block)
|
131
140
|
end
|
132
141
|
end
|
142
|
+
# rubocop:enable ClassLength
|
133
143
|
end
|
@@ -63,14 +63,14 @@ module LightService
|
|
63
63
|
private
|
64
64
|
|
65
65
|
def scoped_reduction(ctx, steps)
|
66
|
-
ctx.
|
66
|
+
ctx.reset_skip_remaining! unless ctx.failure?
|
67
67
|
ctx =
|
68
68
|
if steps.is_a?(Array)
|
69
69
|
reduce(steps, ctx)
|
70
70
|
else
|
71
71
|
reduce([steps], ctx)
|
72
72
|
end
|
73
|
-
ctx.
|
73
|
+
ctx.reset_skip_remaining! unless ctx.failure?
|
74
74
|
|
75
75
|
ctx
|
76
76
|
end
|
@@ -36,8 +36,8 @@ module LightService
|
|
36
36
|
next context
|
37
37
|
end
|
38
38
|
|
39
|
-
if
|
40
|
-
|
39
|
+
if skip_remaining?(context)
|
40
|
+
write_skip_remaining_log(context, action)
|
41
41
|
next context
|
42
42
|
end
|
43
43
|
|
@@ -56,17 +56,17 @@ module LightService
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def log_expects(action)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
return unless defined?(action.expects) && action.expects.any?
|
60
|
+
|
61
|
+
logger.info("[LightService] - expects: " \
|
62
|
+
"#{extract_keys(action.expects)}")
|
63
63
|
end
|
64
64
|
|
65
65
|
def log_promises(action)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
return unless defined?(action.promises) && action.promises.any?
|
67
|
+
|
68
|
+
logger.info("[LightService] - promises: " \
|
69
|
+
"#{extract_keys(action.promises)}")
|
70
70
|
end
|
71
71
|
|
72
72
|
def extract_keys(keys)
|
@@ -83,11 +83,11 @@ module LightService
|
|
83
83
|
@logged = true
|
84
84
|
end
|
85
85
|
|
86
|
-
def
|
87
|
-
context.respond_to?(:
|
86
|
+
def skip_remaining?(context)
|
87
|
+
context.respond_to?(:skip_remaining?) && context.skip_remaining?
|
88
88
|
end
|
89
89
|
|
90
|
-
def
|
90
|
+
def write_skip_remaining_log(context, action)
|
91
91
|
msg = "[LightService] - ;-) <#{action}> has decided " \
|
92
92
|
"to skip the rest of the actions"
|
93
93
|
logger.info(msg)
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'light-service/testing/context_factory'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module LightService
|
2
|
+
module Testing
|
3
|
+
class ContextFactory
|
4
|
+
class ContextFactoryOrganizer
|
5
|
+
extend LightService::Organizer
|
6
|
+
class << self
|
7
|
+
attr_accessor :actions
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.call(ctx)
|
11
|
+
with(ctx).reduce(actions)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :organizer
|
16
|
+
|
17
|
+
def self.make_from(organizer)
|
18
|
+
new(organizer)
|
19
|
+
end
|
20
|
+
|
21
|
+
def for(action)
|
22
|
+
ContextFactoryOrganizer.actions = find_up_to(action)
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def with(ctx)
|
27
|
+
ContextFactoryOrganizer.call(ctx)
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(organizer)
|
31
|
+
@organizer = organizer
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_up_to(action)
|
35
|
+
original_actions = organizer.actions
|
36
|
+
|
37
|
+
original_actions.take_while do |current_action|
|
38
|
+
current_action != action
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/light-service.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.add_dependency("activesupport", ">= 3.0")
|
20
20
|
|
21
21
|
gem.add_development_dependency("rspec", "~> 3.0")
|
22
|
-
gem.add_development_dependency("simplecov", "~> 0.
|
22
|
+
gem.add_development_dependency("simplecov", "~> 0.14.1")
|
23
23
|
gem.add_development_dependency("rubocop", "~> 0.42")
|
24
24
|
gem.add_development_dependency("pry", "~> 0.10")
|
25
25
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "skip_all! has been deprecated" do
|
4
|
+
it "is now skip_remaining!" do
|
5
|
+
class SkipAllDeprecatedAction
|
6
|
+
extend LightService::Action
|
7
|
+
|
8
|
+
executed do |ctx|
|
9
|
+
ctx.skip_all!("No need to execute other actions.")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
expected_msg = "Using skip_all! has been deprecated, " \
|
14
|
+
"please use `skip_remaining!` instead."
|
15
|
+
expect(ActiveSupport::Deprecation).to receive(:warn)
|
16
|
+
.with(expected_msg)
|
17
|
+
|
18
|
+
SkipAllDeprecatedAction.execute
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_doubles'
|
3
|
+
|
4
|
+
class AdditionOrganizerContextFactory
|
5
|
+
def self.make_for(action, number)
|
6
|
+
number += 3 # You can add more logic to prepare your context
|
7
|
+
|
8
|
+
LightService::Testing::ContextFactory
|
9
|
+
.make_from(TestDoubles::AdditionOrganizer)
|
10
|
+
.for(action)
|
11
|
+
.with(:number => number)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
RSpec.describe TestDoubles::AddsThreeAction do
|
16
|
+
it "creates a context for the action with ContextFactory wrapper" do
|
17
|
+
context =
|
18
|
+
AdditionOrganizerContextFactory
|
19
|
+
.make_for(TestDoubles::AddsThreeAction, 1)
|
20
|
+
|
21
|
+
expect(context.number).to eq(7)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "creates a context for the action using the ContextFactory" do
|
25
|
+
context =
|
26
|
+
LightService::Testing::ContextFactory
|
27
|
+
.make_from(TestDoubles::AdditionOrganizer)
|
28
|
+
.for(TestDoubles::AddsThreeAction)
|
29
|
+
.with(:number => 4) # Context is a "glorified" hash
|
30
|
+
|
31
|
+
expect(context.number).to eq(7)
|
32
|
+
end
|
33
|
+
end
|
data/spec/action_spec.rb
CHANGED
@@ -43,7 +43,7 @@ describe LightService::Action do
|
|
43
43
|
|
44
44
|
context "when the action context skips all" do
|
45
45
|
it "returns immediately" do
|
46
|
-
context.
|
46
|
+
context.skip_remaining!
|
47
47
|
|
48
48
|
TestDoubles::AddsTwoActionWithFetch.execute(context)
|
49
49
|
|
@@ -54,7 +54,7 @@ describe LightService::Action do
|
|
54
54
|
TestDoubles::AddsTwoActionWithFetch.execute(context)
|
55
55
|
expect(context.to_hash).to eq(:number => 2)
|
56
56
|
|
57
|
-
context.
|
57
|
+
context.skip_remaining!
|
58
58
|
|
59
59
|
TestDoubles::AddsTwoActionWithFetch.execute(context)
|
60
60
|
# Since the action was skipped, the number remains 2
|
data/spec/context_spec.rb
CHANGED
@@ -50,10 +50,10 @@ describe LightService::Context do
|
|
50
50
|
expect(context).to be_failure
|
51
51
|
end
|
52
52
|
|
53
|
-
it "can be asked for
|
54
|
-
context.
|
53
|
+
it "can be asked for skip_remaining?" do
|
54
|
+
context.skip_remaining!
|
55
55
|
|
56
|
-
expect(context.
|
56
|
+
expect(context.skip_remaining?).to be_truthy
|
57
57
|
end
|
58
58
|
|
59
59
|
it "can be pushed into a SUCCESS state" do
|
@@ -129,9 +129,9 @@ describe LightService::Context do
|
|
129
129
|
end
|
130
130
|
|
131
131
|
it "can set a flag to skip all subsequent actions" do
|
132
|
-
context.
|
132
|
+
context.skip_remaining!
|
133
133
|
|
134
|
-
expect(context).to
|
134
|
+
expect(context).to be_skip_remaining
|
135
135
|
end
|
136
136
|
|
137
137
|
context "stopping additional processing in an action" do
|
@@ -141,7 +141,7 @@ describe LightService::Context do
|
|
141
141
|
end
|
142
142
|
|
143
143
|
it "flags processing to stop when remaining actions should be skipped" do
|
144
|
-
context.
|
144
|
+
context.skip_remaining!
|
145
145
|
expect(context.stop_processing?).to be_truthy
|
146
146
|
end
|
147
147
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/test_doubles.rb
CHANGED
@@ -22,7 +22,7 @@ module TestDoubles
|
|
22
22
|
|
23
23
|
class SkipAllAction
|
24
24
|
extend LightService::Action
|
25
|
-
executed(&:
|
25
|
+
executed(&:skip_remaining!)
|
26
26
|
end
|
27
27
|
|
28
28
|
class FailureAction
|
@@ -161,7 +161,8 @@ module TestDoubles
|
|
161
161
|
context[:latte] = "#{context.coffee} - with lots of #{context.milk}"
|
162
162
|
|
163
163
|
if context.milk == "5%"
|
164
|
-
|
164
|
+
msg = "Can't make a latte with a fatty milk like that!"
|
165
|
+
context.skip_remaining!(msg)
|
165
166
|
next context
|
166
167
|
end
|
167
168
|
end
|
@@ -223,11 +224,15 @@ module TestDoubles
|
|
223
224
|
extend LightService::Organizer
|
224
225
|
|
225
226
|
def self.call(number)
|
226
|
-
with(:number => number).reduce(
|
227
|
+
with(:number => number).reduce(actions)
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.actions
|
231
|
+
[
|
227
232
|
AddsOneAction,
|
228
233
|
AddsTwoAction,
|
229
234
|
AddsThreeAction
|
230
|
-
|
235
|
+
]
|
231
236
|
end
|
232
237
|
end
|
233
238
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_doubles'
|
3
|
+
|
4
|
+
describe 'ContextFactory - used with AdditionOrganizer' do
|
5
|
+
context 'when called with the first action' do
|
6
|
+
it 'does not alter the context' do
|
7
|
+
ctx =
|
8
|
+
LightService::Testing::ContextFactory
|
9
|
+
.make_from(TestDoubles::AdditionOrganizer)
|
10
|
+
.for(TestDoubles::AddsOneAction)
|
11
|
+
.with(:number => 1)
|
12
|
+
|
13
|
+
expect(ctx[:number]).to eq(1)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when called with the second action' do
|
18
|
+
it 'adds one to the number provided' do
|
19
|
+
ctx =
|
20
|
+
LightService::Testing::ContextFactory
|
21
|
+
.make_from(TestDoubles::AdditionOrganizer)
|
22
|
+
.for(TestDoubles::AddsTwoAction)
|
23
|
+
.with(:number => 1)
|
24
|
+
|
25
|
+
expect(ctx.number).to eq(2)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when called with third action' do
|
30
|
+
it 'creates a context up-to the action defined' do
|
31
|
+
ctx =
|
32
|
+
LightService::Testing::ContextFactory
|
33
|
+
.make_from(TestDoubles::AdditionOrganizer)
|
34
|
+
.for(TestDoubles::AddsThreeAction)
|
35
|
+
.with(:number => 1)
|
36
|
+
|
37
|
+
expect(ctx.number).to eq(4)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
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.1
|
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-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.14.1
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.14.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rubocop
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,6 +116,8 @@ files:
|
|
116
116
|
- lib/light-service/organizer/with_reducer.rb
|
117
117
|
- lib/light-service/organizer/with_reducer_factory.rb
|
118
118
|
- lib/light-service/organizer/with_reducer_log_decorator.rb
|
119
|
+
- lib/light-service/testing.rb
|
120
|
+
- lib/light-service/testing/context_factory.rb
|
119
121
|
- lib/light-service/version.rb
|
120
122
|
- light-service.gemspec
|
121
123
|
- resources/fail_actions.png
|
@@ -135,6 +137,8 @@ files:
|
|
135
137
|
- spec/acceptance/orchestrator/reduce_if_spec.rb
|
136
138
|
- spec/acceptance/orchestrator/reduce_until_spec.rb
|
137
139
|
- spec/acceptance/rollback_spec.rb
|
140
|
+
- spec/acceptance/skip_all_warning_spec.rb
|
141
|
+
- spec/acceptance/testing/context_factory_spec.rb
|
138
142
|
- spec/action_expected_keys_spec.rb
|
139
143
|
- spec/action_expects_and_promises_spec.rb
|
140
144
|
- spec/action_promised_keys_spec.rb
|
@@ -154,6 +158,7 @@ files:
|
|
154
158
|
- spec/sample/tax/provides_free_shipping_action.rb
|
155
159
|
- spec/spec_helper.rb
|
156
160
|
- spec/test_doubles.rb
|
161
|
+
- spec/testing/context_factory_spec.rb
|
157
162
|
homepage: https://github.com/adomokos/light-service
|
158
163
|
licenses:
|
159
164
|
- MIT
|
@@ -174,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
179
|
version: '0'
|
175
180
|
requirements: []
|
176
181
|
rubyforge_project:
|
177
|
-
rubygems_version: 2.
|
182
|
+
rubygems_version: 2.6.8
|
178
183
|
signing_key:
|
179
184
|
specification_version: 4
|
180
185
|
summary: A service skeleton with an emphasis on simplicity
|
@@ -192,6 +197,8 @@ test_files:
|
|
192
197
|
- spec/acceptance/orchestrator/reduce_if_spec.rb
|
193
198
|
- spec/acceptance/orchestrator/reduce_until_spec.rb
|
194
199
|
- spec/acceptance/rollback_spec.rb
|
200
|
+
- spec/acceptance/skip_all_warning_spec.rb
|
201
|
+
- spec/acceptance/testing/context_factory_spec.rb
|
195
202
|
- spec/action_expected_keys_spec.rb
|
196
203
|
- spec/action_expects_and_promises_spec.rb
|
197
204
|
- spec/action_promised_keys_spec.rb
|
@@ -211,3 +218,4 @@ test_files:
|
|
211
218
|
- spec/sample/tax/provides_free_shipping_action.rb
|
212
219
|
- spec/spec_helper.rb
|
213
220
|
- spec/test_doubles.rb
|
221
|
+
- spec/testing/context_factory_spec.rb
|