decouplio 1.0.0alpha2 → 1.0.0alpha5

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +11 -1
  3. data/.rubocop.yml +6 -0
  4. data/.ruby-version +1 -1
  5. data/README.md +2 -17
  6. data/benchmarks/multi_step_benchmark.rb +11 -10
  7. data/benchmarks/single_step_benchmark.rb +1 -1
  8. data/decouplio.gemspec +4 -4
  9. data/lib/decouplio/action.rb +12 -0
  10. data/lib/decouplio/composer.rb +47 -24
  11. data/lib/decouplio/const/doby_aide_options.rb +16 -0
  12. data/lib/decouplio/const/error_messages.rb +9 -0
  13. data/lib/decouplio/const/types.rb +14 -6
  14. data/lib/decouplio/const/validations/aide.rb +38 -0
  15. data/lib/decouplio/const/validations/doby.rb +36 -0
  16. data/lib/decouplio/const/validations/fail.rb +4 -0
  17. data/lib/decouplio/const/validations/octo.rb +2 -1
  18. data/lib/decouplio/errors/{deny_can_not_be_first_step_error.rb → aide_can_not_be_first_step_error.rb} +3 -3
  19. data/lib/decouplio/errors/aide_controversial_keys_error.rb +26 -0
  20. data/lib/decouplio/errors/aide_finish_him_error.rb +26 -0
  21. data/lib/decouplio/errors/doby_controversial_keys_error.rb +26 -0
  22. data/lib/decouplio/errors/doby_finish_him_error.rb +26 -0
  23. data/lib/decouplio/errors/execution_error.rb +20 -0
  24. data/lib/decouplio/errors/step_is_not_defined_for_aide_error.rb +26 -0
  25. data/lib/decouplio/errors/step_is_not_defined_for_doby_error.rb +27 -0
  26. data/lib/decouplio/errors/step_is_not_defined_for_pass_error.rb +27 -0
  27. data/lib/decouplio/logic_dsl.rb +23 -8
  28. data/lib/decouplio/options_validator.rb +157 -13
  29. data/lib/decouplio/steps/aide.rb +37 -0
  30. data/lib/decouplio/steps/base_resq.rb +13 -3
  31. data/lib/decouplio/steps/doby.rb +9 -8
  32. data/lib/decouplio/steps/octo.rb +7 -2
  33. data/lib/decouplio/validators/condition.rb +10 -0
  34. data/lib/decouplio/version.rb +1 -1
  35. metadata +24 -42
  36. data/docs/_config.yml +0 -1
  37. data/docs/benchmarks.md +0 -1
  38. data/docs/context.md +0 -74
  39. data/docs/context.rb +0 -62
  40. data/docs/deny.rb +0 -59
  41. data/docs/doby.rb +0 -38
  42. data/docs/doby_deny.md +0 -171
  43. data/docs/error_store.md +0 -347
  44. data/docs/error_store.rb +0 -202
  45. data/docs/fail.md +0 -1159
  46. data/docs/fail.rb +0 -859
  47. data/docs/index.md +0 -25
  48. data/docs/inner_action.md +0 -63
  49. data/docs/inner_action.rb +0 -43
  50. data/docs/logic_block.md +0 -25
  51. data/docs/octo.md +0 -269
  52. data/docs/octo.rb +0 -164
  53. data/docs/pass.md +0 -309
  54. data/docs/pass.rb +0 -213
  55. data/docs/quick_start.md +0 -71
  56. data/docs/quick_start.rb +0 -38
  57. data/docs/resq.md +0 -263
  58. data/docs/resq.rb +0 -176
  59. data/docs/step.md +0 -885
  60. data/docs/step.rb +0 -627
  61. data/docs/step_as_a_service.md +0 -123
  62. data/docs/step_as_a_service.rb +0 -77
  63. data/docs/wrap.md +0 -240
  64. data/docs/wrap.rb +0 -137
  65. data/lib/decouplio/const/validations/deny.rb +0 -11
  66. data/lib/decouplio/steps/deny.rb +0 -31
