u-case 3.0.0.rc5 → 3.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.
@@ -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,11 +22,14 @@ module Micro
22
22
  new(options).__call__
23
23
  end
24
24
 
25
+ INVALID_INVOCATION_OF_THE_THE_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 Error::InvalidInvocationOfTheThenMethod if use_case
32
+ raise INVALID_INVOCATION_OF_THE_THE_METHOD if use_case
30
33
  raise NotImplementedError if !can_yield_self
31
34
 
32
35
  yield_self(&block)
@@ -70,16 +73,9 @@ module Micro
70
73
  end
71
74
 
72
75
  def self.__new__(result, arg)
73
- instance = new(arg)
74
- instance.__set_result__(result)
75
- instance
76
- end
76
+ input = result.__set_accessible_attributes__(arg)
77
77
 
78
- def self.__call_and_set_transition__(result, arg)
79
- input =
80
- arg.is_a?(Hash) ? result.__set_transitions_accessible_attributes__(arg) : arg
81
-
82
- __new__(result, input).__call__
78
+ new(input).__set_result__(result)
83
79
  end
84
80
 
85
81
  def self.__flow_builder__
@@ -132,7 +128,7 @@ module Micro
132
128
  end
133
129
 
134
130
  def __call__
135
- __call!
131
+ call
136
132
  end
137
133
 
138
134
  def __set_result__(result)
@@ -140,12 +136,16 @@ module Micro
140
136
  raise Error::ResultIsAlreadyDefined if defined?(@__result)
141
137
 
142
138
  @__result = result
139
+
140
+ self
143
141
  end
144
142
 
145
143
  private
146
144
 
147
- # This method was reserved for a new feature
148
145
  def call
146
+ return __call_use_case_flow if __call_use_case_flow?
147
+
148
+ __call_use_case
149
149
  end
150
150
 
151
151
  def __setup_use_case(input)
@@ -156,12 +156,6 @@ module Micro
156
156
  self.attributes = input
157
157
  end
158
158
 
159
- def __call!
160
- return __call_use_case_flow if __call_use_case_flow?
161
-
162
- __call_use_case
163
- end
164
-
165
159
  def __call_use_case
166
160
  result = call!
167
161
 
@@ -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 enable_transitions=(value)
17
- Micro::Case::Result.class_variable_set(
18
- :@@transition_tracking_disabled, !Kind::Of::Boolean(value)
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
+ @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
@@ -46,7 +46,9 @@ module Micro
46
46
  end
47
47
 
48
48
  class InvalidInvocationOfTheThenMethod < StandardError
49
- def initialize; super('Invalid invocation of the Micro::Case::Result#then method'); end
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)
@@ -7,15 +7,23 @@ module Micro
7
7
  class Result
8
8
  Kind::Types.add(self)
9
9
 
10
- @@transition_tracking_disabled = false
10
+ INVALID_INVOCATION_OF_THE_THE_METHOD =
11
+ Error::InvalidInvocationOfTheThenMethod.new(self.name)
12
+
13
+ @@transitions_enabled = true
14
+
15
+ def self.transitions_enabled?
16
+ @@transitions_enabled
17
+ end
11
18
 
12
19
  attr_reader :type, :data, :use_case
13
20
 
14
21
  alias value data
15
22
 
16
23
  def initialize
17
- @__transitions__ = []
18
- @__transitions_accessible_attributes__ = {}
24
+ @__transitions = @@transitions_enabled ? [] : Kind::Empty::ARRAY
25
+ @__accumulated_data = {}
26
+ @__accessible_attributes = {}
19
27
  end
20
28
 
21
29
  def to_ary
@@ -84,18 +92,16 @@ module Micro
84
92
  can_yield_self = respond_to?(:yield_self)
85
93
 
86
94
  if block
87
- raise Error::InvalidInvocationOfTheThenMethod if use_case
95
+ raise INVALID_INVOCATION_OF_THE_THE_METHOD if use_case
88
96
  raise NotImplementedError if !can_yield_self
89
97
 
90
98
  yield_self(&block)
91
99
  else
92
100
  return yield_self if !use_case && can_yield_self
101
+ return failure? ? self : __call_proc(use_case, 'then(-> {})'.freeze) if use_case.is_a?(Proc)
102
+ return failure? ? self : __call_method(use_case, attributes) if use_case.is_a?(Method)
93
103
 
94
- if use_case.is_a?(Proc)
95
- return failure? ? self : __call_proc(use_case, expected: 'then(-> {})'.freeze)
96
- end
97
-
98
- raise Error::InvalidInvocationOfTheThenMethod unless ::Micro.case_or_flow?(use_case)
104
+ raise INVALID_INVOCATION_OF_THE_THE_METHOD unless ::Micro.case_or_flow?(use_case)
99
105
 
