u-case 3.0.0.rc4 → 3.0.0.rc9

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.
@@ -18,10 +18,25 @@ module Micro
18
18
 
19
19
  include Micro::Attributes.without(:strict_initialize)
20
20
 
21
- def self.call(options = {})
21
+ def self.call(options = Kind::Empty::HASH)
22
22
  new(options).__call__
23
23
  end
24
24
 
25
+ def self.then(use_case = nil, &block)
26
+ can_yield_self = respond_to?(:yield_self)
27
+
28
+ if block
29
+ raise Error::InvalidInvocationOfTheThenMethod if use_case
30
+ raise NotImplementedError if !can_yield_self
31
+
32
+ yield_self(&block)
33
+ else
34
+ return yield_self if !use_case && can_yield_self
35
+
36
+ self.call.then(use_case)
37
+ end
38
+ end
39
+
25
40
  def self.to_proc
26
41
  Proc.new { |arg| call(arg) }
27
42
  end
@@ -55,16 +70,9 @@ module Micro
55
70
  end
56
71
 
57
72
  def self.__new__(result, arg)
58
- instance = new(arg)
59
- instance.__set_result__(result)
60
- instance
61
- end
62
-
63
- def self.__call_and_set_transition__(result, arg)
64
- input =
65
- arg.is_a?(Hash) ? result.__set_transitions_accessible_attributes__(arg) : arg
73
+ input = result.__set_transitions_accessible_attributes__(arg)
66
74
 
67
- __new__(result, input).__call__
75
+ new(input).__set_result__(result)
68
76
  end
69
77
 
70
78
  def self.__flow_builder__
@@ -85,7 +93,7 @@ module Micro
85
93
  @__flow = __flow_builder__.build(args)
86
94
  end
87
95
 
88
- FLOW_STEP = 'Flow_Step'.freeze
96
+ FLOW_STEP = 'Self'.freeze
89
97
 
90
98
  private_constant :FLOW_STEP
91
99
 
@@ -125,6 +133,8 @@ module Micro
125
133
  raise Error::ResultIsAlreadyDefined if defined?(@__result)
126
134
 
127
135
  @__result = result
136
+
137
+ self
128
138
  end
129
139
 
130
140
  private
@@ -196,11 +206,7 @@ module Micro
196
206
  private_constant :MapFailureType
197
207
  end
198
208
 
199
- def self.case?(arg)
200
- (arg.is_a?(Class) && arg < Case) || arg.is_a?(Case)
201
- end
202
-
203
209
  def self.case_or_flow?(arg)
204
- case?(arg) || arg.is_a?(Cases::Flow)
210
+ (arg.is_a?(Class) && arg < Case) || arg.is_a?(Cases::Flow)
205
211
  end
206
212
  end
@@ -15,7 +15,7 @@ module Micro
15
15
 
16
16
  def enable_transitions=(value)
17
17
  Micro::Case::Result.class_variable_set(
18
- :@@transition_tracking_disabled, !Kind::Of::Boolean(value)
18
+ :@@transitions_enabled, Kind::Of::Boolean(value)
19
19
  )
20
20
  end
21
21
  end
@@ -7,15 +7,20 @@ module Micro
7
7
  class Result
8
8
  Kind::Types.add(self)
9
9
 
10
- @@transition_tracking_disabled = false
10
+ @@transitions_enabled = true
11
+
12
+ def self.transitions_enabled?
13
+ @@transitions_enabled
14
+ end
11
15
 
12
16
  attr_reader :type, :data, :use_case
13
17
 
14
18
  alias value data
15
19
 
16
20
  def initialize
17
- @__transitions__ = []
18
- @__transitions_accessible_attributes__ = {}
21
+ @__transitions = []
22
+ @__transitions_accumulated_data = {}
23
+ @__transitions_accessible_attributes = {}
19
24
  end
20
25
 
21
26
  def to_ary