data/docs/error_store.md DELETED
@@ -1,347 +0,0 @@
1
- # Error store
2
-
3
- It's an object to store errors. By default `Decouplio::DefaultErrorHandler` is used for `Decouplio::Action`
4
-
5
- ```ruby
6
- module Decouplio
7
- class DefaultErrorHandler
8
- attr_reader :errors
9
-
10
- def initialize
11
- @errors = {}
12
- end
13
-
14
- def add_error(key, message)
15
- @errors.store(
16
- key,
17
- (@errors[key] || []) + [message].flatten
18
- )
19
- end
20
-
21
- def merge(error_store)
22
- @errors = @errors.merge(error_store.errors) do |_key, this_val, other_val|
23
- this_val + other_val
24
- end
25
- end
26
- end
27
- end
28
- ```
29
-
30
- ## How to use
31
- Inside step method you can call `#add_error` method
32
-
33
- ```ruby
34
- add_error(key, message)
35
- ```
36
-
37
- ```ruby
38
- require 'decouplio'
39
-
40
- class SomeAction < Decouplio::Action
41
- logic do
42
- step :step_one
43
- fail :fail_one
44
- end
45
-
46
- def step_one(**)
47
- false
48
- end
49
-
50
- def fail_one(**)
51
- add_error(:something_went_wrong, 'Something went wrong')
52
- end
53
- end
54
-
55
- action = SomeAction.call
56
-
57
- action # =>
58
- # Result: failure
59
-
60
- # Railway Flow:
61
- # step_one -> fail_one
62
-
63
- # Context:
64
- # {}
65
-
66
- # Errors:
67
- # {:something_went_wrong=>["Something went wrong"]}
68
-
69
- action.errors # =>
70
- # {:something_went_wrong=>["Something went wrong"]}
71
- ```
72
-
73
- ## Behavior
74
-
75
- - If error was added, it doesn't mean that action result is `failure`, action can be `success` and have errors, so basically `error store` is just a container for errors. Such behavior was implemented to provide more freedom.
76
- - Error store for parent an inner action should be the same. It's because different error stores may have different `add_error` method signature and error hash structure.
77
-
78
- ## Custom error store
79
-
80
- If you want to use your own custom error store then you can do it in this way:
81
-
82
- - Define our own class with two public methods
83
- - `#add_error(<signature you want>)` - method which adds error to `error_store`
84
- - `#merge(error_store_to_merge)` - will be used by `Decouplio` to merge errors from inner actions to parent action.
85
- - should have `attr_reader :errors`
86
-
87
- <details><summary><b>EXAMPLE (CLICK ME)</b></summary>
88
- <p>
89
-
90
- ```ruby
91
- require 'decouplio'
92
-
93
- class CustomErrorStore
94
- attr_reader :errors
95
-
96
- def initialize
97
- @errors = {}
98
- end
99
-
100
- def add_error(key:, message:, namespace: :root)
101
- @errors[namespace] ||= {}
102
- @errors[namespace].store(
103
- key,
104
- (@errors[namespace][key] || []) + [message].flatten
105
- )
106
- end
107
-
108
- def merge(error_store)
109
- @errors = deep_merge(@errors, error_store.errors)
110
- end
111
-
112
- private
113
-
114
- def deep_merge(this_hash, other_hash)
115
- this_hash.merge(other_hash) do |_key, this_val, other_val|
116
- if this_val.is_a?(Hash) && other_val.is_a?(Hash)
117
- deep_merge(this_val, other_val)
118
- else
119
- this_val + other_val
120
- end
121
- end
122
- end
123
- end
124
-
125
- class SomeActionWithCustomErrorStore < Decouplio::Action
126
- error_store_class CustomErrorStore
127
-
128
- logic do
129
- step :step_one
130
- step :step_two
131
- end
132
-
133
- def step_one(**)
134
- add_error(
135
- key: :under_root,
136
- message: 'Error Message One'
137
- )
138
- end
139
-
140
- def step_two(**)
141
- add_error(
142
- namespace: :step_two,
143
- key: :error_happened,
144
- message: 'Error Message Two'
145
- )
146
- end
147
- end
148
-
149
- action = SomeActionWithCustomErrorStore.call
150
-
151
- action # =>
152
- # Result: success
153
-
154
- # Railway Flow:
155
- # step_one -> step_two
156
-
157
- # Context:
158
- # {}
159
-
160
- # Errors:
161
- # {:root=>{:under_root=>["Error Message One"]}, :step_two=>{:error_happened=>["Error Message Two"]}}
162
-
163
- action.errors # =>
164
- # {:root=>{:under_root=>["Error Message One"]}, :step_two=>{:error_happened=>["Error Message Two"]}}
165
- ```
166
-
167
- </p>
168
- </details>
169
-
170
- ***
171
-
172
- ## Custom error store and inner action
173
-
174
- ### When error store is the same for parent and inner action
175
- <details><summary><b>EXAMPLE (CLICK ME)</b></summary>
176
- <p>
177
-
178
- ```ruby
179
- require 'decouplio'
180
-
181
- class CustomErrorStore
182
- attr_reader :errors
183
-
184
- def initialize
185
- @errors = {}
186
- end
187
-
188
- def add_error(key:, message:, namespace: :root)
189
- @errors[namespace] ||= {}
190
- @errors[namespace].store(
191
- key,
192
- (@errors[namespace][key] || []) + [message].flatten
193
- )
194
- end
195
-
196
- def merge(error_store)
197
- @errors = deep_merge(@errors, error_store.errors)
198
- end
199
-
200
- private
201
-
202
- def deep_merge(this_hash, other_hash)
203
- this_hash.merge(other_hash) do |_key, this_val, other_val|
204
- if this_val.is_a?(Hash) && other_val.is_a?(Hash)
205
- deep_merge(this_val, other_val)
206
- else
207
- this_val + other_val
208
- end
209
- end
210
- end
211
- end
212
-
213
- class InnerActionWithCustomErrorStore < Decouplio::Action
214
- error_store_class CustomErrorStore
215
-
216
- logic do
217
- step :inner_step
218
- end
219
-
220
- def inner_step(**)
221
- add_error(
222
- namespace: :inner,
223
- key: :inner_key,
224
- message: 'Somebody was told me...'
225
- )
226
- end
227
- end
228
-
229
- class ParentActionWithCustomErrorStore < Decouplio::Action
230
- error_store_class CustomErrorStore
231
-
232
- logic do
233
- step :step_one, action: InnerActionWithCustomErrorStore
234
- step :step_two
235
- end
236
-
237
- def step_two(**)
238
- add_error(
239
- namespace: :parent,
240
- key: :error_happened,
241
- message: 'Message'
242
- )
243
- end
244
- end
245
-
246
- action = ParentActionWithCustomErrorStore.call
247
-
248
- puts action # =>
249
- # Result: success
250
-
251
- # Railway Flow:
252
- # step_one -> inner_step -> step_two
253
-
254
- # Context:
255
- # {}
256
-
257
- # Errors:
258
- # {:inner=>{:inner_key=>["Somebody was told me..."]}, :parent=>{:error_happened=>["Message"]}}
259
-
260
- puts action.errors # =>
261
- # {:inner=>{:inner_key=>["Somebody was told me..."]}, :parent=>{:error_happened=>["Message"]}}
262
-
263
- ```
264
-
265
- </p>
266
- </details>
267
-
268
- ***
269
-
270
- ### When error store is different for parent and inner action
271
- If inner action error store is different from parent action error store then error will be raised.
272
-
273
- <details><summary><b>EXAMPLE (CLICK ME)</b></summary>
274
- <p>
275
-
276
- ```ruby
277
- require 'decouplio'
278
-
279
- class CustomErrorStore
280
- attr_reader :errors
281
-
282
- def initialize
283
- @errors = {}
284
- end
285
-
286
- def add_error(key:, message:, namespace: :root)
287
- @errors[namespace] ||= {}
288
- @errors[namespace].store(
289
- key,
290
- (@errors[namespace][key] || []) + [message].flatten
291
- )
292
- end
293
-
294
- def merge(error_store)
295
- @errors = deep_merge(@errors, error_store.errors)
296
- end
297
-
298
- private
299
-
300
- def deep_merge(this_hash, other_hash)
301
- this_hash.merge(other_hash) do |_key, this_val, other_val|
302
- if this_val.is_a?(Hash) && other_val.is_a?(Hash)
303
- deep_merge(this_val, other_val)
304
- else
305
- this_val + other_val
306
- end
307
- end
308
- end
309
- end
310
-
311
- class InnerActionWithDefaultErrorStore < Decouplio::Action
312
- logic do
313
- step :inner_step
314
- end
315
-
316
- def inner_step(**)
317
- add_error(
318
- key: :inner_key,
319
- message: 'Somebody was told me...'
320
- )
321
- end
322
- end
323
-
324
- class ParentActionForInnerActionDefaultErrorStore < Decouplio::Action
325
- error_store_class CustomErrorStore
326
-
327
- logic do
328
- step :step_one, action: InnerActionWithDefaultErrorStore
329
- step :step_two
330
- end
331
-
332
- def step_two(**)
333
- add_error(
334
- namespace: :parent,
335
- key: :error_happened,
336
- message: 'Message'
337
- )
338
- end
339
- end # =>
340
- # Error store for action and inner action should be the same. (Decouplio::Errors::ErrorStoreError)
341
-
342
- ```
343
-
344
- </p>
345
- </details>
346
-
347
- ***
data/docs/error_store.rb DELETED
@@ -1,202 +0,0 @@
1
- require_relative '../lib/decouplio'
2
-
3
- # How to use
4
- class SomeAction < Decouplio::Action
5
- logic do
6
- step :step_one
7
- fail :fail_one
8
- end
9
-
10
- def step_one(**)
11
- false
12
- end
13
-
14
- def fail_one(**)
15
- add_error(:something_went_wrong, 'Something went wrong')
16
- end
17
- end
18
-
19
- action = SomeAction.call
20
-
21
- puts action # =>
22
- # Result: failure
23
-
24
- # Railway Flow:
25
- # step_one -> fail_one
26
-
27
- # Context:
28
- # {}
29
-
30
- # Errors:
31
- # {:something_went_wrong=>["Something went wrong"]}
32
-
33
- puts action.errors # =>
34
- # {:something_went_wrong=>["Something went wrong"]}
35
-
36
-
37
-
38
-
39
- # Custom error store
40
- class CustomErrorStore
41
- attr_reader :errors
42
-
43
- def initialize
44
- @errors = {}
45
- end
46
-
47
- def add_error(key:, message:, namespace: :root)
48
- @errors[namespace] ||= {}
49
- @errors[namespace].store(
50
- key,
51
- (@errors[namespace][key] || []) + [message].flatten
52
- )
53
- end
54
-
55
- def merge(error_store)
56
- @errors = deep_merge(@errors, error_store.errors)
57
- end
58
-
59
- private
60
-
61
- def deep_merge(this_hash, other_hash)
62
- this_hash.merge(other_hash) do |_key, this_val, other_val|
63
- if this_val.is_a?(Hash) && other_val.is_a?(Hash)
64
- deep_merge(this_val, other_val)
65
- else
66
- this_val + other_val
67
- end
68
- end
69
- end
70
- end
71
-
72
- class SomeActionWithCustomErrorStore < Decouplio::Action
73
- error_store_class CustomErrorStore
74
-
75
- logic do
76
- step :step_one
77
- step :step_two
78
- end
79
-
80
- def step_one(**)
81
- add_error(
82
- key: :under_root,
83
- message: 'Error Message One'
84
- )
85
- end
86
-
87
- def step_two(**)
88
- add_error(
89
- namespace: :step_two,
90
- key: :error_happened,
91
- message: 'Error Message Two'
92
- )
93
- end
94
- end
95
-
96
- action = SomeActionWithCustomErrorStore.call
97
-
98
- puts action # =>
99
- # Result: success
100
-
101
- # Railway Flow:
102
- # step_one -> step_two
103
-
104
- # Context:
105
- # {}
106
-
107
- # Errors:
108
- # {:root=>{:under_root=>["Error Message One"]}, :step_two=>{:error_happened=>["Error Message Two"]}}
109
-
110
- puts action.errors # =>
111
- # {:root=>{:under_root=>["Error Message One"]}, :step_two=>{:error_happened=>["Error Message Two"]}}
112
-
113
-
114
-
115
-
116
- # When error store is the same for parent and inner action
117
-
118
- class InnerActionWithCustomErrorStore < Decouplio::Action
119
- error_store_class CustomErrorStore
120
-
121
- logic do
122
- step :inner_step
123
- end
124
-
125
- def inner_step(**)
126
- add_error(
127
- namespace: :inner,
128
- key: :inner_key,
129
- message: 'Somebody was told me...'
130
- )
131
- end
132
- end
133
-
134
- class ParentActionWithCustomErrorStore < Decouplio::Action
135
- error_store_class CustomErrorStore
136
-
137
- logic do
138
- step :step_one, action: InnerActionWithCustomErrorStore
139
- step :step_two
140
- end
141
-
142
- def step_two(**)
143
- add_error(
144
- namespace: :parent,
145
- key: :error_happened,
146
- message: 'Message'
147
- )
148
- end
149
- end
150
-
151
- action = ParentActionWithCustomErrorStore.call
152
-
153
- puts action # =>
154
- # Result: success
155
-
156
- # Railway Flow:
157
- # step_one -> inner_step -> step_two
158
-
159
- # Context:
160
- # {}
161
-
162
- # Errors:
163
- # {:inner=>{:inner_key=>["Somebody was told me..."]}, :parent=>{:error_happened=>["Message"]}}
164
-
165
- puts action.errors # =>
166
- # {:inner=>{:inner_key=>["Somebody was told me..."]}, :parent=>{:error_happened=>["Message"]}}
167
-
168
-
169
-
170
-
171
- # When error store is different for parent and inner action
172
-
173
- class InnerActionWithDefaultErrorStore < Decouplio::Action
174
- logic do
175
- step :inner_step
176
- end
177
-
178
- def inner_step(**)
179
- add_error(
180
- key: :inner_key,
181
- message: 'Somebody was told me...'
182
- )
183
- end
184
- end
185
-
186
- class ParentActionForInnerActionDefaultErrorStore < Decouplio::Action
187
- error_store_class CustomErrorStore
188
-
189
- logic do
190
- step :step_one, action: InnerActionWithDefaultErrorStore
191
- step :step_two
192
- end
193
-
194
- def step_two(**)
195
- add_error(
196
- namespace: :parent,
197
- key: :error_happened,
198
- message: 'Message'
199
- )
200
- end
201
- end # =>
202
- # Error store for action and inner action should be the same. (Decouplio::Errors::ErrorStoreError)