flow 0.10.8 → 0.11.1

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
  SHA256:
3
- metadata.gz: b52c5f113180717df9e242c75b51a80cff0ca0d246007c0adf99247f23137ede
4
- data.tar.gz: 51245f2c5609c2788c79fa5a29df9201783c0071a8671f464d42d32b381537a8
3
+ metadata.gz: a2cbf274b4eeeec407044f9e1fa36f9adbb4e764c80fcddf8341faf71e2f579a
4
+ data.tar.gz: 3ba508665ba607fdabc7fe878199133ac5d194889eb4d911ec5b22656c47ef23
5
5
  SHA512:
6
- metadata.gz: bb6a28b1fbed617b3143c2905bc6912a72b1847e54bcbfc69a26856b116a783d79b64455544d103a7c5cdcef85ffab2928aa325ea8c7b1dad5f32055f0657bea
7
- data.tar.gz: 38db040a5c7d17b287a46c739f75e16b61861005b9a0ca6b08775083372f9b479620b9f78cefe0cfa1b9cab6f8371cc239e4c6119e1f52dbdc4dbecd3fd6fe8e
6
+ metadata.gz: d18ff6721175ce0189f883775bcc0953375837248ce8645c36ef5684d70f1dd47eb74cf5449c3a1e5d9dd0957058bd73a17dbd806108d2892218d42d40434c08
7
+ data.tar.gz: 7f60552c0bde342aa962eb6afee720f5d58cfe90ab63794457219c83a63724056833a6b482e81f192ee406288dc434f47ddd3b98e59b3eca0703ba5050d55746
data/README.md CHANGED
@@ -216,12 +216,12 @@ If the `Flow` fails you can see the failures on the instance:
216
216
 
217
217
  ## Wiki
218
218
 
