business_flow 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1548094c4a7a8b46825a764e4263b325c14a2638
4
- data.tar.gz: 4c0e8ccdb9f0879688a4296beeb876f888d96753
3
+ metadata.gz: 30ea0891a62bcdd44afbf082b704e4a3deb7e5b1
4
+ data.tar.gz: 6cc8b240e591ffe7d9415cbc0293a1b466c880d7
5
5
  SHA512:
6
- metadata.gz: bd2f51dd71d2b4b3895907e453797cab7ca368007e841a41a73baf04f356f137f4270f54819cfdf79ecc3f3a42d8629c0e0c5ebd36cdfc4bbd20c76642e3b86e
7
- data.tar.gz: f023287d3915f2df21a43e0a678b68eb20173940586b3e3d4161956c3c19dc649ae2cfd52f049b09bab82086180706afcd43d52bf0b544e6ced5d6ed8d6af880
6
+ metadata.gz: 8d706886574479bc3c9bbd2cf1b1c444bf76737473d612b0beb429fcfbfb23de2e26b1c86428095bdeab950beefc7aff647f65be2584f86ed511e370cd3a8ce5
7
+ data.tar.gz: e480293a62820301a174da33c9264b81db9c098a9715d1aaac65c67b09e7290f7e859a1de83420c800ba0bf9fdf7a5f06e099e2db43a3f96418580bcd0892309
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- business_flow (0.16.0)
4
+ business_flow (0.17.0)
5
5
  activemodel (>= 3.0)
6
6
  activesupport (>= 3.0)
7
7
 
@@ -16,16 +16,19 @@ module BusinessFlow
16
16
 
17
17
  def add_needs(fields)
18
18
  @all += fields
19
+ @all.uniq!
19
20
  @needs.add_fields(fields)
20
21
  end
21
22
 
22
23
  def add_optional(fields)
23
24
  @all += fields
25
+ @all.uniq!
24
26
  @optionals.add_fields(fields)
25
27
  end
26
28
 
27
29
  def add_wants(field)
28
30
  @all << field.name
31
+ @all.uniq!
29
32
  @optionals.add_field(field)
30
33
  end
31
34
  end
@@ -46,10 +49,23 @@ module BusinessFlow
46
49
  inputs.add_optional(fields)
47
50
  end
48
51
 
52
+ # Provides an alternate way to look up the value for a field. This can be
53
+ # thought of as using a 'wants' combined with an expectation of presence,
54
+ # without having to check for whether or not the wants can be executed.
55
+ #
56
+ # :reek:NilCheck This is one of the places where we eliminate nil.
57
+ def lookup(field, by:, with:)
58
+ by = Array.wrap(by)
59
+ optional(*by)
60
+ wants field, with, unless: -> { by.any? { |input| send(input).nil? } },
61
+ default_output: field
62
+ end
63
+
49
64
  # Allows a field to be retrieved from the initialiaztion parameters
50
- def wants(field, default = proc { nil }, opts = {})
65
+ def wants(field, default = nil, opts = {}, &blk)
51
66
  internal_name = "wants_#{field}".to_sym
52
- uses(internal_name, default, opts)
67
+ default = proc { nil } unless default || block_given?
68
+ uses(internal_name, default, opts, &blk)
53
69
  inputs.add_wants(ParameterField.new(field, internal_name))
54
70
  end
55
71
 
@@ -59,8 +75,8 @@ module BusinessFlow
59
75
 
60
76
  # Declares that you will expose a field to the outside world.
61
77
  def provides(*fields)
62
- @provides ||= FieldList.new([], PublicField, [self, const_get(:Result)])
63
- @result_copy ||= 'def from_flow(flow)'
78
+ @provides ||= FieldList.new([], PublicField, [self, @result_klass])
79
+ @result_copy ||= FROM_FLOW_PREAMBLE
64
80
  @result_copy += fields.map { |field| "\n@#{field} = flow.#{field}" }
65
81
  .join
66
82
  @provides.add_fields(fields)
@@ -71,16 +87,16 @@ module BusinessFlow
71
87
  def uses(field, klass = nil, opts = {}, &blk)
72
88
  step = Step.new(Callable.new(klass || blk),
73
89
  { default_output: field }.merge(opts))
74
- retriever = proc { step.call(self).output }
90
+ retriever = proc { step.call(self).merge_into(self) }
75
91
  UsesField.new(field, retriever).add_to(self)
76
92
  end
77
93
 
78
- def step(klass, opts = {})
79
- step = Step.new(Callable.new(klass), opts)
94
+ # :reek:ControlParameter It's just nicer to have this fall back to a
95
+ # block than have a different DSL method when using/not using blocks
96
+ def step(klass, opts = {}, &blk)
97
+ step = Step.new(Callable.new(blk || klass), opts)
80
98
  step_queue.push(step)
81
- step.outputs
82
- .values
83
- .select { |field| field.is_a?(Symbol) }
99
+ step.output_fields
84
100
  .each { |field| Field.new(field).add_to(self) }