@@ -30,6 +35,18 @@ module Micro
30
35
  data.values_at(*keys)
31
36
  end
32
37
 
38
+ def key?(key)
39
+ data.key?(key)
40
+ end
41
+
42
+ def value?(value)
43
+ data.value?(value)
44
+ end
45
+
46
+ def slice(*keys)
47
+ Utils.slice_hash(data, keys)
48
+ end
49
+
33
50
  def success?
34
51
  @success
35
52
  end
@@ -78,34 +95,36 @@ module Micro
78
95
  yield_self(&block)
79
96
  else
80
97
  return yield_self if !use_case && can_yield_self
98
+ return failure? ? self : __call_proc(use_case, 'then(-> {})'.freeze) if use_case.is_a?(Proc)
99
+ return failure? ? self : __call_method(use_case, attributes) if use_case.is_a?(Method)
81
100
 
82
- if use_case.is_a?(Proc)
83
- return failure? ? self : __call_proc(use_case, expected: 'then(-> {})'.freeze)
84
- end
85
-
86
- # TODO: Test the then method with a Micro::Cases.{flow,safe_flow}() instance.
87
101
  raise Error::InvalidInvocationOfTheThenMethod unless ::Micro.case_or_flow?(use_case)
88
102
 
89
103
  return self if failure?
90
104
 
91
105
  input = attributes.is_a?(Hash) ? self.data.merge(attributes) : self.data
92
106
 
93
- use_case.__call_and_set_transition__(self, input)
107
+ if use_case.is_a?(::Micro::Cases::Flow)
108
+ use_case.call!(input: input, result: self)
109
+ else
110
+ use_case.__new__(self, input).__call__
111
+ end
94
112
  end
95
113
  end
96
114
 
97
115
  def |(arg)
98
116
  return self if failure?
99
117
 
100
- return __call_proc(arg, expected: '| -> {}'.freeze) if arg.is_a?(Proc)
118
+ return __call_proc(arg, '| -> {}'.freeze) if arg.is_a?(Proc)
119
+ return __call_method(arg) if arg.is_a?(Method)
101
120
 
102
121
  raise Error::InvalidInvocationOfTheThenMethod unless ::Micro.case_or_flow?(arg)
103
122
 
104
- failure? ? self : arg.__call_and_set_transition__(self, data)
123
+ failure? ? self : arg.__new__(self, data).__call__
105
124
  end
106
125
 
107
126
  def transitions
108
- @__transitions__.clone
127
+ @__transitions.clone
109
128
  end
110
129
 
111
130
  FetchData = -> (data) do
@@ -117,7 +136,7 @@ module Micro
117
136
 
118
137
  def __set__(is_success, data, type, use_case)
119
138
  raise Error::InvalidResultType unless type.is_a?(Symbol)
120
- raise Error::InvalidUseCase unless ::Micro.case?(use_case)
139
+ raise Error::InvalidUseCase unless use_case.is_a?(::Micro::Case)
121
140
 
122
141
  @success, @type, @use_case = is_success, type, use_case
123
142
 
@@ -125,29 +144,53 @@ module Micro
125
144
 
126
145
  raise Micro::Case::Error::InvalidResult.new(is_success, type, use_case) unless @data
127
146
 
128
- __set_transition unless @@transition_tracking_disabled
147
+ @__transitions_accumulated_data.merge!(@data)
148
+
149
+ use_case_attributes = Utils.symbolize_hash_keys(@use_case.attributes)
150
+
151
+ __update_transitions_accessible_attributes(use_case_attributes)
152
+
153
+ __set_transition(use_case_attributes) if @@transitions_enabled
129
154
 
130
155
  self
131
156
  end
132
157
 
133
- def __set_transitions_accessible_attributes__(attributes_data)
134
- return attributes_data if @@transition_tracking_disabled
158
+ def __set_transitions_accessible_attributes__(arg)
159
+ return arg unless arg.is_a?(Hash)
135
160
 
