davidlee-state-fu 0.0.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. data/README.textile +13 -1
  2. data/lib/state-fu.rb +4 -3
  3. data/lib/state_fu/active_support_lite/array/access.rb +53 -0
  4. data/lib/state_fu/active_support_lite/array/conversions.rb +196 -0
  5. data/lib/state_fu/active_support_lite/array/extract_options.rb +20 -0
  6. data/lib/state_fu/active_support_lite/array/grouping.rb +106 -0
  7. data/lib/state_fu/active_support_lite/array/random_access.rb +12 -0
  8. data/lib/state_fu/active_support_lite/array/wrapper.rb +24 -0
  9. data/lib/state_fu/active_support_lite/array.rb +7 -0
  10. data/lib/state_fu/active_support_lite/blank.rb +58 -0
  11. data/lib/state_fu/active_support_lite/cattr_reader.rb +54 -0
  12. data/lib/state_fu/active_support_lite/inheritable_attributes.rb +1 -0
  13. data/lib/state_fu/active_support_lite/keys.rb +52 -0
  14. data/lib/state_fu/active_support_lite/object.rb +6 -0
  15. data/lib/state_fu/active_support_lite/string.rb +33 -0
  16. data/lib/state_fu/active_support_lite/symbol.rb +15 -0
  17. data/lib/state_fu/binding.rb +113 -58
  18. data/lib/state_fu/core_ext.rb +12 -13
  19. data/lib/state_fu/event.rb +4 -4
  20. data/lib/state_fu/exceptions.rb +12 -0
  21. data/lib/state_fu/helper.rb +74 -12
  22. data/lib/state_fu/lathe.rb +15 -0
  23. data/lib/state_fu/machine.rb +17 -25
  24. data/lib/state_fu/mock_transition.rb +38 -0
  25. data/lib/state_fu/persistence/active_record.rb +2 -2
  26. data/lib/state_fu/persistence/attribute.rb +4 -4
  27. data/lib/state_fu/persistence/base.rb +1 -1
  28. data/lib/state_fu/sprocket.rb +4 -0
  29. data/lib/state_fu/state.rb +4 -4
  30. data/lib/state_fu/transition.rb +24 -22
  31. data/spec/helper.rb +5 -3
  32. data/spec/integration/binding_extension_spec.rb +41 -0
  33. data/spec/integration/dynamic_requirement_spec.rb +160 -0
  34. data/spec/integration/example_01_document_spec.rb +2 -1
  35. data/spec/integration/lathe_extension_spec.rb +67 -0
  36. data/spec/integration/requirement_reflection_spec.rb +71 -11
  37. data/spec/integration/temp_spec.rb +17 -0
  38. data/spec/integration/transition_spec.rb +31 -19
  39. data/spec/units/binding_spec.rb +6 -0
  40. data/spec/units/event_spec.rb +6 -5
  41. data/spec/units/lathe_spec.rb +4 -2
  42. metadata +40 -17
@@ -5,8 +5,7 @@ module StateFu
5
5
  def self.prepare_field( klass, field_name )
6
6
  _field_name = field_name
7
7
  klass.send :before_save, :state_fu!
8
- # validates_presence_of _field_name
9
-
8
+ # validates_presence_of _field_name
10
9
  end
11
10
 
12
11
  private
@@ -19,6 +18,7 @@ module StateFu
19
18
  end
20
19
 
21
20
  def write_attribute( string_value )
21
+ # Logger.warn(" :write_attribute,#{ field_name},#{ string_value} \n=========================================================")
22
22
  object.send( :write_attribute, field_name, string_value )
23
23
  end
24
24
 
@@ -4,7 +4,7 @@ module StateFu
4
4
 
5
5
  def self.prepare_field( klass, field_name )
6
6
  # ensure getter exists
7
- unless klass.instance_methods.include?( field_name )
7
+ unless klass.instance_methods.map(&:to_sym).include?( field_name.to_sym )
8
8
  Logger.info "Adding attr_reader :#{field_name} for #{klass}"
