functional-light-service 6.1.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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/lib/functional-light-service.rb +6 -31
  3. metadata +15 -297
  4. data/.github/workflows/project-build.yml +0 -71
  5. data/.gitignore +0 -22
  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 -273
  12. data/CODE_OF_CONDUCT.md +0 -22
  13. data/Gemfile +0 -4
  14. data/LICENSE +0 -22
  15. data/README.md +0 -1578
  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 -33
  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 -97
  24. data/lib/functional-light-service/configuration.rb +0 -26
  25. data/lib/functional-light-service/context/key_verifier.rb +0 -124
  26. data/lib/functional-light-service/context.rb +0 -195
  27. data/lib/functional-light-service/deprecations.rb +0 -26
  28. data/lib/functional-light-service/errors.rb +0 -8
  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/localization_adapter.rb +0 -48
  37. data/lib/functional-light-service/organizer/execute.rb +0 -16
  38. data/lib/functional-light-service/organizer/iterate.rb +0 -30
  39. data/lib/functional-light-service/organizer/reduce_if.rb +0 -19
  40. data/lib/functional-light-service/organizer/reduce_until.rb +0 -22
  41. data/lib/functional-light-service/organizer/scoped_reducable.rb +0 -15
  42. data/lib/functional-light-service/organizer/with_callback.rb +0 -28
  43. data/lib/functional-light-service/organizer/with_reducer.rb +0 -81
  44. data/lib/functional-light-service/organizer/with_reducer_factory.rb +0 -20
  45. data/lib/functional-light-service/organizer/with_reducer_log_decorator.rb +0 -110
  46. data/lib/functional-light-service/organizer.rb +0 -114
  47. data/lib/functional-light-service/testing/context_factory.rb +0 -48
  48. data/lib/functional-light-service/testing.rb +0 -3
  49. data/lib/functional-light-service/version.rb +0 -5
  50. data/resources/fail_actions.png +0 -0
  51. data/resources/light-service.png +0 -0
  52. data/resources/organizer_and_actions.png +0 -0
  53. data/resources/skip_actions.png +0 -0
  54. data/spec/acceptance/add_numbers_spec.rb +0 -11
  55. data/spec/acceptance/after_actions_spec.rb +0 -87
  56. data/spec/acceptance/around_each_spec.rb +0 -19
  57. data/spec/acceptance/before_actions_spec.rb +0 -115
  58. data/spec/acceptance/custom_log_from_organizer_spec.rb +0 -61
  59. data/spec/acceptance/deprecation_warnings_spec.rb +0 -82
  60. data/spec/acceptance/fail_spec.rb +0 -52
  61. data/spec/acceptance/log_from_organizer_spec.rb +0 -154
  62. data/spec/acceptance/message_localization_spec.rb +0 -119
  63. data/spec/acceptance/organizer/add_aliases_spec.rb +0 -28
  64. data/spec/acceptance/organizer/add_to_context_spec.rb +0 -30
  65. data/spec/acceptance/organizer/around_each_with_reduce_if_spec.rb +0 -42
  66. data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +0 -68
  67. data/spec/acceptance/organizer/execute_spec.rb +0 -46
  68. data/spec/acceptance/organizer/iterate_spec.rb +0 -44
  69. data/spec/acceptance/organizer/reduce_if_spec.rb +0 -89
  70. data/spec/acceptance/organizer/reduce_until_spec.rb +0 -49
  71. data/spec/acceptance/organizer/with_callback_spec.rb +0 -113
  72. data/spec/acceptance/organizer_entry_point_spec.rb +0 -35
  73. data/spec/acceptance/rollback_spec.rb +0 -183
  74. data/spec/acceptance/testing/context_factory_spec.rb +0 -54
  75. data/spec/action_expected_keys_spec.rb +0 -63
  76. data/spec/action_expects_and_promises_spec.rb +0 -97
  77. data/spec/action_promised_keys_spec.rb +0 -126
  78. data/spec/action_spec.rb +0 -97
  79. data/spec/context/inspect_spec.rb +0 -42
  80. data/spec/context_spec.rb +0 -289
  81. data/spec/examples/amount_spec.rb +0 -77
  82. data/spec/examples/controller_spec.rb +0 -63
  83. data/spec/examples/validate_address_spec.rb +0 -38
  84. data/spec/lib/deterministic/class_mixin_spec.rb +0 -24
  85. data/spec/lib/deterministic/currify_spec.rb +0 -90
  86. data/spec/lib/deterministic/monad_axioms.rb +0 -46
  87. data/spec/lib/deterministic/monad_spec.rb +0 -47
  88. data/spec/lib/deterministic/null_spec.rb +0 -65
  89. data/spec/lib/deterministic/option_spec.rb +0 -140
  90. data/spec/lib/deterministic/result/failure_spec.rb +0 -65
  91. data/spec/lib/deterministic/result/result_map_spec.rb +0 -155
  92. data/spec/lib/deterministic/result/result_shared.rb +0 -25
  93. data/spec/lib/deterministic/result/success_spec.rb +0 -41
  94. data/spec/lib/deterministic/result_spec.rb +0 -63
  95. data/spec/lib/deterministic/sequencer_spec.rb +0 -506
  96. data/spec/lib/edge_cases_spec.rb +0 -156
  97. data/spec/lib/enum_spec.rb +0 -114
  98. data/spec/lib/native_pattern_matching_spec.rb +0 -74
  99. data/spec/localization_adapter_spec.rb +0 -83
  100. data/spec/organizer/with_reducer_spec.rb +0 -56
  101. data/spec/organizer_key_aliases_spec.rb +0 -29
  102. data/spec/organizer_spec.rb +0 -115
  103. data/spec/readme_spec.rb +0 -45
  104. data/spec/sample/calculates_order_tax_action_spec.rb +0 -16
  105. data/spec/sample/calculates_tax_spec.rb +0 -30
  106. data/spec/sample/looks_up_tax_percentage_action_spec.rb +0 -55
  107. data/spec/sample/provides_free_shipping_action_spec.rb +0 -25
  108. data/spec/sample/tax/calculates_order_tax_action.rb +0 -10
  109. data/spec/sample/tax/calculates_tax.rb +0 -11
  110. data/spec/sample/tax/looks_up_tax_percentage_action.rb +0 -28
  111. data/spec/sample/tax/provides_free_shipping_action.rb +0 -11
  112. data/spec/spec_helper.rb +0 -29
  113. data/spec/support.rb +0 -1
  114. data/spec/test_doubles.rb +0 -628
  115. data/spec/testing/context_factory/iterate_spec.rb +0 -39
  116. data/spec/testing/context_factory/reduce_if_spec.rb +0 -40
  117. data/spec/testing/context_factory/reduce_until_spec.rb +0 -40
  118. data/spec/testing/context_factory/with_callback_spec.rb +0 -38
  119. 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,42 +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, 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, 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, aliases: {})"
