u-case 3.0.0.rc7 → 4.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.
- checksums.yaml +4 -4
- data/.travis.sh +8 -4
- data/Gemfile +9 -1
- data/README.md +191 -122
- data/README.pt-BR.md +212 -143
- data/lib/micro/case.rb +23 -17
- data/lib/micro/case/config.rb +16 -4
- data/lib/micro/case/error.rb +7 -2
- data/lib/micro/case/result.rb +58 -47
- data/lib/micro/case/result/transitions.rb +18 -0
- data/lib/micro/case/safe.rb +2 -2
- data/lib/micro/case/strict.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
- data/u-case.gemspec +3 -3
- metadata +11 -8
data/lib/micro/case.rb
CHANGED
@@ -8,31 +8,36 @@ 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'
|
16
16
|
|
17
17
|
require 'micro/cases'
|
18
18
|
|
19
|
-
include Micro::Attributes.
|
19
|
+
include Micro::Attributes.with(:initialize, :diff)
|
20
20
|
|
21
21
|
def self.call(options = Kind::Empty::HASH)
|
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
|
@@ -58,7 +63,8 @@ module Micro
|
|
58
63
|
end
|
59
64
|
|
60
65
|
def self.inherited(subclass)
|
61
|
-
subclass.
|
66
|
+
subclass.__attributes_set_after_inherit__(self.__attributes_data__)
|
67
|
+
|
62
68
|
subclass.extend ::Micro::Attributes.const_get('Macros::ForSubclasses'.freeze)
|
63
69
|
|
64
70
|
if self.send(:__flow_use_cases) && !subclass.name.to_s.end_with?(FLOW_STEP)
|
@@ -70,11 +76,9 @@ module Micro
|
|
70
76
|
end
|
71
77
|
|
72
78
|
def self.__new__(result, arg)
|
73
|
-
input = result.
|
79
|
+
input = result.__set_accessible_attributes__(arg)
|
74
80
|
|
75
|
-
|
76
|
-
instance.__set_result__(result)
|
77
|
-
instance
|
81
|
+
new(input).__set_result__(result)
|
78
82
|
end
|
79
83
|
|
80
84
|
def self.__flow_builder__
|
@@ -127,7 +131,7 @@ module Micro
|
|
127
131
|
end
|
128
132
|
|
129
133
|
def __call__
|
130
|
-
|
134
|
+
call
|
131
135
|
end
|
132
136
|
|
133
137
|
def __set_result__(result)
|
@@ -135,12 +139,20 @@ module Micro
|
|
135
139
|
raise Error::ResultIsAlreadyDefined if defined?(@__result)
|
136
140
|
|
137
141
|
@__result = result
|
142
|
+
|
143
|
+
self
|
138
144
|
end
|
139
145
|
|
140
146
|
private
|
141
147
|
|
142
|
-
|
148
|
+
def apply(name)
|
149
|
+
method(name)
|
150
|
+
end
|
151
|
+
|
143
152
|
def call
|
153
|
+
return __call_use_case_flow if __call_use_case_flow?
|
154
|
+
|
155
|
+
__call_use_case
|
144
156
|
end
|
145
157
|
|
146
158
|
def __setup_use_case(input)
|
@@ -151,12 +163,6 @@ module Micro
|
|
151
163
|
self.attributes = input
|
152
164
|
end
|
153
165
|
|
154
|
-
def __call!
|
155
|
-
return __call_use_case_flow if __call_use_case_flow?
|
156
|
-
|
157
|
-
__call_use_case
|
158
|
-
end
|
159
|
-
|
160
166
|
def __call_use_case
|
161
167
|
result = call!
|
162
168
|
|
@@ -203,7 +209,7 @@ module Micro
|
|
203
209
|
__result.__set__(is_success, value, type, self)
|
204
210
|
end
|
205
211
|
|
206
|
-
|
212
|
+
private_constant :MapFailureType, :INVALID_INVOCATION_OF_THE_THEN_METHOD
|
207
213
|
end
|
208
214
|
|
209
215
|
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,11 +46,16 @@ 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)
|
53
|
-
|
55
|
+
case exception
|
56
|
+
when Kind::Error, ArgumentError, InvalidResult, UnexpectedResult then true
|
57
|
+
else false
|
58
|
+
end
|
54
59
|
end
|
55
60
|
end
|
56
61
|
end
|
data/lib/micro/case/result.rb
CHANGED
@@ -5,24 +5,41 @@ 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 = Transitions::MapEverything)
|
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 if enable_transitions
|
20
33
|
end
|
21
34
|
|
22
35
|
def to_ary
|
23
36
|
[data, type]
|
24
37
|
end
|
25
38
|
|
39
|
+
def to_sym
|
40
|
+
@__success ? :success : :failure
|
41
|
+
end
|
42
|
+
|
26
43
|
def [](key)
|
27
44
|
data[key]
|
28
45
|
end
|
@@ -44,13 +61,17 @@ module Micro
|
|
44
61
|
end
|
45
62
|
|
46
63
|
def success?
|
47
|
-
@
|
64
|
+
@__success
|
48
65
|
end
|
49
66
|
|
50
67
|
def failure?
|
51
68
|
!success?
|
52
69
|
end
|
53
70
|
|
71
|
+
def accessible_attributes
|
72
|
+
@__accessible_attributes.keys
|
73
|
+
end
|
74
|
+
|
54
75
|
def on_success(expected_type = nil)
|
55
76
|
return self unless __success_type?(expected_type)
|
56
77
|
|
@@ -85,7 +106,7 @@ module Micro
|
|
85
106
|
can_yield_self = respond_to?(:yield_self)
|
86
107
|
|
87
108
|
if block
|
88
|
-
raise
|
109
|
+
raise INVALID_INVOCATION_OF_THE_THEN_METHOD if use_case
|
89
110
|
raise NotImplementedError if !can_yield_self
|
90
111
|
|
91
112
|
yield_self(&block)
|
@@ -94,7 +115,7 @@ module Micro
|
|
94
115
|
return failure? ? self : __call_proc(use_case, 'then(-> {})'.freeze) if use_case.is_a?(Proc)
|
95
116
|
return failure? ? self : __call_method(use_case, attributes) if use_case.is_a?(Method)
|
96
117
|
|
97
|
-
raise
|
118
|
+
raise INVALID_INVOCATION_OF_THE_THEN_METHOD unless ::Micro.case_or_flow?(use_case)
|
98
119
|
|
99
120
|
return self if failure?
|
100
121
|
|
@@ -114,13 +135,13 @@ module Micro
|
|
114
135
|
return __call_proc(arg, '| -> {}'.freeze) if arg.is_a?(Proc)
|
115
136
|
return __call_method(arg) if arg.is_a?(Method)
|
116
137
|
|
117
|
-
raise
|
138
|
+
raise INVALID_INVOCATION_OF_THE_THEN_METHOD unless ::Micro.case_or_flow?(arg)
|
118
139
|
|
119
140
|
failure? ? self : arg.__new__(self, data).__call__
|
120
141
|
end
|
121
142
|
|
122
143
|
def transitions
|
123
|
-
@__transitions.
|
144
|
+
@__transitions.dup
|
124
145
|
end
|
125
146
|
|
126
147
|
FetchData = -> (data) do
|
@@ -134,42 +155,46 @@ module Micro
|
|
134
155
|
raise Error::InvalidResultType unless type.is_a?(Symbol)
|
135
156
|
raise Error::InvalidUseCase unless use_case.is_a?(::Micro::Case)
|
136
157
|
|
137
|
-
@
|
158
|
+
@__success, @type, @use_case = is_success, type, use_case
|
138
159
|
|
139
|
-
@data = FetchData.call(data)
|
160
|
+
@data = FetchData.call(data).freeze
|
140
161
|
|
141
162
|
raise Micro::Case::Error::InvalidResult.new(is_success, type, use_case) unless @data
|
142
163
|
|
143
|
-
@
|
164
|
+
@__accumulated_data.merge!(@data)
|
165
|
+
|
166
|
+
use_case_attributes = Utils.symbolize_hash_keys(@use_case.attributes)
|
144
167
|
|
145
|
-
|
168
|
+
__update_accessible_attributes(use_case_attributes)
|
169
|
+
|
170
|
+
__set_transition(use_case_attributes) unless @__transitions.frozen?
|
146
171
|
|
147
172
|
self
|
148
173
|
end
|
149
174
|
|
150
|
-
def
|
151
|
-
return arg unless
|
175
|
+
def __set_accessible_attributes__(arg)
|
176
|
+
return arg unless arg.is_a?(Hash)
|
152
177
|
|
153
|
-
|
154
|
-
attributes = Utils.symbolize_hash_keys(arg)
|
178
|
+
attributes = Utils.symbolize_hash_keys(arg)
|
155
179
|
|
156
|
-
|
157
|
-
|
180
|
+
__update_accessible_attributes(attributes)
|
181
|
+
__fetch_accessible_attributes
|
158
182
|
end
|
159
183
|
|
160
184
|
private
|
161
185
|
|
162
|
-
def
|
163
|
-
|
164
|
-
|
165
|
-
opt ? opt.merge(@__transitions_accumulated_data) : @__transitions_accumulated_data
|
166
|
-
)
|
186
|
+
def __update_accessible_attributes(attributes)
|
187
|
+
@__accessible_attributes.merge!(attributes)
|
188
|
+
end
|
167
189
|
|
168
|
-
|
190
|
+
def __fetch_accessible_attributes
|
191
|
+
@__accessible_attributes.dup
|
169
192
|
end
|
170
193
|
|
171
194
|
def __call_proc(fn, expected)
|
172
|
-
|
195
|
+
__update_accessible_attributes(@__accumulated_data)
|
196
|
+
|
197
|
+
result = fn.arity.zero? ? fn.call : fn.call(__fetch_accessible_attributes)
|
173
198
|
|
174
199
|
return self if result === self
|
175
200
|
|
@@ -177,7 +202,9 @@ module Micro
|
|
177
202
|
end
|
178
203
|
|
179
204
|
def __call_method(methd, attributes = nil)
|
180
|
-
|
205
|
+
__update_accessible_attributes(attributes ? attributes.merge(@__accumulated_data) : @__accumulated_data)
|
206
|
+
|
207
|
+
result = methd.arity.zero? ? methd.call : methd.call(**__fetch_accessible_attributes)
|
181
208
|
|
182
209
|
return self if result === self
|
183
210
|
|
@@ -192,27 +219,11 @@ module Micro
|
|
192
219
|
failure? && (expected_type.nil? || expected_type == type)
|
193
220
|
end
|
194
221
|
|
195
|
-
def
|
196
|
-
@
|
197
|
-
@__transitions_accessible_attributes
|
198
|
-
end
|
199
|
-
|
200
|
-
def __set_transition
|
201
|
-
use_case_class = @use_case.class
|
202
|
-
use_case_attributes = Utils.symbolize_hash_keys(@use_case.attributes)
|
203
|
-
|
204
|
-
__update_transitions_accessible_attributes(use_case_attributes)
|
205
|
-
|
206
|
-
result = @success ? :success : :failure
|
207
|
-
|
208
|
-
@__transitions << {
|
209
|
-
use_case: { class: use_case_class, attributes: use_case_attributes },
|
210
|
-
result => { type: @type, result: data },
|
211
|
-
accessible_attributes: @__transitions_accessible_attributes.keys
|
212
|
-
}
|
222
|
+
def __set_transition(use_case_attributes)
|
223
|
+
@__transitions << @__transitions_mapper.call(self, use_case_attributes)
|
213
224
|
end
|
214
225
|
|
215
|
-
|
226
|
+
private_constant :FetchData, :INVALID_INVOCATION_OF_THE_THEN_METHOD
|
216
227
|
end
|
217
228
|
end
|
218
229
|
end
|
@@ -0,0 +1,18 @@
|
|
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
|
+
{
|
9
|
+
use_case: { class: result.use_case.class, attributes: use_case_attributes },
|
10
|
+
result.to_sym => { type: result.type, result: result.data },
|
11
|
+
accessible_attributes: result.accessible_attributes
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
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/strict.rb
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
module Micro
|
4
4
|
class Case
|
5
5
|
class Strict < ::Micro::Case
|
6
|
-
include Micro::Attributes::Features::
|
6
|
+
include Micro::Attributes::Features::Initialize::Strict
|
7
7
|
|
8
8
|
class Safe < ::Micro::Case::Safe
|
9
|
-
include Micro::Attributes::Features::
|
9
|
+
include Micro::Attributes::Features::Initialize::Strict
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
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
|