u-case 3.0.0.rc6 → 3.1.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.
- checksums.yaml +4 -4
- data/.travis.sh +8 -4
- data/Gemfile +9 -1
- data/README.md +160 -113
- data/README.pt-BR.md +181 -134
- data/lib/micro/case.rb +20 -15
- data/lib/micro/case/config.rb +16 -4
- data/lib/micro/case/error.rb +3 -1
- data/lib/micro/case/result.rb +54 -49
- data/lib/micro/case/result/transitions.rb +20 -0
- data/lib/micro/case/safe.rb +2 -2
- data/lib/micro/case/utils.rb +1 -0
- data/lib/micro/case/version.rb +1 -1
- data/lib/micro/case/with_activemodel_validation.rb +3 -1
- data/lib/micro/cases/flow.rb +18 -14
- data/lib/micro/cases/safe/flow.rb +1 -1
- metadata +5 -4
data/lib/micro/case.rb
CHANGED
@@ -8,8 +8,8 @@ require 'micro/case/version'
|
|
8
8
|
module Micro
|
9
9
|
class Case
|
10
10
|
require 'micro/case/utils'
|
11
|
-
require 'micro/case/result'
|
12
11
|
require 'micro/case/error'
|
12
|
+
require 'micro/case/result'
|
13
13
|
require 'micro/case/safe'
|
14
14
|
require 'micro/case/strict'
|
15
15
|
require 'micro/case/config'
|
@@ -22,17 +22,22 @@ module Micro
|
|
22
22
|
new(options).__call__
|
23
23
|
end
|
24
24
|
|
25
|
+
INVALID_INVOCATION_OF_THE_THEN_METHOD =
|
26
|
+
Error::InvalidInvocationOfTheThenMethod.new("#{self.name}.")
|
27
|
+
|
25
28
|
def self.then(use_case = nil, &block)
|
26
29
|
can_yield_self = respond_to?(:yield_self)
|
27
30
|
|
28
31
|
if block
|
29
|
-
raise
|
32
|
+
raise INVALID_INVOCATION_OF_THE_THEN_METHOD if use_case
|
30
33
|
raise NotImplementedError if !can_yield_self
|
31
34
|
|
32
35
|
yield_self(&block)
|
33
36
|
else
|
34
37
|
return yield_self if !use_case && can_yield_self
|
35
38
|
|
39
|
+
raise INVALID_INVOCATION_OF_THE_THEN_METHOD unless ::Micro.case_or_flow?(use_case)
|
40
|
+
|
36
41
|
self.call.then(use_case)
|
37
42
|
end
|
38
43
|
end
|
@@ -70,11 +75,9 @@ module Micro
|
|
70
75
|
end
|
71
76
|
|
72
77
|
def self.__new__(result, arg)
|
73
|
-
input = result.
|
78
|
+
input = result.__set_accessible_attributes__(arg)
|
74
79
|
|
75
|
-
|
76
|
-
instance.__set_result__(result)
|
77
|
-
instance
|
80
|
+
new(input).__set_result__(result)
|
78
81
|
end
|
79
82
|
|
80
83
|
def self.__flow_builder__
|
@@ -127,7 +130,7 @@ module Micro
|
|
127
130
|
end
|
128
131
|
|
129
132
|
def __call__
|
130
|
-
|
133
|
+
call
|
131
134
|
end
|
132
135
|
|
133
136
|
def __set_result__(result)
|
@@ -135,12 +138,20 @@ module Micro
|
|
135
138
|
raise Error::ResultIsAlreadyDefined if defined?(@__result)
|
136
139
|
|
137
140
|
@__result = result
|
141
|
+
|
142
|
+
self
|
138
143
|
end
|
139
144
|
|
140
145
|
private
|
141
146
|
|
142
|
-
|
147
|
+
def apply(name)
|
148
|
+
method(name)
|
149
|
+
end
|
150
|
+
|
143
151
|
def call
|
152
|
+
return __call_use_case_flow if __call_use_case_flow?
|
153
|
+
|
154
|
+
__call_use_case
|
144
155
|
end
|
145
156
|
|
146
157
|
def __setup_use_case(input)
|
@@ -151,12 +162,6 @@ module Micro
|
|
151
162
|
self.attributes = input
|
152
163
|
end
|
153
164
|
|
154
|
-
def __call!
|
155
|
-
return __call_use_case_flow if __call_use_case_flow?
|
156
|
-
|
157
|
-
__call_use_case
|
158
|
-
end
|
159
|
-
|
160
165
|
def __call_use_case
|
161
166
|
result = call!
|
162
167
|
|
@@ -203,7 +208,7 @@ module Micro
|
|
203
208
|
__result.__set__(is_success, value, type, self)
|
204
209
|
end
|
205
210
|
|
206
|
-
|
211
|
+
private_constant :MapFailureType, :INVALID_INVOCATION_OF_THE_THEN_METHOD
|
207
212
|
end
|
208
213
|
|
209
214
|
def self.case_or_flow?(arg)
|
data/lib/micro/case/config.rb
CHANGED
@@ -7,16 +7,28 @@ module Micro
|
|
7
7
|
class Config
|
8
8
|
include Singleton
|
9
9
|
|
10
|
+
def enable_transitions=(value)
|
11
|
+
Micro::Case::Result.class_variable_set(
|
12
|
+
:@@transitions_enabled, Kind::Of::Boolean(value)
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
10
16
|
def enable_activemodel_validation=(value)
|
11
17
|
return unless Kind::Of::Boolean(value)
|
12
18
|
|
13
19
|
require 'micro/case/with_activemodel_validation'
|
14
20
|
end
|
15
21
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
)
|
22
|
+
def set_activemodel_validation_errors_failure=(value)
|
23
|
+
return unless value
|
24
|
+
|
25
|
+
@activemodel_validation_errors_failure = Kind.of(Symbol, value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def activemodel_validation_errors_failure
|
29
|
+
return @activemodel_validation_errors_failure if defined?(@activemodel_validation_errors_failure)
|
30
|
+
|
31
|
+
@activemodel_validation_errors_failure = :invalid_attributes
|
20
32
|
end
|
21
33
|
end
|
22
34
|
end
|
data/lib/micro/case/error.rb
CHANGED
@@ -46,7 +46,9 @@ module Micro
|
|
46
46
|
end
|
47
47
|
|
48
48
|
class InvalidInvocationOfTheThenMethod < StandardError
|
49
|
-
def initialize
|
49
|
+
def initialize(class_name)
|
50
|
+
super("Invalid invocation of the #{class_name}then method")
|
51
|
+
end
|
50
52
|
end
|
51
53
|
|
52
54
|
def self.by_wrong_usage?(exception)
|
data/lib/micro/case/result.rb
CHANGED
@@ -5,18 +5,31 @@ require 'set'
|
|
5
5
|
module Micro
|
6
6
|
class Case
|
7
7
|
class Result
|
8
|
+
require 'micro/case/result/transitions'
|
9
|
+
|
8
10
|
Kind::Types.add(self)
|
9
11
|
|
10
|
-
|
12
|
+
INVALID_INVOCATION_OF_THE_THEN_METHOD =
|
13
|
+
Error::InvalidInvocationOfTheThenMethod.new("#{self.name}#")
|
14
|
+
|
15
|
+
@@transitions_enabled = true
|
16
|
+
|
17
|
+
def self.transitions_enabled?
|
18
|
+
@@transitions_enabled
|
19
|
+
end
|
11
20
|
|
12
21
|
attr_reader :type, :data, :use_case
|
13
22
|
|
14
23
|
alias value data
|
15
24
|
|
16
|
-
def initialize
|
17
|
-
@
|
18
|
-
@
|
19
|
-
|
25
|
+
def initialize(transitions_mapper = nil)
|
26
|
+
@__accumulated_data = {}
|
27
|
+
@__accessible_attributes = {}
|
28
|
+
|
29
|
+
enable_transitions = @@transitions_enabled
|
30
|
+
|
31
|
+
@__transitions = enable_transitions ? [] : Kind::Empty::ARRAY
|
32
|
+
@__transitions_mapper = transitions_mapper || Transitions::MapEverything if enable_transitions
|
20
33
|
end
|
21
34
|
|
22
35
|
def to_ary
|
@@ -44,13 +57,17 @@ module Micro
|
|
44
57
|
end
|
45
58
|
|
46
59
|
def success?
|
47
|
-
@
|
60
|
+
@__success
|
48
61
|
end
|
49
62
|
|
50
63
|
def failure?
|
51
64
|
!success?
|
52
65
|
end
|
53
66
|
|
67
|
+
def accessible_attributes
|
68
|
+
@__accessible_attributes.keys
|
69
|
+
end
|
70
|
+
|
54
71
|
def on_success(expected_type = nil)
|
55
72
|
return self unless __success_type?(expected_type)
|
56
73
|
|
@@ -85,7 +102,7 @@ module Micro
|
|
85
102
|
can_yield_self = respond_to?(:yield_self)
|
86
103
|
|
87
104
|
if block
|
88
|
-
raise
|
105
|
+
raise INVALID_INVOCATION_OF_THE_THEN_METHOD if use_case
|
89
106
|
raise NotImplementedError if !can_yield_self
|
90
107
|
|
91
108
|
yield_self(&block)
|
@@ -94,7 +111,7 @@ module Micro
|
|
94
111
|
return failure? ? self : __call_proc(use_case, 'then(-> {})'.freeze) if use_case.is_a?(Proc)
|
95
112
|
return failure? ? self : __call_method(use_case, attributes) if use_case.is_a?(Method)
|
96
113
|
|
97
|
-
raise
|
114
|
+
raise INVALID_INVOCATION_OF_THE_THEN_METHOD unless ::Micro.case_or_flow?(use_case)
|
98
115
|
|
99
116
|
return self if failure?
|
100
117
|
|
@@ -114,13 +131,13 @@ module Micro
|
|
114
131
|
return __call_proc(arg, '| -> {}'.freeze) if arg.is_a?(Proc)
|
115
132
|
return __call_method(arg) if arg.is_a?(Method)
|
116
133
|
|
117
|
-
raise
|
134
|
+
raise INVALID_INVOCATION_OF_THE_THEN_METHOD unless ::Micro.case_or_flow?(arg)
|
118
135
|
|
119
136
|
failure? ? self : arg.__new__(self, data).__call__
|
120
137
|
end
|
121
138
|
|
122
139
|
def transitions
|
123
|
-
@__transitions.
|
140
|
+
@__transitions.dup
|
124
141
|
end
|
125
142
|
|
126
143
|
FetchData = -> (data) do
|
@@ -134,44 +151,46 @@ module Micro
|
|
134
151
|
raise Error::InvalidResultType unless type.is_a?(Symbol)
|
135
152
|
raise Error::InvalidUseCase unless use_case.is_a?(::Micro::Case)
|
136
153
|
|
137
|
-
@
|
154
|
+
@__success, @type, @use_case = is_success, type, use_case
|
138
155
|
|
139
|
-
@data = FetchData.call(data)
|
156
|
+
@data = FetchData.call(data).freeze
|
140
157
|
|
141
158
|
raise Micro::Case::Error::InvalidResult.new(is_success, type, use_case) unless @data
|
142
159
|
|
143
|
-
|
144
|
-
@__transitions_accumulated_data.merge!(@data)
|
160
|
+
@__accumulated_data.merge!(@data)
|
145
161
|
|
146
|
-
|
147
|
-
|
162
|
+
use_case_attributes = Utils.symbolize_hash_keys(@use_case.attributes)
|
163
|
+
|
164
|
+
__update_accessible_attributes(use_case_attributes)
|
165
|
+
|
166
|
+
__set_transition(use_case_attributes) unless @__transitions.frozen?
|
148
167
|
|
149
168
|
self
|
150
169
|
end
|
151
170
|
|
152
|
-
def
|
153
|
-
return arg unless
|
171
|
+
def __set_accessible_attributes__(arg)
|
172
|
+
return arg unless arg.is_a?(Hash)
|
154
173
|
|
155
|
-
|
156
|
-
attributes = Utils.symbolize_hash_keys(arg)
|
174
|
+
attributes = Utils.symbolize_hash_keys(arg)
|
157
175
|
|
158
|
-
|
159
|
-
|
176
|
+
__update_accessible_attributes(attributes)
|
177
|
+
__fetch_accessible_attributes
|
160
178
|
end
|
161
179
|
|
162
180
|
private
|
163
181
|
|
164
|
-
def
|
165
|
-
|
166
|
-
|
167
|
-
opt ? opt.merge(@__transitions_accumulated_data) : @__transitions_accumulated_data
|
168
|
-
)
|
182
|
+
def __update_accessible_attributes(attributes)
|
183
|
+
@__accessible_attributes.merge!(attributes)
|
184
|
+
end
|
169
185
|
|
170
|
-
|
186
|
+
def __fetch_accessible_attributes
|
187
|
+
@__accessible_attributes.dup
|
171
188
|
end
|
172
189
|
|
173
190
|
def __call_proc(fn, expected)
|
174
|
-
|
191
|
+
__update_accessible_attributes(@__accumulated_data)
|
192
|
+
|
193
|
+
result = fn.arity.zero? ? fn.call : fn.call(__fetch_accessible_attributes)
|
175
194
|
|
176
195
|
return self if result === self
|
177
196
|
|
@@ -179,7 +198,9 @@ module Micro
|
|
179
198
|
end
|
180
199
|
|
181
200
|
def __call_method(methd, attributes = nil)
|
182
|
-
|
201
|
+
__update_accessible_attributes(attributes ? attributes.merge(@__accumulated_data) : @__accumulated_data)
|
202
|
+
|
203
|
+
result = methd.arity.zero? ? methd.call : methd.call(**__fetch_accessible_attributes)
|
183
204
|
|
184
205
|
return self if result === self
|
185
206
|
|
@@ -194,27 +215,11 @@ module Micro
|
|
194
215
|
failure? && (expected_type.nil? || expected_type == type)
|
195
216
|
end
|
196
217
|
|
197
|
-
def
|
198
|
-
@
|
199
|
-
@__transitions_accessible_attributes
|
200
|
-
end
|
201
|
-
|
202
|
-
def __set_transition
|
203
|
-
use_case_class = @use_case.class
|
204
|
-
use_case_attributes = Utils.symbolize_hash_keys(@use_case.attributes)
|
205
|
-
|
206
|
-
__update_transitions_accessible_attributes(use_case_attributes)
|
207
|
-
|
208
|
-
result = @success ? :success : :failure
|
209
|
-
|
210
|
-
@__transitions << {
|
211
|
-
use_case: { class: use_case_class, attributes: use_case_attributes },
|
212
|
-
result => { type: @type, result: data },
|
213
|
-
accessible_attributes: @__transitions_accessible_attributes.keys
|
214
|
-
}
|
218
|
+
def __set_transition(use_case_attributes)
|
219
|
+
@__transitions << @__transitions_mapper.call(self, use_case_attributes)
|
215
220
|
end
|
216
221
|
|
217
|
-
|
222
|
+
private_constant :FetchData, :INVALID_INVOCATION_OF_THE_THEN_METHOD
|
218
223
|
end
|
219
224
|
end
|
220
225
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Micro
|
4
|
+
class Case
|
5
|
+
class Result
|
6
|
+
class Transitions
|
7
|
+
MapEverything = -> (result, use_case_attributes) do
|
8
|
+
result_track = result.success? ? :success : :failure
|
9
|
+
|
10
|
+
{
|
11
|
+
use_case: { class: result.use_case.class, attributes: use_case_attributes },
|
12
|
+
result_track => { type: result.type, result: result.data },
|
13
|
+
accessible_attributes: result.accessible_attributes
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
data/lib/micro/case/safe.rb
CHANGED
@@ -3,12 +3,12 @@
|
|
3
3
|
module Micro
|
4
4
|
class Case
|
5
5
|
class Safe < ::Micro::Case
|
6
|
-
def self.
|
6
|
+
def self.__flow_builder__
|
7
7
|
Cases::Safe::Flow
|
8
8
|
end
|
9
9
|
|
10
10
|
def __call__
|
11
|
-
|
11
|
+
call
|
12
12
|
rescue => exception
|
13
13
|
raise exception if Error.by_wrong_usage?(exception)
|
14
14
|
|
data/lib/micro/case/utils.rb
CHANGED
data/lib/micro/case/version.rb
CHANGED
@@ -37,7 +37,9 @@ module Micro
|
|
37
37
|
def failure_by_validation_error(object)
|
38
38
|
errors = object.respond_to?(:errors) ? object.errors : object
|
39
39
|
|
40
|
-
Failure
|
40
|
+
Failure Micro::Case::Config.instance.activemodel_validation_errors_failure, result: {
|
41
|
+
errors: errors
|
42
|
+
}
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
data/lib/micro/cases/flow.rb
CHANGED
@@ -10,9 +10,7 @@ module Micro
|
|
10
10
|
attr_reader :use_cases
|
11
11
|
|
12
12
|
def self.map_use_cases(arg)
|
13
|
-
|
14
|
-
|
15
|
-
Array(arg)
|
13
|
+
arg.is_a?(Flow) ? arg.use_cases : Array(arg)
|
16
14
|
end
|
17
15
|
|
18
16
|
def self.build(args)
|
@@ -24,17 +22,17 @@ module Micro
|
|
24
22
|
end
|
25
23
|
|
26
24
|
def initialize(use_cases)
|
27
|
-
@use_cases = use_cases
|
28
|
-
@
|
29
|
-
@
|
25
|
+
@use_cases = use_cases.dup.freeze
|
26
|
+
@next_ones = use_cases.dup
|
27
|
+
@first = @next_ones.shift
|
30
28
|
end
|
31
29
|
|
32
30
|
def call!(input:, result:)
|
33
|
-
first_result =
|
31
|
+
first_result = __case_use_case(@first, result, input)
|
34
32
|
|
35
|
-
return first_result if @
|
33
|
+
return first_result if @next_ones.empty?
|
36
34
|
|
37
|
-
|
35
|
+
__call_next_use_cases(first_result)
|
38
36
|
end
|
39
37
|
|
40
38
|
def call(input = Kind::Empty::HASH)
|
@@ -51,28 +49,34 @@ module Micro
|
|
51
49
|
can_yield_self = respond_to?(:yield_self)
|
52
50
|
|
53
51
|
if block
|
54
|
-
|
52
|
+
raise_invalid_invocation_of_the_then_method if use_case
|
55
53
|
raise NotImplementedError if !can_yield_self
|
56
54
|
|
57
55
|
yield_self(&block)
|
58
56
|
else
|
59
57
|
return yield_self if !use_case && can_yield_self
|
60
58
|
|
59
|
+
raise_invalid_invocation_of_the_then_method unless ::Micro.case_or_flow?(use_case)
|
60
|
+
|
61
61
|
self.call.then(use_case)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
private
|
66
66
|
|
67
|
-
def
|
67
|
+
def raise_invalid_invocation_of_the_then_method
|
68
|
+
raise Case::Error::InvalidInvocationOfTheThenMethod.new("#{self.class.name}#")
|
69
|
+
end
|
70
|
+
|
71
|
+
def __case_use_case(use_case, result, input)
|
68
72
|
use_case.__new__(result, input).__call__
|
69
73
|
end
|
70
74
|
|
71
|
-
def
|
72
|
-
@
|
75
|
+
def __call_next_use_cases(first_result)
|
76
|
+
@next_ones.reduce(first_result) do |result, use_case|
|
73
77
|
break result if result.failure?
|
74
78
|
|
75
|
-
|
79
|
+
__case_use_case(use_case, result, result.data)
|
76
80
|
end
|
77
81
|
end
|
78
82
|
end
|