9
9
  _field_name = field_name
10
10
  klass.class_eval do
@@ -14,7 +14,7 @@ module StateFu
14
14
  end
15
15
 
16
16
  # ensure setter exists
17
- unless klass.instance_methods.include?( "#{field_name}=" )
17
+ unless klass.instance_methods.map(&:to_sym).include?( :"#{field_name}=" )
18
18
  Logger.info "Adding attr_writer :#{field_name}= for #{klass}"
19
19
  _field_name = field_name
20
20
  klass.class_eval do
@@ -31,13 +31,13 @@ module StateFu
31
31
 
32
32
  def read_attribute
33
33
  string = object.send( field_name )
34
- Logger.info "Read attribute #{field_name}, got #{string} for #{object}"
34
+ Logger.info "Read attribute #{field_name}, got #{string.inspect} for #{object.inspect}"
35
35
  string
36
36
  end
37
37
 
38
38
  def write_attribute( string_value )
39
39
  writer_method = "#{field_name}="
40
- Logger.info "Writing attribute #{field_name} -> #{string_value} for #{object}"
40
+ Logger.info "Writing attribute #{field_name} -> #{string_value.inspect} for #{object.inspect}"
41
41
  object.send( writer_method, string_value )
42
42
  end
43
43
 
@@ -38,7 +38,7 @@ module StateFu
38
38
  Logger.info("Machine has no states: #{machine}") if machine.states.empty?
39
39
  else
40
40
  persist!
41
- Logger.debug("Object resumes at #{current_state.name}: #{object}")
41
+ # Logger.debug("Object #{object} resuming #{binding.method_name} at #{current_state.name}: #{object.inspect}")
42
42
  end
43
43
  end
44
44
 
@@ -22,6 +22,10 @@ module StateFu
22
22
  StateFu::Lathe.new( machine, self, options, &block )
23
23
  end
24
24
 
25
+ def deep_copy
26
+ raise NotImeplementedError # abstract
27
+ end
28
+
25
29
  end
26
30
  end
27
31
 
@@ -25,15 +25,15 @@ module StateFu
25
25
  end
26
26
  end
27
27
 
28
- def enterable_by?( binding )
28
+ def enterable_by?( binding, *args )
29
29
  entry_requirements.reject do |r|
30
- res = binding.evaluate_requirement( r )
30
+ res = binding.evaluate_requirement_with_args( r, *args )
31
31
  end.empty?
32
32
  end
33
33
 
34
- def exitable_by?( binding )
34
+ def exitable_by?( binding, *args )
35
35
  exit_requirements.reject do |r|
36
- binding.evaluate_requirement( r )
36
+ binding.evaluate_requirement_with_args( r, *args )
37
37
  end.empty?
38
38
  end
39
39
 
@@ -9,6 +9,7 @@ module StateFu
9
9
  class Transition
10
10
  include StateFu::Helper
11
11
  include ContextualEval
