flow 0.9.3 → 0.10.0

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +177 -245
  3. data/lib/flow.rb +2 -0
  4. data/lib/flow/concerns/transaction_wrapper.rb +10 -17
  5. data/lib/flow/custom_matchers.rb +5 -3
  6. data/lib/flow/custom_matchers/define_failure.rb +21 -0
  7. data/lib/flow/custom_matchers/define_output.rb +34 -0
  8. data/lib/flow/custom_matchers/handle_error.rb +32 -0
  9. data/lib/flow/custom_matchers/have_on_state.rb +54 -0
  10. data/lib/flow/custom_matchers/use_operations.rb +13 -11
  11. data/lib/flow/custom_matchers/wrap_in_transaction.rb +60 -0
  12. data/lib/flow/flow/callbacks.rb +1 -1
  13. data/lib/flow/flow/core.rb +1 -0
  14. data/lib/flow/flow/flux.rb +0 -2
  15. data/lib/flow/flow/status.rb +0 -4
  16. data/lib/flow/flow/transactions.rb +2 -2
  17. data/lib/flow/flow/trigger.rb +1 -1
  18. data/lib/flow/flow_base.rb +13 -15
  19. data/lib/flow/operation/accessors.rb +66 -0
  20. data/lib/flow/operation/callbacks.rb +12 -10
  21. data/lib/flow/operation/core.rb +10 -8
  22. data/lib/flow/operation/error_handler.rb +18 -12
  23. data/lib/flow/operation/errors/already_executed.rb +5 -3
  24. data/lib/flow/operation/errors/already_rewound.rb +5 -3
  25. data/lib/flow/operation/execute.rb +28 -26
  26. data/lib/flow/operation/failures.rb +48 -42
  27. data/lib/flow/operation/status.rb +18 -21
  28. data/lib/flow/operation/transactions.rb +8 -6
  29. data/lib/flow/operation_base.rb +15 -13
  30. data/lib/flow/rspec_configuration.rb +5 -0
  31. data/lib/flow/spec_helper.rb +3 -0
  32. data/lib/flow/state/errors/not_validated.rb +9 -0
  33. data/lib/flow/state/output.rb +59 -0
  34. data/lib/flow/state/status.rb +22 -0
  35. data/lib/flow/state_base.rb +9 -16
  36. data/lib/flow/version.rb +1 -1
  37. data/lib/generators/flow/application_flow/templates/application_flow.rb +1 -1
  38. data/lib/generators/flow/application_operation/templates/application_operation.rb +1 -1
  39. data/lib/generators/flow/application_state/templates/application_state.rb +1 -1
  40. data/lib/generators/flow/operation/USAGE +1 -1
  41. data/lib/generators/flow/operation/templates/operation.rb.erb +0 -5
  42. data/lib/generators/flow/state/USAGE +1 -1
  43. data/lib/generators/flow/state/templates/state.rb.erb +2 -1
  44. data/lib/generators/rspec/application_flow/templates/application_flow_spec.rb +1 -1
  45. data/lib/generators/rspec/application_operation/templates/application_operation_spec.rb +1 -9
  46. data/lib/generators/rspec/application_state/templates/application_state_spec.rb +1 -1
  47. data/lib/generators/rspec/flow/templates/flow_spec.rb.erb +0 -8
  48. data/lib/generators/rspec/operation/templates/operation_spec.rb.erb +5 -11
  49. data/lib/generators/rspec/state/templates/state_spec.rb.erb +8 -10
  50. metadata +39 -52
  51. data/lib/flow/custom_matchers/define_argument.rb +0 -19
  52. data/lib/flow/custom_matchers/define_attribute.rb +0 -19
  53. data/lib/flow/custom_matchers/define_option.rb +0 -26
  54. data/lib/flow/flow/ebb.rb +0 -28
  55. data/lib/flow/flow/revert.rb +0 -18
  56. data/lib/flow/operation/rewind.rb +0 -25
  57. data/lib/flow/state/arguments.rb +0 -30
  58. data/lib/flow/state/attributes.rb +0 -31
  59. data/lib/flow/state/callbacks.rb +0 -13
  60. data/lib/flow/state/core.rb +0 -14
  61. data/lib/flow/state/options.rb +0 -45
  62. data/lib/flow/state/string.rb +0 -34
