Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Make states comparable (see README for an example).

  • Loading branch information...
commit 80eda5c085babf5a88138ef19c16dcbfa6a41fa7 1 parent 73d944e
@svoop authored
Showing with 38 additions and 3 deletions.
  1. +12 −0 README.markdown
  2. +20 −3 lib/workflow.rb
  3. +6 −0 test/main_test.rb
View
12 README.markdown
@@ -67,6 +67,18 @@ of possible events and other meta information:
@transitions_to=:awaiting_review, @name=:submit, @meta={}>},
name:new, meta{}
+On Ruby 1.9 and above, you can check whether a state comes before or
+after another state (by the order they were defined):
+
+ article.current_state
+ => being_reviewed
+ article.current_state < :accepted
+ => true
+ article.current_state >= :accepted
+ => false
+ article.between? :awaiting_review, :rejected
+ => true
+
Now we can call the submit event, which transitions to the
<tt>:awaiting_review</tt> state:
View
23 lib/workflow.rb
@@ -22,7 +22,7 @@ def state_names
def state(name, meta = {:meta => {}}, &events_and_etc)
# meta[:meta] to keep the API consistent..., gah
- new_state = Workflow::State.new(name, meta[:meta])
+ new_state = Workflow::State.new(name, self, meta[:meta])
@initial_state = new_state if @states.empty?
@states[name.to_sym] = new_state
@scoped_state = new_state
@@ -79,9 +79,25 @@ class WorkflowDefinitionError < Exception; end
class State
attr_accessor :name, :events, :meta, :on_entry, :on_exit
+ attr_reader :spec
- def initialize(name, meta = {})
- @name, @events, @meta = name, Hash.new, meta
+ def initialize(name, spec, meta = {})
+ @name, @spec, @events, @meta = name, spec, Hash.new, meta
+ end
+
+ unless RUBY_VERSION < '1.9'
+ include Comparable
+
+ def <=>(other_state)
+ states = spec.states.keys
+ if states.index(self.to_sym) < states.index(other_state.to_sym)
+ -1
+ elsif states.index(self.to_sym) > states.index(other_state.to_sym)
+ 1
+ else
+ 0
+ end
+ end
end
def to_s
@@ -143,6 +159,7 @@ def workflow(&specification)
end
module WorkflowInstanceMethods
+
def current_state
loaded_state = load_workflow_state
res = spec.states[loaded_state.to_sym] if loaded_state
View
6 test/main_test.rb
@@ -244,6 +244,12 @@ def assert_state(title, expected_state, klass = Order)
assert !o.shipped?
end
+ test 'compare states' do
+ o = assert_state 'some order', 'accepted'
+ assert o.current_state < :shipped
+ assert o.current_state > :submitted
+ end
+
test 'correct exception for event, that is not allowed in current state' do
o = assert_state 'some order', 'accepted'
assert_raise Workflow::NoTransitionAllowed do
Please sign in to comment.
Something went wrong with that request. Please try again.