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/index.md DELETED
@@ -1,25 +0,0 @@
1
- ## Decouplio
2
-
3
- Decouplio is a zero dependency, thread safe and framework agnostic gem designed to encapsulate application business logic. It's reverse engineered through TDD and inspired by such frameworks and gems like Trailblazer, Interactor.
4
-
5
- ### Compatibility
6
- Ruby:
7
- - 2.7
8
- - 3.0
9
-
10
- ### Docs
11
-
12
- - [Quick start](https://github.com/differencialx/decouplio/blob/master/docs/quick_start.md)
13
- - [Logic block](https://github.com/differencialx/decouplio/blob/master/docs/logic_block.md)
14
- - [Context](https://github.com/differencialx/decouplio/blob/master/docs/context.md)
15
- - [Step](https://github.com/differencialx/decouplio/blob/master/docs/step.md)
16
- - [Fail](https://github.com/differencialx/decouplio/blob/master/docs/fail.md)
17
- - [Pass](https://github.com/differencialx/decouplio/blob/master/docs/pass.md)
18
- - [Octo](https://github.com/differencialx/decouplio/blob/master/docs/octo.md)
19
- - [Wrap](https://github.com/differencialx/decouplio/blob/master/docs/wrap.md)
20
- - [Resq](https://github.com/differencialx/decouplio/blob/master/docs/resq.md)
21
- - [Inner action](https://github.com/differencialx/decouplio/blob/master/docs/inner_action.md)
22
- - [Doby](https://github.com/differencialx/decouplio/blob/master/docs/doby.md)
23
- - [Step as a service](https://github.com/differencialx/decouplio/blob/master/docs/step_as_a_service.md)
24
- - [Error store](https://github.com/differencialx/decouplio/blob/master/docs/error_store.md)
25
- - [Benchmarks](https://github.com/differencialx/decouplio/blob/master/docs/benchmarks.md)
data/docs/inner_action.md DELETED
@@ -1,63 +0,0 @@
1
- # Inner Action
2
-
3
- `step/fail/pass` steps can perform another action instead of method.
4
-
5
- ```ruby
6
- require 'decouplio'
7
-
8
- class InnerAction < Decouplio::Action
9
- logic do
10
- step :step_one
11
- step :step_two
12
- end
13
-
14
- def step_one(**)
15
- ctx # => ctx from parent action(SomeAction)
16
- ctx[:step_one] = 'Success'
17
- end
18
-
19
- def step_two(**)
20
- ctx # => ctx from parent action(SomeAction)
21
- ctx[:step_two] = 'Success'
22
- end
23
- end
24
-
25
-
26
- class SomeAction < Decouplio::Action
27
- logic do
28
- step InnerAction
29
- # OR
30
- # fail InnerAction
31
- # OR
32
- # pass InnerAction
33
- end
34
- end
35
-
36
- action = SomeAction.call
37
-
38
- action # =>
39
- # Result: success
40
-
41
- # Railway Flow:
42
- # InnerAction -> step_one -> step_two
43
-
44
- # Context:
45
- # {:step_one=>"Success", :step_two=>"Success"}
46
-
47
- # Errors:
48
- # {}
49
- ```
50
-
51
- ```mermaid
52
- flowchart LR
53
- 1(start)-->2(any_name);
54
- subgraph inner action;
55
- 2(step_one)-->|success track|3(step_two);
56
- end
57
- 3(step_two)-->|success track|4(finish success);
58
- ```
59
-
60
- The parent action context will be passed into inner action
61
-
62
- ## Options
63
- All options for `step/fail/pass` can be applied along with `action` option.
data/docs/inner_action.rb DELETED
@@ -1,43 +0,0 @@
1
- require_relative '../lib/decouplio'
2
-
3
- class InnerAction < Decouplio::Action
4
- logic do
5
- step :step_one
6
- step :step_two
7
- end
8
-
9
- def step_one(**)
10
- ctx # => ctx from parent action(SomeAction)
11
- ctx[:step_one] = 'Success'
12
- end
13
-
14
- def step_two(**)
15
- ctx # => ctx from parent action(SomeAction)
16
- ctx[:step_two] = 'Success'
17
- end
18
- end
19
-
20
-
21
- class SomeAction < Decouplio::Action
22
- logic do
23
- step InnerAction
24
- # OR
25
- # fail InnerAction
26
- # OR
27
- # pass InnerAction
28
- end
29
- end
30
-
31
- action = SomeAction.call
32
-
33
- puts action # =>
34
- # Result: success
35
-
36
- # Railway Flow:
37
- # InnerAction -> step_one -> step_two
38
-
39
- # Context:
40
- # {:step_one=>"Success", :step_two=>"Success"}
41
-
42
- # Errors:
43
- # {}
data/docs/logic_block.md DELETED
@@ -1,25 +0,0 @@
1
- ## Logic block
2
-
3
- It's just a block witch contains flow logic
4
-
5
- ```ruby
6
- require 'decouplio'
7
-
8
- class SomeAction < Decouplio::Action
9
- logic do
10
- # define your logic here
11
- end
12
- end
13
- ```
14
-
15
- What to put inside `logic` block?
16
-
17
- Possible logic steps:
18
- |Step kind|Docs|
19
- |---------|----|
20
- |step|[--->>>](https://github.com/differencialx/decouplio/blob/master/docs/step.md)|
21
- |fail|[--->>>](https://github.com/differencialx/decouplio/blob/master/docs/fail.md)|
22
- |pass|[--->>>](https://github.com/differencialx/decouplio/blob/master/docs/pass.md)|
23
- |octo|[--->>>](https://github.com/differencialx/decouplio/blob/master/docs/octo.md)|
24
- |wrap|[--->>>](https://github.com/differencialx/decouplio/blob/master/docs/wrap.md)|
25
- |resq|[--->>>](https://github.com/differencialx/decouplio/blob/master/docs/resq.md)|
data/docs/octo.md DELETED
@@ -1,269 +0,0 @@
1
- # Octo
2
-
3
- It's a step type which helps to implement strategy pattern.
4
-
5
- ## Signature
6
-
7
- ```ruby
8
- octo(octo_name, ctx_key:, **options) do
9
- on :key1, palp: :palp_name_one
10
- on :key2, palp: :palp_name_two
11
- on :key3, palp: :palp_name_three
12
- end
13
- ```
14
-
15
- ## Behavior
16
-
17
- - depending on the value inside `ctx_key` in context `octo` will perform flow defined for this key. So basically `octo` will be replaces with flow you defined.
18
- ```ruby
19
- logic do
20
- palp :palp_name_one do
21
- step :step_one, on_failure: :step_final
22
- step :step_two
23
- end
24
-
25
- palp :palp_name_two do
26
- step :step_two
27
- step :step_three
28
- end
29
-
30
- palp :palp_name_three do
31
- step :step_three
32
- step :step_one
33
- end
34
-
35
- step :init_step
36
-
37
- octo :octo_name, ctx_key: :some_key do
38
- on :key1, palp: :palp_name_one
39
- on :key2, palp: :palp_name_two
40
- on :key3, palp: :palp_name_three
41
- end
42
-
43
- step :step_final
44
- end
45
- ```
46
-
47
- ```mermaid
48
- flowchart TD
49
- 0(init_step)-->1(octo)
50
- 1(octo)-->|when ctx_key value == :key1 value|12(palp_name_one);
51
- 12(palp_name_one)-->3(step_one)
52
- 3(step_one)-->4(step_two);
53
- 1(octo)-->|when ctx_key value == :key2|13(palp_name_two);
54
- 13(palp_name_two)-->6(step_two);
55
- 6(step_two)-->7(step_three);
56
- 1(octo)-->|when ctx_key value == :key3|14(palp_name_three);
57
- 14(palp_name_three)-->9(step_three);
58
- 9(step_three)-->10(step_one);
59
- 4(step_two)-->11(final_step);
60
- 7(step_three)-->11(final_step);
61
- 10(step_one)-->11(final_step);
62
- ```
63
-
64
- ### Palp
65
- Currently only one possibility is present to define flow for `octo`, it's `palp`
66
-
67
- <details><summary><b>EXAMPLE (CLICK ME)</b></summary>
68
- <p>
69
-
70
- ```ruby
71
- require 'decouplio'
72
-
73
- class SomeAction < Decouplio::Action
74
- logic do
75
- # it doesn't matter where you define palp
76
- # at the beginning of logic block
77
- # or at the end or in the middle
78
- palp :option_one_palp do
79
- step :step_one, on_failure: :final_step
80
- step :step_two
81
- end
82
-
83
- palp :option_two_palp do
84
- step :step_two
85
- step :step_three
86
- end
87
-
88
- palp :option_three_palp do
89
- step :step_three
90
- step :step_one
91
- fail :fail_one
92
- end
93
-
94
- step :init_step
95
-
96
- octo :my_octo, ctx_key: :custom_key do
97
- on :option_one, palp: :option_one_palp
98
- on :option_two, palp: :option_two_palp
99
- on :option_three, palp: :option_three_palp
100
- end
101
-
102
- step :final_step
103
- fail :fail_two
104
- end
105
-
106
- def init_step(octo_key:, **)
107
- ctx[:custom_key] = octo_key
108
- end
109
-
110
- def step_one(param_for_step_one:, **)
111
- ctx[:step_one] = param_for_step_one
112
- end
113
-
114
- def step_two(param_for_step_two:, **)
115
- ctx[:step_two] = param_for_step_two
116
- end
117
-
118
- def step_three(param_for_step_three:, **)
119
- ctx[:step_three] = param_for_step_three
120
- end
121
-
122
- def fail_one(**)
123
- ctx[:fail_one] = 'Failure'
124
- end
125
-
126
- def final_step(**)
127
- ctx[:final_step] = 'Success'
128
- end
129
-
130
- def fail_two(**)
131
- ctx[:fail_two] = 'Failure'
132
- end
133
- end
134
-
135
-
136
- octo_option_one_success = SomeAction.call(
137
- octo_key: :option_one,
138
- param_for_step_one: true,
139
- param_for_step_two: true
140
- )
141
- octo_option_one_failure = SomeAction.call(
142
- octo_key: :option_one,
143
- param_for_step_one: false,
144
- param_for_step_two: true
145
- )
146
- octo_option_two_success = SomeAction.call(
147
- octo_key: :option_two,
148
- param_for_step_two: true,
149
- param_for_step_three: true
150
- )
151
- octo_option_two_failure = SomeAction.call(
152
- octo_key: :option_two,
153
- param_for_step_two: true,
154
- param_for_step_three: false
155
- )
156
- octo_option_three_success = SomeAction.call(
157
- octo_key: :option_three,
158
- param_for_step_one: true,
159
- param_for_step_three: true
160
- )
161
- octo_option_three_failure = SomeAction.call(
162
- octo_key: :option_three,
163
- param_for_step_one: false,
164
- param_for_step_three: true
165
- )
166
- octo_option_one_success # =>
167
- # Result: success
168
-
169
- # Railway Flow:
170
- # init_step -> my_octo -> step_one -> step_two -> final_step
171
-
172
- # Context:
173
- # {:octo_key=>:option_one, :param_for_step_one=>true, :param_for_step_two=>true, :custom_key=>:option_one, :step_one=>true, :step_two=>true, :final_step=>"Success"}
174
-
175
- # Errors:
176
- # {}
177
- octo_option_one_failure # =>
178
- # Result: success
179
-
180
- # Railway Flow:
181
- # init_step -> my_octo -> step_one -> final_step
182
-
183
- # Context:
184
- # {:octo_key=>:option_one, :param_for_step_one=>false, :param_for_step_two=>true, :custom_key=>:option_one, :step_one=>false, :final_step=>"Success"}
185
-
186
- # Errors:
187
- # {}
188
- octo_option_two_success # =>
189
- # Result: success
190
-
191
- # Railway Flow:
192
- # init_step -> my_octo -> step_two -> step_three -> final_step
193
-
194
- # Context:
195
- # {:octo_key=>:option_two, :param_for_step_two=>true, :param_for_step_three=>true, :custom_key=>:option_two, :step_two=>true, :step_three=>true, :final_step=>"Success"}
196
-
197
- # Errors:
198
- # {}
199
- octo_option_two_failure # =>
200
- # Result: failure
201
-
202
- # Railway Flow:
203
- # init_step -> my_octo -> step_two -> step_three -> fail_two
204
-
205
- # Context:
206
- # {:octo_key=>:option_two, :param_for_step_two=>true, :param_for_step_three=>false, :custom_key=>:option_two, :step_two=>true, :step_three=>false, :fail_two=>"Failure"}
207
-
208
- # Errors:
209
- # {}
210
- octo_option_three_success # =>
211
- # Result: success
212
-
213
- # Railway Flow:
214
- # init_step -> my_octo -> step_three -> step_one -> final_step
215
-
216
- # Context:
217
- # {:octo_key=>:option_three, :param_for_step_one=>true, :param_for_step_three=>true, :custom_key=>:option_three, :step_three=>true, :step_one=>true, :final_step=>"Success"}
218
-
219
- # Errors:
220
- # {}
221
- octo_option_three_failure # =>
222
- # Result: failure
223
-
224
- # Railway Flow:
225
- # init_step -> my_octo -> step_three -> step_one -> fail_one -> fail_two
226
-
227
- # Context:
228
- # {:octo_key=>:option_three, :param_for_step_one=>false, :param_for_step_three=>true, :custom_key=>:option_three, :step_three=>true, :step_one=>false, :fail_one=>"Failure", :fail_two=>"Failure"}
229
-
230
- # Errors:
231
- # {}
232
- ```
233
-
234
- ```mermaid
235
- flowchart TD
236
- 1(start)-->2(init_step);
237
- 2(init_step)-->|success track|3(octo);
238
- 2(init_step)-->|failure track|11(fail_two);
239
- 3(octo)-->|custom_key value == :option_one|4(option_one_palp);
240
- 4(option_one_palp)-->|success track|5(step_one);
241
- 5(step_one)-->|success track|6(step_two);
242
- 6(step_two)-->|success track|7(final_step);
243
- 5(step_one)-->|failure track|7(final_step);
244
- 6(step_two)-->|failure track|11(fail_two);
245
- 3(octo)-->|custom_key value == :option_two|8(option_two_palp);
246
- 8(option_two_palp)-->|success track|9(step_two);
247
- 9(step_two)-->|success track|10(step_three);
248
- 9(step_two)-->|failure track|11(fail_two);
249
- 10(step_three)-->|success track|7(final_step);
250
- 10(step_three)-->|failure track|11(fail_two);
251
- 3(octo)-->|custom_key value == :option_three|12(option_three_palp);
252
- 12(option_three_palp)-->|success track|13(step_three);
253
- 13(step_three)-->|success track|14(step_one);
254
- 14(step_one)-->|success track|7(final_step);
255
- 13(step_three)-->|failure track|15(fail_one);
256
- 14(step_one)-->|failure track|15(fail_one);
257
- 15(fail_one)-->|failure track|11(fail_two);
258
- ```
259
-
260
- </p>
261
- </details>
262
-
263
- ***
264
- ## Options
265
-
266
- ### if: condition method name
267
- The same as for [step](https://github.com/differencialx/decouplio/blob/master/docs/step.md)
268
- ### unless: condition method name
269
- The same as for [step](https://github.com/differencialx/decouplio/blob/master/docs/step.md)
data/docs/octo.rb DELETED
@@ -1,164 +0,0 @@
1
- require_relative '../lib/decouplio'
2
-
3
-
4
- # Palp
5
-
6
- class SomeAction < Decouplio::Action
7
- logic do
8
- # it doesn't matter where you define palp
9
- # at the beginning of logic block
10
- # or at the end or in the middle
11
- palp :option_one_palp do
12
- step :step_one, on_failure: :final_step
13
- step :step_two
14
- end
15
-
16
- palp :option_two_palp do
17
- step :step_two
18
- step :step_three
19
- end
20
-
21
- palp :option_three_palp do
22
- step :step_three
23
- step :step_one
24
- fail :fail_one
25
- end
26
-
27
- step :init_step
28
-
29
- octo :my_octo, ctx_key: :custom_key do
30
- on :option_one, palp: :option_one_palp
31
- on :option_two, palp: :option_two_palp
32
- on :option_three, palp: :option_three_palp
33
- end
34
-
35
- step :final_step
36
- fail :fail_two
37
- end
38
-
39
- def init_step(octo_key:, **)
40
- ctx[:custom_key] = octo_key
41
- end
42
-
43
- def step_one(param_for_step_one:, **)
44
- ctx[:step_one] = param_for_step_one
45
- end
46
-
47
- def step_two(param_for_step_two:, **)
48
- ctx[:step_two] = param_for_step_two
49
- end
50
-
51
- def step_three(param_for_step_three:, **)
52
- ctx[:step_three] = param_for_step_three
53
- end
54
-
55
- def fail_one(**)
56
- ctx[:fail_one] = 'Failure'
57
- end
58
-
59
- def final_step(**)
60
- ctx[:final_step] = 'Success'
61
- end
62
-
63
- def fail_two(**)
64
- ctx[:fail_two] = 'Failure'
65
- end
66
- end
67
-
68
-
69
- octo_option_one_success = SomeAction.call(
70
- octo_key: :option_one,
71
- param_for_step_one: true,
72
- param_for_step_two: true
73
- )
74
- octo_option_one_failure = SomeAction.call(
75
- octo_key: :option_one,
76
- param_for_step_one: false,
77
- param_for_step_two: true
78
- )
79
- octo_option_two_success = SomeAction.call(
80
- octo_key: :option_two,
81
- param_for_step_two: true,
82
- param_for_step_three: true
83
- )
84
- octo_option_two_failure = SomeAction.call(
85
- octo_key: :option_two,
86
- param_for_step_two: true,
87
- param_for_step_three: false
88
- )
89
- octo_option_three_success = SomeAction.call(
90
- octo_key: :option_three,
91
- param_for_step_one: true,
92
- param_for_step_three: true
93
- )
94
- octo_option_three_failure = SomeAction.call(
95
- octo_key: :option_three,
96
- param_for_step_one: false,
97
- param_for_step_three: true
98
- )
99
- puts octo_option_one_success # =>
100
- # Result: success
101
-
102
- # Railway Flow:
103
- # init_step -> my_octo -> step_one -> step_two -> final_step
104
-
105
- # Context:
106
- # {:octo_key=>:option_one, :param_for_step_one=>true, :param_for_step_two=>true, :custom_key=>:option_one, :step_one=>true, :step_two=>true, :final_step=>"Success"}
107
-
108
- # Errors:
109
- # {}
110
- puts octo_option_one_failure # =>
111
- # Result: success
112
-
113
- # Railway Flow:
114
- # init_step -> my_octo -> step_one -> final_step
115
-
116
- # Context:
117
- # {:octo_key=>:option_one, :param_for_step_one=>false, :param_for_step_two=>true, :custom_key=>:option_one, :step_one=>false, :final_step=>"Success"}
118
-
119
- # Errors:
120
- # {}
121
- puts octo_option_two_success # =>
122
- # Result: success
123
-
124
- # Railway Flow:
125
- # init_step -> my_octo -> step_two -> step_three -> final_step
126
-
127
- # Context:
128
- # {:octo_key=>:option_two, :param_for_step_two=>true, :param_for_step_three=>true, :custom_key=>:option_two, :step_two=>true, :step_three=>true, :final_step=>"Success"}
129
-
130
- # Errors:
131
- # {}
132
- puts octo_option_two_failure # =>
133
- # Result: failure
134
-
135
- # Railway Flow:
136
- # init_step -> my_octo -> step_two -> step_three -> fail_two
137
-
138
- # Context:
139
- # {:octo_key=>:option_two, :param_for_step_two=>true, :param_for_step_three=>false, :custom_key=>:option_two, :step_two=>true, :step_three=>false, :fail_two=>"Failure"}
140
-
141
- # Errors:
142
- # {}
143
- puts octo_option_three_success # =>
144
- # Result: success
145
-
146
- # Railway Flow:
147
- # init_step -> my_octo -> step_three -> step_one -> final_step
148
-
149
- # Context:
150
- # {:octo_key=>:option_three, :param_for_step_one=>true, :param_for_step_three=>true, :custom_key=>:option_three, :step_three=>true, :step_one=>true, :final_step=>"Success"}
151
-
152
- # Errors:
153
- # {}
154
- puts octo_option_three_failure # =>
155
- # Result: failure
156
-
157
- # Railway Flow:
158
- # init_step -> my_octo -> step_three -> step_one -> fail_one -> fail_two
159
-
160
- # Context:
161
- # {:octo_key=>:option_three, :param_for_step_one=>false, :param_for_step_three=>true, :custom_key=>:option_three, :step_three=>true, :step_one=>false, :fail_one=>"Failure", :fail_two=>"Failure"}
162
-
163
- # Errors:
164
- # {}