functional-light-service 0.4.4 → 6.0.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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/project-build.yml +43 -11
  3. data/.rubocop.yml +101 -160
  4. data/AUDIT-functional-light-service.md +352 -0
  5. data/Appraisals +4 -0
  6. data/CHANGELOG.md +118 -0
  7. data/Gemfile +0 -2
  8. data/README.md +1544 -1426
  9. data/Rakefile +1 -1
  10. data/VERSION +1 -1
  11. data/audit/bench.rb +99 -0
  12. data/audit/verify_findings.rb +172 -0
  13. data/functional-light-service.gemspec +15 -16
  14. data/lib/functional-light-service/action.rb +97 -101
  15. data/lib/functional-light-service/configuration.rb +26 -24
  16. data/lib/functional-light-service/context/key_verifier.rb +124 -118
  17. data/lib/functional-light-service/context.rb +63 -20
  18. data/lib/functional-light-service/deprecations.rb +26 -0
  19. data/lib/functional-light-service/errors.rb +8 -6
  20. data/lib/functional-light-service/functional/enum.rb +286 -250
  21. data/lib/functional-light-service/functional/maybe.rb +21 -15
  22. data/lib/functional-light-service/functional/monad.rb +77 -66
  23. data/lib/functional-light-service/functional/null.rb +88 -74
  24. data/lib/functional-light-service/functional/option.rb +100 -97
  25. data/lib/functional-light-service/functional/result.rb +129 -116
  26. data/lib/functional-light-service/localization_adapter.rb +48 -47
  27. data/lib/functional-light-service/organizer/execute.rb +16 -14
  28. data/lib/functional-light-service/organizer/iterate.rb +30 -25
  29. data/lib/functional-light-service/organizer/reduce_if.rb +19 -17
  30. data/lib/functional-light-service/organizer/reduce_until.rb +22 -20
  31. data/lib/functional-light-service/organizer/scoped_reducable.rb +15 -13
  32. data/lib/functional-light-service/organizer/with_callback.rb +28 -26
  33. data/lib/functional-light-service/organizer/with_reducer.rb +81 -71
  34. data/lib/functional-light-service/organizer/with_reducer_factory.rb +20 -18
  35. data/lib/functional-light-service/organizer/with_reducer_log_decorator.rb +110 -105
  36. data/lib/functional-light-service/organizer.rb +114 -104
  37. data/lib/functional-light-service/testing/context_factory.rb +48 -42
  38. data/lib/functional-light-service/testing.rb +3 -1
  39. data/lib/functional-light-service/version.rb +5 -3
  40. data/lib/functional-light-service.rb +30 -28
  41. data/spec/acceptance/after_actions_spec.rb +87 -71
  42. data/spec/acceptance/before_actions_spec.rb +115 -98
  43. data/spec/acceptance/custom_log_from_organizer_spec.rb +61 -60
  44. data/spec/acceptance/deprecation_warnings_spec.rb +82 -0
  45. data/spec/acceptance/fail_spec.rb +52 -50
  46. data/spec/acceptance/message_localization_spec.rb +119 -118
  47. data/spec/acceptance/organizer/add_aliases_spec.rb +28 -0
  48. data/spec/acceptance/organizer/add_to_context_spec.rb +30 -0
  49. data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +68 -65
  50. data/spec/acceptance/organizer/iterate_spec.rb +7 -0
  51. data/spec/acceptance/organizer/reduce_if_spec.rb +89 -83
  52. data/spec/acceptance/organizer/reduce_until_spec.rb +6 -0
  53. data/spec/acceptance/organizer/with_callback_spec.rb +113 -110
  54. data/spec/acceptance/{not_having_call_method_warning_spec.rb → organizer_entry_point_spec.rb} +10 -7
  55. data/spec/acceptance/rollback_spec.rb +183 -132
  56. data/spec/action_expects_and_promises_spec.rb +97 -93
  57. data/spec/action_promised_keys_spec.rb +126 -122
  58. data/spec/action_spec.rb +8 -0
  59. data/spec/context_spec.rb +289 -197
  60. data/spec/examples/controller_spec.rb +63 -63
  61. data/spec/examples/validate_address_spec.rb +38 -37
  62. data/spec/lib/deterministic/currify_spec.rb +90 -88
  63. data/spec/lib/deterministic/null_spec.rb +6 -1
  64. data/spec/lib/deterministic/option_spec.rb +140 -133
  65. data/spec/lib/deterministic/result/result_map_spec.rb +155 -154
  66. data/spec/lib/deterministic/result/result_shared.rb +3 -2
  67. data/spec/lib/deterministic/result_spec.rb +2 -2
  68. data/spec/lib/edge_cases_spec.rb +156 -0
  69. data/spec/lib/enum_spec.rb +1 -1
  70. data/spec/lib/native_pattern_matching_spec.rb +74 -0
  71. data/spec/organizer_spec.rb +115 -93
  72. data/spec/readme_spec.rb +45 -47
  73. data/spec/sample/calculates_order_tax_action_spec.rb +16 -16
  74. data/spec/sample/calculates_tax_spec.rb +1 -1
  75. data/spec/sample/looks_up_tax_percentage_action_spec.rb +55 -55
  76. data/spec/sample/provides_free_shipping_action_spec.rb +1 -1
  77. data/spec/sample/tax/calculates_order_tax_action.rb +10 -9
  78. data/spec/sample/tax/looks_up_tax_percentage_action.rb +28 -27
  79. data/spec/sample/tax/provides_free_shipping_action.rb +11 -10
  80. data/spec/spec_helper.rb +21 -13
  81. data/spec/test_doubles.rb +628 -564
  82. data/spec/testing/context_factory_spec.rb +21 -0
  83. metadata +49 -117
  84. data/.travis.yml +0 -24
  85. data/lib/functional-light-service/organizer/verify_call_method_exists.rb +0 -29
  86. data/spec/acceptance/include_warning_spec.rb +0 -29
data/spec/context_spec.rb CHANGED
@@ -1,197 +1,289 @@
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
- expect(context.fetch(:madeup, :default)).to eq(:default)
171
- end
172
-
173
- context "when aliases are included via .make" do
174
- let(:context) do
175
- FunctionalLightService::Context.make(
176
- :foo => "foobar",
177
- :foo2 => false,
178
- :_aliases => aliases
179
- )
180
- end
181
- let(:aliases) { { :foo => :bar, :foo2 => :bar2 } }
182
-
183
- it "contains the aliases" do
184
- expect(context.aliases).to eq(aliases)
185
- expect(context).to include(:foo, :bar)
186
- end
187
-
188
- it "returns the correct values for #[] and #fetch" do
189
- expect(context[:bar]).to eq context[:foo]
190
- expect(context.fetch(:bar)).to eq context[:foo]
191
- end
192
-
193
- it "can contain false values" do
194
- expect(context[:bar2]).to eq false
195
- end
196
- end
197
- end
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,63 +1,63 @@
1
- require 'spec_helper'
2
-
3
- module FunctionalLightService
4
- module Procify
5
- def py(m, *args)
6
- args.count > 0 ? 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
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