workflow-orchestrator 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +36 -0
  4. data/CHANGELOG.md +133 -0
  5. data/Gemfile +3 -0
  6. data/MIT-LICENSE +22 -0
  7. data/README.md +707 -0
  8. data/Rakefile +30 -0
  9. data/gemfiles/Gemfile.rails-3.x +12 -0
  10. data/gemfiles/Gemfile.rails-4.0 +14 -0
  11. data/gemfiles/Gemfile.rails-4.1 +14 -0
  12. data/gemfiles/Gemfile.rails-4.2 +14 -0
  13. data/gemfiles/Gemfile.rails-edge +14 -0
  14. data/lib/workflow/adapters/active_record.rb +75 -0
  15. data/lib/workflow/adapters/remodel.rb +15 -0
  16. data/lib/workflow/draw.rb +79 -0
  17. data/lib/workflow/errors.rb +20 -0
  18. data/lib/workflow/event.rb +38 -0
  19. data/lib/workflow/event_collection.rb +36 -0
  20. data/lib/workflow/specification.rb +83 -0
  21. data/lib/workflow/state.rb +44 -0
  22. data/lib/workflow/version.rb +3 -0
  23. data/lib/workflow.rb +307 -0
  24. data/orders_workflow.png +0 -0
  25. data/test/active_record_scopes_test.rb +56 -0
  26. data/test/active_record_scopes_with_values_test.rb +79 -0
  27. data/test/adapter_hook_test.rb +52 -0
  28. data/test/advanced_examples_test.rb +84 -0
  29. data/test/advanced_hooks_and_validation_test.rb +119 -0
  30. data/test/attr_protected_test.rb +107 -0
  31. data/test/before_transition_test.rb +36 -0
  32. data/test/couchtiny_example.rb +46 -0
  33. data/test/enum_values_in_memory_test.rb +23 -0
  34. data/test/enum_values_test.rb +30 -0
  35. data/test/incline_column_test.rb +54 -0
  36. data/test/inheritance_test.rb +56 -0
  37. data/test/main_test.rb +588 -0
  38. data/test/multiple_workflows_test.rb +84 -0
  39. data/test/new_versions/compare_states_test.rb +32 -0
  40. data/test/new_versions/persistence_test.rb +62 -0
  41. data/test/on_error_test.rb +52 -0
  42. data/test/on_unavailable_transition_test.rb +85 -0
  43. data/test/readme_example.rb +37 -0
  44. data/test/test_helper.rb +39 -0
  45. data/test/without_active_record_test.rb +54 -0
  46. data/workflow-orchestrator.gemspec +42 -0
  47. metadata +267 -0
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+ require 'active_record'
3
+ require 'logger'
4
+ require 'sqlite3'
5
+ require 'workflow'
6
+ require 'mocha/setup'
7
+ require 'stringio'
8
+
9
+ ActiveRecord::Migration.verbose = false
10
+
11
+ class PersistenceTestOrder < ActiveRecord::Base
12
+ include Workflow
13
+
14
+ workflow do
15
+ state :submitted do
16
+ event :accept, :transitions_to => :accepted, :meta => {:doc_weight => 8} do |reviewer, args|
17
+ end
18
+ end
19
+ state :accepted do
20
+ event :ship, :transitions_to => :shipped
21
+ end
22
+ state :shipped
23
+ end
24
+
25
+ attr_accessible :title # protecting all the other attributes
26
+
27
+ end
28
+
29
+ PersistenceTestOrder.logger = Logger.new(STDOUT) # active_record 2.3 expects a logger instance
30
+ PersistenceTestOrder.logger.level = Logger::WARN # switch to Logger::DEBUG to see the SQL statements
31
+
32
+ class PersistenceTest < ActiveRecordTestCase
33
+
34
+ def setup
35
+ super
36
+
37
+ ActiveRecord::Schema.define do
38
+ create_table :persistence_test_orders do |t|
39
+ t.string :title, :null => false
40
+ t.string :workflow_state
41
+ end
42
+ end
43
+
44
+ exec "INSERT INTO persistence_test_orders(title, workflow_state) VALUES('order6', 'accepted')"
45
+ end
46
+
47
+ def assert_state(title, expected_state, klass = PersistenceTestOrder)
48
+ o = klass.find_by_title(title)
49
+ assert_equal expected_state, o.read_attribute(klass.workflow_column)
50
+ o
51
+ end
52
+
53
+ test 'ensure other dirty attributes are not saved on state change' do
54
+ o = assert_state 'order6', 'accepted'
55
+ o.title = 'going to change the title'
56
+ assert o.changed?
57
+ o.ship!
58
+ assert o.changed?, 'title should not be saved and the change still stay pending'
59
+ end
60
+
61
+ end
62
+
@@ -0,0 +1,52 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+ require 'workflow'
3
+
4
+ class OnErrorTest < Test::Unit::TestCase
5
+ # A class that does not handle errors in an error block
6
+ class NoErrorBlock
7
+ include Workflow
8
+ workflow do
9
+ state :first do
10
+ event :forward, :transitions_to => :second do
11
+ raise "This is some random runtime error"
12
+ end
13
+ end
14
+ state :second
15
+ end
16
+ end
17
+
18
+ # A class that handles errors in an error block
19
+ class ErrorBlock
20
+ attr_reader :errors
21
+
22
+ def initialize
23
+ @errors = {}
24
+ end
25
+
26
+ include Workflow
27
+ workflow do
28
+ state :first do
29
+ event :forward, :transitions_to => :second do
30
+ raise "This is some random runtime error"
31
+ end
32
+ end
33
+ state :second
34
+ on_error { |error, from, to, event, *args| @errors.merge!({:error => error.class, :from => from, :to => to, :event => event, :args => args}) }
35
+ end
36
+ end
37
+
38
+
39
+ test 'that an exception is raised if there is no associated on_error block' do
40
+ flow = NoErrorBlock.new
41
+ assert_raise( RuntimeError, "This is some random runtime error" ) { flow.forward! }
42
+ assert_equal(true, flow.first?)
43
+ end
44
+
45
+ test 'that on_error block is called when an exception is raised and the transition is halted' do
46
+ flow = ErrorBlock.new
47
+ assert_nothing_raised { flow.forward! }
48
+ assert_equal({:error => RuntimeError, :from=>:first, :to=>:second, :event=>:forward, :args=>[]}, flow.errors)
49
+ # transition should not happen
50
+ assert_equal(true, flow.first?)
51
+ end
52
+ end
@@ -0,0 +1,85 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+ require 'workflow'
3
+
4
+ class OnUnavailableTransitionTest < Test::Unit::TestCase
5
+
6
+ class NoUnavailableTransitionBlock
7
+ attr_reader :unavailable_transitions
8
+
9
+ def initialize
10
+ @unavailable_transitions = {}
11
+ end
12
+
13
+ include Workflow
14
+ workflow do
15
+ state :first
16
+ state :second do
17
+ event :backward, :transitions_to => :first
18
+ end
19
+ end
20
+ end
21
+
22
+ class UnavailableTransitionBlock
23
+ attr_reader :unavailable_transitions
24
+
25
+ def initialize
26
+ @unavailable_transitions = {}
27
+ end
28
+
29
+ include Workflow
30
+ workflow do
31
+ state :first
32
+ state :second do
33
+ event :backward, :transitions_to => :first
34
+ end
35
+ on_unavailable_transition do |from, to_name, *args|
36
+ @unavailable_transitions.merge!({:from => from, :to_name => to_name, :args => args})
37
+ end
38
+ end
39
+ end
40
+
41
+ class UnavailableTransitionBlockThrowsException
42
+ attr_reader :unavailable_transitions
43
+
44
+ def initialize
45
+ @unavailable_transitions = {}
46
+ end
47
+
48
+ include Workflow
49
+ workflow do
50
+ state :first
51
+ state :second do
52
+ event :backward, :transitions_to => :first
53
+ end
54
+ on_unavailable_transition do |from, to_name, *args|
55
+ @unavailable_transitions.merge!({:from => from, :to_name => to_name, :args => args})
56
+ false
57
+ end
58
+ end
59
+ end
60
+
61
+ test 'that NoUnavailableTransitionBlock is raised when no on_unavailable_transition block is defined' do
62
+ flow = NoUnavailableTransitionBlock.new
63
+ assert_raise( Workflow::NoTransitionAllowed ) { flow.backward! }
64
+ assert_equal({}, flow.unavailable_transitions)
65
+ # transition should not happen
66
+ assert_equal(true, flow.first?)
67
+ end
68
+
69
+ test 'that on_unavailable_transition block is called when an undefined event is called' do
70
+ flow = UnavailableTransitionBlock.new
71
+ assert_nothing_raised { flow.backward! }
72
+ assert_equal({:from => :first, :to_name => :backward, :args=>[]}, flow.unavailable_transitions)
73
+ # transition should not happen
74
+ assert_equal(true, flow.first?)
75
+ end
76
+
77
+ test 'that on_unavailable_transition block is called when an undefined event is called and throws NoUnavailableTransitionBlock as false is returned' do
78
+ flow = UnavailableTransitionBlockThrowsException.new
79
+ assert_raise( Workflow::NoTransitionAllowed ) { flow.backward! }
80
+ assert_equal({:from => :first, :to_name => :backward, :args=>[]}, flow.unavailable_transitions)
81
+ # transition should not happen
82
+ assert_equal(true, flow.first?)
83
+ end
84
+
85
+ end
@@ -0,0 +1,37 @@
1
+ require 'workflow'
2
+ class Article
3
+ include Workflow
4
+ workflow do
5
+ state :new do
6
+ event :submit, :transitions_to => :awaiting_review
7
+ end
8
+ state :awaiting_review do
9
+ event :review, :transitions_to => :being_reviewed
10
+ end
11
+ state :being_reviewed do
12
+ event :accept, :transitions_to => :accepted
13
+ event :reject, :transitions_to => :rejected
14
+ end
15
+ state :accepted
16
+ state :rejected
17
+ end
18
+ end
19
+
20
+ article = Article.new
21
+ article.accepted? # => false
22
+ article.new? # => true
23
+ article.submit!
24
+ article.review!
25
+
26
+ puts article.current_state # => being_reviewed
27
+
28
+
29
+ class Article
30
+ def reject
31
+ puts "send email to the author here explaining the reason for the rejection"
32
+ end
33
+ end
34
+
35
+ article.reject! # will cause a state transition, would persist the new
36
+ # state (if inherited from ActiveRecord), and invoke the callback -
37
+ # send email to the author.
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_record'
4
+
5
+ class << Test::Unit::TestCase
6
+ def test(name, &block)
7
+ test_name = :"test_#{name.gsub(' ','_')}"
8
+ raise ArgumentError, "#{test_name} is already defined" if self.instance_methods.include? test_name.to_s
9
+ if block
10
+ define_method test_name, &block
11
+ else
12
+ puts "PENDING: #{name}"
13
+ end
14
+ end
15
+ end
16
+
17
+ class ActiveRecordTestCase < Test::Unit::TestCase
18
+ def exec(sql)
19
+ ActiveRecord::Base.connection.execute sql
20
+ end
21
+
22
+ def setup
23
+ ActiveRecord::Base.establish_connection(
24
+ :adapter => "sqlite3",
25
+ :database => ":memory:" #"tmp/test"
26
+ )
27
+
28
+ # eliminate ActiveRecord warning. TODO: delete as soon as ActiveRecord is fixed
29
+ ActiveRecord::Base.connection.reconnect!
30
+ end
31
+
32
+ def teardown
33
+ ActiveRecord::Base.connection.disconnect!
34
+ end
35
+
36
+ def default_test
37
+ end
38
+ end
39
+
@@ -0,0 +1,54 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+ require 'workflow'
3
+
4
+ class WithoutWorkflowTest < Test::Unit::TestCase
5
+ class Article
6
+ include Workflow
7
+ workflow do
8
+ state :new do
9
+ event :submit, :transitions_to => :awaiting_review
10
+ end
11
+ state :awaiting_review do
12
+ event :review, :transitions_to => :being_reviewed
13
+ end
14
+ state :being_reviewed do
15
+ event :accept, :transitions_to => :accepted
16
+ event :reject, :transitions_to => :rejected
17
+ end
18
+ state :accepted
19
+ state :rejected
20
+ end
21
+ end
22
+
23
+ def test_readme_example_article
24
+ article = Article.new
25
+ assert article.new?
26
+ end
27
+
28
+ test 'better error message on transitions_to typo' do
29
+ assert_raise Workflow::WorkflowDefinitionError do
30
+ Class.new do
31
+ include Workflow
32
+ workflow do
33
+ state :new do
34
+ event :event1, :transitionnn => :next # missing transitions_to target
35
+ end
36
+ state :next
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ test 'check transition_to alias' do
43
+ Class.new do
44
+ include Workflow
45
+ workflow do
46
+ state :new do
47
+ event :event1, :transition_to => :next
48
+ end
49
+ state :next
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'workflow/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "workflow-orchestrator"
8
+ gem.version = Workflow::VERSION
9
+ gem.authors = ["Lorefnon"]
10
+ gem.email = ["lorefnon@gmail.com"]
11
+ gem.description = <<DOC
12
+ A ruby DSL for modeling business logic as [Finite State Machines](https://en.wikipedia.org/wiki/Finite-state_machine).
13
+
14
+ The aim of this library is to make the expression of these concepts as clear as possible, utilizing the expressiveness of ruby language, and using similar terminology as found in state machine theory.
15
+ DOC
16
+ gem.summary = "A ruby DSL for modeling business logic as Finite State Machines"
17
+ gem.homepage = "https://github.com/lorefnon/workflow-orchestrator"
18
+
19
+ gem.files = `git ls-files`.split($/)
20
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
21
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
22
+ gem.require_paths = ["lib"]
23
+
24
+ gem.extra_rdoc_files = [
25
+ "README.md"
26
+ ]
27
+
28
+ gem.add_development_dependency 'rdoc', [">= 3.12"]
29
+ gem.add_development_dependency 'bundler', [">= 1.0.0"]
30
+ gem.add_development_dependency 'activerecord'
31
+ gem.add_development_dependency 'protected_attributes'
32
+ gem.add_development_dependency 'sqlite3'
33
+ gem.add_development_dependency 'mocha'
34
+ gem.add_development_dependency 'rake'
35
+ gem.add_development_dependency 'test-unit'
36
+ gem.add_development_dependency 'pry-rails'
37
+ gem.add_development_dependency 'pry-byebug'
38
+ gem.add_development_dependency 'ruby-graphviz', ['~> 1.0.0']
39
+
40
+ gem.required_ruby_version = '>= 1.9.2'
41
+ end
42
+
metadata ADDED
@@ -0,0 +1,267 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: workflow-orchestrator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Lorefnon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdoc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: protected_attributes
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mocha
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: test-unit
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry-rails
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry-byebug
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: ruby-graphviz
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.0.0
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.0.0
167
+ description: |
168
+ A ruby DSL for modeling business logic as [Finite State Machines](https://en.wikipedia.org/wiki/Finite-state_machine).
169
+
170
+ The aim of this library is to make the expression of these concepts as clear as possible, utilizing the expressiveness of ruby language, and using similar terminology as found in state machine theory.
171
+ email:
172
+ - lorefnon@gmail.com
173
+ executables: []
174
+ extensions: []
175
+ extra_rdoc_files:
176
+ - README.md
177
+ files:
178
+ - ".gitignore"
179
+ - ".travis.yml"
180
+ - CHANGELOG.md
181
+ - Gemfile
182
+ - MIT-LICENSE
183
+ - README.md
184
+ - Rakefile
185
+ - gemfiles/Gemfile.rails-3.x
186
+ - gemfiles/Gemfile.rails-4.0
187
+ - gemfiles/Gemfile.rails-4.1
188
+ - gemfiles/Gemfile.rails-4.2
189
+ - gemfiles/Gemfile.rails-edge
190
+ - lib/workflow.rb
191
+ - lib/workflow/adapters/active_record.rb
192
+ - lib/workflow/adapters/remodel.rb
193
+ - lib/workflow/draw.rb
194
+ - lib/workflow/errors.rb
195
+ - lib/workflow/event.rb
196
+ - lib/workflow/event_collection.rb
197
+ - lib/workflow/specification.rb
198
+ - lib/workflow/state.rb
199
+ - lib/workflow/version.rb
200
+ - orders_workflow.png
201
+ - test/active_record_scopes_test.rb
202
+ - test/active_record_scopes_with_values_test.rb
203
+ - test/adapter_hook_test.rb
204
+ - test/advanced_examples_test.rb
205
+ - test/advanced_hooks_and_validation_test.rb
206
+ - test/attr_protected_test.rb
207
+ - test/before_transition_test.rb
208
+ - test/couchtiny_example.rb
209
+ - test/enum_values_in_memory_test.rb
210
+ - test/enum_values_test.rb
211
+ - test/incline_column_test.rb
212
+ - test/inheritance_test.rb
213
+ - test/main_test.rb
214
+ - test/multiple_workflows_test.rb
215
+ - test/new_versions/compare_states_test.rb
216
+ - test/new_versions/persistence_test.rb
217
+ - test/on_error_test.rb
218
+ - test/on_unavailable_transition_test.rb
219
+ - test/readme_example.rb
220
+ - test/test_helper.rb
221
+ - test/without_active_record_test.rb
222
+ - workflow-orchestrator.gemspec
223
+ homepage: https://github.com/lorefnon/workflow-orchestrator
224
+ licenses: []
225
+ metadata: {}
226
+ post_install_message:
227
+ rdoc_options: []
228
+ require_paths:
229
+ - lib
230
+ required_ruby_version: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - ">="
233
+ - !ruby/object:Gem::Version
234
+ version: 1.9.2
235
+ required_rubygems_version: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - ">="
238
+ - !ruby/object:Gem::Version
239
+ version: '0'
240
+ requirements: []
241
+ rubyforge_project:
242
+ rubygems_version: 2.5.1
243
+ signing_key:
244
+ specification_version: 4
245
+ summary: A ruby DSL for modeling business logic as Finite State Machines
246
+ test_files:
247
+ - test/active_record_scopes_test.rb
248
+ - test/active_record_scopes_with_values_test.rb
249
+ - test/adapter_hook_test.rb
250
+ - test/advanced_examples_test.rb
251
+ - test/advanced_hooks_and_validation_test.rb
252
+ - test/attr_protected_test.rb
253
+ - test/before_transition_test.rb
254
+ - test/couchtiny_example.rb
255
+ - test/enum_values_in_memory_test.rb
256
+ - test/enum_values_test.rb
257
+ - test/incline_column_test.rb
258
+ - test/inheritance_test.rb
259
+ - test/main_test.rb
260
+ - test/multiple_workflows_test.rb
261
+ - test/new_versions/compare_states_test.rb
262
+ - test/new_versions/persistence_test.rb
263
+ - test/on_error_test.rb
264
+ - test/on_unavailable_transition_test.rb
265
+ - test/readme_example.rb
266
+ - test/test_helper.rb
267
+ - test/without_active_record_test.rb