@@ -0,0 +1,59 @@
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 Flow::State::Errors::NotValidated 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
@@ -0,0 +1,22 @@
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
@@ -1,21 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "state/callbacks"
4
- require_relative "state/attributes"
5
- require_relative "state/arguments"
6
- require_relative "state/options"
7
- require_relative "state/core"
8
- require_relative "state/string"
3
+ require_relative "state/errors/not_validated"
4
+
5
+ require_relative "state/status"
6
+ require_relative "state/output"
9
7
 
10
8
  # A **State** is an aggregation of input and derived data.
11
- class StateBase
12
- include ShortCircuIt
13
- include Technologic
14
- include ActiveModel::Model
15
- include State::Callbacks
16
- include State::Attributes
17
- include State::Arguments
18
- include State::Options
19
- include State::Core
20
- include State::String
9
+ module Flow
10
+ class StateBase < Instructor::Base
11
+ include Flow::State::Status
12
+ include Flow::State::Output
13
+ end
21
14
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flow
4
- VERSION = "0.9.3"
4
+ VERSION = "0.10.0"
5
5
  end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ApplicationFlow < FlowBase; end
3
+ class ApplicationFlow < Flow::FlowBase; end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ApplicationOperation < OperationBase; end
3
+ class ApplicationOperation < Flow::OperationBase; end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ApplicationState < StateBase; end
3
+ class ApplicationState < Flow::StateBase; end
@@ -2,7 +2,7 @@ Description:
2
2
  Stub a Operation with test.
3
3
 
4
4
  Example:
5
- `rails generate operation foo`
5
+ `rails generate flow:operation foo`
6
6
 
7
7
  Generates:
8
8
  Operation: app/operations/foo.rb
@@ -4,9 +4,4 @@ class <%= class_name %> < ApplicationOperation
4
4
  def behavior
5
5
  # Define what this operation does here
6
6
  end
7
-
8
- def undo
9
- # If your operation can be undone, define how here.
10
- # Otherwise you can delete this method.
11
- end
12
7
  end
@@ -2,7 +2,7 @@ Description:
2
2
  Stub a State with test.
3
3
 
4
4
  Example:
5
- `rails generate state foo`
5
+ `rails generate flow:state foo`
6
6
 
7
7
  Generates:
8
8
  State: app/states/foo_state.rb
@@ -2,8 +2,9 @@
2
2
 
3
3
  class <%= class_name %>State < ApplicationState
4
4
  # argument :required_input
5
+ # argument :necessary_input, allow_nil: false
5
6
  # option :optional_input
6
7
  # option :option_with_default, default: :default_static_value
7
8
  # option(:option_with_default_from_block) { required_input.default_dynamic_value }
8
- # attribute :some_runtime_value
9
+ # output :some_runtime_value
9
10
  end
@@ -3,5 +3,5 @@
3
3
  require "rails_helper"
4
4
 
5
5
  RSpec.describe ApplicationFlow, type: :flow do
6
- it { is_expected.to inherit_from FlowBase }
6
+ it { is_expected.to inherit_from Flow::FlowBase }
7
7
  end
@@ -7,19 +7,11 @@ RSpec.describe ApplicationOperation, type: :operation do
7
7
 
8
8
  let(:state) { double }
9
9
 
10
- it { is_expected.to inherit_from OperationBase }
10
+ it { is_expected.to inherit_from Flow::OperationBase }
11
11
 
12
12
  describe "#execute" do
13
13
  subject(:execute) { operation.execute }
14
14
 
15
15
  it "has some behavior"
16
16
  end
17
-
18
- describe "#rewind" do
19
- subject(:rewind) { operation.rewind }
20
-
21
- before { operation.execute }
22
-
23
- it "undoes some behavior"
24
- end
25
17
  end
@@ -3,5 +3,5 @@
3
3
  require "rails_helper"
