flow 0.9.2 → 0.9.3
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 +1262 -16
- data/lib/flow/concerns/transaction_wrapper.rb +1 -1
- data/lib/flow/custom_matchers.rb +1 -0
- data/lib/flow/custom_matchers/define_attribute.rb +19 -0
- data/lib/flow/flow/operations.rb +1 -1
- data/lib/flow/flow/status.rb +1 -1
- data/lib/flow/flow/transactions.rb +1 -1
- data/lib/flow/flow_base.rb +1 -1
- data/lib/flow/operation/core.rb +1 -1
- data/lib/flow/operation/error_handler.rb +1 -1
- data/lib/flow/operation/errors/already_executed.rb +7 -0
- data/lib/flow/operation/errors/already_rewound.rb +7 -0
- data/lib/flow/operation/execute.rb +2 -1
- data/lib/flow/operation/failures.rb +1 -1
- data/lib/flow/operation/rewind.rb +1 -0
- data/lib/flow/operation/status.rb +6 -1
- data/lib/flow/operation/transactions.rb +1 -1
- data/lib/flow/operation_base.rb +3 -2
- data/lib/flow/state/attributes.rb +2 -1
- data/lib/flow/state/core.rb +1 -1
- data/lib/flow/state_base.rb +1 -1
- data/lib/flow/version.rb +1 -1
- data/lib/generators/flow/state/templates/state.rb.erb +1 -0
- data/lib/generators/rspec/flow/templates/flow_spec.rb.erb +14 -0
- data/lib/generators/rspec/operation/templates/operation_spec.rb.erb +12 -2
- data/lib/generators/rspec/state/templates/state_spec.rb.erb +1 -0
- metadata +5 -2
data/lib/flow/custom_matchers.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# RSpec matcher for flow state attributes.
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
#
|
7
|
+
# RSpec.describe ExampleState, type: :state do
|
8
|
+
# subject { described_class.new(**input) }
|
9
|
+
#
|
10
|
+
# let(:input) { {} }
|
11
|
+
#
|
12
|
+
# it { is_expected.to define_attribute :foo }
|
13
|
+
# end
|
14
|
+
|
15
|
+
RSpec::Matchers.define :define_attribute do |attribute|
|
16
|
+
match { |state| expect(state.class._attributes).to include attribute }
|
17
|
+
description { "has attribute #{attribute}" }
|
18
|
+
failure_message { |state| "expected #{state.class.name}# to have attribute #{attribute}" }
|
19
|
+
end
|
data/lib/flow/flow/operations.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Operations are an ordered list of the behaviors which
|
3
|
+
# Operations are an ordered list of the behaviors which are executed with (and possibly change) the Flow's state.
|
4
4
|
module Flow
|
5
5
|
module Operations
|
6
6
|
extend ActiveSupport::Concern
|
data/lib/flow/flow/status.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# Flows where no operation should be persisted unless all are successful should use a transaction.
|
4
4
|
module Flow
|
5
5
|
module Transactions
|
6
6
|
extend ActiveSupport::Concern
|
data/lib/flow/flow_base.rb
CHANGED
@@ -12,7 +12,7 @@ require_relative "flow/status"
|
|
12
12
|
require_relative "flow/transactions"
|
13
13
|
require_relative "flow/trigger"
|
14
14
|
|
15
|
-
# A
|
15
|
+
# A **Flow** is a collection of procedurally executed **Operations** sharing a common **State**.
|
16
16
|
class FlowBase
|
17
17
|
include ShortCircuIt
|
18
18
|
include Technologic
|
data/lib/flow/operation/core.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# When an exception is raised during during execution, but a handler can rescue, it causes a failure instead.
|
4
4
|
module Operation
|
5
5
|
module ErrorHandler
|
6
6
|
extend ActiveSupport::Concern
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Operations
|
3
|
+
# Operations define a `#behavior` that occurs when `#execute` is called.
|
4
4
|
module Operation
|
5
5
|
module Execute
|
6
6
|
extend ActiveSupport::Concern
|
@@ -11,6 +11,7 @@ module Operation
|
|
11
11
|
attr_reader :operation_failure
|
12
12
|
|
13
13
|
set_callback :execute, :around, ->(_, block) { surveil(:execute) { block.call } }
|
14
|
+
set_callback :execute, :before, -> { raise Operation::Errors::AlreadyExecuted }, if: :executed?
|
14
15
|
end
|
15
16
|
|
16
17
|
def execute!
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# When `#execute` is unsuccessful, expected problems are
|
3
|
+
# When `#execute` is unsuccessful, expected problems are **failures** and unexpected problems are **Exceptions**.
|
4
4
|
module Operation
|
5
5
|
module Failures
|
6
6
|
extend ActiveSupport::Concern
|
@@ -7,16 +7,21 @@ module Operation
|
|
7
7
|
|
8
8
|
included do
|
9
9
|
set_callback(:execute, :before) { self.was_executed = true }
|
10
|
+
set_callback(:rewind, :before) { self.was_rewound = true }
|
10
11
|
|
11
12
|
private
|
12
13
|
|
13
|
-
attr_accessor :was_executed
|
14
|
+
attr_accessor :was_executed, :was_rewound
|
14
15
|
end
|
15
16
|
|
16
17
|
def executed?
|
17
18
|
was_executed.present?
|
18
19
|
end
|
19
20
|
|
21
|
+
def rewound?
|
22
|
+
was_rewound.present?
|
23
|
+
end
|
24
|
+
|
20
25
|
def failed?
|
21
26
|
operation_failure.present?
|
22
27
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# Operations which modify several persisted objects together should use a transaction.
|
4
4
|
module Operation
|
5
5
|
module Transactions
|
6
6
|
extend ActiveSupport::Concern
|
data/lib/flow/operation_base.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "operation/errors/already_executed"
|
4
|
+
require_relative "operation/errors/already_rewound"
|
4
5
|
|
5
6
|
require_relative "operation/callbacks"
|
6
7
|
require_relative "operation/core"
|
@@ -11,7 +12,7 @@ require_relative "operation/rewind"
|
|
11
12
|
require_relative "operation/status"
|
12
13
|
require_relative "operation/transactions"
|
13
14
|
|
14
|
-
#
|
15
|
+
# An **Operation** is a service object which is executed with a **State**.
|
15
16
|
class OperationBase
|
16
17
|
include ShortCircuIt
|
17
18
|
include Technologic
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# A state's attributes provide accessors to the input data it was initialized with.
|
4
4
|
module State
|
5
5
|
module Attributes
|
6
6
|
extend ActiveSupport::Concern
|
@@ -25,6 +25,7 @@ module State
|
|
25
25
|
attr_accessor attribute
|
26
26
|
define_attribute_methods attribute
|
27
27
|
end
|
28
|
+
alias_method :attribute, :define_attribute
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
data/lib/flow/state/core.rb
CHANGED
data/lib/flow/state_base.rb
CHANGED
@@ -7,7 +7,7 @@ require_relative "state/options"
|
|
7
7
|
require_relative "state/core"
|
8
8
|
require_relative "state/string"
|
9
9
|
|
10
|
-
# A
|
10
|
+
# A **State** is an aggregation of input and derived data.
|
11
11
|
class StateBase
|
12
12
|
include ShortCircuIt
|
13
13
|
include Technologic
|
data/lib/flow/version.rb
CHANGED
@@ -11,4 +11,18 @@ RSpec.describe <%= class_name %>Flow, type: :flow do
|
|
11
11
|
|
12
12
|
it { is_expected.to inherit_from ApplicationFlow }
|
13
13
|
# it { is_expected.to use_operations ExampleOperation }
|
14
|
+
|
15
|
+
describe "#trigger" do
|
16
|
+
subject(:trigger) { flow.trigger! }
|
17
|
+
|
18
|
+
pending "describe the effects of a successful `Flow#flux` (or delete) #{__FILE__}"
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#revert" do
|
22
|
+
before { flow.trigger! }
|
23
|
+
|
24
|
+
subject(:revert) { flow.revert }
|
25
|
+
|
26
|
+
pending "describe the effects of a successful `Flow#ebb` (or delete) #{__FILE__}"
|
27
|
+
end
|
14
28
|
end
|
@@ -18,7 +18,17 @@ RSpec.describe <%= class_name %>, type: :operation do
|
|
18
18
|
|
19
19
|
it { is_expected.to inherit_from ApplicationOperation }
|
20
20
|
|
21
|
-
describe "#execute" do
|
22
|
-
|
21
|
+
describe "#execute!" do
|
22
|
+
subject(:execute!) { operation.execute! }
|
23
|
+
|
24
|
+
pending "describe `Operation#behavior` (or delete) #{__FILE__}"
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#rewind" do
|
28
|
+
before { operation.execute! }
|
29
|
+
|
30
|
+
subject(:execute!) { operation.rewind }
|
31
|
+
|
32
|
+
pending "describe `Operation#undo` (or delete) #{__FILE__}"
|
23
33
|
end
|
24
34
|
end
|
@@ -15,4 +15,5 @@ RSpec.describe <%= class_name %>State, type: :state do
|
|
15
15
|
# it { is_expected.to define_option(:foo).with_default_value(:bar) }
|
16
16
|
# it { is_expected.to define_option(:foo).with_default_value_block }
|
17
17
|
# it { is_expected.to validate_presence_of ... }
|
18
|
+
# it { is_expected.to define_attribute :foo }
|
18
19
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Garside
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -234,6 +234,7 @@ files:
|
|
234
234
|
- lib/flow/concerns/transaction_wrapper.rb
|
235
235
|
- lib/flow/custom_matchers.rb
|
236
236
|
- lib/flow/custom_matchers/define_argument.rb
|
237
|
+
- lib/flow/custom_matchers/define_attribute.rb
|
237
238
|
- lib/flow/custom_matchers/define_option.rb
|
238
239
|
- lib/flow/custom_matchers/use_operations.rb
|
239
240
|
- lib/flow/flow/callbacks.rb
|
@@ -250,6 +251,8 @@ files:
|
|
250
251
|
- lib/flow/operation/callbacks.rb
|
251
252
|
- lib/flow/operation/core.rb
|
252
253
|
- lib/flow/operation/error_handler.rb
|
254
|
+
- lib/flow/operation/errors/already_executed.rb
|
255
|
+
- lib/flow/operation/errors/already_rewound.rb
|
253
256
|
- lib/flow/operation/execute.rb
|
254
257
|
- lib/flow/operation/failures.rb
|
255
258
|
- lib/flow/operation/rewind.rb
|