flow 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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: {}