4
4
 
5
5
  RSpec.describe ApplicationState, type: :state do
6
- it { is_expected.to inherit_from StateBase }
6
+ it { is_expected.to inherit_from Flow::StateBase }
7
7
  end
@@ -17,12 +17,4 @@ RSpec.describe <%= class_name %>Flow, type: :flow do
17
17
 
18
18
  pending "describe the effects of a successful `Flow#flux` (or delete) #{__FILE__}"
19
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
28
20
  end
@@ -5,11 +5,13 @@ require "rails_helper"
5
5
  RSpec.describe <%= class_name %>, type: :operation do
6
6
  subject(:operation) { described_class.new(state) }
7
7
 
8
- let(:state) { example_state_class.new(**state_input) }
8
+ let(:state) { example_state_class.new(**state_input).tap(&:validate) }
9
9
  let(:example_state_class) do
10
10
  Class.new(ApplicationState) do
11
11
  # argument :foo
12
12
  # option :bar
13
+ # attribute :baz
14
+ # output :gaz
13
15
  end
14
16
  end
15
17
  let(:state_input) do
@@ -18,17 +20,9 @@ RSpec.describe <%= class_name %>, type: :operation do
18
20
 
19
21
  it { is_expected.to inherit_from ApplicationOperation }
20
22
 
21
- describe "#execute!" do
22
- subject(:execute!) { operation.execute! }
23
+ describe "#execute" do
24
+ subject(:execute) { operation.execute }
23
25
 
24
26
  pending "describe `Operation#behavior` (or delete) #{__FILE__}"
25
27
  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__}"
33
- end
34
28
  end
@@ -3,17 +3,15 @@
3
3
  require "rails_helper"
4
4
 
5
5
  RSpec.describe <%= class_name %>State, type: :state do
6
- subject(:state) { described_class.new(**input) }
7
-
8
- let(:input) do
9
- {}
10
- end
6
+ subject(:state) { described_class }
11
7
 
12
8
  it { is_expected.to inherit_from ApplicationState }
13
- # it { is_expected.to define_argument :foo }
14
- # it { is_expected.to define_option(:foo) }
15
- # it { is_expected.to define_option(:foo).with_default_value(:bar) }
16
- # it { is_expected.to define_option(:foo).with_default_value_block }
9
+ # it { is_expected.to define_argument :required_input }
10
+ # it { is_expected.to define_argument :necessary_input, allow_nil: false }
11
+ # it { is_expected.to define_option(:optional_input) }
12
+ # it { is_expected.to define_option(:option_with_default, default: :default_static_value) }
13
+ # it { is_expected.to define_option(:option_with_default_from_block, default: default_block_value) }
17
14
  # it { is_expected.to validate_presence_of ... }
18
- # it { is_expected.to define_attribute :foo }
15
+ # it { is_expected.to define_output :foo }
16
+ # it { is_expected.to define_output :foo, default: :bar }
19
17
  end
metadata CHANGED
@@ -1,14 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Garside
8
+ - Allen Rettberg
9
+ - Jordan Minneti
10
+ - Vinod Lala
8
11
  autorequire:
9
12
  bindir: bin
10
13
  cert_chain: []
11
- date: 2019-04-10 00:00:00.000000000 Z
14
+ date: 2019-05-13 00:00:00.000000000 Z
12
15
  dependencies:
13
16
  - !ruby/object:Gem::Dependency
14
17
  name: activemodel
@@ -58,28 +61,28 @@ dependencies:
58
61
  requirements:
59
62
  - - "~>"
60
63
  - !ruby/object:Gem::Version
61
- version: 0.6.3
64
+ version: 0.8.3
62
65
  type: :runtime
63
66
  prerelease: false
64
67
  version_requirements: !ruby/object:Gem::Requirement
65
68
  requirements:
66
69
  - - "~>"
67
70
  - !ruby/object:Gem::Version
68
- version: 0.6.3
71
+ version: 0.8.3
69
72
  - !ruby/object:Gem::Dependency
70
73
  name: bundler
