Skip to content

Commit

Permalink
ActiveRecord now passing but I've broken the rest of the tests
Browse files Browse the repository at this point in the history
  • Loading branch information
markmansour committed Jan 9, 2009
1 parent 269ee0d commit 9ee3fcf
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 80 deletions.
54 changes: 39 additions & 15 deletions lib/workflow.rb
Expand Up @@ -8,7 +8,7 @@ def self.logger() @@logger; end
def logger() @@logger; end

WORKFLOW_DEFAULT_LOGGER = Logger.new(STDERR)
WORKFLOW_DEFAULT_LOGGER.level = Logger::WARN
WORKFLOW_DEFAULT_LOGGER.level = Logger::DEBUG

@@specifications = {}

Expand Down Expand Up @@ -66,23 +66,23 @@ def initialize(attributes = nil)
initialize_before_workflow(attributes)
@workflow = Workflow.new(self.class)
@workflow.bind_to(self)
puts "after initialize the workflow state is #{self.workflow_state}"
self.workflow_state = Workflow.new(self.class).state.to_s if workflow_state.nil?
puts "1 within initialize #{self.workflow_state.inspect}"
end

def after_find
puts "1 within after_find #{self.workflow_state.inspect}"
puts "class of #{self.workflow_state.class}"
Workflow.logger.debug "after find called"
@workflow = if workflow_state.nil?
Workflow.new(self.class)
else
Workflow.reconstitute(workflow_state.to_sym, self.class)
end
puts "1 within after_find #{self.workflow_state}"
@workflow.bind_to(self)
end

before_save :workflow_before_save # chain the before save method

def workflow_before_save
Workflow.logger.debug "before save called"
self.workflow_state = @workflow.state.to_s
puts "2 within after_find #{self.workflow_state}"
end
end
end
Expand Down Expand Up @@ -132,6 +132,7 @@ def blat(meta = {}, &specification)
private

def state(name, meta = {:meta => {}}, &events_and_etc)
puts "**** This one"
Workflow.logger.debug "Defining state(#{name}) for #{self}"
# meta[:meta] to keep the API consistent..., gah
self.states << State.new(name, meta[:meta])
Expand Down Expand Up @@ -163,31 +164,39 @@ def scoped_state
class Instance

class TransitionHalted < Exception

attr_reader :halted_because

def initialize(msg = nil)
@halted_because = msg
super msg
end

end

attr_accessor :states, :meta, :current_state, :on_transition, :context

def initialize(states, on_transition, meta = {}, reconstitute_at = nil)
Workflow.logger.debug "Creating workflow instance"
@states, @on_transition, @meta = states, on_transition, meta
@context = self
puts "in the instance init the context is #{context}, #{@context}"
if reconstitute_at.nil?
transition(nil, states.first, nil)
else
puts "Instance.init = start"
self.current_state = states(reconstitute_at)
puts "Instance.init = end"
end
end

def current_state=(var)
puts "setting state to #{var}"
puts "1 self is #{self}"
puts "2 self.context is #{self.context}"
puts "3 wfs is #{self.context.workflow_state}" if self.context
@current_state=var
end

def state(fetch = nil)
# puts "calling state(#{fetch.inspect})"
puts "calling state(#{fetch.inspect})"
if fetch
states(fetch)
else
Expand Down Expand Up @@ -222,6 +231,7 @@ def method_missing(name, *args)

def bind_to(another_context)
self.context = another_context
puts "setting #{self}.context to #{another_context}"
patch_context(another_context) if another_context != self
end

Expand Down Expand Up @@ -260,11 +270,11 @@ def patch_context(context)
alias :respond_to_before_workflow :respond_to?

# rails 2.2 is stricter about method_missing, now we need respond_to
def respond_to?(method)
def respond_to?(method, include_private=false)
if potential_methods.include?(method.to_sym)
return true
else
respond_to_before_workflow(method)
respond_to_before_workflow(method, include_private)
end
end

Expand All @@ -276,8 +286,12 @@ def method_missing(method, *args)
# for example, perhaps a NoMethodError is raised in an on_entry block or similar.
# "potential_methods" should probably be calculated elsewhere, not per invocation
if potential_methods.include?(method.to_sym)
@workflow.send(method, *args)
puts "MM: sending #{method} to @workflow"
result = @workflow.send(method, *args)
puts "MM: result was #{result}"
result
else
puts "MM: calling workflow's method missing"
method_missing_before_workflow(method, *args)
end
end
Expand Down Expand Up @@ -326,6 +340,16 @@ def halt!(reason = nil)
def transition(from, to, name, *args)
run_on_exit(from, to, name, *args)
self.current_state = to
if @context
puts "TRANSITION: wfs was #{@context.workflow_state}"
else
puts "TRANSITION: CONTEXT NOT SET"
end
@context.workflow_state = to.name.to_s if @context # may not have been defined when bind_to is called
puts "TRANSITION: wfs is #{@context.workflow_state}" if @context
puts "***** context is #{@context}"
puts "***** current_state is #{current_state}"
puts "***** workflow state is #{@context.workflow_state} and current state is #{to.name}" if @context
run_on_entry(to, from, name, *args)
end

Expand Down
21 changes: 19 additions & 2 deletions specs/active_record_spec.rb
Expand Up @@ -88,13 +88,31 @@ class SubItem < Item
end

it 'default to first state if workflow_state is nil in the database' do
@item.next # go to second
@item.save
@item.connection.execute("update items set workflow_state = null where id = #{@item.id}")
@item = Item.find(@item.id)
@item.workflow.state.should == :first
end

it 'should keep all state fields in sync' do
@item.state.should == :first
@item.workflow.state.should == :first
@item.workflow.current_state.name.should == :first
@item.workflow_state.should == "first"

@item.next # go to second
@item.state.should == :second
@item.workflow.state.should == :second
@item.workflow.current_state.name.should == :second
@item.workflow_state.should == "second"

@item.next # go to third
@item.state.should == :third
@item.workflow.state.should == :third
@item.workflow.current_state.name.should == :third
@item.workflow_state.should == "third"
end

it 'behaves well with the override of initialize'
it 'can use a custom field for serializing the current state to'

Expand Down Expand Up @@ -147,7 +165,6 @@ class SubItem < Item
def standard_tests(ar_object)
ar_object.workflow.should be_kind_of(Workflow::Instance)
ar_object.state(ar_object.state).events.should_not be_empty
ar_object.should respond_to(:workflow_before_save)
ar_object.should respond_to(:after_find)
end
end

0 comments on commit 9ee3fcf

Please sign in to comment.