Skip to content

Commit

Permalink
Use the standard visualizations for initial (open arrow) and final (d…
Browse files Browse the repository at this point in the history
…ouble circle) states

Fix states with only outgoing loopbacks not being considered final
  • Loading branch information
obrie committed Mar 11, 2009
1 parent 2b319f9 commit b2b841d
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rdoc
@@ -1,5 +1,6 @@
== master

* Use the standard visualizations for initial (open arrow) and final (double circle) states
* Highlight final states in GraphViz drawings

== 0.6.2 / 2009-03-08
Expand Down
Binary file modified examples/AutoShop_state.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/Car_state.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/TrafficLight_state.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/Vehicle_state.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 8 additions & 4 deletions lib/state_machine/state.rb
Expand Up @@ -75,7 +75,7 @@ def final?
!machine.events.any? do |event|
event.guards.any? do |guard|
guard.state_requirements.any? do |requirement|
requirement[:from].matches?(name)
requirement[:from].matches?(name) && !requirement[:to].matches?(name, :from => name)
end
end
end
Expand Down Expand Up @@ -195,13 +195,17 @@ def call(object, method, *args, &block)
#
# The actual node generated on the graph will be returned.
def draw(graph)
graph.add_node(name ? name.to_s : 'nil',
node = graph.add_node(name ? name.to_s : 'nil',
:label => description,
:width => '1',
:height => '1',
:shape => initial? ? 'doublecircle' : 'ellipse',
:penwidth => final? ? '3' : '1'
:shape => final? ? 'doublecircle' : 'ellipse'
)

# Add open arrow for initial state
graph.add_edge(graph.add_node('starting_state', :shape => 'point'), node) if initial?

node
end

# Generates a nicely formatted description of this state's contents.
Expand Down
43 changes: 27 additions & 16 deletions test/unit/state_test.rb
Expand Up @@ -291,6 +291,14 @@ def test_should_be_final_with_input_transitions

assert @state.final?
end

def test_should_be_final_with_loopback
@machine.event :ignite do
transition :parked => same
end

assert @state.final?
end
end

class StateNotFinalTest < Test::Unit::TestCase
Expand Down Expand Up @@ -322,14 +330,6 @@ def test_should_not_be_final_with_outgoing_blacklist_transitions

assert !@state.final?
end

def test_should_not_be_final_with_loopback
@machine.event :ignite do
transition :parked => same
end

assert !@state.final?
end
end

class StateWithConflictingHelpersTest < Test::Unit::TestCase
Expand Down Expand Up @@ -591,6 +591,9 @@ def test_should_pass_both_arguments_and_blocks_through
class StateDrawingTest < Test::Unit::TestCase
def setup
@machine = StateMachine::Machine.new(Class.new)
@machine.event :ignite do
transition :parked => :idling
end
@state = StateMachine::State.new(@machine, :parked, :value => 1)

graph = GraphViz.new('G')
Expand Down Expand Up @@ -621,14 +624,22 @@ def test_should_use_description_as_label
class StateDrawingInitialTest < Test::Unit::TestCase
def setup
@machine = StateMachine::Machine.new(Class.new)
@machine.event :ignite do
transition :parked => :idling
end
@state = StateMachine::State.new(@machine, :parked, :initial => true)

graph = GraphViz.new('G')
@node = @state.draw(graph)
@graph = GraphViz.new('G')
@node = @state.draw(@graph)
end

def test_should_use_doublecircle_as_shape
assert_equal 'doublecircle', @node['shape']
def test_should_use_ellipse_as_shape
assert_equal 'ellipse', @node['shape']
end

def test_should_draw_edge_between_point_and_state
assert_equal 2, @graph.node_count
assert_equal 1, @graph.edge_count
end
end

Expand Down Expand Up @@ -680,8 +691,8 @@ def setup
@node = @state.draw(graph)
end

def test_should_set_penwidth_to_one
assert_equal '1', @node['penwidth']
def test_should_use_ellipse_as_shape
assert_equal 'ellipse', @node['shape']
end
end

Expand All @@ -694,8 +705,8 @@ def setup
@node = @state.draw(graph)
end

def test_should_set_penwidth_to_three
assert_equal '3', @node['penwidth']
def test_should_use_doublecircle_as_shape
assert_equal 'doublecircle', @node['shape']
end
end
rescue LoadError
Expand Down

0 comments on commit b2b841d

Please sign in to comment.