workflow 0.8.1 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://www.rubygems.org"
2
+
3
+ group :development do
4
+ gem "rdoc", "~> 3.12"
5
+ gem "bundler", ">= 1.0.0"
6
+ gem "jeweler", "~> 1.8.4"
7
+ end
8
+
9
+ gemspec
@@ -67,6 +67,18 @@ of possible events and other meta information:
67
67
  @transitions_to=:awaiting_review, @name=:submit, @meta={}>},
68
68
  name:new, meta{}
69
69
 
70
+ On Ruby 1.9 and above, you can check whether a state comes before or
71
+ after another state (by the order they were defined):
72
+
73
+ article.current_state
74
+ => being_reviewed
75
+ article.current_state < :accepted
76
+ => true
77
+ article.current_state >= :accepted
78
+ => false
79
+ article.between? :awaiting_review, :rejected
80
+ => true
81
+
70
82
  Now we can call the submit event, which transitions to the
71
83
  <tt>:awaiting_review</tt> state:
72
84
 
@@ -330,6 +342,26 @@ example][advanced_hooks_and_validation_test].
330
342
 
331
343
  [advanced_hooks_and_validation_test]: http://github.com/geekq/workflow/blob/master/test/advanced_hooks_and_validation_test.rb
332
344
 
345
+ ### on_error
346
+
347
+ If you want to do custom exception handling internal to workflow, you can define an `on_error` hook in your workflow.
348
+ For example:
349
+
350
+ workflow do
351
+ state :first do
352
+ event :forward, :transitions_to => :second
353
+ end
354
+ state :second
355
+
356
+ on_error do |error, from, to, event, *args|
357
+ Log.info "Exception(#error.class) on #{from} -> #{to}"
358
+ end
359
+ end
360
+
361
+ If forward! results in an exception, `on_error` is invoked and the workflow stays in a 'first' state. This capability
362
+ is particularly useful if your errors are transient and you want to queue up a job to retry in the future without
363
+ affecting the existing workflow state.
364
+
333
365
  ### Guards
334
366
 
335
367
  If you want to halt the transition conditionally, you can just raise an
data/Rakefile CHANGED
@@ -1,10 +1,20 @@
1
1
  require 'rubygems'
2
+ require 'bundler'
2
3
  require 'rubygems/package_task'
3
4
  require 'rake/testtask'
4
5
  require 'rdoc/task'
5
6
 
6
7
  task :default => [:test]
7
8
 
9
+ begin
10
+ Bundler.setup(:default, :development)
11
+ rescue Bundler::BundlerError => e
12
+ $stderr.puts e.message
13
+ $stderr.puts "Run `bundle install` to install missing gems"
14
+ exit e.status_code
15
+ end
16
+
17
+ require 'rake'
8
18
  Rake::TestTask.new do |t|
9
19
  t.verbose = true
10
20
  t.warning = true
@@ -16,16 +26,16 @@ Rake::RDocTask.new do |rdoc|
16
26
  rdoc.options << "-S"
17
27
  end
18
28
 
19
- begin
20
- require 'jeweler'
21
- Jeweler::Tasks.new do |gemspec|
22
- gemspec.name = "workflow"
23
- gemspec.rubyforge_project = 'workflow'
24
- gemspec.email = "vladimir@geekq.net"
25
- gemspec.homepage = "http://www.geekq.net/workflow/"
26
- gemspec.authors = ["Vladimir Dobriakov"]
27
- gemspec.summary = "A replacement for acts_as_state_machine."
28
- gemspec.description = <<-EOS
29
+ require 'jeweler'
30
+
31
+ Jeweler::Tasks.new do |gemspec|
32
+ gemspec.name = "workflow"
33
+ gemspec.rubyforge_project = 'workflow'
34
+ gemspec.email = "vladimir@geekq.net"
35
+ gemspec.homepage = "http://www.geekq.net/workflow/"
36
+ gemspec.authors = ["Vladimir Dobriakov"]
37
+ gemspec.summary = "A replacement for acts_as_state_machine."
38
+ gemspec.description = <<-EOS
29
39
  Workflow is a finite-state-machine-inspired API for modeling and interacting
30
40
  with what we tend to refer to as 'workflow'.
31
41
 
@@ -34,11 +44,7 @@ begin
34
44
  * various hooks for single transitions, entering state etc.
35
45
  * convenient access to the workflow specification: list states, possible events
36
46
  for particular state
37
- EOS
47
+ EOS
38
48
 
39
- Jeweler::GemcutterTasks.new
40
- end
41
- rescue LoadError
42
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
49
+ Jeweler::GemcutterTasks.new
43
50
  end
44
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.1
1
+ 0.8.3
@@ -6,7 +6,7 @@ module Workflow
6
6
  class Specification
