2007-03-14 15:12:11 -04:00
|
|
|
module TBTestHelpers # :nodoc:
|
2007-03-14 14:12:55 -04:00
|
|
|
module Should
|
2007-03-14 15:12:11 -04:00
|
|
|
def Should.included(other) # :nodoc:
|
2007-03-14 19:05:34 -04:00
|
|
|
@@context_names = []
|
|
|
|
@@setup_blocks = []
|
|
|
|
@@teardown_blocks = []
|
2007-03-14 14:12:55 -04:00
|
|
|
end
|
|
|
|
|
2007-03-14 15:12:11 -04:00
|
|
|
# Creates a context block with the given name. The context block can contain setup, should, should_eventually, and teardown blocks.
|
2007-03-14 14:12:55 -04:00
|
|
|
def context(name, &context_block)
|
2007-03-14 19:05:34 -04:00
|
|
|
saved_setups = @@setup_blocks.dup
|
|
|
|
saved_teardowns = @@teardown_blocks.dup
|
|
|
|
saved_contexts = @@context_names.dup
|
|
|
|
|
|
|
|
@@context_names << name
|
2007-03-14 14:12:55 -04:00
|
|
|
context_block.bind(self).call
|
2007-03-14 19:05:34 -04:00
|
|
|
|
|
|
|
@@context_names = saved_contexts
|
|
|
|
@@setup_blocks = saved_setups
|
|
|
|
@@teardown_blocks = saved_teardowns
|
2007-03-14 14:12:55 -04:00
|
|
|
end
|
|
|
|
|
2007-03-14 15:12:11 -04:00
|
|
|
# Run before every should block in the current context
|
2007-03-14 14:12:55 -04:00
|
|
|
def setup(&setup_block)
|
2007-03-14 19:05:34 -04:00
|
|
|
@@setup_blocks << setup_block
|
2007-03-14 14:12:55 -04:00
|
|
|
end
|
|
|
|
|
2007-03-14 15:12:11 -04:00
|
|
|
# Run after every should block in the current context
|
2007-03-14 14:12:55 -04:00
|
|
|
def teardown(&teardown_block)
|
2007-03-14 19:05:34 -04:00
|
|
|
@@teardown_blocks << teardown_block
|
2007-03-14 14:12:55 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
# Defines a specification. Can be called either inside our outside of a context.
|
|
|
|
def should(name, opts = {}, &should_block)
|
2007-03-14 19:05:34 -04:00
|
|
|
test_name = ["test", @@context_names, "should", "#{name}"].flatten.join(' ').to_sym
|
2007-04-04 13:39:56 -04:00
|
|
|
|
|
|
|
name_defined = eval("self.instance_methods.include?('#{test_name.to_s.gsub(/['"]/, '\$1')}')", should_block.binding)
|
|
|
|
raise ArgumentError, "'#{test_name}' is already defined" and return if name_defined
|
2007-03-14 14:12:55 -04:00
|
|
|
|
2007-03-14 19:05:34 -04:00
|
|
|
setup_blocks = @@setup_blocks.dup
|
|
|
|
teardown_blocks = @@teardown_blocks.dup
|
2007-03-14 14:12:55 -04:00
|
|
|
|
|
|
|
if opts[:unimplemented]
|
2007-03-14 19:05:34 -04:00
|
|
|
define_method test_name do |*args|
|
2007-03-14 14:12:55 -04:00
|
|
|
# XXX find a better way of doing this.
|
|
|
|
assert true
|
|
|
|
STDOUT.putc "X" # Tests for this model are missing.
|
|
|
|
end
|
|
|
|
else
|
2007-03-14 19:05:34 -04:00
|
|
|
define_method test_name do |*args|
|
|
|
|
begin
|
|
|
|
setup_blocks.each {|b| b.bind(self).call }
|
|
|
|
should_block.bind(self).call(*args)
|
|
|
|
ensure
|
|
|
|
teardown_blocks.reverse.each {|b| b.bind(self).call }
|
|
|
|
end
|
2007-03-14 14:12:55 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2007-03-14 15:12:11 -04:00
|
|
|
|
|
|
|
# Defines a specification that is not yet implemented. Will be displayed as an 'X' when running tests, and failures will not be shown.
|
2007-03-14 14:12:55 -04:00
|
|
|
def should_eventually(name, &block)
|
|
|
|
should("eventually #{name}", {:unimplemented => true}, &block)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|