light-service 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/project-build.yml +1 -1
- data/.rubocop.yml +117 -3
- data/README.md +9 -6
- data/RELEASES.md +6 -0
- data/lib/generators/light_service/generator_utils.rb +0 -2
- data/lib/light-service/context/key_verifier.rb +4 -2
- data/lib/light-service/context.rb +6 -9
- data/lib/light-service/errors.rb +4 -0
- data/lib/light-service/orchestrator.rb +1 -1
- data/lib/light-service/organizer/reduce_case.rb +48 -0
- data/lib/light-service/organizer/with_reducer.rb +6 -8
- data/lib/light-service/organizer/with_reducer_log_decorator.rb +2 -2
- data/lib/light-service/organizer.rb +4 -0
- data/lib/light-service/testing/context_factory.rb +2 -0
- data/lib/light-service/version.rb +1 -1
- data/lib/light-service.rb +1 -0
- data/light-service.gemspec +2 -2
- data/spec/acceptance/after_actions_spec.rb +3 -9
- data/spec/acceptance/before_actions_spec.rb +3 -9
- data/spec/acceptance/organizer/reduce_case_spec.rb +53 -0
- data/spec/acceptance/organizer/reduce_if_spec.rb +2 -0
- data/spec/context/inspect_spec.rb +5 -21
- data/spec/context_spec.rb +1 -1
- data/spec/lib/generators/action_generator_advanced_spec.rb +1 -1
- data/spec/lib/generators/action_generator_simple_spec.rb +1 -1
- data/spec/lib/generators/organizer_generator_advanced_spec.rb +1 -1
- data/spec/lib/generators/organizer_generator_simple_spec.rb +1 -1
- data/spec/sample/calculates_tax_spec.rb +0 -1
- data/spec/sample/looks_up_tax_percentage_action_spec.rb +3 -1
- data/spec/test_doubles.rb +11 -5
- metadata +12 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d713cae791654b29dfc20e3cbffe16094badcc49b8221ccff0765dbd479b40c2
|
4
|
+
data.tar.gz: 1e2d61c708b70466a904f8e07aa4ba4aa383bd405342efeb51014286209b2ebb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1d3f210ecbc0430bae9f573a945d599fcbf36a4acf26f5a49b9997c735dea8eba14f367e7c7a639d5cb8ff458feb5945ecd0078986140f763bb17b967947389
|
7
|
+
data.tar.gz: d2715e9fe494e4163efd52b4e2ce32011c3e275e8bdd1ba45e8ef1c2aff8705f2d2c994e02de0b8e20896ea5067ec75fb6a7ca333ac7f9b333544fcd82d2c7ca
|
@@ -13,7 +13,7 @@ jobs:
|
|
13
13
|
fail-fast: false
|
14
14
|
matrix:
|
15
15
|
os: [ubuntu, macos]
|
16
|
-
ruby: [2.
|
16
|
+
ruby: [2.7.4, 3.0.2, 3.1.0]
|
17
17
|
gemfile: [activesupport_5, activesupport_6]
|
18
18
|
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
19
19
|
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
|
data/.rubocop.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require: rubocop-performance
|
1
|
+
# require: rubocop-performance
|
2
2
|
|
3
3
|
AllCops:
|
4
|
-
TargetRubyVersion: 2.
|
4
|
+
TargetRubyVersion: 2.7
|
5
5
|
Exclude:
|
6
6
|
- 'lib/light-service.rb'
|
7
7
|
- 'vendor/bundle/**/*'
|
@@ -47,8 +47,122 @@ Metrics/BlockLength:
|
|
47
47
|
Exclude:
|
48
48
|
- 'spec/**/*.rb'
|
49
49
|
|
50
|
-
Layout/
|
50
|
+
Layout/TrailingEmptyLines:
|
51
51
|
Enabled: false
|
52
52
|
|
53
53
|
Layout/EndOfLine:
|
54
54
|
EnforcedStyle: lf
|
55
|
+
|
56
|
+
Lint/ConstantDefinitionInBlock:
|
57
|
+
Exclude:
|
58
|
+
- 'spec/**/*.rb'
|
59
|
+
|
60
|
+
Lint/EmptyClass:
|
61
|
+
Exclude:
|
62
|
+
- 'spec/**/*.rb'
|
63
|
+
|
64
|
+
# Defaults after the Rubocop upgrade
|
65
|
+
Gemspec/DateAssignment: # new in 1.10
|
66
|
+
Enabled: true
|
67
|
+
Layout/LineEndStringConcatenationIndentation: # new in 1.18
|
68
|
+
Enabled: true
|
69
|
+
Layout/SpaceBeforeBrackets: # new in 1.7
|
70
|
+
Enabled: true
|
71
|
+
Lint/AmbiguousAssignment: # new in 1.7
|
72
|
+
Enabled: true
|
73
|
+
Lint/AmbiguousOperatorPrecedence: # new in 1.21
|
74
|
+
Enabled: true
|
75
|
+
Lint/AmbiguousRange: # new in 1.19
|
76
|
+
Enabled: true
|
77
|
+
Lint/DeprecatedConstants: # new in 1.8
|
78
|
+
Enabled: true
|
79
|
+
Lint/DuplicateBranch: # new in 1.3
|
80
|
+
Enabled: true
|
81
|
+
Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
|
82
|
+
Enabled: true
|
83
|
+
Lint/EmptyBlock: # new in 1.1
|
84
|
+
Enabled: true
|
85
|
+
Lint/EmptyClass: # new in 1.3
|
86
|
+
Enabled: true
|
87
|
+
Lint/EmptyInPattern: # new in 1.16
|
88
|
+
Enabled: true
|
89
|
+
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
|
90
|
+
Enabled: true
|
91
|
+
Lint/LambdaWithoutLiteralBlock: # new in 1.8
|
92
|
+
Enabled: true
|
93
|
+
Lint/NoReturnInBeginEndBlocks: # new in 1.2
|
94
|
+
Enabled: true
|
95
|
+
Lint/NumberedParameterAssignment: # new in 1.9
|
96
|
+
Enabled: true
|
97
|
+
Lint/OrAssignmentToConstant: # new in 1.9
|
98
|
+
Enabled: true
|
99
|
+
Lint/RedundantDirGlobSort: # new in 1.8
|
100
|
+
Enabled: true
|
101
|
+
Lint/SymbolConversion: # new in 1.9
|
102
|
+
Enabled: true
|
103
|
+
Lint/ToEnumArguments: # new in 1.1
|
104
|
+
Enabled: true
|
105
|
+
Lint/TripleQuotes: # new in 1.9
|
106
|
+
Enabled: true
|
107
|
+
Lint/UnexpectedBlockArity: # new in 1.5
|
108
|
+
Enabled: true
|
109
|
+
Lint/UnmodifiedReduceAccumulator: # new in 1.1
|
110
|
+
Enabled: true
|
111
|
+
Style/ArgumentsForwarding: # new in 1.1
|
112
|
+
Enabled: true
|
113
|
+
Style/CollectionCompact: # new in 1.2
|
114
|
+
Enabled: true
|
115
|
+
Style/DocumentDynamicEvalDefinition: # new in 1.1
|
116
|
+
Enabled: true
|
117
|
+
Style/EndlessMethod: # new in 1.8
|
118
|
+
Enabled: true
|
119
|
+
Style/HashConversion: # new in 1.10
|
120
|
+
Enabled: true
|
121
|
+
Style/HashExcept: # new in 1.7
|
122
|
+
Enabled: true
|
123
|
+
Style/IfWithBooleanLiteralBranches: # new in 1.9
|
124
|
+
Enabled: true
|
125
|
+
Style/InPatternThen: # new in 1.16
|
126
|
+
Enabled: true
|
127
|
+
Style/MultilineInPatternThen: # new in 1.16
|
128
|
+
Enabled: true
|
129
|
+
Style/NegatedIfElseCondition: # new in 1.2
|
130
|
+
Enabled: true
|
131
|
+
Style/NilLambda: # new in 1.3
|
132
|
+
Enabled: true
|
133
|
+
Style/QuotedSymbols: # new in 1.16
|
134
|
+
Enabled: true
|
135
|
+
Style/RedundantArgument: # new in 1.4
|
136
|
+
Enabled: true
|
137
|
+
Style/RedundantSelfAssignmentBranch: # new in 1.19
|
138
|
+
Enabled: true
|
139
|
+
Style/StringChars: # new in 1.12
|
140
|
+
Enabled: true
|
141
|
+
Style/SwapValues: # new in 1.1
|
142
|
+
Enabled: true
|
143
|
+
Gemspec/RequireMFA: # new in 1.23
|
144
|
+
Enabled: true
|
145
|
+
Lint/RequireRelativeSelfPath: # new in 1.22
|
146
|
+
Enabled: true
|
147
|
+
Lint/UselessRuby2Keywords: # new in 1.23
|
148
|
+
Enabled: true
|
149
|
+
Naming/BlockForwarding: # new in 1.24
|
150
|
+
Enabled: true
|
151
|
+
Security/IoMethods: # new in 1.22
|
152
|
+
Enabled: true
|
153
|
+
Style/FileRead: # new in 1.24
|
154
|
+
Enabled: true
|
155
|
+
Style/FileWrite: # new in 1.24
|
156
|
+
Enabled: true
|
157
|
+
Style/MapToHash: # new in 1.24
|
158
|
+
Enabled: true
|
159
|
+
Style/NestedFileDirname: # new in 1.26
|
160
|
+
Enabled: true
|
161
|
+
Style/NumberedParameters: # new in 1.22
|
162
|
+
Enabled: true
|
163
|
+
Style/NumberedParametersLimit: # new in 1.22
|
164
|
+
Enabled: true
|
165
|
+
Style/OpenStructUse: # new in 1.23
|
166
|
+
Enabled: true
|
167
|
+
Style/SelectByRegexp: # new in 1.22
|
168
|
+
Enabled: true
|
data/README.md
CHANGED
@@ -959,16 +959,17 @@ end
|
|
959
959
|
|
960
960
|
This code is much easier to reason about, it's less noisy and it captures the goal of LightService well: simple, declarative code that's easy to understand.
|
961
961
|
|
962
|
-
The
|
962
|
+
The 9 different orchestrator constructs an organizer can have:
|
963
963
|
|
964
964
|
1. `reduce_until`
|
965
965
|
2. `reduce_if`
|
966
966
|
3. `reduce_if_else`
|
967
|
-
4. `
|
968
|
-
5. `
|
969
|
-
6. `
|
970
|
-
7. `
|
971
|
-
8. `
|
967
|
+
4. `reduce_case`
|
968
|
+
5. `iterate`
|
969
|
+
6. `execute`
|
970
|
+
7. `with_callback`
|
971
|
+
8. `add_to_context`
|
972
|
+
9. `add_aliases`
|
972
973
|
|
973
974
|
`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/organizer/reduce_until_spec.rb) to see how it's used.
|
974
975
|
|
@@ -976,6 +977,8 @@ The 7 different orchestrator constructs an organizer can have:
|
|
976
977
|
|
977
978
|
`reduce_if_else` takes three arguments, a condition lambda, a first set of "if true" steps, and a second set of "if false" steps. If the lambda evaluates to true, the "if true" steps are executed, otherwise the "else steps" are executed. [This acceptance test](spec/acceptance/organizer/reduce_if_else_spec.rb) describes this functionality.
|
978
979
|
|
980
|
+
`reduce_case` behaves like a Ruby `case` statement. The first parameter `value` is the key of the value within the context that will be worked with. The second parameter `when` is a hash where the keys are conditional values and the values are steps to take if the condition matches. The final parameter `else` is a set of steps to take if no conditions within the `when` parameter are met. [This acceptance test](spec/acceptance/organizer/reduce_case_spec.rb) describes this functionality.
|
981
|
+
|
979
982
|
`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 organizer 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/organizer/iterate_spec.rb) should provide you with an example.
|
980
983
|
|
981
984
|
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/organizer/execute_spec.rb) describes how you can use it.
|
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.18.0
|
4
|
+
* [Remove Ruby 2.6, add 3.1 to build](https://github.com/adomokos/light-service/pull/233)
|
5
|
+
* [Add reduce_when](https://github.com/adomokos/light-service/pull/232)
|
6
|
+
* [Drop Ruby 2.5 version support, add 3.0 build](https://github.com/adomokos/light-service/pull/225)
|
7
|
+
* [Support for named argument in Ruby](https://github.com/adomokos/light-service/pull/224)
|
8
|
+
|
3
9
|
### 0.17.0
|
4
10
|
* [Fix around_action hook for nested actions](https://github.com/adomokos/light-service/pull/217)
|
5
11
|
* [Add ReduceIfElse macro](https://github.com/adomokos/light-service/pull/218)
|
@@ -25,7 +25,6 @@ module LightService
|
|
25
25
|
options.tests? && test_framework_supported?
|
26
26
|
end
|
27
27
|
|
28
|
-
# rubocop:disable Metrics/AbcSize
|
29
28
|
def create_required_gen_vals_from(name)
|
30
29
|
path_parts = name.underscore.split('/')
|
31
30
|
|
@@ -39,7 +38,6 @@ module LightService
|
|
39
38
|
:full_class_name => name.classify
|
40
39
|
}
|
41
40
|
end
|
42
|
-
# rubocop:enable Metrics/AbcSize
|
43
41
|
end
|
44
42
|
end
|
45
43
|
end
|
@@ -24,7 +24,7 @@ module LightService
|
|
24
24
|
|
25
25
|
def error_message
|
26
26
|
"#{type_name} #{format_keys(keys_not_found(keys))} " \
|
27
|
-
|
27
|
+
"to be in the context during #{action}"
|
28
28
|
end
|
29
29
|
|
30
30
|
def throw_error_predicate(_keys)
|
@@ -95,7 +95,7 @@ module LightService
|
|
95
95
|
|
96
96
|
def error_message
|
97
97
|
"promised or expected keys cannot be a " \
|
98
|
-
|
98
|
+
"reserved key: [#{format_keys(violated_keys)}]"
|
99
99
|
end
|
100
100
|
|
101
101
|
def keys
|
@@ -116,9 +116,11 @@ module LightService
|
|
116
116
|
end
|
117
117
|
|
118
118
|
class ReservedKeysViaOrganizerVerifier < ReservedKeysVerifier
|
119
|
+
# rubocop:disable Lint/MissingSuper
|
119
120
|
def initialize(context_data)
|
120
121
|
@context = LightService::Context.make(context_data)
|
121
122
|
end
|
123
|
+
# rubocop:enable Lint/MissingSuper
|
122
124
|
|
123
125
|
def violated_keys
|
124
126
|
context.keys.map(&:to_sym) & reserved_keys
|
@@ -6,11 +6,12 @@ module LightService
|
|
6
6
|
FAILURE = 1
|
7
7
|
end
|
8
8
|
|
9
|
-
# rubocop:disable ClassLength
|
9
|
+
# rubocop:disable Metrics/ClassLength
|
10
10
|
class Context < Hash
|
11
11
|
attr_accessor :message, :error_code, :current_action, :around_actions,
|
12
12
|
:organized_by
|
13
13
|
|
14
|
+
# rubocop:disable Metrics/ParameterLists, Lint/MissingSuper
|
14
15
|
def initialize(context = {},
|
15
16
|
outcome = Outcomes::SUCCESS,
|
16
17
|
message = '',
|
@@ -22,6 +23,7 @@ module LightService
|
|
22
23
|
|
23
24
|
context.to_hash.each { |k, v| self[k] = v }
|
24
25
|
end
|
26
|
+
# rubocop:enable Metrics/ParameterLists, Lint/MissingSuper
|
25
27
|
|
26
28
|
def self.make(context = {})
|
27
29
|
unless context.is_a?(Hash) || context.is_a?(LightService::Context)
|
@@ -152,13 +154,8 @@ module LightService
|
|
152
154
|
end
|
153
155
|
|
154
156
|
def inspect
|
155
|
-
"#{self.class}(#{self}, " \
|
156
|
-
|
157
|
-
+ "message: #{check_nil(message)}, " \
|
158
|
-
+ "error_code: #{check_nil(error_code)}, " \
|
159
|
-
+ "skip_remaining: #{@skip_remaining}, " \
|
160
|
-
+ "aliases: #{@aliases}" \
|
161
|
-
+ ")"
|
157
|
+
"#{self.class}(#{self}, success: #{success?}, message: #{check_nil(message)}, error_code: " \
|
158
|
+
"#{check_nil(error_code)}, skip_remaining: #{@skip_remaining}, aliases: #{@aliases})"
|
162
159
|
end
|
163
160
|
|
164
161
|
private
|
@@ -169,5 +166,5 @@ module LightService
|
|
169
166
|
"'#{value}'"
|
170
167
|
end
|
171
168
|
end
|
172
|
-
# rubocop:enable ClassLength
|
169
|
+
# rubocop:enable Metrics/ClassLength
|
173
170
|
end
|
data/lib/light-service/errors.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
module LightService
|
2
2
|
class FailWithRollbackError < StandardError; end
|
3
|
+
|
3
4
|
class ExpectedKeysNotInContextError < StandardError; end
|
5
|
+
|
4
6
|
class PromisedKeysNotInContextError < StandardError; end
|
7
|
+
|
5
8
|
class ReservedKeysInContextError < StandardError; end
|
9
|
+
|
6
10
|
class UnusableExpectKeyDefaultError < StandardError; end
|
7
11
|
end
|
@@ -115,7 +115,7 @@ module LightService
|
|
115
115
|
|
116
116
|
def issue_deprecation_warning_for(method_name)
|
117
117
|
msg = "`Orchestrator##{method_name}` is DEPRECATED and will be " \
|
118
|
-
|
118
|
+
"removed, please switch to `Organizer##{method_name} instead. "
|
119
119
|
ActiveSupport::Deprecation.warn(msg)
|
120
120
|
end
|
121
121
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module LightService
|
2
|
+
module Organizer
|
3
|
+
class ReduceCase
|
4
|
+
extend ScopedReducable
|
5
|
+
|
6
|
+
class Arguments
|
7
|
+
attr_reader :value, :when, :else
|
8
|
+
|
9
|
+
def initialize(**args)
|
10
|
+
validate_arguments(**args)
|
11
|
+
@value = args[:value]
|
12
|
+
@when = args[:when]
|
13
|
+
@else = args[:else]
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# rubocop:disable Style/MultilineIfModifier
|
19
|
+
def validate_arguments(**args)
|
20
|
+
raise(
|
21
|
+
ArgumentError,
|
22
|
+
"Expected keyword arguments: [:value, :when, :else]. Given: #{args.keys}"
|
23
|
+
) unless args.keys.intersection(mandatory_arguments).count == mandatory_arguments.count
|
24
|
+
end
|
25
|
+
# rubocop:enable Style/MultilineIfModifier
|
26
|
+
|
27
|
+
def mandatory_arguments
|
28
|
+
%i[value when else]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.run(organizer, **args)
|
33
|
+
arguments = Arguments.new(**args)
|
34
|
+
|
35
|
+
lambda do |ctx|
|
36
|
+
return ctx if ctx.stop_processing?
|
37
|
+
|
38
|
+
matched_case = arguments.when.keys.find { |k| k.eql?(ctx[arguments.value]) }
|
39
|
+
steps = arguments.when[matched_case] || arguments.else
|
40
|
+
|
41
|
+
ctx = scoped_reduce(organizer, ctx, steps)
|
42
|
+
|
43
|
+
ctx
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -34,14 +34,12 @@ module LightService
|
|
34
34
|
actions.flatten!
|
35
35
|
|
36
36
|
actions.each_with_object(context) do |action, current_context|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
yield(current_context, action) if block_given?
|
44
|
-
end
|
37
|
+
invoke_action(current_context, action)
|
38
|
+
rescue FailWithRollbackError
|
39
|
+
reduce_rollback(actions)
|
40
|
+
ensure
|
41
|
+
# For logging
|
42
|
+
yield(current_context, action) if block_given?
|
45
43
|
end
|
46
44
|
end
|
47
45
|
|
@@ -5,7 +5,7 @@ module LightService
|
|
5
5
|
|
6
6
|
alias logged? logged
|
7
7
|
|
8
|
-
def initialize(organizer, decorated: WithReducer.new
|
8
|
+
def initialize(organizer, logger:, decorated: WithReducer.new)
|
9
9
|
@decorated = decorated
|
10
10
|
@organizer = organizer
|
11
11
|
|
@@ -22,7 +22,7 @@ module LightService
|
|
22
22
|
|
23
23
|
logger.info do
|
24
24
|
"[LightService] - keys in context: " \
|
25
|
-
|
25
|
+
"#{extract_keys(decorated.context.keys)}"
|
26
26
|
end
|
27
27
|
self
|
28
28
|
end
|
@@ -26,11 +26,13 @@ module LightService
|
|
26
26
|
|
27
27
|
# More than one arguments can be passed to the
|
28
28
|
# Organizer's #call method
|
29
|
+
# rubocop:disable Style/ArgumentsForwarding
|
29
30
|
def with(*args, &block)
|
30
31
|
catch(:return_ctx_from_execution) do
|
31
32
|
@organizer.call(*args, &block)
|
32
33
|
end
|
33
34
|
end
|
35
|
+
# rubocop:enable Style/ArgumentsForwarding
|
34
36
|
|
35
37
|
def initialize(organizer)
|
36
38
|
@organizer = organizer
|
data/lib/light-service.rb
CHANGED
@@ -15,6 +15,7 @@ require 'light-service/organizer/with_reducer_factory'
|
|
15
15
|
require 'light-service/organizer/reduce_if'
|
16
16
|
require 'light-service/organizer/reduce_if_else'
|
17
17
|
require 'light-service/organizer/reduce_until'
|
18
|
+
require 'light-service/organizer/reduce_case'
|
18
19
|
require 'light-service/organizer/iterate'
|
19
20
|
require 'light-service/organizer/execute'
|
20
21
|
require 'light-service/organizer/with_callback'
|
data/light-service.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.name = "light-service"
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
gem.version = LightService::VERSION
|
18
|
-
gem.required_ruby_version = '>= 2.
|
18
|
+
gem.required_ruby_version = '>= 2.6.0'
|
19
19
|
|
20
20
|
gem.add_runtime_dependency("activesupport", ">= 4.0.0")
|
21
21
|
|
@@ -25,7 +25,7 @@ Gem::Specification.new do |gem|
|
|
25
25
|
gem.add_development_dependency("rspec", "~> 3.0")
|
26
26
|
gem.add_development_dependency("simplecov", "~> 0.17")
|
27
27
|
gem.add_development_dependency("codecov", "~> 0.1")
|
28
|
-
gem.add_development_dependency("rubocop", "~>
|
28
|
+
gem.add_development_dependency("rubocop", "~> 1.26.0")
|
29
29
|
gem.add_development_dependency("rubocop-performance", "~> 1.2.0")
|
30
30
|
gem.add_development_dependency("pry", "~> 0.12.2")
|
31
31
|
end
|
@@ -34,14 +34,10 @@ RSpec.describe 'Action after_actions' do
|
|
34
34
|
class AdditionOrganizer
|
35
35
|
extend LightService::Organizer
|
36
36
|
after_actions (lambda do |ctx|
|
37
|
-
if ctx.current_action == TestDoubles::AddsOneAction
|
38
|
-
ctx.number -= 2
|
39
|
-
end
|
37
|
+
ctx.number -= 2 if ctx.current_action == TestDoubles::AddsOneAction
|
40
38
|
end),
|
41
39
|
(lambda do |ctx|
|
42
|
-
if ctx.current_action == TestDoubles::AddsThreeAction
|
43
|
-
ctx.number -= 3
|
44
|
-
end
|
40
|
+
ctx.number -= 3 if ctx.current_action == TestDoubles::AddsThreeAction
|
45
41
|
end)
|
46
42
|
|
47
43
|
def self.call(number)
|
@@ -69,9 +65,7 @@ RSpec.describe 'Action after_actions' do
|
|
69
65
|
it 'ensures the correct :current_action is set' do
|
70
66
|
TestDoubles::TestWithCallback.after_actions = [
|
71
67
|
lambda do |ctx|
|
72
|
-
if ctx.current_action == TestDoubles::IterateCollectionAction
|
73
|
-
ctx.total -= 1000
|
74
|
-
end
|
68
|
+
ctx.total -= 1000 if ctx.current_action == TestDoubles::IterateCollectionAction
|
75
69
|
end
|
76
70
|
]
|
77
71
|
|
@@ -34,14 +34,10 @@ RSpec.describe 'Action before_actions' do
|
|
34
34
|
class AdditionOrganizer
|
35
35
|
extend LightService::Organizer
|
36
36
|
before_actions (lambda do |ctx|
|
37
|
-
if ctx.current_action == TestDoubles::AddsOneAction
|
38
|
-
ctx.number -= 2
|
39
|
-
end
|
37
|
+
ctx.number -= 2 if ctx.current_action == TestDoubles::AddsOneAction
|
40
38
|
end),
|
41
39
|
(lambda do |ctx|
|
42
|
-
if ctx.current_action == TestDoubles::AddsThreeAction
|
43
|
-
ctx.number -= 3
|
44
|
-
end
|
40
|
+
ctx.number -= 3 if ctx.current_action == TestDoubles::AddsThreeAction
|
45
41
|
end)
|
46
42
|
|
47
43
|
def self.call(number)
|
@@ -69,9 +65,7 @@ RSpec.describe 'Action before_actions' do
|
|
69
65
|
it 'can interact with actions from the outside' do
|
70
66
|
TestDoubles::TestWithCallback.before_actions = [
|
71
67
|
lambda do |ctx|
|
72
|
-
if ctx.current_action == TestDoubles::AddToTotalAction
|
73
|
-
ctx.total -= 1000
|
74
|
-
end
|
68
|
+
ctx.total -= 1000 if ctx.current_action == TestDoubles::AddToTotalAction
|
75
69
|
end
|
76
70
|
]
|
77
71
|
result = TestDoubles::TestWithCallback.call
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_doubles'
|
3
|
+
|
4
|
+
RSpec.describe LightService::Organizer do
|
5
|
+
class TestReduceCase
|
6
|
+
extend LightService::Organizer
|
7
|
+
|
8
|
+
def self.call(context)
|
9
|
+
with(context).reduce(actions)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.actions
|
13
|
+
[
|
14
|
+
reduce_case(
|
15
|
+
:value => :incr_num,
|
16
|
+
:when => {
|
17
|
+
:one => [TestDoubles::AddsOneAction],
|
18
|
+
:two => [TestDoubles::AddsTwoAction],
|
19
|
+
:three => [TestDoubles::AddsThreeAction]
|
20
|
+
},
|
21
|
+
:else => [TestDoubles::FailureAction]
|
22
|
+
)
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'adds one if the incr_num is one' do
|
28
|
+
result = TestReduceCase.call(:number => 0, :incr_num => :one)
|
29
|
+
|
30
|
+
expect(result).to be_success
|
31
|
+
expect(result[:number]).to eq(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'adds two if the incr_num is two' do
|
35
|
+
result = TestReduceCase.call(:number => 0, :incr_num => :two)
|
36
|
+
|
37
|
+
expect(result).to be_success
|
38
|
+
expect(result[:number]).to eq(2)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'adds three if the incr_num is three' do
|
42
|
+
result = TestReduceCase.call(:number => 0, :incr_num => :three)
|
43
|
+
|
44
|
+
expect(result).to be_success
|
45
|
+
expect(result[:number]).to eq(3)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'will fail if the incr_num is neither one, two, or three' do
|
49
|
+
result = TestReduceCase.call(:number => 0, :incr_num => :four)
|
50
|
+
|
51
|
+
expect(result).to be_failure
|
52
|
+
end
|
53
|
+
end
|
@@ -63,6 +63,7 @@ RSpec.describe LightService::Organizer do
|
|
63
63
|
reduce(actions)
|
64
64
|
end
|
65
65
|
|
66
|
+
# rubocop:disable Metrics/AbcSize
|
66
67
|
def self.actions
|
67
68
|
[
|
68
69
|
reduce_if(
|
@@ -76,6 +77,7 @@ RSpec.describe LightService::Organizer do
|
|
76
77
|
execute(->(c) { c[:last_outside] = true })
|
77
78
|
]
|
78
79
|
end
|
80
|
+
# rubocop:enable Metrics/AbcSize
|
79
81
|
end
|
80
82
|
|
81
83
|
result = org.call
|
@@ -13,13 +13,7 @@ RSpec.describe LightService::Context do
|
|
13
13
|
describe '#inspect' do
|
14
14
|
it 'inspects the hash with all the fields' do
|
15
15
|
inspected_context =
|
16
|
-
|
17
|
-
+ 'success: true, ' \
|
18
|
-
+ 'message: \'\', ' \
|
19
|
-
+ 'error_code: nil, ' \
|
20
|
-
+ 'skip_remaining: false, ' \
|
21
|
-
+ 'aliases: {}' \
|
22
|
-
+ ')'
|
16
|
+
"LightService::Context({}, success: true, message: '', error_code: nil, skip_remaining: false, aliases: {})"
|
23
17
|
|
24
18
|
expect(context.inspect).to eq(inspected_context)
|
25
19
|
end
|
@@ -28,13 +22,8 @@ RSpec.describe LightService::Context do
|
|
28
22
|
context.fail!('There was an error')
|
29
23
|
|
30
24
|
inspected_context =
|
31
|
-
|
32
|
-
|
33
|
-
+ 'message: \'There was an error\', ' \
|
34
|
-
+ 'error_code: nil, ' \
|
35
|
-
+ 'skip_remaining: false, ' \
|
36
|
-
+ 'aliases: {}' \
|
37
|
-
+ ')'
|
25
|
+
"LightService::Context({}, success: false, message: 'There was an error', error_code: nil, " \
|
26
|
+
"skip_remaining: false, aliases: {})"
|
38
27
|
|
39
28
|
expect(context.inspect).to eq(inspected_context)
|
40
29
|
end
|
@@ -43,13 +32,8 @@ RSpec.describe LightService::Context do
|
|
43
32
|
context.skip_remaining!('No need to process')
|
44
33
|
|
45
34
|
inspected_context =
|
46
|
-
|
47
|
-
|
48
|
-
+ 'message: \'No need to process\', ' \
|
49
|
-
+ 'error_code: nil, ' \
|
50
|
-
+ 'skip_remaining: true, ' \
|
51
|
-
+ 'aliases: {}' \
|
52
|
-
+ ')'
|
35
|
+
"LightService::Context({}, success: true, message: 'No need to process', error_code: nil, " \
|
36
|
+
"skip_remaining: true, aliases: {})"
|
53
37
|
|
54
38
|
expect(context.inspect).to eq(inspected_context)
|
55
39
|
end
|
data/spec/context_spec.rb
CHANGED
@@ -167,7 +167,7 @@ RSpec.describe LightService::Context do
|
|
167
167
|
end
|
168
168
|
|
169
169
|
it "allows a default block value for #fetch" do
|
170
|
-
expect(context.fetch(:madeup
|
170
|
+
expect(context.fetch(:madeup, :default)).to eq(:default)
|
171
171
|
end
|
172
172
|
|
173
173
|
context "when aliases are included via .make" do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
require_relative '../../../lib/generators/light_service/action_generator
|
3
|
+
require_relative '../../../lib/generators/light_service/action_generator'
|
4
4
|
require_relative './full_generator_test_blobs'
|
5
5
|
|
6
6
|
describe LightService::Generators::ActionGenerator, :type => :generator do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
require_relative '../../../lib/generators/light_service/action_generator
|
3
|
+
require_relative '../../../lib/generators/light_service/action_generator'
|
4
4
|
require_relative './full_generator_test_blobs'
|
5
5
|
|
6
6
|
describe LightService::Generators::ActionGenerator, :type => :generator do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
require_relative '../../../lib/generators/light_service/organizer_generator
|
3
|
+
require_relative '../../../lib/generators/light_service/organizer_generator'
|
4
4
|
require_relative './full_generator_test_blobs'
|
5
5
|
|
6
6
|
describe LightService::Generators::OrganizerGenerator, :type => :generator do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
require_relative '../../../lib/generators/light_service/organizer_generator
|
3
|
+
require_relative '../../../lib/generators/light_service/organizer_generator'
|
4
4
|
require_relative './full_generator_test_blobs'
|
5
5
|
|
6
6
|
describe LightService::Generators::OrganizerGenerator, :type => :generator do
|
data/spec/test_doubles.rb
CHANGED
@@ -45,6 +45,7 @@ module TestDoubles
|
|
45
45
|
|
46
46
|
class TestLogger
|
47
47
|
attr_accessor :logs
|
48
|
+
|
48
49
|
def initialize
|
49
50
|
@logs = []
|
50
51
|
end
|
@@ -93,8 +94,13 @@ module TestDoubles
|
|
93
94
|
end
|
94
95
|
end
|
95
96
|
|
96
|
-
class AnAction
|
97
|
-
|
97
|
+
class AnAction
|
98
|
+
extend LightService::Action
|
99
|
+
end
|
100
|
+
|
101
|
+
class AnotherAction
|
102
|
+
extend LightService::Action
|
103
|
+
end
|
98
104
|
|
99
105
|
class AnOrganizer
|
100
106
|
extend LightService::Organizer
|
@@ -176,9 +182,7 @@ module TestDoubles
|
|
176
182
|
promises :latte
|
177
183
|
|
178
184
|
executed do |context|
|
179
|
-
if context.milk == :very_hot
|
180
|
-
context.fail!("Can't make a latte from a milk that's very hot!")
|
181
|
-
end
|
185
|
+
context.fail!("Can't make a latte from a milk that's very hot!") if context.milk == :very_hot
|
182
186
|
|
183
187
|
if context.milk == :super_hot
|
184
188
|
error_message = "Can't make a latte from a milk that's super hot!"
|
@@ -488,7 +492,9 @@ module TestDoubles
|
|
488
492
|
class NullAction
|
489
493
|
extend LightService::Action
|
490
494
|
|
495
|
+
# rubocop:disable Lint/EmptyBlock
|
491
496
|
executed { |_ctx| }
|
497
|
+
# rubocop:enable Lint/EmptyBlock
|
492
498
|
end
|
493
499
|
|
494
500
|
class TestIterate
|
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.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Attila Domokos
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 1.26.0
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: 1.26.0
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: rubocop-performance
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -189,6 +189,7 @@ files:
|
|
189
189
|
- lib/light-service/organizer.rb
|
190
190
|
- lib/light-service/organizer/execute.rb
|
191
191
|
- lib/light-service/organizer/iterate.rb
|
192
|
+
- lib/light-service/organizer/reduce_case.rb
|
192
193
|
- lib/light-service/organizer/reduce_if.rb
|
193
194
|
- lib/light-service/organizer/reduce_if_else.rb
|
194
195
|
- lib/light-service/organizer/reduce_until.rb
|
@@ -230,6 +231,7 @@ files:
|
|
230
231
|
- spec/acceptance/organizer/execute_spec.rb
|
231
232
|
- spec/acceptance/organizer/execute_with_add_to_context_spec.rb
|
232
233
|
- spec/acceptance/organizer/iterate_spec.rb
|
234
|
+
- spec/acceptance/organizer/reduce_case_spec.rb
|
233
235
|
- spec/acceptance/organizer/reduce_if_else_spec.rb
|
234
236
|
- spec/acceptance/organizer/reduce_if_spec.rb
|
235
237
|
- spec/acceptance/organizer/reduce_until_spec.rb
|
@@ -273,7 +275,7 @@ homepage: https://github.com/adomokos/light-service
|
|
273
275
|
licenses:
|
274
276
|
- MIT
|
275
277
|
metadata: {}
|
276
|
-
post_install_message:
|
278
|
+
post_install_message:
|
277
279
|
rdoc_options: []
|
278
280
|
require_paths:
|
279
281
|
- lib
|
@@ -281,15 +283,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
281
283
|
requirements:
|
282
284
|
- - ">="
|
283
285
|
- !ruby/object:Gem::Version
|
284
|
-
version: 2.
|
286
|
+
version: 2.6.0
|
285
287
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
286
288
|
requirements:
|
287
289
|
- - ">="
|
288
290
|
- !ruby/object:Gem::Version
|
289
291
|
version: '0'
|
290
292
|
requirements: []
|
291
|
-
rubygems_version: 3.
|
292
|
-
signing_key:
|
293
|
+
rubygems_version: 3.3.12
|
294
|
+
signing_key:
|
293
295
|
specification_version: 4
|
294
296
|
summary: A service skeleton with an emphasis on simplicity
|
295
297
|
test_files:
|
@@ -317,6 +319,7 @@ test_files:
|
|
317
319
|
- spec/acceptance/organizer/execute_spec.rb
|
318
320
|
- spec/acceptance/organizer/execute_with_add_to_context_spec.rb
|
319
321
|
- spec/acceptance/organizer/iterate_spec.rb
|
322
|
+
- spec/acceptance/organizer/reduce_case_spec.rb
|
320
323
|
- spec/acceptance/organizer/reduce_if_else_spec.rb
|
321
324
|
- spec/acceptance/organizer/reduce_if_spec.rb
|
322
325
|
- spec/acceptance/organizer/reduce_until_spec.rb
|