7
7
 
8
8
  attr_accessor :states, :initial_state, :meta,
9
- :on_transition_proc, :before_transition_proc, :after_transition_proc
9
+ :on_transition_proc, :before_transition_proc, :after_transition_proc, :on_error_proc
10
10
 
11
11
  def initialize(meta = {}, &specification)
12
12
  @states = Hash.new
@@ -22,7 +22,7 @@ module Workflow
22
22
 
23
23
  def state(name, meta = {:meta => {}}, &events_and_etc)
24
24
  # meta[:meta] to keep the API consistent..., gah
25
- new_state = Workflow::State.new(name, meta[:meta])
25
+ new_state = Workflow::State.new(name, self, meta[:meta])
26
26
  @initial_state = new_state if @states.empty?
27
27
  @states[name.to_sym] = new_state
28
28
  @scoped_state = new_state
@@ -57,6 +57,10 @@ module Workflow
57
57
  def on_transition(&proc)
58
58
  @on_transition_proc = proc
59
59
  end
60
+
61
+ def on_error(&proc)
62
+ @on_error_proc = proc
63
+ end
60
64
  end
61
65
 
62
66
  class TransitionHalted < Exception
@@ -79,9 +83,26 @@ module Workflow
79
83
  class State
80
84
 
81
85
  attr_accessor :name, :events, :meta, :on_entry, :on_exit
82
-
83
- def initialize(name, meta = {})
84
- @name, @events, @meta = name, Hash.new, meta
86
+ attr_reader :spec
87
+
88
+ def initialize(name, spec, meta = {})
89
+ @name, @spec, @events, @meta = name, spec, Hash.new, meta
90
+ end
91
+
92
+ unless RUBY_VERSION < '1.9'
93
+ include Comparable
94
+
95
+ def <=>(other_state)
96
+ states = spec.states.keys
97
+ raise ArgumentError, "state `#{other_state}' does not exist" unless other_state.in? states
98
+ if states.index(self.to_sym) < states.index(other_state.to_sym)
99
+ -1
100
+ elsif states.index(self.to_sym) > states.index(other_state.to_sym)
101
+ 1
102
+ else
103
+ 0
104
+ end
105
+ end
85
106
  end
86
107
 
87
108
  def to_s
@@ -143,6 +164,7 @@ module Workflow
143
164
  end
144
165
 
145
166
  module WorkflowInstanceMethods
167
+
146
168
  def current_state
147
169
  loaded_state = load_workflow_state
148
170
  res = spec.states[loaded_state.to_sym] if loaded_state
@@ -177,7 +199,12 @@ module Workflow
177
199
  run_before_transition(from, to, name, *args)
178
200
  return false if @halted
179
201
 
180
- return_value = run_action(event.action, *args) || run_action_callback(event.name, *args)
202
+ begin
203
+ return_value = run_action(event.action, *args) || run_action_callback(event.name, *args)
204
+ rescue Exception => e
205
+ run_on_error(e, from, to, name, *args)
206
+ end
207
+
181
208
  return false if @halted
182
209
 
183
210
  run_on_transition(from, to, name, *args)
@@ -236,6 +263,15 @@ module Workflow
236
263
  spec.before_transition_proc
237
264
  end
238
265
 
266
+ def run_on_error(error, from, to, event, *args)
267
+ if spec.on_error_proc
268
+ instance_exec(error, from.name, to.name, event, *args, &spec.on_error_proc)
269
+ halt(error.message)
270
+ else
271
+ raise error
272
+ end
273
+ end
274
+
239
275
  def run_on_transition(from, to, event, *args)
240
276
  instance_exec(from.name, to.name, event, *args, &spec.on_transition_proc) if spec.on_transition_proc
241
277
  end
@@ -248,9 +284,14 @@ module Workflow
248
284
  def run_action(action, *args)
249
285
  instance_exec(*args, &action) if action
250
286
  end
287
+
288
+ def has_callback?(action)
289
+ self.respond_to?(action) or self.class.private_method_defined?(action)
290
+ end
251
291
 
252
292
  def run_action_callback(action_name, *args)
253
- self.send action_name.to_sym, *args if self.respond_to?(action_name.to_sym)
293
+ action = action_name.to_sym
294
+ self.send(action, *args) if has_callback?(action)
254
295
  end
255
296
 
256
297
  def run_on_entry(state, prior_state, triggering_event, *args)
@@ -297,7 +338,7 @@ module Workflow
297
338
  # On transition the new workflow state is immediately saved in the
298
339
  # database.
299
340
  def persist_workflow_state(new_value)
300
- update_attribute self.class.workflow_column, new_value
341
+ update_attributes self.class.workflow_column => new_value
301
342
  end
302
343
 
303
344
  private