71
74
  requirement: !ruby/object:Gem::Requirement
72
75
  requirements:
73
76
  - - "~>"
74
77
  - !ruby/object:Gem::Version
75
- version: '1.16'
78
+ version: 2.0.1
76
79
  type: :development
77
80
  prerelease: false
78
81
  version_requirements: !ruby/object:Gem::Requirement
79
82
  requirements:
80
83
  - - "~>"
81
84
  - !ruby/object:Gem::Version
82
- version: '1.16'
85
+ version: 2.0.1
83
86
  - !ruby/object:Gem::Dependency
84
87
  name: rake
85
88
  requirement: !ruby/object:Gem::Requirement
@@ -123,103 +126,89 @@ dependencies:
123
126
  - !ruby/object:Gem::Version
124
127
  version: '0.16'
125
128
  - !ruby/object:Gem::Dependency
126
- name: rubocop
129
+ name: faker
127
130
  requirement: !ruby/object:Gem::Requirement
128
131
  requirements:
129
132
  - - "~>"
130
133
  - !ruby/object:Gem::Version
131
- version: '0.58'
134
+ version: '1.8'
132
135
  type: :development
133
136
  prerelease: false
134
137
  version_requirements: !ruby/object:Gem::Requirement
135
138
  requirements:
136
139
  - - "~>"
137
140
  - !ruby/object:Gem::Version
138
- version: '0.58'
141
+ version: '1.8'
139
142
  - !ruby/object:Gem::Dependency
140
- name: rubocop-rspec
143
+ name: pry-byebug
141
144
  requirement: !ruby/object:Gem::Requirement
142
145
  requirements:
143
- - - "~>"
146
+ - - ">="
144
147
  - !ruby/object:Gem::Version
145
- version: '1.27'
148
+ version: 3.7.0
146
149
  type: :development
147
150
  prerelease: false
148
151
  version_requirements: !ruby/object:Gem::Requirement
149
152
  requirements:
150
- - - "~>"
153
+ - - ">="
151
154
  - !ruby/object:Gem::Version
152
- version: '1.27'
155
+ version: 3.7.0
153
156
  - !ruby/object:Gem::Dependency
154
- name: faker
157
+ name: sqlite3
155
158
  requirement: !ruby/object:Gem::Requirement
156
159
  requirements:
157
160
  - - "~>"
158
161
  - !ruby/object:Gem::Version
159
- version: '1.8'
162
+ version: 1.3.6
160
163
  type: :development
161
164
  prerelease: false
162
165
  version_requirements: !ruby/object:Gem::Requirement
163
166
  requirements:
164
167
  - - "~>"
165
168
  - !ruby/object:Gem::Version
166
- version: '1.8'
167
- - !ruby/object:Gem::Dependency
168
- name: pry
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: 0.11.3
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: 0.11.3
169
+ version: 1.3.6
181
170
  - !ruby/object:Gem::Dependency
182
- name: sqlite3
171
+ name: rspice
183
172
  requirement: !ruby/object:Gem::Requirement
184
173
  requirements:
185
174
  - - "~>"
186
175
  - !ruby/object:Gem::Version
187
- version: 1.3.6
176
+ version: 0.8.3
188
177
  type: :development
189
178
  prerelease: false
190
179
  version_requirements: !ruby/object:Gem::Requirement
191
180
  requirements:
192
181
  - - "~>"
193
182
  - !ruby/object:Gem::Version
194
- version: 1.3.6
183
+ version: 0.8.3
195
184
  - !ruby/object:Gem::Dependency
196
- name: rspice
185
+ name: spicerack-styleguide
197
186
  requirement: !ruby/object:Gem::Requirement
198
187
  requirements:
199
188
  - - "~>"
200
189
  - !ruby/object:Gem::Version
201
- version: 0.4.3
190
+ version: 0.8.3
202
191
  type: :development
203
192
  prerelease: false
204
193
  version_requirements: !ruby/object:Gem::Requirement
205
194
  requirements:
206
195
  - - "~>"
207
196
  - !ruby/object:Gem::Version