136
- attributes = Utils.symbolize_hash_keys(attributes_data)
161
+ attributes = Utils.symbolize_hash_keys(arg)
137
162
 
138
163
  __update_transitions_accessible_attributes(attributes)
139
164
  end
140
165
 
141
166
  private
142
167
 
143
- def __call_proc(arg, expected:)
144
- result = arg.arity.zero? ? arg.call : arg.call(data.clone)
168
+ def __fetch_accumulated_data(opt = nil)
169
+ __update_transitions_accessible_attributes(
170
+ opt ? opt.merge(@__transitions_accumulated_data) : @__transitions_accumulated_data
171
+ )
172
+ end
173
+
174
+ def __call_proc(fn, expected)
175
+ input = __fetch_accumulated_data
176
+
177
+ result = fn.arity.zero? ? fn.call : fn.call(input)
145
178
 
146
- return result if result.is_a?(Result)
179
+ return self if result === self
147
180
 
148
181
  raise Error::UnexpectedResult.new("#{Result.name}##{expected}")
149
182
  end
150
183
 
184
+ def __call_method(methd, attributes = nil)
185
+ input = __fetch_accumulated_data(attributes)
186
+
187
+ result = methd.arity.zero? ? methd.call : methd.call(**input)
188
+
189
+ return self if result === self
190
+
191
+ raise Error::UnexpectedResult.new("#{use_case.class.name}#method(:#{methd.name})")
192
+ end
193
+
151
194
  def __success_type?(expected_type)
152
195
  success? && (expected_type.nil? || expected_type == type)
153
196
  end
@@ -157,22 +200,19 @@ module Micro
157
200
  end
158
201
 
159
202
  def __update_transitions_accessible_attributes(attributes)
160
- @__transitions_accessible_attributes__.merge!(attributes)
161
- @__transitions_accessible_attributes__
203
+ @__transitions_accessible_attributes.merge!(attributes)
204
+ @__transitions_accessible_attributes
162
205
  end
163
206
 
164
- def __set_transition
207
+ def __set_transition(use_case_attributes)
165
208
  use_case_class = @use_case.class
166
- use_case_attributes = Utils.symbolize_hash_keys(@use_case.attributes)
167
-
168
- __update_transitions_accessible_attributes(use_case_attributes)
169
209
 
170
210
  result = @success ? :success : :failure
171
211
 
