functional-light-service 6.2.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/functional-light-service.rb +6 -36
- metadata +14 -307
- data/.github/workflows/project-build.yml +0 -71
- data/.gitignore +0 -24
- data/.rspec +0 -3
- data/.rubocop.yml +0 -101
- data/.solargraph.yml +0 -11
- data/AUDIT-functional-light-service.md +0 -352
- data/Appraisals +0 -7
- data/CHANGELOG.md +0 -292
- data/CODE_OF_CONDUCT.md +0 -22
- data/Gemfile +0 -4
- data/LICENSE +0 -22
- data/README.md +0 -1663
- data/Rakefile +0 -12
- data/VERSION +0 -1
- data/audit/bench.rb +0 -99
- data/audit/verify_findings.rb +0 -172
- data/functional-light-service.gemspec +0 -35
- data/gemfiles/dry_inflector_0_2_1.gemfile +0 -5
- data/gemfiles/i18n_1_8_11.gemfile +0 -5
- data/lib/functional-light-service/action.rb +0 -145
- data/lib/functional-light-service/configuration.rb +0 -36
- data/lib/functional-light-service/context/key_verifier.rb +0 -124
- data/lib/functional-light-service/context.rb +0 -208
- data/lib/functional-light-service/deprecations.rb +0 -26
- data/lib/functional-light-service/errors.rb +0 -9
- data/lib/functional-light-service/functional/enum.rb +0 -286
- data/lib/functional-light-service/functional/maybe.rb +0 -21
- data/lib/functional-light-service/functional/monad.rb +0 -77
- data/lib/functional-light-service/functional/null.rb +0 -88
- data/lib/functional-light-service/functional/option.rb +0 -100
- data/lib/functional-light-service/functional/result.rb +0 -129
- data/lib/functional-light-service/functional/sequencer.rb +0 -144
- data/lib/functional-light-service/i18n/localization_adapter.rb +0 -50
- data/lib/functional-light-service/localization_adapter.rb +0 -39
- data/lib/functional-light-service/localization_map.rb +0 -9
- data/lib/functional-light-service/organizer/execute.rb +0 -16
- data/lib/functional-light-service/organizer/iterate.rb +0 -30
- data/lib/functional-light-service/organizer/reduce_case.rb +0 -50
- data/lib/functional-light-service/organizer/reduce_if.rb +0 -19
- data/lib/functional-light-service/organizer/reduce_if_else.rb +0 -23
- data/lib/functional-light-service/organizer/reduce_until.rb +0 -22
- data/lib/functional-light-service/organizer/reduce_while.rb +0 -31
- data/lib/functional-light-service/organizer/scoped_reducable.rb +0 -15
- data/lib/functional-light-service/organizer/with_callback.rb +0 -28
- data/lib/functional-light-service/organizer/with_reducer.rb +0 -81
- data/lib/functional-light-service/organizer/with_reducer_factory.rb +0 -20
- data/lib/functional-light-service/organizer/with_reducer_log_decorator.rb +0 -111
- data/lib/functional-light-service/organizer.rb +0 -129
- data/lib/functional-light-service/testing/context_factory.rb +0 -48
- data/lib/functional-light-service/testing.rb +0 -3
- data/lib/functional-light-service/version.rb +0 -5
- data/resources/fail_actions.png +0 -0
- data/resources/light-service.png +0 -0
- data/resources/organizer_and_actions.png +0 -0
- data/resources/skip_actions.png +0 -0
- data/spec/acceptance/add_numbers_spec.rb +0 -11
- data/spec/acceptance/after_actions_spec.rb +0 -87
- data/spec/acceptance/around_each_spec.rb +0 -19
- data/spec/acceptance/before_actions_spec.rb +0 -115
- data/spec/acceptance/custom_log_from_organizer_spec.rb +0 -61
- data/spec/acceptance/deprecation_warnings_spec.rb +0 -82
- data/spec/acceptance/fail_spec.rb +0 -52
- data/spec/acceptance/log_from_organizer_spec.rb +0 -154
- data/spec/acceptance/message_localization_spec.rb +0 -119
- data/spec/acceptance/organizer/add_aliases_spec.rb +0 -28
- data/spec/acceptance/organizer/add_to_context_spec.rb +0 -54
- data/spec/acceptance/organizer/around_each_with_reduce_if_spec.rb +0 -42
- data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +0 -90
- data/spec/acceptance/organizer/execute_spec.rb +0 -67
- data/spec/acceptance/organizer/iterate_spec.rb +0 -44
- data/spec/acceptance/organizer/reduce_case_spec.rb +0 -65
- data/spec/acceptance/organizer/reduce_if_else_spec.rb +0 -60
- data/spec/acceptance/organizer/reduce_if_spec.rb +0 -89
- data/spec/acceptance/organizer/reduce_until_spec.rb +0 -49
- data/spec/acceptance/organizer/reduce_while_spec.rb +0 -96
- data/spec/acceptance/organizer/with_callback_spec.rb +0 -113
- data/spec/acceptance/organizer_entry_point_spec.rb +0 -35
- data/spec/acceptance/rollback_spec.rb +0 -183
- data/spec/acceptance/skip_all_remaining_spec.rb +0 -139
- data/spec/acceptance/testing/context_factory_spec.rb +0 -54
- data/spec/action_expected_keys_spec.rb +0 -63
- data/spec/action_expects_and_promises_spec.rb +0 -97
- data/spec/action_optional_expected_keys_spec.rb +0 -107
- data/spec/action_promised_keys_spec.rb +0 -126
- data/spec/action_spec.rb +0 -97
- data/spec/context/inspect_spec.rb +0 -52
- data/spec/context_spec.rb +0 -301
- data/spec/examples/amount_spec.rb +0 -77
- data/spec/examples/controller_spec.rb +0 -63
- data/spec/examples/validate_address_spec.rb +0 -38
- data/spec/i18n_localization_adapter_spec.rb +0 -83
- data/spec/lib/deterministic/class_mixin_spec.rb +0 -24
- data/spec/lib/deterministic/currify_spec.rb +0 -90
- data/spec/lib/deterministic/monad_axioms.rb +0 -46
- data/spec/lib/deterministic/monad_spec.rb +0 -47
- data/spec/lib/deterministic/null_spec.rb +0 -65
- data/spec/lib/deterministic/option_spec.rb +0 -140
- data/spec/lib/deterministic/result/failure_spec.rb +0 -65
- data/spec/lib/deterministic/result/result_map_spec.rb +0 -155
- data/spec/lib/deterministic/result/result_shared.rb +0 -25
- data/spec/lib/deterministic/result/success_spec.rb +0 -41
- data/spec/lib/deterministic/result_spec.rb +0 -63
- data/spec/lib/deterministic/sequencer_spec.rb +0 -506
- data/spec/lib/edge_cases_spec.rb +0 -156
- data/spec/lib/enum_spec.rb +0 -114
- data/spec/lib/native_pattern_matching_spec.rb +0 -74
- data/spec/localization_adapter_spec.rb +0 -66
- data/spec/organizer/with_reducer_spec.rb +0 -56
- data/spec/organizer_key_aliases_spec.rb +0 -29
- data/spec/organizer_spec.rb +0 -115
- data/spec/readme_spec.rb +0 -45
- data/spec/sample/calculates_order_tax_action_spec.rb +0 -16
- data/spec/sample/calculates_tax_spec.rb +0 -30
- data/spec/sample/looks_up_tax_percentage_action_spec.rb +0 -55
- data/spec/sample/provides_free_shipping_action_spec.rb +0 -25
- data/spec/sample/tax/calculates_order_tax_action.rb +0 -10
- data/spec/sample/tax/calculates_tax.rb +0 -11
- data/spec/sample/tax/looks_up_tax_percentage_action.rb +0 -28
- data/spec/sample/tax/provides_free_shipping_action.rb +0 -11
- data/spec/spec_helper.rb +0 -32
- data/spec/support.rb +0 -1
- data/spec/test_doubles.rb +0 -656
- data/spec/testing/context_factory/iterate_spec.rb +0 -39
- data/spec/testing/context_factory/reduce_if_spec.rb +0 -40
- data/spec/testing/context_factory/reduce_until_spec.rb +0 -40
- data/spec/testing/context_factory/with_callback_spec.rb +0 -38
- data/spec/testing/context_factory_spec.rb +0 -76
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
class RollbackOrganizer
|
|
5
|
-
extend FunctionalLightService::Organizer
|
|
6
|
-
|
|
7
|
-
def self.call(number)
|
|
8
|
-
with(:number => number).reduce(
|
|
9
|
-
AddsOneWithRollbackAction,
|
|
10
|
-
TestDoubles::AddsTwoAction,
|
|
11
|
-
AddsThreeWithRollbackAction
|
|
12
|
-
)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
class AddsOneWithRollbackAction
|
|
17
|
-
extend FunctionalLightService::Action
|
|
18
|
-
|
|
19
|
-
expects :number
|
|
20
|
-
promises :number
|
|
21
|
-
|
|
22
|
-
executed do |context|
|
|
23
|
-
context.fail_with_rollback! if context.number.zero?
|
|
24
|
-
|
|
25
|
-
context.number += 1
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
rolled_back do |context|
|
|
29
|
-
context.number -= 1
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
class AddsThreeWithRollbackAction
|
|
34
|
-
extend FunctionalLightService::Action
|
|
35
|
-
|
|
36
|
-
expects :number
|
|
37
|
-
|
|
38
|
-
executed do |context|
|
|
39
|
-
context.number = context.number + 3
|
|
40
|
-
|
|
41
|
-
context.fail_with_rollback!("I did not like this!")
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
rolled_back do |context|
|
|
45
|
-
context.number -= 3
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
class RollbackOrganizerWithNoRollback
|
|
50
|
-
extend FunctionalLightService::Organizer
|
|
51
|
-
|
|
52
|
-
def self.call(number)
|
|
53
|
-
with(:number => number).reduce(
|
|
54
|
-
TestDoubles::AddsOneAction,
|
|
55
|
-
TestDoubles::AddsTwoAction,
|
|
56
|
-
AddsThreeWithNoRollbackAction
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
class AddsThreeWithNoRollbackAction
|
|
62
|
-
extend FunctionalLightService::Action
|
|
63
|
-
|
|
64
|
-
expects :number
|
|
65
|
-
|
|
66
|
-
executed do |context|
|
|
67
|
-
context.number = context.number + 3
|
|
68
|
-
|
|
69
|
-
context.fail_with_rollback!("I did not like this!")
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
class RollbackOrganizerWithMiddleRollback
|
|
74
|
-
extend FunctionalLightService::Organizer
|
|
75
|
-
|
|
76
|
-
def self.call(number)
|
|
77
|
-
with(:number => number).reduce(
|
|
78
|
-
TestDoubles::AddsOneAction,
|
|
79
|
-
AddsTwoActionWithRollback,
|
|
80
|
-
TestDoubles::AddsThreeAction
|
|
81
|
-
)
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
class AddsTwoActionWithRollback
|
|
86
|
-
extend FunctionalLightService::Action
|
|
87
|
-
|
|
88
|
-
expects :number
|
|
89
|
-
|
|
90
|
-
executed do |context|
|
|
91
|
-
context.number = context.number + 2
|
|
92
|
-
|
|
93
|
-
context.fail_with_rollback!("I did not like this a bit!")
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
rolled_back do |context|
|
|
97
|
-
context.number -= 2
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
class RollbackOrganizerWithDuplicatedAction
|
|
102
|
-
extend FunctionalLightService::Organizer
|
|
103
|
-
|
|
104
|
-
def self.call(ctx)
|
|
105
|
-
with(ctx).reduce(
|
|
106
|
-
TracksRollbackAction,
|
|
107
|
-
FailsOnSecondRunWithRollbackAction,
|
|
108
|
-
TracksRollbackAction,
|
|
109
|
-
FailsOnSecondRunWithRollbackAction
|
|
110
|
-
)
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
class TracksRollbackAction
|
|
115
|
-
extend FunctionalLightService::Action
|
|
116
|
-
|
|
117
|
-
executed do |context|
|
|
118
|
-
(context[:executed] ||= []) << :tracks
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
rolled_back do |context|
|
|
122
|
-
(context[:rolled_back] ||= []) << :tracks
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
class FailsOnSecondRunWithRollbackAction
|
|
127
|
-
extend FunctionalLightService::Action
|
|
128
|
-
|
|
129
|
-
executed do |context|
|
|
130
|
-
(context[:executed] ||= []) << :fails
|
|
131
|
-
context.fail_with_rollback!("boom") if context[:executed].count(:fails) == 2
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
rolled_back do |context|
|
|
135
|
-
(context[:rolled_back] ||= []) << :fails
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
describe "Rolling back actions when there is a failure" do
|
|
140
|
-
it "Adds 1, 2, 3 to 1 and rolls back " do
|
|
141
|
-
result = RollbackOrganizer.call 1
|
|
142
|
-
number = result.fetch(:number)
|
|
143
|
-
|
|
144
|
-
expect(result).to be_failure
|
|
145
|
-
expect(result.message).to eq("I did not like this!")
|
|
146
|
-
expect(number).to eq(3)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
it "won't error out when actions don't define rollback" do
|
|
150
|
-
result = RollbackOrganizerWithNoRollback.call 1
|
|
151
|
-
number = result.fetch(:number)
|
|
152
|
-
|
|
153
|
-
expect(result).to be_failure
|
|
154
|
-
expect(result.message).to eq("I did not like this!")
|
|
155
|
-
expect(number).to eq(7)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
it "rolls back properly when triggered with an action in the middle" do
|
|
159
|
-
result = RollbackOrganizerWithMiddleRollback.call 1
|
|
160
|
-
number = result.fetch(:number)
|
|
161
|
-
|
|
162
|
-
expect(result).to be_failure
|
|
163
|
-
expect(result.message).to eq("I did not like this a bit!")
|
|
164
|
-
expect(number).to eq(2)
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
it "rolls back from the first action" do
|
|
168
|
-
result = RollbackOrganizer.call 0
|
|
169
|
-
number = result.fetch(:number)
|
|
170
|
-
|
|
171
|
-
expect(result).to be_failure
|
|
172
|
-
expect(number).to eq(-1)
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
it "rolls back every executed action when the same action appears twice" do
|
|
176
|
-
result = RollbackOrganizerWithDuplicatedAction.call({})
|
|
177
|
-
|
|
178
|
-
expect(result).to be_failure
|
|
179
|
-
expect(result[:executed]).to eq(%i[tracks fails tracks fails])
|
|
180
|
-
# tutte e 4 le azioni eseguite vengono compensate, in ordine inverso
|
|
181
|
-
expect(result[:rolled_back]).to eq(%i[fails tracks fails tracks])
|
|
182
|
-
end
|
|
183
|
-
end
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
RSpec.describe "skip_all_remaining!" do
|
|
4
|
-
context "with regular organizer" do
|
|
5
|
-
let(:organizer) do
|
|
6
|
-
Class.new do
|
|
7
|
-
extend FunctionalLightService::Organizer
|
|
8
|
-
|
|
9
|
-
def self.call(ctx)
|
|
10
|
-
with(ctx).reduce(actions)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.actions
|
|
14
|
-
[
|
|
15
|
-
execute(->(c) { c[:first] = true }),
|
|
16
|
-
execute(lambda(&:skip_all_remaining!)),
|
|
17
|
-
execute(->(c) { c[:second] = true })
|
|
18
|
-
]
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "skips all remaining actions" do
|
|
24
|
-
result = organizer.call(FunctionalLightService::Context.make)
|
|
25
|
-
|
|
26
|
-
expect(result[:first]).to be true
|
|
27
|
-
expect(result[:second]).to be_nil
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
context "with an organizer with a reducer" do
|
|
32
|
-
let(:organizer) do
|
|
33
|
-
Class.new do
|
|
34
|
-
extend FunctionalLightService::Organizer
|
|
35
|
-
|
|
36
|
-
def self.call(ctx)
|
|
37
|
-
with(ctx).reduce(actions)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def self.actions
|
|
41
|
-
[
|
|
42
|
-
reduce_if(
|
|
43
|
-
->(_) { true },
|
|
44
|
-
[
|
|
45
|
-
execute(->(c) { c[:first_inside] = true }),
|
|
46
|
-
execute(lambda(&:skip_all_remaining!)),
|
|
47
|
-
execute(->(c) { c[:second_inside] = true })
|
|
48
|
-
]
|
|
49
|
-
),
|
|
50
|
-
execute(->(c) { c[:outside] = true })
|
|
51
|
-
]
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "skips all remaining actions inside and outside the reducer" do
|
|
57
|
-
result = organizer.call(FunctionalLightService::Context.make)
|
|
58
|
-
|
|
59
|
-
expect(result[:first_inside]).to be true
|
|
60
|
-
expect(result[:second_inside]).to be_nil
|
|
61
|
-
expect(result[:outside]).to be_nil
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
context "with a message" do
|
|
66
|
-
let(:organizer) do
|
|
67
|
-
Class.new do
|
|
68
|
-
extend FunctionalLightService::Organizer
|
|
69
|
-
|
|
70
|
-
def self.call(ctx)
|
|
71
|
-
with(ctx).reduce(actions)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def self.actions
|
|
75
|
-
[
|
|
76
|
-
reduce_if(
|
|
77
|
-
->(_) { true },
|
|
78
|
-
[
|
|
79
|
-
execute(->(c) { c.skip_all_remaining!("Skipping with message") })
|
|
80
|
-
]
|
|
81
|
-
),
|
|
82
|
-
execute(->(c) { c[:outside] = true })
|
|
83
|
-
]
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it "preserves the message when exiting scoped reducers" do
|
|
89
|
-
result = organizer.call(FunctionalLightService::Context.make)
|
|
90
|
-
|
|
91
|
-
expect(result.message).to eq("Skipping with message")
|
|
92
|
-
expect(result[:outside]).to be_nil
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
context "with an organizer with nested reducers" do
|
|
97
|
-
let(:organizer) do
|
|
98
|
-
Class.new do
|
|
99
|
-
extend FunctionalLightService::Organizer
|
|
100
|
-
|
|
101
|
-
def self.call(ctx)
|
|
102
|
-
with(ctx).reduce(actions)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def self.actions # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
106
|
-
[
|
|
107
|
-
reduce_if(
|
|
108
|
-
->(_) { true },
|
|
109
|
-
[
|
|
110
|
-
iterate(:items, [
|
|
111
|
-
execute(->(c) {
|
|
112
|
-
c[:executed_items] ||= []
|
|
113
|
-
c[:executed_items] << c[:item]
|
|
114
|
-
}),
|
|
115
|
-
execute(->(c) { c.skip_all_remaining! if c[:item] == 2 }),
|
|
116
|
-
execute(->(c) {
|
|
117
|
-
c[:skipped_in_iterate] ||= []
|
|
118
|
-
c[:skipped_in_iterate] << c[:item]
|
|
119
|
-
})
|
|
120
|
-
]),
|
|
121
|
-
execute(->(c) { c[:after_iterate_inside_if] = true })
|
|
122
|
-
]
|
|
123
|
-
),
|
|
124
|
-
execute(->(c) { c[:outside] = true })
|
|
125
|
-
]
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
it "skips all remaining actions across all nested scopes" do
|
|
131
|
-
result = organizer.call(FunctionalLightService::Context.make(:items => [1, 2, 3]))
|
|
132
|
-
|
|
133
|
-
expect(result[:executed_items]).to eq([1, 2])
|
|
134
|
-
expect(result[:skipped_in_iterate]).to eq([1])
|
|
135
|
-
expect(result[:after_iterate_inside_if]).to be_nil
|
|
136
|
-
expect(result[:outside]).to be_nil
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
end
|
|
@@ -1,54 +0,0 @@
|
|
|
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
|
-
FunctionalLightService::Testing::ContextFactory
|
|
9
|
-
.make_from(TestDoubles::AdditionOrganizer)
|
|
10
|
-
.for(action)
|
|
11
|
-
.with(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
|
-
FunctionalLightService::Testing::ContextFactory
|
|
27
|
-
.make_from(TestDoubles::AdditionOrganizer)
|
|
28
|
-
.for(TestDoubles::AddsThreeAction)
|
|
29
|
-
.with(4) # Context is a "glorified" hash
|
|
30
|
-
|
|
31
|
-
expect(context.number).to eq(7)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it "works with multiple arguments passed to Organizer's call method" do
|
|
35
|
-
context = FunctionalLightService::Testing::ContextFactory
|
|
36
|
-
.make_from(TestDoubles::ExtraArgumentAdditionOrganizer)
|
|
37
|
-
.for(described_class)
|
|
38
|
-
.with(4, 2)
|
|
39
|
-
|
|
40
|
-
expect(context.number).to eq(9)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
RSpec.describe TestDoubles::AddsTwoAction do
|
|
45
|
-
it 'does not execute a callback entirely from a ContextFactory' do
|
|
46
|
-
context = FunctionalLightService::Testing::ContextFactory
|
|
47
|
-
.make_from(TestDoubles::CallbackOrganizer)
|
|
48
|
-
.for(described_class)
|
|
49
|
-
.with(:number => 0)
|
|
50
|
-
|
|
51
|
-
# add 1, add 10, then stop before executing first add 2
|
|
52
|
-
expect(context.number).to eq(11)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
describe ":expects macro" do
|
|
5
|
-
context "when expected keys are in the context" do
|
|
6
|
-
it "can access the keys as class methods" do
|
|
7
|
-
resulting_context = TestDoubles::MakesTeaWithMilkAction.execute(
|
|
8
|
-
:tea => "black",
|
|
9
|
-
:milk => "full cream",
|
|
10
|
-
:something => "else"
|
|
11
|
-
)
|
|
12
|
-
expect(resulting_context[:milk_tea]).to eq("black - full cream")
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
context "when an expected key is not in the context" do
|
|
17
|
-
it "raises an FunctionalLightService::ExpectedKeysNotInContextError" do
|
|
18
|
-
exception_msg = "expected :milk to be in the context during " \
|
|
19
|
-
"TestDoubles::MakesTeaWithMilkAction"
|
|
20
|
-
expect do
|
|
21
|
-
TestDoubles::MakesTeaWithMilkAction.execute(:tea => "black")
|
|
22
|
-
end.to \
|
|
23
|
-
raise_error(FunctionalLightService::ExpectedKeysNotInContextError, exception_msg)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
context "when the `expects` macro is called multiple times" do
|
|
28
|
-
it "can collect expected keys " do
|
|
29
|
-
result = TestDoubles::MultipleExpectsAction.execute(
|
|
30
|
-
:tea => "black",
|
|
31
|
-
:milk => "full cream",
|
|
32
|
-
:chocolate => "dark chocolate"
|
|
33
|
-
)
|
|
34
|
-
expect(result[:milk_tea]).to \
|
|
35
|
-
eq("black - full cream - with dark chocolate")
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
context "when a reserved key is listed as an expected key" do
|
|
40
|
-
it "raises an error indicating a reserved key is expected" do
|
|
41
|
-
exception_msg = "promised or expected keys cannot be a reserved key: " \
|
|
42
|
-
"[:message]"
|
|
43
|
-
expect do
|
|
44
|
-
TestDoubles::MakesTeaExpectingReservedKey.execute(:tea => "black",
|
|
45
|
-
:message => "no no")
|
|
46
|
-
end.to \
|
|
47
|
-
raise_error(FunctionalLightService::ReservedKeysInContextError, exception_msg)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "raises an error indicating that multiple reserved keys are expected" do
|
|
51
|
-
exception_msg = "promised or expected keys cannot be a reserved key: " \
|
|
52
|
-
"[:message, :error_code, :current_action]"
|
|
53
|
-
expect do
|
|
54
|
-
TestDoubles::MakesTeaExpectingMultipleReservedKeys
|
|
55
|
-
.execute(:tea => "black",
|
|
56
|
-
:message => "no no",
|
|
57
|
-
:error_code => 1,
|
|
58
|
-
:current_action => "update")
|
|
59
|
-
end.to raise_error(FunctionalLightService::ReservedKeysInContextError,
|
|
60
|
-
exception_msg)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe ":expects and :promises macros" do
|
|
4
|
-
describe "actions are backward compatible" do
|
|
5
|
-
class FooAction
|
|
6
|
-
extend FunctionalLightService::Action
|
|
7
|
-
|
|
8
|
-
executed do |context|
|
|
9
|
-
baz = context.fetch :baz
|
|
10
|
-
|
|
11
|
-
bar = baz + 2
|
|
12
|
-
context[:bar] = bar
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
it "works without expects and promises" do
|
|
16
|
-
result = FooAction.execute(:baz => 3)
|
|
17
|
-
expect(result).to be_success
|
|
18
|
-
expect(result[:bar]).to eq(5)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
context "when expected keys are not in context" do
|
|
23
|
-
class FooNoExpectedKeyAction
|
|
24
|
-
extend FunctionalLightService::Action
|
|
25
|
-
|
|
26
|
-
expects :baz
|
|
27
|
-
|
|
28
|
-
executed do |context|
|
|
29
|
-
baz = context.fetch :baz
|
|
30
|
-
|
|
31
|
-
bar = baz + 2
|
|
32
|
-
context[:bar] = bar
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
it "throws an ExpectedKeysNotInContextError" do
|
|
36
|
-
# FooAction invoked with nothing in the context
|
|
37
|
-
expect { FooNoExpectedKeyAction.execute }.to \
|
|
38
|
-
raise_error(FunctionalLightService::ExpectedKeysNotInContextError)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
describe "expected keys" do
|
|
43
|
-
class FooWithReaderAction
|
|
44
|
-
extend FunctionalLightService::Action
|
|
45
|
-
|
|
46
|
-
expects :baz
|
|
47
|
-
|
|
48
|
-
executed do |context|
|
|
49
|
-
# Notice how I use `context.baz` here
|
|
50
|
-
bar = context.baz + 2
|
|
51
|
-
context[:bar] = bar
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
it "can be accessed through a reader" do
|
|
55
|
-
result = FooWithReaderAction.execute(:baz => 3)
|
|
56
|
-
expect(result).to be_success
|
|
57
|
-
expect(result[:bar]).to eq(5)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
context "when promised keys are not in context" do
|
|
62
|
-
class FooNoPromisedKeyAction
|
|
63
|
-
extend FunctionalLightService::Action
|
|
64
|
-
|
|
65
|
-
expects :baz
|
|
66
|
-
promises :bar
|
|
67
|
-
|
|
68
|
-
executed do |context|
|
|
69
|
-
# I am not adding anything to the context
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
it "throws a PromisedKeysNotInContextError" do
|
|
73
|
-
# FooAction invoked with nothing placed in the context
|
|
74
|
-
expect { FooNoPromisedKeyAction.execute(:baz => 3) }.to \
|
|
75
|
-
raise_error(FunctionalLightService::PromisedKeysNotInContextError)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
describe "promised keys" do
|
|
80
|
-
class FooWithExpectsAndPromisesAction
|
|
81
|
-
extend FunctionalLightService::Action
|
|
82
|
-
|
|
83
|
-
expects :baz
|
|
84
|
-
promises :bar
|
|
85
|
-
|
|
86
|
-
executed do |context|
|
|
87
|
-
# Notice how I use `context.bar` here
|
|
88
|
-
context.bar = context.baz + 2
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
it "puts the value through the accessor into the context" do
|
|
92
|
-
result = FooWithExpectsAndPromisesAction.execute(:baz => 3)
|
|
93
|
-
expect(result).to be_success
|
|
94
|
-
expect(result[:bar]).to eq(5)
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
describe ":expects macro using defaults" do
|
|
5
|
-
context "when all expected keys are supplied" do
|
|
6
|
-
it "is expected to ignore default values" do
|
|
7
|
-
outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
|
|
8
|
-
:first_number => 3,
|
|
9
|
-
:second_number => 5,
|
|
10
|
-
:third_number => 7
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
expect(outcome.total).to eq 15
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
context "when defaults are supplied" do
|
|
18
|
-
it "is expected to use static values" do
|
|
19
|
-
outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
|
|
20
|
-
:first_number => 3,
|
|
21
|
-
:second_number => 7
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
expect(outcome.total).to eq 20
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "is expected to use dynamic values" do
|
|
28
|
-
outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
|
|
29
|
-
:first_number => 3,
|
|
30
|
-
:third_number => 5
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
expect(outcome.total).to eq 18
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "is expected to process defaults in their defined order" do
|
|
37
|
-
outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
|
|
38
|
-
:third_number => 5,
|
|
39
|
-
:first_number => 3
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
expect(outcome.total).to eq 18
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it "is expected to use all defaults if required" do
|
|
46
|
-
outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
|
|
47
|
-
:first_number => 3
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
expect(outcome.total).to eq 23
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
context "when used within an organizer" do
|
|
55
|
-
it "is expected to process required defaults" do
|
|
56
|
-
outcome = TestDoubles::OrganizerWithActionsUsingDefaults.call
|
|
57
|
-
|
|
58
|
-
expect(outcome.total).to eq 20
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
context "when the expected key is satisfied through an alias" do
|
|
63
|
-
it "is expected to not apply the default" do
|
|
64
|
-
action = Class.new do
|
|
65
|
-
extend FunctionalLightService::Action
|
|
66
|
-
|
|
67
|
-
expects :greeting, :default => "hello"
|
|
68
|
-
promises :greeted
|
|
69
|
-
|
|
70
|
-
executed do |ctx|
|
|
71
|
-
ctx.greeted = ctx.greeting
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
organizer = Class.new do
|
|
76
|
-
extend FunctionalLightService::Organizer
|
|
77
|
-
|
|
78
|
-
aliases :salutation => :greeting
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
outcome = organizer.with(:salutation => "ciao").reduce([action])
|
|
82
|
-
|
|
83
|
-
expect(outcome.greeted).to eq "ciao"
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
context "when defaults are misconfigured" do
|
|
88
|
-
it "is expected to raise an exception" do
|
|
89
|
-
expect do
|
|
90
|
-
# Needs to be specified in the block
|
|
91
|
-
# as error is raised at define time
|
|
92
|
-
class AddsNumbersWithIncorrectDefaults
|
|
93
|
-
extend FunctionalLightService::Action
|
|
94
|
-
|
|
95
|
-
expects :first, :default => 10 # This one is fine. Other two arent
|
|
96
|
-
expects :second, :defalut => ->(ctx) { ctx[:first] + 7 }
|
|
97
|
-
expects :third, :deafult => 10
|
|
98
|
-
promises :total
|
|
99
|
-
|
|
100
|
-
executed do |ctx|
|
|
101
|
-
ctx.total = ctx.first + ctx.second + ctx.third
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end.to raise_error(FunctionalLightService::UnusableExpectKeyDefaultError)
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|