@@ -51,8 +51,9 @@ class Article < ActiveRecord::Base
51
51
  }
52
52
  end
53
53
 
54
- singleton.send :define_method, :validate, &validations
55
- halt! "Event[#{triggering_event}]'s transitions_to[#{to}] is not valid." if self.invalid?
54
+ singleton.send :define_method, :validate_for_transition, &validations
55
+ validate_for_transition
56
+ halt! "Event[#{triggering_event}]'s transitions_to[#{to}] is not valid." unless self.errors.empty?
56
57
  end
57
58
  end
58
59
  end
@@ -244,6 +244,17 @@ class MainTest < ActiveRecordTestCase
244
244
  assert !o.shipped?
245
245
  end
246
246
 
247
+ unless RUBY_VERSION < '1.9'
248
+ test 'compare states' do
249
+ o = assert_state 'some order', 'accepted'
250
+ assert o.current_state < :shipped
251
+ assert o.current_state > :submitted
252
+ assert_raise ArgumentError do
253
+ o.current_state > :unknown
254
+ end
255
+ end
256
+ end
257
+
247
258
  test 'correct exception for event, that is not allowed in current state' do
248
259
  o = assert_state 'some order', 'accepted'
249
260
  assert_raise Workflow::NoTransitionAllowed do
@@ -268,8 +279,36 @@ class MainTest < ActiveRecordTestCase
268
279
  end
269
280
  state :two
270
281
  end
282
+
283
+ private
284
+ def another_transition(args)
285
+ args.another_tran
286
+ end
287
+ end
288
+ a = c.new
289
+ a.my_transition!(args)
290
+ end
291
+
292
+ test '#53 Support for private transition callbacks' do
293
+ args = mock()
294
+ args.expects(:log).once
295
+ c = Class.new
296
+ c.class_eval do
297
+ include Workflow
298
+ workflow do
299
+ state :new do
300
+ event :assign, :transitions_to => :assigned
301
+ end
302
+ state :assigned
303
+ end
304
+
305
+ private
306
+ def assign(args)
307
+ args.log('Assigned')
308
+ end
271
309
  end
272
- c.new.my_transition!(args)
310
+ a = c.new
311
+ a.assign!(args)
273
312
  end
274
313
 
275
314
  test 'Single table inheritance (STI)' do
@@ -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
@@ -4,26 +4,19 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{workflow}
8
- s.version = "0.8.1"
7
+ s.name = "workflow"
8
+ s.version = "0.8.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Vladimir Dobriakov"]
12
- s.date = %q{2011-08-20}
13
- s.description = %q{ Workflow is a finite-state-machine-inspired API for modeling and interacting
14
- with what we tend to refer to as 'workflow'.
15
-
16
- * nice DSL to describe your states, events and transitions
17
- * robust integration with ActiveRecord and non relational data stores
18
- * various hooks for single transitions, entering state etc.
19
- * convenient access to the workflow specification: list states, possible events
20
- for particular state
21
- }
22
- s.email = %q{vladimir@geekq.net}
12
+ s.date = "2012-12-04"
13
+ s.description = " Workflow is a finite-state-machine-inspired API for modeling and interacting\n with what we tend to refer to as 'workflow'.\n\n * nice DSL to describe your states, events and transitions\n * robust integration with ActiveRecord and non relational data stores\n * various hooks for single transitions, entering state etc.\n * convenient access to the workflow specification: list states, possible events\n for particular state\n"
14
+ s.email = "vladimir@geekq.net"
23
15
  s.extra_rdoc_files = [
24
16
  "README.markdown"
25
17
  ]
26
18
  s.files = [
19
+ "Gemfile",
27
20
  "MIT-LICENSE",
28
21
  "README.markdown",
29
22
  "Rakefile",
@@ -34,26 +27,50 @@ Gem::Specification.new do |s|
34
27
  "test/couchtiny_example.rb",
35
28
  "test/main_test.rb",
36
29
  "test/multiple_workflows_test.rb",
30
+ "test/on_error_test.rb",
37
31
  "test/readme_example.rb",
38
32
  "test/test_helper.rb",
39
33
  "test/without_active_record_test.rb",
40
34
  "workflow.gemspec",
41
35
  "workflow.rb"
42
36
  ]
43
- s.homepage = %q{http://www.geekq.net/workflow/}
37
+ s.homepage = "http://www.geekq.net/workflow/"
44
38
  s.require_paths = ["lib"]
45
- s.rubyforge_project = %q{workflow}
46
- s.rubygems_version = %q{1.3.6}
47
- s.summary = %q{A replacement for acts_as_state_machine.}
39
+ s.rubyforge_project = "workflow"
40
+ s.rubygems_version = "1.8.24"
41
+ s.summary = "A replacement for acts_as_state_machine."
48
42
 
49
43
  if s.respond_to? :specification_version then
50
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
44
  s.specification_version = 3
52
45
 
53
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<workflow>, [">= 0"])
48
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
49
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
50
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
51
+ s.add_development_dependency(%q<rake>, [">= 0"])
52
+ s.add_development_dependency(%q<mocha>, [">= 0"])
53
+ s.add_development_dependency(%q<activerecord>, [">= 0"])
54
+ s.add_development_dependency(%q<sqlite3>, [">= 0"])
54
55
  else
