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.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/lib/functional-light-service.rb +6 -36
  3. metadata +14 -307
  4. data/.github/workflows/project-build.yml +0 -71
  5. data/.gitignore +0 -24
  6. data/.rspec +0 -3
  7. data/.rubocop.yml +0 -101
  8. data/.solargraph.yml +0 -11
  9. data/AUDIT-functional-light-service.md +0 -352
  10. data/Appraisals +0 -7
  11. data/CHANGELOG.md +0 -292
  12. data/CODE_OF_CONDUCT.md +0 -22
  13. data/Gemfile +0 -4
  14. data/LICENSE +0 -22
  15. data/README.md +0 -1663
  16. data/Rakefile +0 -12
  17. data/VERSION +0 -1
  18. data/audit/bench.rb +0 -99
  19. data/audit/verify_findings.rb +0 -172
  20. data/functional-light-service.gemspec +0 -35
  21. data/gemfiles/dry_inflector_0_2_1.gemfile +0 -5
  22. data/gemfiles/i18n_1_8_11.gemfile +0 -5
  23. data/lib/functional-light-service/action.rb +0 -145
  24. data/lib/functional-light-service/configuration.rb +0 -36
  25. data/lib/functional-light-service/context/key_verifier.rb +0 -124
  26. data/lib/functional-light-service/context.rb +0 -208
  27. data/lib/functional-light-service/deprecations.rb +0 -26
  28. data/lib/functional-light-service/errors.rb +0 -9
  29. data/lib/functional-light-service/functional/enum.rb +0 -286
  30. data/lib/functional-light-service/functional/maybe.rb +0 -21
  31. data/lib/functional-light-service/functional/monad.rb +0 -77
  32. data/lib/functional-light-service/functional/null.rb +0 -88
  33. data/lib/functional-light-service/functional/option.rb +0 -100
  34. data/lib/functional-light-service/functional/result.rb +0 -129
  35. data/lib/functional-light-service/functional/sequencer.rb +0 -144
  36. data/lib/functional-light-service/i18n/localization_adapter.rb +0 -50
  37. data/lib/functional-light-service/localization_adapter.rb +0 -39
  38. data/lib/functional-light-service/localization_map.rb +0 -9
  39. data/lib/functional-light-service/organizer/execute.rb +0 -16
  40. data/lib/functional-light-service/organizer/iterate.rb +0 -30
  41. data/lib/functional-light-service/organizer/reduce_case.rb +0 -50
  42. data/lib/functional-light-service/organizer/reduce_if.rb +0 -19
  43. data/lib/functional-light-service/organizer/reduce_if_else.rb +0 -23
  44. data/lib/functional-light-service/organizer/reduce_until.rb +0 -22
  45. data/lib/functional-light-service/organizer/reduce_while.rb +0 -31
  46. data/lib/functional-light-service/organizer/scoped_reducable.rb +0 -15
  47. data/lib/functional-light-service/organizer/with_callback.rb +0 -28
  48. data/lib/functional-light-service/organizer/with_reducer.rb +0 -81
  49. data/lib/functional-light-service/organizer/with_reducer_factory.rb +0 -20
  50. data/lib/functional-light-service/organizer/with_reducer_log_decorator.rb +0 -111
  51. data/lib/functional-light-service/organizer.rb +0 -129
  52. data/lib/functional-light-service/testing/context_factory.rb +0 -48
  53. data/lib/functional-light-service/testing.rb +0 -3
  54. data/lib/functional-light-service/version.rb +0 -5
  55. data/resources/fail_actions.png +0 -0
  56. data/resources/light-service.png +0 -0
  57. data/resources/organizer_and_actions.png +0 -0
  58. data/resources/skip_actions.png +0 -0
  59. data/spec/acceptance/add_numbers_spec.rb +0 -11
  60. data/spec/acceptance/after_actions_spec.rb +0 -87
  61. data/spec/acceptance/around_each_spec.rb +0 -19
  62. data/spec/acceptance/before_actions_spec.rb +0 -115
  63. data/spec/acceptance/custom_log_from_organizer_spec.rb +0 -61
  64. data/spec/acceptance/deprecation_warnings_spec.rb +0 -82
  65. data/spec/acceptance/fail_spec.rb +0 -52
  66. data/spec/acceptance/log_from_organizer_spec.rb +0 -154
  67. data/spec/acceptance/message_localization_spec.rb +0 -119
  68. data/spec/acceptance/organizer/add_aliases_spec.rb +0 -28
  69. data/spec/acceptance/organizer/add_to_context_spec.rb +0 -54
  70. data/spec/acceptance/organizer/around_each_with_reduce_if_spec.rb +0 -42
  71. data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +0 -90
  72. data/spec/acceptance/organizer/execute_spec.rb +0 -67
  73. data/spec/acceptance/organizer/iterate_spec.rb +0 -44
  74. data/spec/acceptance/organizer/reduce_case_spec.rb +0 -65
  75. data/spec/acceptance/organizer/reduce_if_else_spec.rb +0 -60
  76. data/spec/acceptance/organizer/reduce_if_spec.rb +0 -89
  77. data/spec/acceptance/organizer/reduce_until_spec.rb +0 -49
  78. data/spec/acceptance/organizer/reduce_while_spec.rb +0 -96
  79. data/spec/acceptance/organizer/with_callback_spec.rb +0 -113
  80. data/spec/acceptance/organizer_entry_point_spec.rb +0 -35
  81. data/spec/acceptance/rollback_spec.rb +0 -183
  82. data/spec/acceptance/skip_all_remaining_spec.rb +0 -139
  83. data/spec/acceptance/testing/context_factory_spec.rb +0 -54
  84. data/spec/action_expected_keys_spec.rb +0 -63
  85. data/spec/action_expects_and_promises_spec.rb +0 -97
  86. data/spec/action_optional_expected_keys_spec.rb +0 -107
  87. data/spec/action_promised_keys_spec.rb +0 -126
  88. data/spec/action_spec.rb +0 -97
  89. data/spec/context/inspect_spec.rb +0 -52
  90. data/spec/context_spec.rb +0 -301
  91. data/spec/examples/amount_spec.rb +0 -77
  92. data/spec/examples/controller_spec.rb +0 -63
  93. data/spec/examples/validate_address_spec.rb +0 -38
  94. data/spec/i18n_localization_adapter_spec.rb +0 -83
  95. data/spec/lib/deterministic/class_mixin_spec.rb +0 -24
  96. data/spec/lib/deterministic/currify_spec.rb +0 -90
  97. data/spec/lib/deterministic/monad_axioms.rb +0 -46
  98. data/spec/lib/deterministic/monad_spec.rb +0 -47
  99. data/spec/lib/deterministic/null_spec.rb +0 -65
  100. data/spec/lib/deterministic/option_spec.rb +0 -140
  101. data/spec/lib/deterministic/result/failure_spec.rb +0 -65
  102. data/spec/lib/deterministic/result/result_map_spec.rb +0 -155
  103. data/spec/lib/deterministic/result/result_shared.rb +0 -25
  104. data/spec/lib/deterministic/result/success_spec.rb +0 -41
  105. data/spec/lib/deterministic/result_spec.rb +0 -63
  106. data/spec/lib/deterministic/sequencer_spec.rb +0 -506
  107. data/spec/lib/edge_cases_spec.rb +0 -156
  108. data/spec/lib/enum_spec.rb +0 -114
  109. data/spec/lib/native_pattern_matching_spec.rb +0 -74
  110. data/spec/localization_adapter_spec.rb +0 -66
  111. data/spec/organizer/with_reducer_spec.rb +0 -56
  112. data/spec/organizer_key_aliases_spec.rb +0 -29
  113. data/spec/organizer_spec.rb +0 -115
  114. data/spec/readme_spec.rb +0 -45
  115. data/spec/sample/calculates_order_tax_action_spec.rb +0 -16
  116. data/spec/sample/calculates_tax_spec.rb +0 -30
  117. data/spec/sample/looks_up_tax_percentage_action_spec.rb +0 -55
  118. data/spec/sample/provides_free_shipping_action_spec.rb +0 -25
  119. data/spec/sample/tax/calculates_order_tax_action.rb +0 -10
  120. data/spec/sample/tax/calculates_tax.rb +0 -11
  121. data/spec/sample/tax/looks_up_tax_percentage_action.rb +0 -28
  122. data/spec/sample/tax/provides_free_shipping_action.rb +0 -11
  123. data/spec/spec_helper.rb +0 -32
  124. data/spec/support.rb +0 -1
  125. data/spec/test_doubles.rb +0 -656
  126. data/spec/testing/context_factory/iterate_spec.rb +0 -39
  127. data/spec/testing/context_factory/reduce_if_spec.rb +0 -40
  128. data/spec/testing/context_factory/reduce_until_spec.rb +0 -40
  129. data/spec/testing/context_factory/with_callback_spec.rb +0 -38
  130. data/spec/testing/context_factory_spec.rb +0 -76