12
+
12
13
  attr_reader( :binding,
13
14
  :machine,
14
15
  :origin,
@@ -24,25 +25,18 @@ module StateFu
24
25
  attr_accessor :test_only, :args, :options
25
26
 
26
27
  def initialize( binding, event, target=nil, *args, &block )
28
+ @binding = binding
29
+ @machine = binding.machine
30
+ @object = binding.object
31
+ @origin = binding.current_state
32
+
27
33
  # ensure event is a StateFu::Event
28
34
  if event.is_a?( Symbol ) && e = binding.machine.events[ event ]
29
35
  event = e
30
36
  end
31
37
  raise( ArgumentError, "Not an event: #{event}" ) unless event.is_a?( StateFu::Event )
32
38
 
33
- # infer target if necessary
34
- case target
35
- when StateFu::State # good
36
- when Symbol
37
- target = binding.machine.states[ target ] ||
38
- raise( ArgumentError, "target cannot be determined: #{target.inspect}" )
39
- when NilClass
40
- unless target = event.target
41
- raise( ArgumentError, "target cannot be determined: #{target.inspect}" )
42
- end
43
- else
44
- raise ArgumentError.new( target.inspect )
45
- end
39
+ target = find_event_target( event, target ) || raise( ArgumentError, "target cannot be determined: #{target.inspect}" )
46
40
 
47
41
  # ensure target is valid for the event
48
42
  unless event.targets.include?( target )
@@ -57,10 +51,6 @@ module StateFu
57
51
  end
58
52
 
59
53
  @options = args.extract_options!.symbolize_keys!
60
- @binding = binding
61
- @machine = binding.machine
62
- @object = binding.object
63
- @origin = binding.current_state
64
54
  @target = target
65
55
  @event = event
66
56
  @args = args
@@ -79,18 +69,30 @@ module StateFu
79
69
 
80
70
  def unmet_requirements
81
71
  requirements.reject do |requirement|
82
- binding.evaluate_requirement( requirement )
72
+ binding.evaluate_requirement_with_transition( requirement, self )
73
+ end
74
+ end
75
+
76
+ def evaluate_requirement_message( name )
77
+ msg = machine.requirement_messages[name]
78
+ case msg
79
+ when String, nil
80
+ msg
81
+ when Symbol, Proc
82
+ evaluate_named_proc_or_method( msg, self )
83
+ else
84
+ raise msg.class.to_s
83
85
  end
84
86
  end
85
87
 
86
88
  def unmet_requirement_messages
87
- unmet_requirements.map do |r|
88
- binding.evaluate_requirement_message(r, self )
89
+ unmet_requirements.map do |requirement|
90
+ evaluate_requirement_message( requirement )
89
91
  end
90
92
  end
91
93
 
92
94
  def check_requirements!
93
- raise RequirementError.new( unmet_requirements.inspect ) unless requirements_met?
95
+ raise RequirementError.new( self, unmet_requirements.inspect ) unless requirements_met?
94
96
  end
95
97
 
96
98
  def requirements_met?
@@ -117,7 +119,7 @@ module StateFu
117
119
  end
118
120
 
119
121
  def run_hook( hook )
120
- evaluate_named_proc_or_method( hook )
122
+ evaluate_named_proc_or_method( hook, self )
121
123
  end
122
124
 
123
125
  def halt!( message )
data/spec/helper.rb CHANGED
@@ -28,8 +28,9 @@ module MySpecHelper
28
28
 
29
29
  def prepare_active_record( options={}, &migration )
30
30
  begin
31
+ require 'activesupport'
31
32
  require 'active_record'
32
- rescue MissingSourceFile => e
33
+ rescue LoadError => e
33
34
  pending "skipping specifications due to load error: #{e}"
34
35
  return false
35
36
  end
@@ -81,9 +82,10 @@ module MySpecHelper
81
82
  end
82
83
 
83
84
  def set_method_arity( object, method_name, needed_arity = 1 )
84
- a = Object.new
85
+ a = Proc.new {}
85
86
  stub( a ).arity() { needed_arity }
86
- stub( object ).method(method_name) { a }
87
+ stub( object ).method( anything ) { |x| object.send(x) }
88
+ stub( object ).method( method_name ) { a }
87
89
  end
88
90
 
89
91
  end
@@ -0,0 +1,41 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../helper")
2
+
3
+ module BenchGrinder
4
+ def snark
5
+ end
6
+ end
7
+
8
+ describe "extending StateFu::Lathe" do
9
+ include MySpecHelper
10
+
11
+ describe "helpers" do
12
+ before do
13
+ reset!
14
+ make_pristine_class('Klass')
15
+ @machine = Klass.machine() do
16
+ state :init
17
+ end
18
+ end # before
19
+
20
+ describe "lathe.helper" do
21
+ it "should add the arguments to the machine's collection of helpers" do
22
+ @machine.should respond_to(:helpers)
23
+ @machine.helpers.should be_empty
24
+ @machine.lathe do
25
+ helper :bench_grinder
26
+ end
27
+ @machine.helpers.should_not be_empty
28
+ @machine.helpers.should include(:bench_grinder)
29
+ end
30
+
31
+ it "should extend the binding with the helper's methods" do
32
+ @machine.lathe do
33
+ helper :bench_grinder
34
+ end
35
+ @machine.helpers.should include(:bench_grinder)
36
+ @obj = Klass.new
37
+ @obj.state_fu.should respond_to(:snark)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,160 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../helper")
2
+
3
+ module MySpecHelper
4
+ module DynamicTransitionObjectInstanceMethods
5
+ def method_which_expects_nothing_passed_to_it()
6
+ true
7
+ end
8
+
9
+ def method_which_requires_one_arg( t )
10
+ t.args.length == 1
11
+ end
12
+
13
+ def given_any_arg?( t = nil )
14
+ t.is_a?( StateFu::Transition ) && !t.args.empty?
15
+ end
16
+
17
+ def falsey?( t = nil )
18
+ t.is_a?( StateFu::Transition ) && !t.args.empty? && t.args.first == false
19
+ end
20
+
21
+ def truthy?( t = nil )
22
+ t.is_a?( StateFu::Transition ) && !t.args.empty? && t.args.first == true
23
+ end
24
+
25
+ def method_which_always_returns_true( t = nil )
26
+ true
27
+ end
28
+
29
+ def method_which_always_returns_false( t = nil )
30
+ false
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "Transition requirement evaluation with dynamic conditions" do
36
+ include MySpecHelper
37
+
38
+ before do
39
+ reset!
40
+ make_pristine_class("Klass")
41
+
42
+ Klass.send :include, MySpecHelper::DynamicTransitionObjectInstanceMethods
43
+
44
+ @machine = Klass.machine do
45
+
46
+ state :default do
47
+ requires :method_which_requires_one_arg, :on => [:entry, :exit]
48
+
49
+ cycle do
50
+ requires :method_which_requires_one_arg
51
+ end
52
+
53
+ event :truthify, :to => :truth do
54
+ requires :truthy?
55
+ end
56
+
57
+ event :falsify, :to => :falsehood do
58
+ requires :falsey?
59
+ requires :method_which_expects_nothing_passed_to_it
60
+ end
61
+
62
+ #event :impossify, :to => :impossible do
63
+ # requires :method_which_always_returns_false
64
+ #end
65
+
66
+ end
67
+ end
68
+ @obj = Klass.new
69
+ @fu = @obj.state_fu # binding
70
+ # Because RR changes the arity of the method on @obj we need to do this:
71
+ # stub( @fu ).limit_arguments( anything ) { |t| t }
72
+ end
73
+
74
+ describe "a requirement that the transition was given one arg" do
75
+
76
+ describe "object.cycle?()" do
77
+
78
+ it "should return false given no args" do
79
+ @fu.cycle?().should == false
80
+ end
81
+
82
+ it "should be true given one arg" do
83
+ @fu.cycle?(1).should == true
84
+ end
85
+
86
+ it "should be false given two args" do
87
+ @fu.cycle?(1,2).should == false
88
+ end
89
+ end
90
+
91
+ it "should evaluate the requirement by passing it a transition when requirements_met? is called" do
92
+ t = @fu.cycle()
93
+ # mock.proxy( @fu ).evaluate_requirement_with_transition(:method_which_requires_one_arg, t ).at_least(2)
94
+ t.requirements_met?.should == false
95
+ t.args = [1]
96
+ t.requirements_met?.should == true
97
+ end
98
+
99
+ describe "binding.evaluate_requirement_with_args" do
100
+
101
+ end
102
+
103
+ describe "valid_transitions" do
104
+ describe "given no arguments" do
105
+ it "should return {}" do
106
+ @fu.valid_transitions.should == {}
107
+ end
108
+ end
109
+
110
+ it "should pass each requirement method a transition object with no args" do
111
+ end
112
+
113
+ it "should call method_which_requires_one_arg given call_on_object_with_optional_args(:method_which_requires_one_arg .. )" do
114
+ t = @fu.blank_mock_transition( :first_arg )
115
+ @obj.respond_to?(:method_which_requires_one_arg).should be_true
116
+ meth = @obj.method(:method_which_requires_one_arg)
117
+ meth.arity.should == 1
118
+ @fu.limit_arguments( meth, t ).should == [t]
119
+ @fu.call_on_object_with_optional_args( :method_which_requires_one_arg, t )
120
+ end
121
+
122
+ it "should call method_which_requires_one_arg with a mock transition with one argument" do
123
+ t = @fu.blank_mock_transition( :first_arg )
124
+ # mock( @obj ).method_which_requires_one_arg( t )
125
+ @fu.call_on_object_with_optional_args( :method_which_requires_one_arg, t ).should == true
126
+ end
127
+
128
+ it "should contain the :cycle_default event only if an arg is supplied" do
129
+ @fu.should == :default
130
+ ves = @fu.valid_events( )
131
+ ves.length.should == 0
132
+ ves = @fu.valid_events( 1 )
133
+ ves.length.should == 1
134
+ ves.first.should == @machine.events[:cycle_default]
135
+
136
+ @machine.events[:cycle_default].target.should == @fu.current_state
137
+ @fu.evaluate_requirement_with_args( :method_which_requires_one_arg ).should == false
138
+ @fu.evaluate_requirement_with_args( :method_which_requires_one_arg, 1 ).should == true
139
+ @fu.current_state.enterable_by?( @fu ).should == false
140
+ @fu.current_state.enterable_by?( @fu, 1 ).should == true
141
+
142
+ vts = @fu.valid_transitions()
143
+ vts.should be_kind_of( Hash )
144
+ vts.should be_empty
145
+ vts = @fu.valid_transitions( 1 )
146
+ vts.should_not be_empty
147
+ vts.length.should == 1
148
+ vts.keys.first.should == @machine.events[:cycle_default]
149
+ vts.values.first.should == [@machine.states[:default]]
150
+ end
151
+
152
+ it "should pass method_which_requires_one_argument() a transition with no arguments" do
153
+ # mock.proxy( @obj ).method_which_requires_one_arg( is_a(StateFu::MockTransition) ).times(3)
154
+ @fu.valid_transitions( 1 )
155
+ end
156
+
157
+ end
158
+ end
159
+
160
+ end
@@ -1,6 +1,7 @@
1
1
  require File.expand_path("#{File.dirname(__FILE__)}/../helper")
2
2
 
3
- require 'activerecord'
3
+ # require 'activesupport'
4
+ # require 'activerecord'
4
5
 
5
6
  describe "Document" do
6
7
  include MySpecHelper
@@ -0,0 +1,67 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../helper")
2
+
3
+ module BenchGrinder
4
+ def snark
5
+ end
6
+ end
7
+
8
+ describe "extending StateFu::Lathe" do
9
+ include MySpecHelper
10
+
11
+ describe "helpers" do
12
+ before do
13
+ reset!
14
+ make_pristine_class('Klass')
15
+ @machine = Klass.machine() do
16
+ state :init
17
+ end
18
+ end # before
19
+
20
+ describe "lathe.tool" do
21
+
22
+ it "should add the arguments to the machine's collection of tools" do
23
+ @machine.should respond_to(:tools)
24
+ @machine.tools.should be_empty
25
+ @machine.lathe do
26
+ tool :bench_grinder
27
+ end
28
+ @machine.tools.should_not be_empty
29
+ @machine.tools.should include(:bench_grinder)
30
+ end
31
+
32
+ it "should extend the machine's lathe" do
33
+ @machine.lathe do
34
+ tool :bench_grinder
35
+ snark()
36
+ end
37
+ @machine.lathe.should respond_to( :snark )
38
+ @machine.lathe.snark
39
+ end
40
+
41
+ it "should extend the machine's lathe for state and events" do
42
+ @machine.lathe do
43
+ tool :bench_grinder
44
+ snark()
45
+ state :grinding do
46
+ snark()
47
+ event :grind do
48
+ snark()
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ it "should not extend another machine's lathe" do
55
+ @machine.lathe do
56
+ tool :bench_grinder
57
+ snark()
58
+ end
59
+ m2 = Klass.machine(:two) do
60
+ end
61
+ lambda { m2.lathe.snark }.should raise_error( NoMethodError )
62
+ end
63
+
64
+ end # tool
65
+
66
+ end
67
+ end
@@ -9,15 +9,15 @@ describe "Transition requirement reflection" do
9
9
  make_pristine_class("Klass")
10
10
  @machine = Klass.machine do
11
11
  state :soviet_russia do
12
- requires( :papers_in_order?,
13
- :money_for_bribe?, :on => [:entry, :exit] )
12
+ requires( :papers_in_order?, :on => [:entry, :exit] )
13
+ requires( :money_for_bribe?, :on => [:entry, :exit] )
14
14
  end
15
15
 
16
16
  state :america do
17
17
  requires( :no_turban?,
18
18
  :us_visa?,
19
19
  :on => :entry )
20
- requires( :no_arrest_warrant, :on => [:entry,:exit] )
20
+ requires( :no_arrest_warrant?, :on => [:entry,:exit] )
21
21
  end
22
22
 
23
23
  state :moon do
@@ -66,18 +66,79 @@ describe "Transition requirement reflection" do
66
66
  end
67
67
  end
68
68
 
69
+ describe "flying from russia to america without one's affairs in order while wearing a turban" do
70
+ before do
71
+ mock( @obj ).us_visa?() { false }
72
+ mock( @obj ).no_turban?() { false }
73
+ mock( @obj ).no_arrest_warrant?() { false }
74
+ mock( @obj ).money_for_bribe?() { false }
75
+ mock( @obj ).papers_in_order?() { false }
76
+ end
77
+
78
+ describe "when no messages are supplied for the requirements" do
79
+ describe "given transition.unmet_requirements" do
80
+ it "should contain a list of failing requirement names as symbols" do
81
+ @obj.state_fu.catch_plane(:america).unmet_requirements.should == [ :papers_in_order?,
82
+ :money_for_bribe?,
83
+ :no_turban?,
84
+ :us_visa?,
85
+ :no_arrest_warrant? ]
86
+ end
87
+ end # unmet requirements
88
+
89
+ describe "given transition.unmet_requirement_messages" do
90
+ it "should return a list of nils" do
91
+ @obj.state_fu.catch_plane(:america).unmet_requirement_messages.should == [nil,nil,nil,nil,nil]
92
+ end
93
+ end # unmet_requirement_messages
94
+ end
95
+
96
+ describe "when a message is supplied for the money_for_bribe? entry requirement" do
97
+ before do
98
+ Klass.machine do
99
+ state :soviet_russia do
100
+ requires( :money_for_bribe?, :message => "This guard is thirsty! Do you have anything to declare?" )
101
+ end
102
+ end
103
+ end
104
+
105
+ describe "given transition.unmet_requirements" do
106
+ it "should still contain a list of failing requirement names as symbols" do
107
+ @obj.state_fu.catch_plane(:america).unmet_requirements.should == [ :papers_in_order?,
108
+ :money_for_bribe?,
109
+ :no_turban?,
110
+ :us_visa?,
111
+ :no_arrest_warrant? ]
112
+ end
113
+ end
114
+
115
+ describe "given transition.unmet_requirement_messages" do
116
+ it "should contain a list of nils plus the requirement message for money_for_bribe? as a string" do
117
+ @obj.state_fu.catch_plane(:america).unmet_requirement_messages.should == [ nil,
118
+ "This guard is thirsty! Do you have anything to declare?",
119
+ nil,
120
+ nil,
121
+ nil ]
122
+ end
123
+ end
124
+ end
125
+ end # flying with a turban
126
+
69
127
  describe "transition.unmet_requirements" do
70
128
  it "should be empty when all requirements are met" do
71
129
  @obj.state_fu.fly_spaceship(:moon).unmet_requirements.should == []
72
130
  end
73
131
 
74
- it "should contain a list of failing requirements" do
75
- mock( @obj ).spacesuit?() { false }
76
- mock( @obj ).fuel?() { false }
77
- @obj.state_fu.fly_spaceship(:moon).unmet_requirements.should == [:spacesuit?, :fuel?]
132
+ describe "when a message is supplied for the requirement" do
133
+ it "should contain a list of the requirement failure messages as strings" do
134
+ mock( @obj ).spacesuit?() { false }
135
+ mock( @obj ).fuel?() { false }
136
+ @obj.state_fu.fly_spaceship(:moon).unmet_requirements.should == [:spacesuit?, :fuel?]
137
+ end
78
138
  end
79
139
  end
80
140
 
141
+
81
142
  describe "transition.unmet_requirement_messages" do
82
143
  describe "when a string message is defined for one of two unmet_requirements" do
83
144
  before do
@@ -162,7 +223,7 @@ describe "Transition requirement reflection" do
162
223
  it "should call the method on @obj given transition.evaluate_named_proc_or_method() with the method name" do
163
224
  @obj.method( :no_spacesuit_msg_method ).arity.should == 1
164
225
  t = @obj.state_fu.fly_spaceship(:moon)
165
- x = t.evaluate_named_proc_or_method(:no_spacesuit_msg_method)
226
+ x = @obj.state_fu.evaluate_named_proc_or_method(:no_spacesuit_msg_method, t)
166
227
  @obj.arg.should == t
167
228
  x.should =~ /You can't go to the moon/
168
229
  end
@@ -170,7 +231,7 @@ describe "Transition requirement reflection" do
170
231
  it "should call t.evaluate_named_proc_or_method(:no_spacesuit_msg_method)" do
171
232
  t = @obj.state_fu.fly_spaceship(:moon)
172
233
  t.unmet_requirements.length.should == 2
173
- mock( t ).evaluate_named_proc_or_method(:no_spacesuit_msg_method) { :my_string }
234
+ mock( t ).evaluate_named_proc_or_method(:no_spacesuit_msg_method, t) { :my_string }
174
235
  messages = t.unmet_requirement_messages
175
236
  messages.should include(:my_string )
176
237
  end
@@ -183,7 +244,7 @@ describe "Transition requirement reflection" do
183
244
  end
184
245
 
185
246
  it "should return the result of the method execution as the message" do
186
- t = @obj.state_fu.fly_spaceship(:moon)
247
+ t = @obj.state_fu.fly_spaceship( :moon )
187
248
  t.unmet_requirements.length.should == 2
188
249
  messages = t.unmet_requirement_messages
189
250
  messages.length.should == 2
@@ -194,7 +255,6 @@ describe "Transition requirement reflection" do
194
255
  end # no named proc
195
256
  end # symbol message
196
257
  end # transition.unmet_requirement_messages
197
-
198
258
  end
199
259
 
200
260
 
@@ -0,0 +1,17 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../helper")
2
+
3
+ describe StateFu::State do
4
+ include MySpecHelper
5
+
6
+ it "should respond to deep_copy" do
7
+ reset!
8
+ make_pristine_class "Klass"
9
+ @machine = Klass.machine do
10
+ state :initial
11
+ end
12
+ @state = @machine.states.first
13
+ @state.should respond_to(:deep_copy)
14
+ end
15
+
16
+ end
17
+