business_flow 0.16.0 → 0.17.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 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