219
- Learn more with our wiki [Getting Started](https://github.com/Freshly/flow/wiki/Getting-Started#installation) page.
219
+ Learn more with our wiki [Getting Started](https://github.com/RubyAfterAll/flow/wiki/Getting-Started#installation) page.
220
220
 
221
221
  You also can download wiki to have offline access.
222
222
  Just simply do:
223
223
 
224
- `git clone git@github.com:Freshly/flow.wiki.git`
224
+ `git clone git@github.com:RubyAfterAll/flow.wiki.git`
225
225
 
226
226
 
227
227
  ## License
@@ -7,6 +7,8 @@ module Flow
7
7
 
8
8
  class_methods do
9
9
  def transaction_provider
10
+ raise TransactionProviderNotDefined, "must explicitly define a transaction provider if ActiveRecord is not available" unless defined?(ActiveRecord)
11
+
10
12
  ActiveRecord::Base
11
13
  end
12
14
 
@@ -10,7 +10,7 @@ require_relative "flow/trigger"
10
10
 
11
11
  # A **Flow** is a collection of procedurally executed **Operations** sharing a common **State**.
12
12
  module Flow
13
- class FlowBase < RootObject
13
+ class FlowBase < Substance::RootObject
14
14
  include Conjunction::Junction
15
15
  suffixed_with "Flow"
16
16
 
@@ -1,58 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "set"
4
+
3
5
  module Flow
4
6
  module Operation
5
7
  module Accessors
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  included do
9
- class_attribute :_state_readers, instance_writer: false, default: []
10
- class_attribute :_state_writers, instance_writer: false, default: []
11
- class_attribute :_state_accessors, instance_writer: false, default: []
11
+ class_attribute :_state_readers, instance_writer: false, default: Set.new
12
+ class_attribute :_state_writers, instance_writer: false, default: Set.new
13
+ class_attribute :_state_accessors, instance_writer: false, default: Set.new
12
14
  end
13
15
 
14
- class_methods do
16
+ module ClassMethods
15
17
  protected
16
18
 
17
- def state_reader(name)
18
- return unless _add_state_reader_tracker(name.to_sym)
19
+ def state_reader(*names, prefix: false)
20
+ names.each do |name|
21
+ delegate name, prefix: prefix, to: :state
19
22
 
20
- delegate name, to: :state
23
+ _add_state_reader_tracker(name.to_sym)
24
+ end
21
25
  end
22
26
 
23
- def state_writer(name)
24
- return unless _add_state_writer_tracker(name.to_sym)
27
+ def state_writer(*names, prefix: false)
28
+ names.each do |name|
29
+ delegate "#{name}=", prefix: prefix, to: :state
25
30
 
26
- delegate("#{name}=", to: :state)
31
+ _add_state_writer_tracker(name.to_sym)
32
+ end
27
33
  end
28
34
 
29
- def state_accessor(name)
30
- state_reader name
31
- state_writer name
35
+ def state_accessor(*names, prefix: false)
36
+ names.each do |name|
37
+ state_reader name, prefix: prefix
38
+ state_writer name, prefix: prefix
39
+ end
32
40
  end
33
41
 
34
42
  private
35
43
 
36
44
  def _add_state_reader_tracker(name)
37
- return false if _state_readers.include?(name)
38
-
39
- _add_state_accessor_tracker(name) if _state_writers.include?(name)
45
+ _state_accessors << name if _state_writers.include?(name)
40
46
  _state_readers << name
41
47
  end
42
48
 
43
49
  def _add_state_writer_tracker(name)
44
- return false if _state_writers.include?(name)
45
-
46
- _add_state_accessor_tracker(name) if _state_readers.include?(name)
50
+ _state_accessors << name if _state_readers.include?(name)
47
51
  _state_writers << name
48
52
  end
49
53
 
50
- def _add_state_accessor_tracker(name)
51
- return if _state_accessors.include?(name)
52
-
53
- _state_accessors << name
54
- end
55
-
56
54
  def inherited(base)
57
55
  base._state_readers = _state_readers.dup
58
56
  base._state_writers = _state_writers.dup
@@ -15,7 +15,7 @@ module Flow
15
15
  class_methods do
16
16
  def state_proxy_class
17
17
  @state_proxy_class ||= Class.new(StateProxy).tap do |proxy_class|
18
- delegate_method_names = _state_writers.map { |method_name| "#{method_name}=" } + _state_readers
18
+ delegate_method_names = _state_writers.map { |method_name| "#{method_name}=" } + _state_readers.to_a
19
19
  proxy_class.delegate(*delegate_method_names, to: :_state) if delegate_method_names.any?
20
20
  end
21
21
  end
@@ -11,7 +11,7 @@ require_relative "operation/transactions"
11
11
 
12
12
  # An **Operation** is a service object which is executed with a **State**.
13
13
  module Flow
14
- class OperationBase < RootObject
14
+ class OperationBase < Substance::RootObject
15
15
  include TransactionWrapper
16
16
  include Operation::Accessors
17
17
  include Operation::Callbacks
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Stubs a given flow to always fail when triggered.
4
+ #
5
+ # Usage:
6
+ # describe SomeFlow do
7
+ # let(:flow) { described_class.new(some: :arguments) }
8
+ #
9
+ # include_context "with invalid state"
10
+ #
11
+ # before { flow.trigger }
12
+ #
13
+ # it "is failed" do
14
+ # expect(flow).not_to be_successful
15
+ # expect(flow.state.errors).to be_present
16
+ # end
17
+ # end
18
+ #
19
+ # Requires let variables to be defined in the inclusion context:
20
+ # * invalid_state_class - the state class that will be used for the flow
21
+ # * expected_state_errors - a hash in the form of:
22
+ # { attribute_name: :error_key
23
+ # # or:
24
+ # another_attributee: "error message!"
25
+ # }
26
+ RSpec.shared_context "with invalid state" do
27
+ before do
28
+ allow(invalid_state_class).to receive(:new).and_wrap_original do |mtd, **kwargs|
29
+ mtd.call(**kwargs).tap do |state|
30
+ allow(state).to receive(:run_validations!).and_wrap_original do |run_validations|
31
+ run_validations.call
32
+
33
+ expected_state_errors.each do |attr, error|
34
+ state.errors.add(attr, error)
35
+ end
36
+
37
+ false
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "shared_contexts/with_failing_operation"
4
+ require_relative "shared_contexts/with_invalid_state"
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "spicerack/spec_helper"
3
+ require "substance/rspec"
4
4
 
5
5
  require_relative "rspec/custom_matchers"
6
6
  require_relative "rspec/shared_contexts"
@@ -1,15 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "state/status"
4
- require_relative "state/output"
5
-
6
3
  # A **State** is an aggregation of input and derived data.
7
4
  module Flow
8
- class StateBase < InputModel
5
+ class StateBase < Substance::OutputObject
9
6
  include Conjunction::Junction
10
7
  suffixed_with "State"
11
-
12
- include State::Status
13
- include State::Output
14
8
  end
15
9
  end
@@ -13,7 +13,7 @@ module Flow
13
13
 
14
14
  ActiveSupport::Deprecation.warn(
15
15
  "Direct state access of `#{method_name}' on #{_state.inspect} will be removed in a future version of flow. "\
16
- "Use a state accessor instead - for more information see github/freshly/flow/deprecation_notice"
16
+ "Use a state accessor instead - for more information see github/RubyAfterAll/flow/deprecation_notice"
17
17
  )
18
18
  _state.public_send(method_name, *arguments, &block)
19
19
  end
data/lib/flow/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flow
4
- VERSION = "0.10.8"
4
+ VERSION = "0.11.1"
5
5
  end
data/lib/flow.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_model"
4
- require "active_record"
5
4
  require "active_support"
6
5
 
7
- require "spicerack"
6
+ require "conjunction"
8
7
  require "malfunction"
8
+ require "substance"
9
9
 
10
10
  require_relative "flow/version"
11
11
 
@@ -15,10 +15,6 @@ require_relative "flow/concerns/transaction_wrapper"
15
15
 
16
16
  require_relative "flow/malfunction/base"
17
17
 
18
- # TODO: Remove inheritance nonsense, just use Substance once deprecation is removed from Spicerack
19
- class Flow::RootObject < (defined?(Substance::RootObject) ? Substance::RootObject : Spicerack::RootObject); end
20
- class Flow::InputModel < (defined?(Substance::InputModel) ? Substance::InputModel : Spicerack::InputModel); end
21
-
22
18
  require_relative "flow/flow_base"
23
19
  require_relative "flow/operation_base"
24
20
  require_relative "flow/state_base"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.8
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Garside
@@ -9,10 +9,10 @@ authors:
9
9
  - Jordan Minneti
10
10
  - Vinod Lala
11
11
  - Andrew Cross
12
- autorequire:
12
+ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2021-06-03 00:00:00.000000000 Z
15
+ date: 2022-03-26 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activemodel
@@ -29,7 +29,7 @@ dependencies:
29
29
  - !ruby/object:Gem::Version
30
30
  version: 5.2.1
31
31
  - !ruby/object:Gem::Dependency
32
- name: activerecord
32
+ name: activesupport
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
35
  - - ">="
@@ -43,21 +43,27 @@ dependencies:
43
43
  - !ruby/object:Gem::Version
44
44
  version: 5.2.1
45
45
  - !ruby/object:Gem::Dependency
46
- name: activesupport
46
+ name: conjunction
47
47
  requirement: !ruby/object:Gem::Requirement
48
48
  requirements:
49
49
  - - ">="
50
50
  - !ruby/object:Gem::Version
51
- version: 5.2.1
51
+ version: 0.2.0
52
+ - - "<"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
52
55
  type: :runtime
53
56
  prerelease: false
54
57
  version_requirements: !ruby/object:Gem::Requirement
55
58
  requirements:
56
59
  - - ">="
57
60
  - !ruby/object:Gem::Version
58
- version: 5.2.1
61
+ version: 0.2.0
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '1.0'
59
65
  - !ruby/object:Gem::Dependency
60
- name: spicerack
66
+ name: short_circu_it
61
67
  requirement: !ruby/object:Gem::Requirement
62
68
  requirements:
63
69
  - - ">="
@@ -77,12 +83,12 @@ dependencies:
77
83
  - !ruby/object:Gem::Version
78
84
  version: '1.0'
79
85
  - !ruby/object:Gem::Dependency
80
- name: short_circu_it
86
+ name: substance
81
87
  requirement: !ruby/object:Gem::Requirement
82
88
  requirements:
83
89
  - - ">="
84
90
  - !ruby/object:Gem::Version
85
- version: 0.2.0
91
+ version: 0.26.0
86
92
  - - "<"
87
93
  - !ruby/object:Gem::Version
88
94
  version: '1.0'
@@ -92,7 +98,7 @@ dependencies:
92
98
  requirements:
93
99
  - - ">="
94
100
  - !ruby/object:Gem::Version
95
- version: 0.2.0
101
+ version: 0.26.0
96
102
  - - "<"
97
103
  - !ruby/object:Gem::Version
98
104
  version: '1.0'
@@ -136,6 +142,20 @@ dependencies:
136
142
  - - "<"
137
143
  - !ruby/object:Gem::Version
138
144
  version: '1.0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: activerecord
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: 5.2.1
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: 5.2.1
139
159
  - !ruby/object:Gem::Dependency
140
160
  name: bundler
141
161
  requirement: !ruby/object:Gem::Requirement
@@ -224,16 +244,16 @@ dependencies:
224
244
  name: shoulda-matchers
225
245
  requirement: !ruby/object:Gem::Requirement
226
246
  requirements:
227
- - - '='
247
+ - - "~>"
228
248
  - !ruby/object:Gem::Version
229
- version: 4.0.1
249
+ version: '4.0'
230
250
  type: :development
231
251
  prerelease: false
232
252
  version_requirements: !ruby/object:Gem::Requirement
233
253
  requirements:
234
- - - '='
254
+ - - "~>"
235
255
  - !ruby/object:Gem::Version
236
- version: 4.0.1
256
+ version: '4.0'
237
257
  - !ruby/object:Gem::Dependency
238
258
  name: rspice
239
259
  requirement: !ruby/object:Gem::Requirement
@@ -318,10 +338,9 @@ files:
318
338
  - lib/flow/rspec/custom_matchers/write_state.rb
319
339
  - lib/flow/rspec/shared_contexts.rb
320
340
  - lib/flow/rspec/shared_contexts/with_failing_operation.rb
341
+ - lib/flow/rspec/shared_contexts/with_invalid_state.rb
321
342
  - lib/flow/rspec/shoulda_matcher_helper.rb
322
343
  - lib/flow/spec_helper.rb
323
- - lib/flow/state/output.rb
324
- - lib/flow/state/status.rb
325
344
  - lib/flow/state_base.rb
326
345
  - lib/flow/state_proxy.rb
327
346
  - lib/flow/version.rb
@@ -363,11 +382,11 @@ files:
363
382
  - lib/generators/rspec/state/USAGE
364
383
  - lib/generators/rspec/state/state_generator.rb
365
384
  - lib/generators/rspec/state/templates/state_spec.rb.erb
366
- homepage: https://github.com/Freshly/flow
385
+ homepage: https://github.com/RubyAfterAll/flow
367
386
  licenses:
368
387
  - MIT
369
388
  metadata: {}
370
- post_install_message:
389
+ post_install_message:
371
390
  rdoc_options: []
372
391
  require_paths:
373
392
  - lib
@@ -382,8 +401,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
382
401
  - !ruby/object:Gem::Version
383
402
  version: '0'
384
403
  requirements: []
385
- rubygems_version: 3.2.17
386
- signing_key:
404
+ rubygems_version: 3.3.9
405
+ signing_key:
387
406
  specification_version: 4
388
407
  summary: Write modular and reusable business logic that's understandable and maintainable.
389
408
  test_files: []
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Output data is created by Operations during runtime and CANNOT be validated or provided as part of the input.
4
- module Flow
5
- module State
6
- module Output
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- class_attribute :_outputs, instance_writer: false, default: []
11
-
12
- delegate :_outputs, to: :class
13
-
14
- after_validation do
15
- next unless validated?
16
-
17
- _outputs.each do |key|
18
- public_send("#{key}=".to_sym, _defaults[key].value) if _defaults.key?(key) && public_send(key).nil?
19
- end
20
- end
21
- end
22
-
23
- class_methods do
24
- def inherited(base)
25
- base._outputs = _outputs.dup
26
- super
27
- end
28
-
29
- private
30
-
31
- def output(output, default: nil, &block)
32
- _outputs << output
33
- define_attribute output
34
- define_default output, static: default, &block
35
- ensure_validation_before output
36
- ensure_validation_before "#{output}=".to_sym
37
- end
38
-
39
- def ensure_validation_before(method)
40
- around_method method do |*arguments|
41
- raise NotValidatedError unless validated?
42
-
43
- super(*arguments)
44
- end
45
- end
46
- end
47
-
48
- def outputs
49
- return {} if _outputs.empty?
50
-
51
- output_struct.new(*_outputs.map(&method(:public_send)))
52
- end
53
-
54
- def output_struct
55
- Struct.new(*_outputs)
56
- end
57
- end
58
- end
59
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # The State status is used to ensure and enforce internal consistency.
4
- module Flow
5
- module State
6
- module Status
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- after_validation { self.was_validated = errors.empty? }
11
-
12
- private
13
-
14
- attr_accessor :was_validated
15
- end
16
-
17
- def validated?
18
- was_validated.present?
19
- end
20
- end
21
- end
22
- end