56
+ s.add_dependency(%q<workflow>, [">= 0"])
57
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
58
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
59
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
60
+ s.add_dependency(%q<rake>, [">= 0"])
61
+ s.add_dependency(%q<mocha>, [">= 0"])
62
+ s.add_dependency(%q<activerecord>, [">= 0"])
63
+ s.add_dependency(%q<sqlite3>, [">= 0"])
55
64
  end
56
65
  else
66
+ s.add_dependency(%q<workflow>, [">= 0"])
67
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
68
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
69
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
70
+ s.add_dependency(%q<rake>, [">= 0"])
71
+ s.add_dependency(%q<mocha>, [">= 0"])
72
+ s.add_dependency(%q<activerecord>, [">= 0"])
73
+ s.add_dependency(%q<sqlite3>, [">= 0"])
57
74
  end
58
75
  end
59
76
 
metadata CHANGED
@@ -1,32 +1,157 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: workflow
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 8
8
- - 1
9
- version: 0.8.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.3
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Vladimir Dobriakov
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-08-20 00:00:00 +02:00
18
- default_executable:
19
- dependencies: []
20
-
21
- description: " Workflow is a finite-state-machine-inspired API for modeling and interacting\n with what we tend to refer to as 'workflow'.\n\n * nice DSL to describe your states, events and transitions\n * robust integration with ActiveRecord and non relational data stores\n * various hooks for single transitions, entering state etc.\n * convenient access to the workflow specification: list states, possible events\n for particular state\n"
12
+ date: 2012-12-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: workflow
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rdoc
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3.12'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3.12'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: jeweler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 1.8.4
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.8.4
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: mocha
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: activerecord
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
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
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: sqlite3
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description: ! " Workflow is a finite-state-machine-inspired API for modeling and
143
+ interacting\n with what we tend to refer to as 'workflow'.\n\n * nice DSL
144
+ to describe your states, events and transitions\n * robust integration with ActiveRecord
145
+ and non relational data stores\n * various hooks for single transitions, entering
146
+ state etc.\n * convenient access to the workflow specification: list states,
147
+ possible events\n for particular state\n"
22
148
  email: vladimir@geekq.net
23
149
  executables: []
24
-
25
150
  extensions: []
26
-
27
- extra_rdoc_files:
151
+ extra_rdoc_files:
28
152
  - README.markdown
29
- files:
153
+ files:
154
+ - Gemfile
30
155
  - MIT-LICENSE
31
156
  - README.markdown
32
157
  - Rakefile
@@ -37,40 +162,37 @@ files:
37
162
  - test/couchtiny_example.rb
38
163
  - test/main_test.rb
39
164
  - test/multiple_workflows_test.rb
165
+ - test/on_error_test.rb
40
166
  - test/readme_example.rb
41
167
  - test/test_helper.rb
42
168
  - test/without_active_record_test.rb
43
169
  - workflow.gemspec
44
170
  - workflow.rb
45
- has_rdoc: true
46
171
  homepage: http://www.geekq.net/workflow/
47
172
  licenses: []
48
-
49
173
  post_install_message:
50
174
  rdoc_options: []
51
-
52
- require_paths:
175
+ require_paths:
53
176
  - lib
54
- required_ruby_version: !ruby/object:Gem::Requirement
55
- requirements:
56
- - - ">="
57
- - !ruby/object:Gem::Version
58
- segments:
59
- - 0
60
- version: "0"
61
- required_rubygems_version: !ruby/object:Gem::Requirement
62
- requirements:
63
- - - ">="
64
- - !ruby/object:Gem::Version
65
- segments:
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ none: false
179
+ requirements:
180
+ - - ! '>='
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ segments:
66
184
  - 0
67
- version: "0"
185
+ hash: 3639477061676612937
186
+ required_rubygems_version: !ruby/object:Gem::Requirement
187
+ none: false
188
+ requirements:
189
+ - - ! '>='
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
68
192
  requirements: []
69
-
70
193
  rubyforge_project: workflow
71
- rubygems_version: 1.3.6
194
+ rubygems_version: 1.8.24
72
195
  signing_key:
73
196
  specification_version: 3
74
197
  summary: A replacement for acts_as_state_machine.
75
198
  test_files: []
76
-