module MiniTest::Spec::DSL

def after type = nil, &block

def after type = nil, &block
  define_method :teardown do
    self.instance_eval(&block)
    super()
  end
end

def before type = nil, &block

def before type = nil, &block
  define_method :setup do
    super()
    self.instance_eval(&block)
  end
end

def children

def children
  @children ||= []
end

def create name, desc # :nodoc:

:nodoc:
def create name, desc # :nodoc:
  cls = Class.new(self) do
    @name = name
    @desc = desc
    nuke_test_methods!
  end
  children << cls
  cls
end

def describe_stack # :nodoc:

:nodoc:
def describe_stack # :nodoc:
  Thread.current[:describe_stack] ||= []
end

def it desc = "anonymous", &block

def it desc = "anonymous", &block
  block ||= proc { skip "(no tests defined)" }
  @specs ||= 0
  @specs += 1
  name = "test_%04d_%s" % [ @specs, desc ]
  define_method name, &block
  self.children.each do |mod|
    mod.send :undef_method, name if mod.public_method_defined? name
  end
  name
end

def let name, &block

def let name, &block
  define_method name do
    @_memoized ||= {}
    @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
  end
end

def name # :nodoc:

:nodoc:
def name # :nodoc:
  defined?(@name) ? @name : super
end

def nuke_test_methods! # :nodoc:

:nodoc:
def nuke_test_methods! # :nodoc:
  self.public_instance_methods.grep(/^test_/).each do |name|
    self.send :undef_method, name
  end
end

def register_spec_type(*args, &block)

def register_spec_type(*args, &block)
  if block then
    matcher, klass = block, args.first
  else
    matcher, klass = *args
  end
  TYPES.unshift [matcher, klass]
end

def spec_type desc

def spec_type desc
  TYPES.find { |matcher, klass|
    if matcher.respond_to? :call then
      matcher.call desc
    else
      matcher === desc.to_s
    end
  }.last
end

def subject &block

def subject &block
  let :subject, &block
end

def to_s # :nodoc:

:nodoc:
def to_s # :nodoc:
  name # Can't alias due to 1.8.7, not sure why
end