100
106
  return self if failure?
101
107
 
@@ -104,7 +110,7 @@ module Micro
104
110
  if use_case.is_a?(::Micro::Cases::Flow)
105
111
  use_case.call!(input: input, result: self)
106
112
  else
107
- use_case.__call_and_set_transition__(self, input)
113
+ use_case.__new__(self, input).__call__
108
114
  end
109
115
  end
110
116
  end
@@ -112,15 +118,16 @@ module Micro
112
118
  def |(arg)
113
119
  return self if failure?
114
120
 
115
- return __call_proc(arg, expected: '| -> {}'.freeze) if arg.is_a?(Proc)
121
+ return __call_proc(arg, '| -> {}'.freeze) if arg.is_a?(Proc)
122
+ return __call_method(arg) if arg.is_a?(Method)
116
123
 
117
- raise Error::InvalidInvocationOfTheThenMethod unless ::Micro.case_or_flow?(arg)
124
+ raise INVALID_INVOCATION_OF_THE_THE_METHOD unless ::Micro.case_or_flow?(arg)
118
125
 
119
- failure? ? self : arg.__call_and_set_transition__(self, data)
126
+ failure? ? self : arg.__new__(self, data).__call__
120
127
  end
121
128
 
122
129
  def transitions
123
- @__transitions__.clone
130
+ @__transitions.clone
124
131
  end
125
132
 
126
133
  FetchData = -> (data) do
@@ -140,29 +147,53 @@ module Micro
140
147
 
141
148
  raise Micro::Case::Error::InvalidResult.new(is_success, type, use_case) unless @data
142
149
 
143
- __set_transition unless @@transition_tracking_disabled
150
+ @__accumulated_data.merge!(@data)
151
+
152
+ use_case_attributes = Utils.symbolize_hash_keys(@use_case.attributes)
153
+
154
+ __update_accessible_attributes(use_case_attributes)
155
+
156
+ __set_transition(use_case_attributes) unless @__transitions.frozen?
144
157
 
145
158
  self
146
159
  end
147
160
 
148
- def __set_transitions_accessible_attributes__(attributes_data)
149
- return attributes_data if @@transition_tracking_disabled
161
+ def __set_accessible_attributes__(arg)
162
+ return arg unless arg.is_a?(Hash)
150
163
 
151
- attributes = Utils.symbolize_hash_keys(attributes_data)
164
+ attributes = Utils.symbolize_hash_keys(arg)
152
165
 
153
- __update_transitions_accessible_attributes(attributes)
166
+ __update_accessible_attributes(attributes)
154
167
  end
155
168
 
156
169
  private
157
170
 
158
- def __call_proc(arg, expected:)
159
- result = arg.arity.zero? ? arg.call : arg.call(data.clone)
171
+ def __fetch_accumulated_data(opt = nil)
172
+ __update_accessible_attributes(
173
+ opt ? opt.merge(@__accumulated_data) : @__accumulated_data
174
+ )
175
+ end
160
176
 
161
- return result if result.is_a?(Result)
177
+ def __call_proc(fn, expected)
178
+ input = __fetch_accumulated_data
179
+
180
+ result = fn.arity.zero? ? fn.call : fn.call(input)
181
+
182
+ return self if result === self
162
183
 
163
184
  raise Error::UnexpectedResult.new("#{Result.name}##{expected}")
164
185
  end
165
186
 
187
+ def __call_method(methd, attributes = nil)
188
+ input = __fetch_accumulated_data(attributes)
189
+
190
+ result = methd.arity.zero? ? methd.call : methd.call(**input)
191
+
192
+ return self if result === self
193
+
194
+ raise Error::UnexpectedResult.new("#{use_case.class.name}#method(:#{methd.name})")
195
+ end
196
+
166
197
  def __success_type?(expected_type)
167
198
  success? && (expected_type.nil? || expected_type == type)
168
199
  end
@@ -171,27 +202,24 @@ module Micro
171
202
  failure? && (expected_type.nil? || expected_type == type)
172
203
  end
173
204
 
174
- def __update_transitions_accessible_attributes(attributes)
175
- @__transitions_accessible_attributes__.merge!(attributes)
176
- @__transitions_accessible_attributes__
205
+ def __update_accessible_attributes(attributes)
206
+ @__accessible_attributes.merge!(attributes)
207
+ @__accessible_attributes.dup
177
208
  end
178
209
 
179
- def __set_transition
210
+ def __set_transition(use_case_attributes)
180
211
  use_case_class = @use_case.class
