flow 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|