172
- @__transitions__ << {
212
+ @__transitions << {
173
213
  use_case: { class: use_case_class, attributes: use_case_attributes },
174
214
  result => { type: @type, result: data },
175
- accessible_attributes: @__transitions_accessible_attributes__.keys
215
+ accessible_attributes: @__transitions_accessible_attributes.keys
176
216
  }
177
217
  end
178
218
 
@@ -14,6 +14,13 @@ module Micro
14
14
  end
15
15
  end
16
16
  end
17
+ def self.slice_hash(hash, keys)
18
+ if Kind::Of::Hash(hash).respond_to?(:slice)
19
+ hash.slice(*keys)
20
+ else
21
+ hash.select { |key, _value| keys.include?(key) }
22
+ end
23
+ end
17
24
  end
18
25
  end
19
26
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  class Case
5
- VERSION = '3.0.0.rc4'.freeze
5
+ VERSION = '3.0.0.rc9'.freeze
6
6
  end
7
7
  end
@@ -29,14 +29,16 @@ module Micro
29
29
  @next_use_cases = use_cases[1..-1]
30
30
  end
31
31
 
32
- def call(arg = {})
33
- memo = arg.is_a?(Hash) ? arg.dup : {}
34
-
35
- first_result = __first_use_case_result(arg)
32
+ def call!(input:, result:)
33
+ first_result = __next_use_case_result(@first_use_case, result, input)
36
34
 
37
35
  return first_result if @next_use_cases.empty?
38
36
 
39
- __next_use_cases_result(first_result, memo)
37
+ __next_use_cases_result(first_result)
38
+ end
39
+
40
+ def call(input = Kind::Empty::HASH)
41
+ call!(input: input, result: Case::Result.new)
40
42
  end
41
43
 
42
44
  alias __call__ call
@@ -45,46 +47,32 @@ module Micro
45
47
  Proc.new { |arg| call(arg) }
46
48
  end
47
49
 
48
- private
49
-
50
- def __is_a_result?(arg)
51
- arg.is_a?(Case::Result)
52
- end
53
-
54
- def __call_arg(arg)
55
- output = arg.__call__
50
+ def then(use_case = nil, &block)
51
+ can_yield_self = respond_to?(:yield_self)
56
52
 
57
- __is_a_result?(output) ? output.value : output
58
- end
53
+ if block
54
+ raise Error::InvalidInvocationOfTheThenMethod if use_case
55
+ raise NotImplementedError if !can_yield_self
59
56
 
60
- def __first_use_case_input(arg)
61
- return __call_arg(arg) if ::Micro.case_or_flow?(arg)
62
- return arg.value if __is_a_result?(arg)
57
+ yield_self(&block)
58
+ else
59
+ return yield_self if !use_case && can_yield_self
63
60
 
64
- arg
61
+ self.call.then(use_case)
65
62
  end
63
+ end
66
64
 
67
- def __first_use_case_result(arg)
68
- input = __first_use_case_input(arg)
69
-
70
- result = Case::Result.new
71
-
72
- @first_use_case.__call_and_set_transition__(result, input)
73
- end
65
+ private
74
66
 
75
67
  def __next_use_case_result(use_case, result, input)
76
68
  use_case.__new__(result, input).__call__
77
69
  end
78
70
 
79
- def __next_use_cases_result(first_result, memo)
71
+ def __next_use_cases_result(first_result)
80
72
  @next_use_cases.reduce(first_result) do |result, use_case|
81
73
  break result if result.failure?
82
74
 
83
- memo.merge!(result.value)
84
-
85
- result.__set_transitions_accessible_attributes__(memo)
86
-
87
- __next_use_case_result(use_case, result, memo)
75
+ __next_use_case_result(use_case, result, result.data)
88
76
  end
89
77
  end
90
78
  end
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Rodrigo Serradura']
10
10
  spec.email = ['rodrigo.serradura@gmail.com']
11
11
 
12
- spec.summary = %q{Create simple and powerful use cases as objects.}
13
- spec.description = %q{Create simple and powerful use cases as objects.}
12
+ spec.summary = %q{Create simple and powerful use cases as Ruby objects.}
13
+ spec.description = %q{Create simple and powerful use cases as Ruby objects.}
14
14
  spec.homepage = 'https://github.com/serradura/u-case'
15
15
  spec.license = 'MIT'
16
16
 
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.rc4
4
+ version: 3.0.0.rc9
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-02 00:00:00.000000000 Z
11
+ date: 2020-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kind
@@ -72,7 +72,7 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '13.0'
75
- description: Create simple and powerful use cases as objects.
75
+ description: Create simple and powerful use cases as Ruby objects.
76
76
  email:
77
77
  - rodrigo.serradura@gmail.com
78
78
  executables: []
@@ -87,6 +87,7 @@ files:
87
87
  - Gemfile
88
88
  - LICENSE.txt
89
89
  - README.md
90
+ - README.pt-BR.md
90
91
  - Rakefile
91
92
  - bin/console
92
93
  - bin/setup
@@ -128,5 +129,5 @@ requirements: []
128
129
  rubygems_version: 3.0.6
129
130
  signing_key:
130
131
  specification_version: 4
131
- summary: Create simple and powerful use cases as objects.
132
+ summary: Create simple and powerful use cases as Ruby objects.
132
133
  test_files: []