181
- use_case_attributes = Utils.symbolize_hash_keys(@use_case.attributes)
182
-
183
- __update_transitions_accessible_attributes(use_case_attributes)
184
212
 
185
213
  result = @success ? :success : :failure
186
214
 
187
- @__transitions__ << {
215
+ @__transitions << {
188
216
  use_case: { class: use_case_class, attributes: use_case_attributes },
189
217
  result => { type: @type, result: data },
190
- accessible_attributes: @__transitions_accessible_attributes__.keys
218
+ accessible_attributes: @__accessible_attributes.keys
191
219
  }
192
220
  end
193
221
 
194
- private_constant :FetchData
222
+ private_constant :FetchData, :INVALID_INVOCATION_OF_THE_THE_METHOD
195
223
  end
196
224
  end
197
225
  end
@@ -8,7 +8,7 @@ module Micro
8
8
  end
9
9
 
10
10
  def __call__
11
- __call!
11
+ call
12
12
  rescue => exception
13
13
  raise exception if Error.by_wrong_usage?(exception)
14
14
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  class Case
5
- VERSION = '3.0.0.rc5'.freeze
5
+ VERSION = '3.0.0'.freeze
6
6
  end
7
7
  end
@@ -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 :validation_error, result: { errors: errors }
40
+ Failure Micro::Case::Config.instance.activemodel_validation_errors_failure, result: {
41
+ errors: errors
42
+ }
41
43
  end
42
44
  end
43
45
  end
@@ -10,9 +10,7 @@ module Micro
10
10
  attr_reader :use_cases
11
11
 
12
12
  def self.map_use_cases(arg)
13
- return arg.use_cases if arg.is_a?(Flow)
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,19 +22,17 @@ module Micro
24
22
  end
25
23
 
26
24
  def initialize(use_cases)
27
- @use_cases = use_cases
28
- @first_use_case = use_cases[0]
29
- @next_use_cases = use_cases[1..-1]
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
- memo = input.is_a?(Hash) ? input.dup : Kind::Empty::HASH
34
-
35
- first_result = @first_use_case.__call_and_set_transition__(result, input)
31
+ first_result = __case_use_case(@first, result, input)
36
32
 
37
- return first_result if @next_use_cases.empty?
33
+ return first_result if @next_ones.empty?
38
34
 
39
- __next_use_cases_result(first_result, memo)
35
+ __call_next_use_cases(first_result)
40
36
  end
41
37
 
42
38
  def call(input = Kind::Empty::HASH)
@@ -53,7 +49,7 @@ module Micro
53
49
  can_yield_self = respond_to?(:yield_self)
54
50
 
55
51
  if block
56
- raise Error::InvalidInvocationOfTheThenMethod if use_case
52
+ raise Error::InvalidInvocationOfTheThenMethod.new(self.class.name) if use_case
57
53
  raise NotImplementedError if !can_yield_self
58
54
 
59
55
  yield_self(&block)
@@ -66,19 +62,15 @@ module Micro
66
62
 
67
63
  private
68
64
 
69
- def __next_use_case_result(use_case, result, input)
65
+ def __case_use_case(use_case, result, input)
70
66
  use_case.__new__(result, input).__call__
71
67
  end
72
68
 
73
- def __next_use_cases_result(first_result, memo)
74
- @next_use_cases.reduce(first_result) do |result, use_case|
69
+ def __call_next_use_cases(first_result)
70
+ @next_ones.reduce(first_result) do |result, use_case|
75
71
  break result if result.failure?
76
72
 
77
- memo.merge!(result.value)
78
-
79
- result.__set_transitions_accessible_attributes__(memo)
80
-
81
- __next_use_case_result(use_case, result, memo)
73
+ __case_use_case(use_case, result, result.data)
82
74
  end
83
75
  end
84
76
  end
@@ -4,7 +4,7 @@ module Micro
4
4
  module Cases
5
5
  module Safe
6
6
  class Flow < Cases::Flow
7
- private def __next_use_case_result(use_case, result, input)
7
+ private def __case_use_case(use_case, result, input)
8
8
  instance = use_case.__new__(result, input)
9
9
  instance.__call__
10
10
  rescue => exception
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-case
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.rc5
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-12 00:00:00.000000000 Z
11
+ date: 2020-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kind
@@ -122,9 +122,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
122
  version: 2.2.0
123
123
  required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  requirements:
125
- - - ">"
125
+ - - ">="
126
126
  - !ruby/object:Gem::Version
127
- version: 1.3.1
127
+ version: '0'
128
128
  requirements: []
129
129
  rubygems_version: 3.0.6
130
130
  signing_key: