flow 0.10.8 → 0.11.1
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 +4 -4
- data/README.md +2 -2
- data/lib/flow/concerns/transaction_wrapper.rb +2 -0
- data/lib/flow/flow_base.rb +1 -1
- data/lib/flow/operation/accessors.rb +23 -25
- data/lib/flow/operation/core.rb +1 -1
- data/lib/flow/operation_base.rb +1 -1
- data/lib/flow/rspec/shared_contexts/with_invalid_state.rb +42 -0
- data/lib/flow/rspec/shared_contexts.rb +1 -0
- data/lib/flow/spec_helper.rb +1 -1
- data/lib/flow/state_base.rb +1 -7
- data/lib/flow/state_proxy.rb +1 -1
- data/lib/flow/version.rb +1 -1
- data/lib/flow.rb +2 -6
- metadata +40 -21
- data/lib/flow/state/output.rb +0 -59
- data/lib/flow/state/status.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2cbf274b4eeeec407044f9e1fa36f9adbb4e764c80fcddf8341faf71e2f579a
|
4
|
+
data.tar.gz: 3ba508665ba607fdabc7fe878199133ac5d194889eb4d911ec5b22656c47ef23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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/
|
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:
|
224
|
+
`git clone git@github.com:RubyAfterAll/flow.wiki.git`
|
225
225
|
|
226
226
|
|
227
227
|
## License
|
data/lib/flow/flow_base.rb
CHANGED
@@ -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
|
-
|
16
|
+
module ClassMethods
|
15
17
|
protected
|
16
18
|
|
17
|
-
def state_reader(
|
18
|
-
|
19
|
+
def state_reader(*names, prefix: false)
|
20
|
+
names.each do |name|
|
21
|
+
delegate name, prefix: prefix, to: :state
|
19
22
|
|
20
|
-
|
23
|
+
_add_state_reader_tracker(name.to_sym)
|
24
|
+
end
|
21
25
|
end
|
22
26
|
|
23
|
-
def state_writer(
|
24
|
-
|
27
|
+
def state_writer(*names, prefix: false)
|
28
|
+
names.each do |name|
|
29
|
+
delegate "#{name}=", prefix: prefix, to: :state
|
25
30
|
|
26
|
-
|
31
|
+
_add_state_writer_tracker(name.to_sym)
|
32
|
+
end
|
27
33
|
end
|
28
34
|
|
29
|
-
def state_accessor(
|
30
|
-
|
31
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/flow/operation/core.rb
CHANGED
@@ -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
|
data/lib/flow/operation_base.rb
CHANGED
@@ -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
|
data/lib/flow/spec_helper.rb
CHANGED
data/lib/flow/state_base.rb
CHANGED
@@ -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 <
|
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
|
data/lib/flow/state_proxy.rb
CHANGED
@@ -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/
|
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
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 "
|
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.
|
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:
|
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:
|
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:
|
46
|
+
name: conjunction
|
47
47
|
requirement: !ruby/object:Gem::Requirement
|
48
48
|
requirements:
|
49
49
|
- - ">="
|
50
50
|
- !ruby/object:Gem::Version
|
51
|
-
version:
|
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:
|
61
|
+
version: 0.2.0
|
62
|
+
- - "<"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '1.0'
|
59
65
|
- !ruby/object:Gem::Dependency
|
60
|
-
name:
|
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:
|
86
|
+
name: substance
|
81
87
|
requirement: !ruby/object:Gem::Requirement
|
82
88
|
requirements:
|
83
89
|
- - ">="
|
84
90
|
- !ruby/object:Gem::Version
|
85
|
-
version: 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.
|
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
|
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
|
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/
|
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.
|
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: []
|
data/lib/flow/state/output.rb
DELETED
@@ -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
|
data/lib/flow/state/status.rb
DELETED
@@ -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
|