@@ -1,126 +0,0 @@
1
- require 'spec_helper'
2
- require 'test_doubles'
3
-
4
- describe ":promises macro" do
5
- context "when the promised key is not in the context" do
6
- it "raises an ArgumentError" do
7
- module TestDoubles
8
- class MakesCappuccinoAction1
9
- extend FunctionalLightService::Action
10
-
11
- expects :coffee, :milk
12
- promises :cappuccino
13
- executed do |context|
14
- context[:macchiato] = "#{context.coffee} - #{context.milk}"
15
- end
16
- end
17
- end
18
-
19
- exception_msg = "promised :cappuccino to be in the context during " \
20
- "TestDoubles::MakesCappuccinoAction1"
21
- expect do
22
- TestDoubles::MakesCappuccinoAction1.execute(:coffee => "espresso",
23
- :milk => "2%")
24
- end.to \
25
- raise_error(FunctionalLightService::PromisedKeysNotInContextError, exception_msg)
26
- end
27
-
28
- it "can fail the context without fulfilling its promise" do
29
- module TestDoubles
30
- class MakesCappuccinoAction2
31
- extend FunctionalLightService::Action
32
-
33
- expects :coffee, :milk
34
- promises :cappuccino
35
- executed do |context|
36
- context.fail!("Sorry, something bad has happened.")
37
- end
38
- end
39
- end
40
-
41
- result_context = TestDoubles::MakesCappuccinoAction2
42
- .execute(:coffee => "espresso",
43
- :milk => "2%")
44
-
45
- expect(result_context).to be_failure
46
- expect(result_context.keys).not_to include(:cappuccino)
47
- end
48
- end
49
-
50
- context "when the promised key is in the context" do
51
- it "can be set with an actual value" do
52
- module TestDoubles
53
- class MakesCappuccinoAction3
54
- extend FunctionalLightService::Action
55
-
56
- expects :coffee, :milk
57
- promises :cappuccino
58
- executed do |context|
59
- context.cappuccino = "#{context.coffee} - with #{context.milk} milk"
60
- context.cappuccino += " hot"
61
- end
62
- end
63
- end
64
-
65
- result_context = TestDoubles::MakesCappuccinoAction3
66
- .execute(:coffee => "espresso",
67
- :milk => "2%")
68
-
69
- expect(result_context).to be_success
70
- expect(result_context.cappuccino).to eq("espresso - with 2% milk hot")
71
- end
72
-
73
- it "can be set with nil" do
74
- module TestDoubles
75
- class MakesCappuccinoAction4
76
- extend FunctionalLightService::Action
77
-
78
- expects :coffee, :milk
79
- promises :cappuccino
80
- executed do |context|
81
- context.cappuccino = nil
82
- end
83
- end
84
- end
85
- result_context = TestDoubles::MakesCappuccinoAction4
86
- .execute(:coffee => "espresso",
87
- :milk => "2%")
88
-
89
- expect(result_context).to be_success
90
- expect(result_context[:cappuccino]).to be_nil
91
- end
92
- end
93
-
94
- context "when a reserved key is listed as a promised key" do
95
- it "raises error indicating a reserved key has been promised" do
96
- exception_msg = "promised or expected keys cannot be a reserved key: " \
97
- "[:message]"
98
- expect do
99
- TestDoubles::MakesTeaPromisingReservedKey.execute(:tea => "black")
100
- end.to \
101
- raise_error(FunctionalLightService::ReservedKeysInContextError, exception_msg)
102
- end
103
-
104
- it "raises error indicating multiple reserved keys have been promised" do
105
- exception_msg = "promised or expected keys cannot be a reserved key: " \
106
- "[:message, :error_code, :current_action]"
107
- expect do
108
- ctx = { :tea => "black" }
109
- TestDoubles::MakesTeaPromisingMultipleReservedKeys.execute(ctx)
110
- end.to \
111
- raise_error(FunctionalLightService::ReservedKeysInContextError, exception_msg)
112
- end
113
- end
114
-
115
- context "when the `promised` macro is called multiple times" do
116
- it "collects promised keys " do
117
- result = TestDoubles::MultiplePromisesAction
118
- .execute(:coffee => "espresso", :milk => "2%")
119
-
120
- expect(result.cappuccino).to \
121
- eq("Cappucino needs espresso and a little milk")
122
- expect(result.latte).to \
123
- eq("Latte needs espresso and a lot of milk")
124
- end
125
- end
126
- end
data/spec/action_spec.rb DELETED
@@ -1,97 +0,0 @@
1
- require 'spec_helper'
2
- require 'test_doubles'
3
-
4
- describe FunctionalLightService::Action do
5
- let(:context) { FunctionalLightService::Context.make }
6
-
7
- context "when the action context has failure" do
8
- it "returns immediately" do
9
- context.fail!("an error")
10
-
11
- TestDoubles::AddsTwoActionWithFetch.execute(context)
12
-
13
- expect(context.to_hash.keys).to be_empty
14
- end
15
-
16
- it "returns the failure message in the context" do
17
- context.fail!("an error")
18
-
19
- returned_context = TestDoubles::AddsTwoActionWithFetch.execute(context)
20
-
21
- expect(returned_context.message).to eq("an error")
22
- end
23
- end
24
-
25
- context "when the action has an explicit success message" do
26
- it "returns the success message in the context" do
27
- context.succeed!("successful")
28
-
29
- returned_context = TestDoubles::AddsTwoActionWithFetch.execute(context)
30
-
31
- expect(returned_context.message).to eq("successful")
32
- end
33
- end
34
-
35
- context "when the action context does not have failure" do
36
- it "executes the block" do
37
- TestDoubles::AddsTwoActionWithFetch.execute(context)
38
-
39
- expect(context.to_hash.keys).to eq [:number]
40
- expect(context.fetch(:number)).to eq(2)
41
- end
42
- end
43
-
44
- context "when the action context skips all" do
45
- it "returns immediately" do
46
- context.skip_remaining!
47
-
48
- TestDoubles::AddsTwoActionWithFetch.execute(context)
49
-
50
- expect(context.to_hash.keys).to be_empty
51
- end
52
-
53
- it "does not execute skipped actions" do
54
- TestDoubles::AddsTwoActionWithFetch.execute(context)
55
- expect(context.to_hash).to eq(:number => 2)
56
-
57
- context.skip_remaining!
58
-
59
- TestDoubles::AddsTwoActionWithFetch.execute(context)
60
- # Since the action was skipped, the number remains 2
61
- expect(context.to_hash).to eq(:number => 2)
62
- end
63
- end
64
-
65
- it "returns the context" do
66
- result = TestDoubles::AddsTwoActionWithFetch.execute(context)
67
-
68
- expect(result.to_hash).to eq(:number => 2)
69
- end
70
-
71
- context "when called directly" do
72
- it "is expected to not be organized" do
73
- result = TestDoubles::AddsTwoActionWithFetch.execute(context)
74
-
75
- expect(result.organized_by).to be_nil
76
- end
77
- end
78
-
79
- context "when invoked with hash" do
80
- it "creates FunctionalLightService::Context implicitly" do
81
- ctx = { :some_key => "some value" }
82
- result = TestDoubles::AddsTwoActionWithFetch.execute(ctx)
83
-
84
- expect(result).to be_success
85
- expect(result.keys).to eq(%i[some_key number])
86
- end
87
- end
88
-
89
- context "when invoked without arguments" do
90
- it "creates FunctionalLightService::Context implicitly" do
91
- result = TestDoubles::AddsTwoActionWithFetch.execute
92
-
93
- expect(result).to be_success
94
- expect(result.keys).to eq([:number])
95
- end
96
- end
97
- end
@@ -1,52 +0,0 @@
1
- require 'spec_helper'
2
- require 'test_doubles'
3
-
4
- RSpec.describe FunctionalLightService::Context do
5
- subject(:context) { FunctionalLightService::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
- "FunctionalLightService::Context({}, success: true, message: '', error_code: nil, " \
17
- "skip_remaining: false, skip_all_remaining: false, aliases: {})"
18
-
19
- expect(context.inspect).to eq(inspected_context)
20
- end
21
-
22
- it 'prints the error message' do
23
- context.fail!('There was an error')
24
-
25
- inspected_context =
26
- "FunctionalLightService::Context({}, success: false, message: 'There was an error', " \
27
- "error_code: nil, skip_remaining: false, skip_all_remaining: false, aliases: {})"
28
-
29
- expect(context.inspect).to eq(inspected_context)
30
- end
31
-
32
- it 'prints skip_remaining' do
33
- context.skip_remaining!('No need to process')
34
-
35
- inspected_context =
36
- "FunctionalLightService::Context({}, success: true, message: 'No need to process', " \
37
- "error_code: nil, skip_remaining: true, skip_all_remaining: false, aliases: {})"
38
-
39
- expect(context.inspect).to eq(inspected_context)
40
- end
41
-
42
- it 'prints skip_all_remaining' do
43
- context.skip_all_remaining!('Nothing else to process')
44
-
45
- inspected_context =
46
- "FunctionalLightService::Context({}, success: true, message: 'Nothing else to process', " \
47
- "error_code: nil, skip_remaining: false, skip_all_remaining: true, aliases: {})"
48
-
49
- expect(context.inspect).to eq(inspected_context)
50
- end
51
- end
52
- end
data/spec/context_spec.rb DELETED
@@ -1,301 +0,0 @@
1
- require 'spec_helper'
2
- require 'test_doubles'
3
-
4
- RSpec.describe FunctionalLightService::Context do
5
- let(:context) { FunctionalLightService::Context.make }
6
-
7
- describe "can be made" do
8
- context "with no arguments" do
9
- subject { FunctionalLightService::Context.make }
10
- it { is_expected.to be_success }
11
- specify "message is empty string" do
12
- expect(context.message).to be_empty
13
- end
14
- end
15
-
16
- context "with a hash" do
17
- it "has the hash values" do
18
- context = FunctionalLightService::Context.make(:one => 1)
19
-
20
- expect(context[:one]).to eq(1)
21
- end
22
- end
23
-
24
- context "with FAILURE" do
25
- it "is failed" do
26
- outcome = FunctionalLightService::Result::Failure(:message => '', :error => nil)
27
- context = FunctionalLightService::Context.new({}, outcome)
28
-
29
- expect(context).to be_failure
30
- end
31
- end
32
- end
33
-
34
- describe "can't be made" do
35
- specify "with invalid parameters" do
36
- expect { FunctionalLightService::Context.make([]) }.to raise_error(ArgumentError)
37
- end
38
- end
39
-
40
- it "can be asked for success?" do
41
- outcome = FunctionalLightService::Result::Success(:message => '', :error => nil)
42
- context = FunctionalLightService::Context.new({}, outcome)
43
-
44
- expect(context).to be_success
45
- end
46
-
47
- it "can be asked for failure?" do
48
- outcome = FunctionalLightService::Result::Failure(:message => '', :error => nil)
49
- context = FunctionalLightService::Context.new({}, outcome)
50
-
51
- expect(context).to be_failure
52
- end
53
-
54
- it "can be asked for skip_remaining?" do
55
- context.skip_remaining!
56
-
57
- expect(context.skip_remaining?).to be_truthy
58
- end
59
-
60
- it "can be pushed into a SUCCESS state" do
61
- context.succeed!("a happy end")
62
-
63
- expect(context).to be_success
64
- end
65
-
66
- it "can be pushed into a SUCCESS state without a message" do
67
- context.succeed!
68
-
69
- expect(context).to be_success
70
- expect(context.message).to be_nil
71
- end
72
-
73
- it "can be pushed into a FAILURE state without a message" do
74
- context.fail!
75
-
76
- expect(context).to be_failure
77
- expect(context.message).to be_nil
78
- end
79
-
80
- it "can be pushed into a FAILURE state with a message" do
81
- context.fail!("a sad end")
82
-
83
- expect(context).to be_failure
84
- end
85
-
86
- it "can be pushed into a FAILURE state with a message in an options hash" do
87
- context.fail!("a sad end")
88
-
89
- expect(context).to be_failure
90
- expect(context.message).to eq("a sad end")
91
- expect(context.error_code).to be_nil
92
- end
93
-
94
- it "can be pushed into a FAILURE state with an error code in options hash" do
95
- context.fail!("a sad end", 10_005)
96
-
97
- expect(context).to be_failure
98
- expect(context.message).to eq("a sad end")
99
- expect(context.error_code).to eq(10_005)
100
- end
101
-
102
- it "uses localization adapter to translate failure message" do
103
- action_class = TestDoubles::AnAction
104
- expect(FunctionalLightService::Configuration.localization_adapter)
105
- .to receive(:failure)
106
- .with(:failure_reason, action_class, {})
107
- .and_return("message")
108
-
109
- context = FunctionalLightService::Context.make
110
- context.current_action = action_class
111
- context.fail!(:failure_reason)
112
-
113
- expect(context).to be_failure
114
- expect(context.message).to eq("message")
115
- end
116
-
117
- it "uses localization adapter to translate success message" do
118
- action_class = TestDoubles::AnAction
119
- expect(FunctionalLightService::Configuration.localization_adapter)
120
- .to receive(:success)
121
- .with(:action_passed, action_class, {})
122
- .and_return("message")
123
-
124
- context = FunctionalLightService::Context.make
125
- context.current_action = action_class
126
- context.succeed!(:action_passed)
127
-
128
- expect(context).to be_success
129
- expect(context.message).to eq("message")
130
- end
131
-
132
- it "can set a flag to skip all subsequent actions" do
133
- context.skip_remaining!
134
-
135
- expect(context).to be_skip_remaining
136
- end
137
-
138
- context "stopping additional processing in an action" do
139
- it "flags processing to stop on failure" do
140
- context.fail!("on purpose")
141
- expect(context.stop_processing?).to be_truthy
142
- end
143
-
144
- it "flags processing to stop when remaining actions should be skipped" do
145
- context.skip_remaining!
146
- expect(context.stop_processing?).to be_truthy
147
- end
148
- end
149
-
150
- it "can fail with FailWithRollBackError" do
151
- expect { context.fail_with_rollback!("roll me back") }.to \
152
- raise_error(FunctionalLightService::FailWithRollbackError)
153
- end
154
-
155
- it "exptected outcome reader get Success and message empty and error nil" do
156
- outcome = FunctionalLightService::Result::Success(:message => "", :error => nil)
157
- expect(context.outcome).to eq(outcome)
158
- end
159
-
160
- it "can contain false values" do
161
- context = FunctionalLightService::Context.make(:foo => false)
162
- expect(context[:foo]).to eq false
163
- end
164
-
165
- it "allows a default value for #fetch" do
166
- expect(context.fetch(:madeup, :default)).to eq(:default)
167
- end
168
-
169
- it "allows a default block value for #fetch" do
170
- # la forma a blocco e' esattamente cio' che il test verifica
171
- expect(context.fetch(:madeup) { :default }).to eq(:default) # rubocop:disable Style/RedundantFetchBlock
172
- end
173
-
174
- describe "#define_accessor_methods_for_keys" do
175
- it "raises when a key conflicts with an existing Hash/Context method" do
176
- expect { context.define_accessor_methods_for_keys([:size]) }
177
- .to raise_error(FunctionalLightService::ReservedKeysInContextError, /:size conflicts/)
178
- end
179
-
180
- it "does not raise when re-defining accessors for the same key" do
181
- ctx = FunctionalLightService::Context.make(:number => 1)
182
- ctx.define_accessor_methods_for_keys([:number])
183
-
184
- expect { ctx.define_accessor_methods_for_keys([:number]) }.not_to raise_error
185
- expect(ctx.number).to eq(1)
186
- end
187
- end
188
-
189
- describe "reserved keys" do
190
- it "rejects infrastructure keys in expects/promises" do
191
- action = Class.new do
192
- extend FunctionalLightService::Action
193
-
194
- expects :_before_actions
195
- executed { |_ctx| } # rubocop:disable Lint/EmptyBlock
196
- end
197
-
198
- expect { action.execute(:_before_actions => []) }
199
- .to raise_error(FunctionalLightService::ReservedKeysInContextError)
200
- end
201
-
202
- it "rejects :organized_by in expects/promises" do
203
- action = Class.new do
204
- extend FunctionalLightService::Action
205
-
206
- expects :organized_by
207
- executed { |_ctx| } # rubocop:disable Lint/EmptyBlock
208
- end
209
-
210
- expect { action.execute(:organized_by => Object) }
211
- .to raise_error(FunctionalLightService::ReservedKeysInContextError)
212
- end
213
- end
214
-
215
- describe "#fail! does not mutate the caller's options hash" do
216
- it "leaves :error_code in the original hash" do
217
- options = { :error_code => 500 }
218
- context.fail!("boom", options)
219
-
220
- expect(options).to eq(:error_code => 500)
221
- expect(context.error_code).to eq(500)
222
- end
223
- end
224
-
225
- describe "#reset_skip_remaining!" do
226
- it "clears the flag but keeps the outcome and its message" do
227
- context.skip_remaining!("No need to process")
228
- context.reset_skip_remaining!
229
-
230
- expect(context.skip_remaining?).to be(false)
231
- expect(context).to be_success
232
- expect(context.message).to eq("No need to process")
233
- end
234
- end
235
-
236
- describe "#fetch honours the Hash#fetch contract" do
237
- it "raises KeyError for a missing key without default" do
238
- expect { context.fetch(:madeup) }.to raise_error(KeyError)
239
- end
240
-
241
- it "does not write to the context when a default is used" do
242
- context.fetch(:madeup, :default)
243
- context.fetch(:another_madeup) { :default } # rubocop:disable Style/RedundantFetchBlock
244
-
245
- expect(context.to_h).not_to have_key(:madeup)
246
- expect(context.to_h).not_to have_key(:another_madeup)
247
- end
248
-
249
- it "returns existing falsy values instead of the default" do
250
- context = FunctionalLightService::Context.make(:flag => false)
251
-
252
- expect(context.fetch(:flag, true)).to eq(false)
253
- end
254
- end
255
-
256
- context "when aliases are included via .make" do
257
- let(:context) do
258
- FunctionalLightService::Context.make(
259
- :foo => "foobar",
260
- :foo2 => false,
261
- :_aliases => aliases
262
- )
263
- end
264
- let(:aliases) { { :foo => :bar, :foo2 => :bar2 } }
265
-
266
- it "contains the aliases" do
267
- expect(context.aliases).to eq(aliases)
268
- expect(context).to include(:foo, :bar)
269
- end
270
-
271
- it "returns the correct values for #[] and #fetch" do
272
- expect(context[:bar]).to eq context[:foo]
273
- expect(context.fetch(:bar)).to eq context[:foo]
274
- end
275
-
276
- it "can contain false values" do
277
- expect(context[:bar2]).to eq false
278
- end
279
-
280
- it "resolves aliases on writes too, symmetrically with reads" do
281
- context[:bar] = "updated"
282
-
283
- expect(context[:bar]).to eq("updated")
284
- expect(context[:foo]).to eq("updated")
285
- # nessuna chiave duplicata: l'alias e' un nome alternativo, non una copia
286
- expect(context.to_h).not_to have_key(:bar)
287
- end
288
-
289
- it "resolves aliases in #key? and friends" do
290
- expect(context.key?(:bar)).to be(true)
291
- expect(context.has_key?(:bar)).to be(true) # rubocop:disable Style/PreferredHashMethods
292
- expect(context.member?(:bar)).to be(true)
293
- expect(context.include?(:bar)).to be(true)
294
- expect(context.key?(:madeup)).to be(false)
295
- end
296
-
297
- it "resolves aliases in #fetch with defaults" do
298
- expect(context.fetch(:bar, :default)).to eq("foobar")
299
- end
300
- end
301
- end
@@ -1,77 +0,0 @@
1
- require 'spec_helper'
2
- require 'functional-light-service/functional/enum'
3
-
4
- Amount = FunctionalLightService.enum do
5
- Due(:amount)
6
- Paid(:amount)
7
- Info(:amount)
8
- end
9
-
10
- class Amount
11
- def self.from_f(f)
12
- f >= 0 ? Amount::Due.new(f) : Amount::Paid.new(-1 * f)
13
- end
14
- end
15
-
16
- FunctionalLightService.impl(Amount) do
17
- def to_s
18
- match do
19
- Due() { |a| format("%0.2f", a) }
20
- Paid() { |a| format("-%0.2f", a) }
21
- Info() { |a| format("(%0.2f)", a) }
22
- end
23
- end
24
-
25
- def to_f
26
- match do
27
- Info() { |_a| 0 }
28
- Due() { |a| a }
29
- Paid() { |a| -1 * a }
30
- end
31
- end
32
-
33
- def +(other)
34
- raise TypeError "Expected other to be an Amount, got #{other.class}" unless other.is_a? Amount
35
-
36
- Amount.from_f(to_f + other.to_f)
37
- end
38
- end
39
-
40
- describe Amount do
41
- # rubocop:disable Naming/MethodName
42
- def Due(a)
43
- Amount::Due.new(a)
44
- end
45
-
46
- def Paid(a)
47
- Amount::Paid.new(a)
48
- end
49
-
50
- def Info(a)
51
- Amount::Info.new(a)
52
- end
53
- # rubocop:enable Naming/MethodName
54
-
55
- it "due" do
56
- amount = Amount::Due.new(100.2)
57
- expect(amount.to_s).to eq "100.20"
58
- end
59
-
60
- it "paid" do
61
- amount = Amount::Paid.new(100.1)
62
- expect(amount.to_s).to eq "-100.10"
63
- end
64
-
65
- it "paid" do
66
- amount = Amount::Info.new(100.31)
67
- expect(amount.to_s).to eq "(100.31)"
68
- end
69
-
70
- it "+" do
71
- expect(Due(10) + Paid(20)).to eq Paid(10)
72
- expect(Due(10) + Paid(10)).to eq Due(0)
73
- expect(Due(10) + Due(10)).to eq Due(20)
74
- expect(Paid(10) + Paid(10)).to eq Paid(20)
75
- expect(Paid(10) + Due(1) + Info(99)).to eq Paid(9)
76
- end
77
- end