85
101
  end
86
102
 
@@ -127,18 +143,18 @@ module BusinessFlow
127
143
  end
128
144
 
129
145
  def result_from(flow)
130
- finalize_result_provider
146
+ finalize_result_provider unless @finalized_result_provider
131
147
  # We use instance_variable_get here instead of making it part of
132
148
  # from_flow to ensure that we do not create the errors object unless
133
149
  # we need it.
134
- result = const_get(:Result).new(flow.instance_variable_get(:@errors))
150
+ result = @result_klass.new(flow.instance_variable_get(:@errors))
135
151
  result.from_flow(flow) if @result_copy
136
152
  result
137
153
  end
138
154
 
139
155
  def finalize_result_provider
140
156
  return if @finalized_result_provider || !@result_copy
141
- const_get(:Result).class_eval "#{@result_copy}\nend", __FILE__, __LINE__
157
+ @result_klass.class_eval "#{@result_copy}\nend", __FILE__, __LINE__
142
158
  @finalized_result_provider = true
143
159
  end
144
160
 
@@ -165,6 +181,11 @@ module BusinessFlow
165
181
  end
166
182
  end
167
183
 
184
+ FROM_FLOW_PREAMBLE = %(
185
+ def from_flow(flow)
186
+ return if errors?
187
+ ).freeze
188
+
168
189
  RESULT_DEF = %(
169
190
  class Result
170
191
  def initialize(errors)
@@ -178,7 +199,7 @@ module BusinessFlow
178
199
  def errors?
179
200
  # We're explicitly using the instance variable here so that if no
180
201
  # errors have been created, we don't initialize the error object.
181
- @errors.present?
202
+ @errors && @errors.present?
182
203
  end
183
204
 
184
205
  def valid?(_context = nil)
@@ -206,6 +227,7 @@ module BusinessFlow
206
227
  def self.included(klass)
207
228
  klass.extend(ClassMethods)
208
229
  klass.class_eval RESULT_DEF, __FILE__, __LINE__
230
+ klass.instance_variable_set(:@result_klass, klass.const_get(:Result))
209
231
  klass.extend(ErrorSupport) unless klass.respond_to?(:human_attribute_name)
210
232
  end
211
233
 
@@ -267,7 +289,7 @@ module BusinessFlow
267
289
  def errors?
268
290
  # We're explicitly using the instance variable here so that if no
269
291
  # errors have been created, we don't initialize the error object.
270
- @errors.present?
292
+ @errors && @errors.present?
271
293
  end
272
294
 
273
295
  def valid?(_context = nil)
@@ -296,6 +318,7 @@ module BusinessFlow
296
318
  fields.each do |field|
297
319
  add_field(@field_klass.new(field))
298
320
  end
321
+ @field_list.uniq! if fields.present?
299
322
  @field_list
300
323
  end
301
324
 
@@ -44,8 +44,8 @@ module BusinessFlow
44
44
  end
45
45
 
46
46
  def merge_into(object)
47
- merge_errors_into(object)
48
- merge_outputs_into(object)
47
+ merge_errors_into(object) if mergeable_errors?
48
+ merge_outputs_into(object) if @output_map
49
49
  output
50
50
  end
51
51
 
@@ -88,7 +88,6 @@ module BusinessFlow
88
88
  end
89
89
 
90
90
  def merge_errors_into(object)
91
- return unless mergeable_errors?
92
91
  @result.errors.each do |attribute, message|
93
92
  (object.errors[attribute] << message).uniq!
94
93
  end
@@ -174,7 +173,7 @@ module BusinessFlow
174
173
  end
175
174
 
176
175
  def result_factory
177
- ResultFactory.new(opts[:outputs] || {},
176
+ ResultFactory.new(opts[:outputs],
178
177
  opts[:output],
179
178
  opts[:default_output])
180
179
  end
@@ -200,6 +199,8 @@ module BusinessFlow
200
199
  update_call_method
201
200
  end
202
201
 
202
+ # This will show up as not covered in coverage reports, because it is
203
+ # dynamically redefined by #update_call_method below.
203
204
  def call(parameter_source)
204
205
  parameters = @input_object.parameters_from_source(parameter_source)
205
206
  if !@condition || @condition.call(parameter_source, parameters)
@@ -218,6 +219,11 @@ module BusinessFlow
218
219
  @result_factory.outputs
219
220
  end
220
221
 
222
+ def output_fields
223
+ return [] unless outputs
224
+ outputs.values.select { |field| field.is_a?(Symbol) }
225
+ end
226
+
221
227
  def to_s
222
228
  @callable.to_s
223
229
  end
@@ -1,3 +1,3 @@
1
1
  module BusinessFlow
2
- VERSION = '0.16.0'.freeze
2
+ VERSION = '0.17.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: business_flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Scarborough
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-25 00:00:00.000000000 Z
11
+ date: 2019-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel