linearly 0.1.2 → 0.1.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: 2fe555b7d9c61204c18afbed62318e77460a1fbb
4
- data.tar.gz: 303030554164e3f5899b5b0f8c0ca9871364516d
2
+ SHA256:
3
+ metadata.gz: 2528725570ecfd8cced2b0718a9859be207fa15ffd6cb265bdd5976f5eb626e4
4
+ data.tar.gz: 478800acf301111d2f714ccd236fa9d9cecbb0d9ffc2b09c0dddf093dd382986
5
5
  SHA512:
6
- metadata.gz: 8b9ec5dbf004c950cb07a8132c82bcef3c1ee9db79bdde6e457f9790aa5612d40eef1cf0c18303b6469b8a0350d1da7d7f546f271501d34e43af854ab202fa82
7
- data.tar.gz: b779d10a8578f69495451ca9af23489639818d4309621c12016fc4c8dd8344653980d5af119ab49c220585e2669dd6583ffb3c43e6f965c05071dee1c5c063ef
6
+ metadata.gz: 4cab82060fe000080f29ba4a01b90cbf8081af67879bc8119da01f0ea6c16fd42a6677b7490cc3135b5e004517c6521cdbc33c0d9af1fbe024f8c45c6947a97d
7
+ data.tar.gz: a4e40ef75656a065a48dee68662b141150dacbca4c2e1e950385fa3359bca844cf1b32bc7dac71d83dbd1d8b2493edccb472d0f4b23b62453fbb10249e700e6e
@@ -9,20 +9,37 @@ module Linearly
9
9
  # @return [Object]
10
10
  # @api public
11
11
  # @example
12
- # Linearly::Errors::StateNotReturned.new('surprise').value
12
+ # Linearly::Errors::StateNotReturned
13
+ # .new(output: 'surprise', step: 'step')
14
+ # .output
13
15
  # => "surprise"
14
- attr_reader :value
16
+ attr_reader :output
17
+
18
+ # Name of the step that caused the error
19
+ #
20
+ # @return String
21
+ # @api public
22
+ # @example
23
+ # Linearly::Errors::StateNotReturned
24
+ # .new(output: 'surprise', step: 'step')
25
+ # .step
26
+ # => "step"
27
+ attr_reader :step
15
28
 
16
29
  # Constructor for the {StateNotReturned} class
17
30
  #
18
- # @param value [Object]
31
+ # @param output: [Object]
32
+ # @param step: [String]
19
33
  #
20
34
  # @api public
21
35
  # @example
22
- # Linearly::Errors::StateNotReturned.new('surprise')
23
- def initialize(value)
24
- super("#{value.class.name} is not a Statefully::State")
25
- @value = value
36
+ # Linearly::Errors::StateNotReturned
37
+ # .new(output: 'surprise', step: 'step')
38
+ def initialize(output:, step:)
39
+ str = output.inspect
40
+ super("#{str}, returned from #{step}, is not a Statefully::State")
41
+ @output = output
42
+ @step = step
26
43
  end
27
44
  end
28
45
  end
data/lib/linearly/flow.rb CHANGED
@@ -3,7 +3,7 @@ require 'forwardable'
3
3
  module Linearly
4
4
  class Flow
5
5
  extend Forwardable
6
- include Mixins::Reducer
6
+ include Mixins::StepCollection
7
7
 
8
8
  # @!method call(state)
9
9
  # Validate the input state and run steps as long as it's a +Success+
@@ -0,0 +1,108 @@
1
+ require 'statefully'
2
+
3
+ module Linearly
4
+ module Mixins
5
+ # {StepCollection} is a mixin to include in all classes which need to run
6
+ # more than one step.
7
+ #
8
+ # @api private
9
+ module StepCollection
10
+ # Keep calling steps as long as long as the state is successful
11
+ #
12
+ # This method reeks of :reek:TooManyStatements and :reek:FeatureEnvy.
13
+ #
14
+ # @param state [Statefully::State]
15
+ #
16
+ # @return [Statefully::State]
17
+ # @api private
18
+ def call(state)
19
+ steps.reduce(state, &Reducer.method(:reduce))
20
+ end
21
+
22
+ # {Reducer} encapsulates the logic required to process a single Step in
23
+ # a larger collection.
24
+ #
25
+ # @api private
26
+ class Reducer
27
+ # Public interface for the {Reducer}
28
+ #
29
+ # @param input [Statefully::State]
30
+ # @param step [Step]
31
+ #
32
+ # @return [Statefully::State]
33
+ # @api private
34
+ def self.reduce(input, step)
35
+ new(input: input, step: step).reduce
36
+ end
37
+
38
+ # Internal Reducer method to create {Step} output
39
+ #
40
+ # @return [Statefully::State]
41
+ # @api private
42
+ def reduce
43
+ return input if input.failed? || input.finished?
44
+ return input.fail(bad_output_error) unless state_returned?
45
+ output
46
+ end
47
+
48
+ private
49
+
50
+ # Return the original {Statefully::State}
51
+ #
52
+ # @return [Statefully::State]
53
+ # @api private
54
+ attr_reader :input
55
+
56
+ # Return the {Step} to run
57
+ #
58
+ # @return [Step]
59
+ # @api private
60
+ attr_reader :step
61
+
62
+ # Private constructor for the {Reducer}
63
+ #
64
+ # @param input [Statefully::State]
65
+ # @param step [Step]
66
+ #
67
+ # @api private
68
+ def initialize(input:, step:)
69
+ @input = input
70
+ @step = step
71
+ end
72
+ private_class_method :new
73
+
74
+ # Construct an {Errors::StateNotReturned} error from internal state
75
+ #
76
+ # @return [Errors::StateNotReturned]
77
+ # @api private
78
+ def bad_output_error
79
+ Errors::StateNotReturned.new(
80
+ output: output,
81
+ step: step.class.name,
82
+ )
83
+ end
84
+
85
+ # Create output and memoize for reuse
86
+ #
87
+ # @return [Statefully::State]
88
+ # @api private
89
+ def output
90
+ @output ||= begin
91
+ step.call(input)
92
+ rescue StandardError => error
93
+ input.fail(error)
94
+ end
95
+ end
96
+
97
+ # Check if output is an instance of {Statefully::State}
98
+ #
99
+ # @return [Boolean]
100
+ # @api private
101
+ def state_returned?
102
+ output.is_a?(Statefully::State)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ private_constant :Mixins
108
+ end
@@ -3,7 +3,7 @@ module Linearly
3
3
  # validates the inputs, runs the step, and validates the outputs.
4
4
  # @api private
5
5
  class Runner
6
- include Mixins::Reducer
6
+ include Mixins::StepCollection
7
7
 
8
8
  # Constructor for the {Runner} object
9
9
  # @param step [Step] anything that implements the +Step+ interface
@@ -1,3 +1,3 @@
1
1
  module Linearly
2
- VERSION = '0.1.2'.freeze
2
+ VERSION = '0.1.3'.freeze
3
3
  end
data/lib/linearly.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'linearly/mixins/flow_builder'
2
- require 'linearly/mixins/reducer'
2
+ require 'linearly/mixins/step_collection'
3
3
  require 'linearly/errors/broken_contract'
4
4
  require 'linearly/errors/state_not_returned'
5
5
  require 'linearly/flow'
@@ -3,11 +3,17 @@ require 'spec_helper'
3
3
  module Linearly
4
4
  module Errors
5
5
  describe StateNotReturned do
6
- let(:value) { 'surprise!' }
7
- let(:error) { described_class.new(value) }
6
+ let(:output) { 'output' }
7
+ let(:step) { 'step' }
8
+ let(:error) { described_class.new(output: output, step: step) }
8
9
 
9
- it { expect(error.message).to eq 'String is not a Statefully::State' }
10
- it { expect(error.value).to eq value }
10
+ it 'reports the right message' do
11
+ expect(error.message)
12
+ .to eq '"output", returned from step, is not a Statefully::State'
13
+ end
14
+
15
+ it { expect(error.output).to eq output }
16
+ it { expect(error.step).to eq step }
11
17
  end
12
18
  end
13
19
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linearly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcin Wyszynski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-22 00:00:00.000000000 Z
11
+ date: 2018-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: statefully
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.7
19
+ version: 0.1.8
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.7
26
+ version: 0.1.8
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -203,7 +203,7 @@ files:
203
203
  - lib/linearly/errors/state_not_returned.rb
204
204
  - lib/linearly/flow.rb
205
205
  - lib/linearly/mixins/flow_builder.rb
206
- - lib/linearly/mixins/reducer.rb
206
+ - lib/linearly/mixins/step_collection.rb
207
207
  - lib/linearly/runner.rb
208
208
  - lib/linearly/step/dynamic.rb
209
209
  - lib/linearly/step/static.rb
@@ -243,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
243
  version: '0'
244
244
  requirements: []
245
245
  rubyforge_project:
246
- rubygems_version: 2.6.13
246
+ rubygems_version: 2.7.4
247
247
  signing_key:
248
248
  specification_version: 4
249
249
  summary: Linear workflow framework based on immutable state
@@ -1,32 +0,0 @@
1
- require 'statefully'
2
-
3
- module Linearly
4
- module Mixins
5
- # {Reducer} is a mixin to include in all classes which need to run more than
6
- # one step.
7
- # @api private
8
- module Reducer
9
- # Keep calling steps as long as the state is successful
10
- #
11
- # This method reeks of :reek:TooManyStatements and :reek:FeatureEnvy.
12
- #
13
- # @param state [Statefully::State]
14
- #
15
- # @return [Statefully::State]
16
- # @api private
17
- def call(state)
18
- steps.reduce(state) do |current, step|
19
- break current if current.failed? || current.finished?
20
- begin
21
- next_state = step.call(current)
22
- rescue StandardError => err
23
- break current.fail(err)
24
- end
25
- next next_state if next_state.is_a?(Statefully::State)
26
- current.fail(Errors::StateNotReturned.new(step))
27
- end
28
- end
29
- end
30
- end
31
- private_constant :Mixins
32
- end