business_flow 0.15.1 → 0.17.3

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
- SHA1:
3
- metadata.gz: f138e6ec77fc0cbcada6bc02b282310b22db7cfb
4
- data.tar.gz: 473e3b3afa5b3af4b78eb6ee92475b77150a56e3
2
+ SHA256:
3
+ metadata.gz: e3e82021d8909a6bc2e1506eabcc81e311eadb03b799146c8ff0731519ce6700
4
+ data.tar.gz: acc5d1ccc792d66d9ea1562f7fa3549af9c06600cfca35178118e08a8635a3cb
5
5
  SHA512:
6
- metadata.gz: c5f6d16dd0671e965ddc9415cf47868c7ba1a01c41af9360ed8c2c9f9cb76fa7ac3cb6f6953fa58388a24f199b53b4c15e5f7902560a7ca5e6feb77c0782f94c
7
- data.tar.gz: 8d95b1ebf703d4bcf4663f2fccd86c8bb0058f0faa4bde05ea3ff17d41104d172123a26ebe423d5c5a8f2f6ab15c566a48dcadfbf09f6cecffcc74114e4bedfe
6
+ metadata.gz: bd4a457dbaf1cd943db479b585379d0f8b1391890e956a265eea09fa9f0badea95fcc8857223a451759844dfe419e661c43324e5db13bcb9fe6ccdd07d741684
7
+ data.tar.gz: '08f2debe4942321aaca7896c99a05147a56a8a2cde31fda83f9c2bfaf1fc8873b5e78a58e6c65b47aa94dfe794040da7be65f049527119147a959040ad940ac1'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- business_flow (0.15.1)
4
+ business_flow (0.17.2)
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
 
@@ -60,7 +76,7 @@ module BusinessFlow
60
76
  # Declares that you will expose a field to the outside world.
61
77
  def provides(*fields)
62
78
  @provides ||= FieldList.new([], PublicField, [self, const_get(:Result)])
63
- @result_copy ||= 'def from_flow(flow)'
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,7 +143,7 @@ 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.
@@ -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)
@@ -267,7 +288,7 @@ module BusinessFlow
267
288
  def errors?
268
289
  # We're explicitly using the instance variable here so that if no
269
290
  # errors have been created, we don't initialize the error object.
270
- @errors.present?
291
+ @errors && @errors.present?
271
292
  end
272
293
 
273
294
  def valid?(_context = nil)
@@ -296,6 +317,7 @@ module BusinessFlow
296
317
  fields.each do |field|
297
318
  add_field(@field_klass.new(field))
298
319
  end
320
+ @field_list.uniq! if fields.present?
299
321
  @field_list
300
322
  end
301
323
 
@@ -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
 
@@ -62,9 +62,11 @@ module BusinessFlow
62
62
  # because that will run validations and a step may return a partially
63
63
  # constructed model. By instead pulling out the errors instance variable
64
64
  # we'll only merge errors if validations have already been run.
65
- elsif @result.class.include?(ActiveModel::Validations) &&
65
+ elsif @result.class.ancestors.include?(ActiveModel::Validations) &&
66
66
  @result.instance_variable_defined?(:@errors)
67
67
  @result.instance_variable_get(:@errors).present?
68
+ elsif @result.respond_to?(:errors)
69
+ @result.errors.present?
68
70
  else
69
71
  false
70
72
  end
@@ -88,9 +90,7 @@ module BusinessFlow
88
90
  end
89
91
 
90
92
  def merge_errors_into(object)
91
- return unless mergeable_errors?
92
93
  @result.errors.each do |attribute, message|
93
- attribute = "#{@result.class.name.underscore}.#{attribute}"
94
94
  (object.errors[attribute] << message).uniq!
95
95
  end
96
96
  throw :halt_step
@@ -175,7 +175,7 @@ module BusinessFlow
175
175
  end
176
176
 
177
177
  def result_factory
178
- ResultFactory.new(opts[:outputs] || {},
178
+ ResultFactory.new(opts[:outputs],
179
179
  opts[:output],
180
180
  opts[:default_output])
181
181
  end
@@ -201,6 +201,8 @@ module BusinessFlow
201
201
  update_call_method
202
202
  end
203
203
 
204
+ # This will show up as not covered in coverage reports, because it is
205
+ # dynamically redefined by #update_call_method below.
204
206
  def call(parameter_source)
205
207
  parameters = @input_object.parameters_from_source(parameter_source)
206
208
  if !@condition || @condition.call(parameter_source, parameters)
@@ -219,6 +221,11 @@ module BusinessFlow
219
221
  @result_factory.outputs
220
222
  end
221
223
 
224
+ def output_fields
225
+ return [] unless outputs
226
+ outputs.values.select { |field| field.is_a?(Symbol) }
227
+ end
228
+
222
229
  def to_s
223
230
  @callable.to_s
224
231
  end
@@ -1,3 +1,3 @@
1
1
  module BusinessFlow
2
- VERSION = '0.15.1'.freeze
2
+ VERSION = '0.17.3'.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.15.1
4
+ version: 0.17.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Scarborough
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-14 00:00:00.000000000 Z
11
+ date: 2021-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -164,7 +164,7 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: 0.9.1
167
- description:
167
+ description:
168
168
  email:
169
169
  - alex@teak.io
170
170
  executables: []
@@ -200,7 +200,7 @@ homepage: https://teak.io
200
200
  licenses:
201
201
  - MIT
202
202
  metadata: {}
203
- post_install_message:
203
+ post_install_message:
204
204
  rdoc_options: []
205
205
  require_paths:
206
206
  - lib
@@ -215,9 +215,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
215
215
  - !ruby/object:Gem::Version
216
216
  version: '0'
217
217
  requirements: []
218
- rubyforge_project:
219
- rubygems_version: 2.6.11
220
- signing_key:
218
+ rubygems_version: 3.1.2
219
+ signing_key:
221
220
  specification_version: 4
222
221
  summary: General purpose management of service object flows
223
222
  test_files: []