class Shoulda::Context

:nodoc:

def am_subcontext?

def am_subcontext?
  parent.is_a?(self.class) # my parent is the same class as myself.
end

def build

def build
  shoulds.each do |should|
    create_test_from_should_hash(should)
  end
  subcontexts.each { |context| context.build }
  print_should_eventuallys
end

def context(name, &blk)

def context(name, &blk)
  self.subcontexts << Context.new(name, self, &blk)
end

def create_test_from_should_hash(should)

def create_test_from_should_hash(should)
  test_name = ["test:", full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym
  if test_unit_class.instance_methods.include?(test_name.to_s)
    warn "  * WARNING: '#{test_name}' is already defined"
  end
  context = self
  test_unit_class.send(:define_method, test_name) do
    begin
      context.run_parent_setup_blocks(self)
      should[:before].bind(self).call if should[:before]
      context.run_current_setup_blocks(self)
      should[:block].bind(self).call
    ensure
      context.run_all_teardown_blocks(self)
    end
  end
end

def full_name

def full_name
  parent_name = parent.full_name if am_subcontext?
  return [parent_name, name].join(" ").strip
end

def initialize(name, parent, &blk)

def initialize(name, parent, &blk)
  Shoulda.add_context(self)
  self.name               = name
  self.parent             = parent
  self.setup_blocks       = []
  self.teardown_blocks    = []
  self.shoulds            = []
  self.should_eventuallys = []
  self.subcontexts        = []
  merge_block(&blk)
  Shoulda.remove_context
end

def merge_block(&blk)

def merge_block(&blk)
  blk.bind(self).call
end

def method_missing(method, *args, &blk)

def method_missing(method, *args, &blk)
  test_unit_class.send(method, *args, &blk)
end

def print_should_eventuallys

def print_should_eventuallys
  should_eventuallys.each do |should|
    test_name = [full_name, "should", "#{should[:name]}. "].flatten.join(' ')
    puts "  * DEFERRED: " + test_name
  end
end

def run_all_setup_blocks(binding)

def run_all_setup_blocks(binding)
  run_parent_setup_blocks(binding)
  run_current_setup_blocks(binding)
end

def run_all_teardown_blocks(binding)

def run_all_teardown_blocks(binding)
  teardown_blocks.reverse.each do |teardown_block|
    teardown_block.bind(binding).call
  end
  self.parent.run_all_teardown_blocks(binding) if am_subcontext?
end

def run_current_setup_blocks(binding)

def run_current_setup_blocks(binding)
  setup_blocks.each do |setup_block|
    setup_block.bind(binding).call
  end
end

def run_parent_setup_blocks(binding)

def run_parent_setup_blocks(binding)
  self.parent.run_all_setup_blocks(binding) if am_subcontext?
end

def setup(&blk)

def setup(&blk)
  self.setup_blocks << blk
end

def should(name, options = {}, &blk)

def should(name, options = {}, &blk)
  if block_given?
    self.shoulds << { :name => name, :before => options[:before], :block => blk }
  else
   self.should_eventuallys << { :name => name }
 end
end

def should_eventually(name, &blk)

def should_eventually(name, &blk)
  self.should_eventuallys << { :name => name, :block => blk }
end

def teardown(&blk)

def teardown(&blk)
  self.teardown_blocks << blk
end

def test_unit_class

def test_unit_class
  am_subcontext? ? parent.test_unit_class : parent
end