u-case 5.5.0 → 5.6.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/CHANGELOG.md +18 -0
- data/README.md +514 -2
- data/README.pt-BR.md +532 -2
- data/lib/micro/case/check.rb +71 -0
- data/lib/micro/case/config.rb +16 -0
- data/lib/micro/case/version.rb +1 -1
- data/lib/micro/case.rb +49 -7
- data/lib/micro/cases/error.rb +9 -0
- data/lib/micro/cases/flow.rb +46 -8
- data/lib/micro/cases.rb +12 -4
- metadata +1 -1
data/lib/micro/case.rb
CHANGED
|
@@ -63,8 +63,11 @@ module Micro
|
|
|
63
63
|
Proc.new { |arg| call(arg) }
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
def self.flow(*args)
|
|
67
|
-
|
|
66
|
+
def self.flow(*args, transaction: nil, steps: nil)
|
|
67
|
+
::Micro::Case.check.flow_steps_kwarg!(args.empty? ? nil : args, steps, "#{self.name}.flow")
|
|
68
|
+
|
|
69
|
+
@__flow_use_cases = Cases::Utils.map_use_cases(steps || args)
|
|
70
|
+
@__flow_transaction = transaction
|
|
68
71
|
end
|
|
69
72
|
|
|
70
73
|
def self.results(&block)
|
|
@@ -81,6 +84,19 @@ module Micro
|
|
|
81
84
|
parent.respond_to?(:__results_contract__) ? parent.__results_contract__ : nil
|
|
82
85
|
end
|
|
83
86
|
|
|
87
|
+
def self.transaction(with:)
|
|
88
|
+
::Micro::Case.check.transaction_owner!(with)
|
|
89
|
+
|
|
90
|
+
@__transaction_class = with
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def self.__transaction_class__
|
|
94
|
+
return @__transaction_class if defined?(@__transaction_class)
|
|
95
|
+
|
|
96
|
+
parent = superclass
|
|
97
|
+
parent.respond_to?(:__transaction_class__) ? parent.__transaction_class__ : nil
|
|
98
|
+
end
|
|
99
|
+
|
|
84
100
|
class << self
|
|
85
101
|
alias __call__ call
|
|
86
102
|
|
|
@@ -129,7 +145,17 @@ module Micro
|
|
|
129
145
|
|
|
130
146
|
self.class_eval('def use_cases; self.class.use_cases; end')
|
|
131
147
|
|
|
132
|
-
@__flow = __flow_builder__.build(args)
|
|
148
|
+
@__flow = __flow_builder__.build(args, transaction: __resolved_flow_transaction)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
private_class_method def self.__flow_transaction
|
|
152
|
+
return @__flow_transaction if defined?(@__flow_transaction)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
private_class_method def self.__resolved_flow_transaction
|
|
156
|
+
return __transaction_class__ || true if __flow_transaction == true
|
|
157
|
+
|
|
158
|
+
__flow_transaction
|
|
133
159
|
end
|
|
134
160
|
|
|
135
161
|
FLOW_STEP = 'Self'.freeze
|
|
@@ -301,15 +327,31 @@ module Micro
|
|
|
301
327
|
@__result.__set__(is_success, value, type, self)
|
|
302
328
|
end
|
|
303
329
|
|
|
304
|
-
def transaction(adapter = :
|
|
305
|
-
|
|
330
|
+
def transaction(adapter = nil, with: nil)
|
|
331
|
+
# Backward-compat shim for the pre-5.6.0 positional form:
|
|
332
|
+
# transaction(:activerecord) { ... }
|
|
333
|
+
# The `:activerecord` value was the only positional value the
|
|
334
|
+
# helper ever accepted on prior versions. Anything else raises.
|
|
335
|
+
if adapter
|
|
336
|
+
raise ArgumentError,
|
|
337
|
+
"transaction(#{adapter.inspect}) is not supported; use transaction(with: SomeARClass) or transaction without arguments" unless adapter == :activerecord
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
::Micro::Case.check.transaction_owner!(with) if with
|
|
341
|
+
|
|
342
|
+
owner = with || self.class.__transaction_class__
|
|
343
|
+
|
|
344
|
+
if owner.nil?
|
|
345
|
+
::Micro::Case.check.activerecord_loaded!
|
|
346
|
+
owner = Config.instance.default_transaction_class.call
|
|
347
|
+
end
|
|
306
348
|
|
|
307
349
|
result = nil
|
|
308
350
|
|
|
309
|
-
|
|
351
|
+
owner.transaction do
|
|
310
352
|
result = yield
|
|
311
353
|
|
|
312
|
-
raise ActiveRecord::Rollback if result.failure?
|
|
354
|
+
raise ::ActiveRecord::Rollback if result.failure?
|
|
313
355
|
end
|
|
314
356
|
|
|
315
357
|
result
|
data/lib/micro/cases/error.rb
CHANGED
|
@@ -7,6 +7,15 @@ module Micro
|
|
|
7
7
|
class InvalidUseCases < ArgumentError
|
|
8
8
|
def initialize; super('argument must be a collection of `Micro::Case` classes'.freeze); end
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
class TransactionAdapterMissing < RuntimeError
|
|
12
|
+
def initialize
|
|
13
|
+
super(
|
|
14
|
+
'transaction: true requires ActiveRecord to be loaded. '\
|
|
15
|
+
"Add `require 'active_record'` (or `gem 'activerecord'` to your Gemfile) before invoking the flow.".freeze
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
10
19
|
end
|
|
11
20
|
|
|
12
21
|
end
|
data/lib/micro/cases/flow.rb
CHANGED
|
@@ -8,30 +8,31 @@ module Micro
|
|
|
8
8
|
|
|
9
9
|
attr_reader :use_cases
|
|
10
10
|
|
|
11
|
-
def self.build(args)
|
|
11
|
+
def self.build(args, transaction: nil)
|
|
12
12
|
use_cases = Utils.map_use_cases(args)
|
|
13
13
|
|
|
14
14
|
::Micro::Case.check.flow_use_cases!(use_cases)
|
|
15
15
|
|
|
16
|
-
new(use_cases)
|
|
16
|
+
new(use_cases, transaction: transaction)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def initialize(use_cases)
|
|
19
|
+
def initialize(use_cases, transaction: nil)
|
|
20
20
|
@use_cases = use_cases.dup.freeze
|
|
21
21
|
@next_ones = use_cases.dup
|
|
22
22
|
@first = @next_ones.shift
|
|
23
|
+
@transaction = ::Micro::Case.check.transaction_kwarg!(transaction)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def inspect
|
|
26
|
-
'#<(%s) use_cases=%s>' % [self.class, @use_cases]
|
|
27
|
+
return '#<(%s) use_cases=%s>' % [self.class, @use_cases] unless @transaction
|
|
28
|
+
|
|
29
|
+
'#<(%s) transaction=%p use_cases=%s>' % [self.class, @transaction, @use_cases]
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
def call!(input:, result:)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return first_result if @next_ones.empty?
|
|
33
|
+
return __call_steps(input, result) unless @transaction
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
__wrap_in_transaction { __call_steps(input, result) }
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def call(input = Kind::Empty::HASH)
|
|
@@ -75,6 +76,43 @@ module Micro
|
|
|
75
76
|
raise Case::Error::InvalidInvocationOfTheThenMethod.new("#{self.class.name}#")
|
|
76
77
|
end
|
|
77
78
|
|
|
79
|
+
def __call_steps(input, result)
|
|
80
|
+
first_result = __call_use_case(@first, result, input)
|
|
81
|
+
|
|
82
|
+
return first_result if @next_ones.empty?
|
|
83
|
+
|
|
84
|
+
__call_next_use_cases(first_result)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def __wrap_in_transaction
|
|
88
|
+
owner = __transaction_owner
|
|
89
|
+
|
|
90
|
+
result = nil
|
|
91
|
+
|
|
92
|
+
owner.transaction do
|
|
93
|
+
result = yield
|
|
94
|
+
|
|
95
|
+
raise ::ActiveRecord::Rollback if result.failure?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
result
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def __transaction_owner
|
|
102
|
+
return @transaction if @transaction.is_a?(Class)
|
|
103
|
+
|
|
104
|
+
callback = ::Micro::Case::Config.instance.default_transaction_class
|
|
105
|
+
|
|
106
|
+
# Only the gem's default callback (`-> { ActiveRecord::Base }`)
|
|
107
|
+
# needs the AR-loaded guard. A user-supplied callback can
|
|
108
|
+
# return whatever class they want — we trust it.
|
|
109
|
+
if callback.equal?(::Micro::Case::Config::DEFAULT_TRANSACTION_CLASS_CALLBACK)
|
|
110
|
+
::Micro::Case.check.activerecord_loaded!
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
callback.call
|
|
114
|
+
end
|
|
115
|
+
|
|
78
116
|
def __call_use_case(use_case, result, input)
|
|
79
117
|
__build_use_case(use_case, result, input).__call__
|
|
80
118
|
end
|
data/lib/micro/cases.rb
CHANGED
|
@@ -8,16 +8,24 @@ require 'micro/cases/map'
|
|
|
8
8
|
|
|
9
9
|
module Micro
|
|
10
10
|
module Cases
|
|
11
|
-
def self.flow(args)
|
|
12
|
-
|
|
11
|
+
def self.flow(args = nil, transaction: nil, steps: nil)
|
|
12
|
+
args = nil if args.is_a?(Array) && args.empty?
|
|
13
|
+
|
|
14
|
+
::Micro::Case.check.flow_steps_kwarg!(args, steps, 'Micro::Cases.flow')
|
|
15
|
+
|
|
16
|
+
Flow.build(steps || args, transaction: transaction)
|
|
13
17
|
end
|
|
14
18
|
|
|
15
|
-
def self.safe_flow(args)
|
|
19
|
+
def self.safe_flow(args = nil, transaction: nil, steps: nil)
|
|
16
20
|
if Case::Config.instance.disable_safe_features
|
|
17
21
|
raise Case::Error::SafeFeaturesDisabled.new('Micro::Cases.safe_flow')
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
args = nil if args.is_a?(Array) && args.empty?
|
|
25
|
+
|
|
26
|
+
::Micro::Case.check.flow_steps_kwarg!(args, steps, 'Micro::Cases.safe_flow')
|
|
27
|
+
|
|
28
|
+
Safe::Flow.build(steps || args, transaction: transaction)
|
|
21
29
|
end
|
|
22
30
|
|
|
23
31
|
def self.map(args)
|