208
- version: 0.4.3
197
+ version: 0.8.3
209
198
  - !ruby/object:Gem::Dependency
210
199
  name: shoulda-matchers
211
200
  requirement: !ruby/object:Gem::Requirement
212
201
  requirements:
213
202
  - - '='
214
203
  - !ruby/object:Gem::Version
215
- version: 4.0.0.rc1
204
+ version: 4.0.1
216
205
  type: :development
217
206
  prerelease: false
218
207
  version_requirements: !ruby/object:Gem::Requirement
219
208
  requirements:
220
209
  - - '='
221
210
  - !ruby/object:Gem::Version
222
- version: 4.0.0.rc1
211
+ version: 4.0.1
223
212
  description: Tired of kitchen sink services, god-objects, and fat-everything? So were
224
213
  we. Get in the flow.
225
214
  email:
@@ -233,21 +222,22 @@ files:
233
222
  - lib/flow.rb
234
223
  - lib/flow/concerns/transaction_wrapper.rb
235
224
  - lib/flow/custom_matchers.rb
236
- - lib/flow/custom_matchers/define_argument.rb
237
- - lib/flow/custom_matchers/define_attribute.rb
238
- - lib/flow/custom_matchers/define_option.rb
225
+ - lib/flow/custom_matchers/define_failure.rb
226
+ - lib/flow/custom_matchers/define_output.rb
227
+ - lib/flow/custom_matchers/handle_error.rb
228
+ - lib/flow/custom_matchers/have_on_state.rb
239
229
  - lib/flow/custom_matchers/use_operations.rb
230
+ - lib/flow/custom_matchers/wrap_in_transaction.rb
240
231
  - lib/flow/flow/callbacks.rb
241
232
  - lib/flow/flow/core.rb
242
- - lib/flow/flow/ebb.rb
243
233
  - lib/flow/flow/errors/state_invalid.rb
244
234
  - lib/flow/flow/flux.rb
245
235
  - lib/flow/flow/operations.rb
246
- - lib/flow/flow/revert.rb
247
236
  - lib/flow/flow/status.rb
248
237
  - lib/flow/flow/transactions.rb
249
238
  - lib/flow/flow/trigger.rb
250
239
  - lib/flow/flow_base.rb
240
+ - lib/flow/operation/accessors.rb
251
241
  - lib/flow/operation/callbacks.rb
252
242
  - lib/flow/operation/core.rb
253
243
  - lib/flow/operation/error_handler.rb
@@ -255,18 +245,15 @@ files:
255
245
  - lib/flow/operation/errors/already_rewound.rb
256
246
  - lib/flow/operation/execute.rb
257
247
  - lib/flow/operation/failures.rb
258
- - lib/flow/operation/rewind.rb
259
248
  - lib/flow/operation/status.rb
260
249
  - lib/flow/operation/transactions.rb
261
250
  - lib/flow/operation_base.rb
251
+ - lib/flow/rspec_configuration.rb
262
252
  - lib/flow/shoulda_matcher_helper.rb
263
253
  - lib/flow/spec_helper.rb
264
- - lib/flow/state/arguments.rb
265
- - lib/flow/state/attributes.rb
266
- - lib/flow/state/callbacks.rb
267
- - lib/flow/state/core.rb
268
- - lib/flow/state/options.rb
269
- - lib/flow/state/string.rb
254
+ - lib/flow/state/errors/not_validated.rb
255
+ - lib/flow/state/output.rb
256
+ - lib/flow/state/status.rb
270
257
  - lib/flow/state_base.rb
271
258
  - lib/flow/version.rb
272
259
  - lib/generators/flow/USAGE
@@ -307,7 +294,7 @@ files:
307
294
  - lib/generators/rspec/state/USAGE
308
295
  - lib/generators/rspec/state/state_generator.rb
309
296
  - lib/generators/rspec/state/templates/state_spec.rb.erb
310
- homepage: http://www.freshly.com
297
+ homepage: https://github.com/Freshly/flow
311
298
  licenses:
312
299
  - MIT
313
300
  metadata: {}