u-case 3.0.0.rc6 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|