38
-
39
- expect(context.inspect).to eq(inspected_context)
40
- end
41
- end
42
- end
data/spec/context_spec.rb DELETED
@@ -1,289 +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
- end
202
-
203
- describe "#fail! does not mutate the caller's options hash" do
204
- it "leaves :error_code in the original hash" do
205
- options = { :error_code => 500 }
206
- context.fail!("boom", options)
207
-
208
- expect(options).to eq(:error_code => 500)
209
- expect(context.error_code).to eq(500)
210
- end
211
- end
212
-
213
- describe "#reset_skip_remaining!" do
214
- it "clears the flag but keeps the outcome and its message" do
215
- context.skip_remaining!("No need to process")
216
- context.reset_skip_remaining!
217
-
218
- expect(context.skip_remaining?).to be(false)
219
- expect(context).to be_success
220
- expect(context.message).to eq("No need to process")
221
- end
222
- end
223
-
224
- describe "#fetch honours the Hash#fetch contract" do
225
- it "raises KeyError for a missing key without default" do
226
- expect { context.fetch(:madeup) }.to raise_error(KeyError)
227
- end
228
-
229
- it "does not write to the context when a default is used" do
230
- context.fetch(:madeup, :default)
231
- context.fetch(:another_madeup) { :default } # rubocop:disable Style/RedundantFetchBlock
232
-
233
- expect(context.to_h).not_to have_key(:madeup)
234
- expect(context.to_h).not_to have_key(:another_madeup)
235
- end
236
-
237
- it "returns existing falsy values instead of the default" do
238
- context = FunctionalLightService::Context.make(:flag => false)
239
-
240
- expect(context.fetch(:flag, true)).to eq(false)
241
- end
242
- end
243
-
244
- context "when aliases are included via .make" do
245
- let(:context) do
246
- FunctionalLightService::Context.make(
247
- :foo => "foobar",
248
- :foo2 => false,
249
- :_aliases => aliases
250
- )
251
- end
252
- let(:aliases) { { :foo => :bar, :foo2 => :bar2 } }
253
-
254
- it "contains the aliases" do
255
- expect(context.aliases).to eq(aliases)
256
- expect(context).to include(:foo, :bar)
257
- end
258
-
259
- it "returns the correct values for #[] and #fetch" do
260
- expect(context[:bar]).to eq context[:foo]
261
- expect(context.fetch(:bar)).to eq context[:foo]
262
- end
263
-
264
- it "can contain false values" do
265
- expect(context[:bar2]).to eq false
266
- end
267
-
268
- it "resolves aliases on writes too, symmetrically with reads" do
269
- context[:bar] = "updated"
270
-
271
- expect(context[:bar]).to eq("updated")
272
- expect(context[:foo]).to eq("updated")
273
- # nessuna chiave duplicata: l'alias e' un nome alternativo, non una copia
274
- expect(context.to_h).not_to have_key(:bar)
275
- end
276
-
277
- it "resolves aliases in #key? and friends" do
278
- expect(context.key?(:bar)).to be(true)
279
- expect(context.has_key?(:bar)).to be(true) # rubocop:disable Style/PreferredHashMethods
280
- expect(context.member?(:bar)).to be(true)
281
- expect(context.include?(:bar)).to be(true)
282
- expect(context.key?(:madeup)).to be(false)
283
- end
284
-
285
- it "resolves aliases in #fetch with defaults" do
286
- expect(context.fetch(:bar, :default)).to eq("foobar")
287
- end
288
- end
289
- 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
@@ -1,63 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module FunctionalLightService
4
- module Procify
5
- def py(m, *args)
6
- args.any? ? method(m).to_proc.curry[*args] : method(m)
7
- end
8
- end
9
- end
10
-
11
- class BookingController
12
- include FunctionalLightService::Prelude::Result
13
- include FunctionalLightService::Procify
14
-
15
- Context = Struct.new(:booking, :ability, :format)
16
-
17
- def index(id, format = :html)
18
- get_booking(id) << log(:booking) >>
19
- py(:ability) << log(:ability) >>
20
- py(:present, format) << log(:presenter) >>
21
- py(:render) << log(:render)
22
- end
23
-
24
- def log(step)
25
- ->(data) { [step, data] }
26
- end
27
-
28
- def ability(ctx)
29
- ctx.ability = {} # Ability.new(@booking)
30
- Success(ctx)
31
- end
32
-
33
- def present(format, ctx)
34
- ctx.format = format
35
-
36
- Success(ctx)
37
- end
38
-
39
- def render(ctx)
40
- send(ctx.format, ctx)
41
- end
42
-
43
- def html(ctx)
44
- Success(ctx)
45
- end
46
-
47
- def get_booking(id)
48
- ctx = Context.new
49
- ctx.booking = { :ref_anixe => id }
50
- Success(ctx)
51
- # @booking = @bms.booking_by_id(id)
52
- # rescue BSON::InvalidObjectId => ex
53
- # @booking = nil
54
- # @ui.error(404, ex.message)
55
- end
56
- end
57
-
58
- describe BookingController do
59
- it "does something" do
60
- bc = BookingController.new
61
- bc.index('1234', :html)
62
- end
63
- end