Class: Scope::TestCase
- Inherits:
-
MiniTest::Unit::TestCase
- Object
- MiniTest::Unit::TestCase
- Scope::TestCase
- Defined in:
- lib/scope.rb
Overview
A test case class which provides nested contexts. Subclasses will have the “setup”, “teardown”, and “should” methods available as class methods.
Class Method Summary collapse
- .context(name, &block) ⇒ Object
-
.context_for_test ⇒ Object
A map of test name => Context.
-
.focus ⇒ Object
“Focuses” the next test that’s defined after this method is called, ensuring that only that test is run.
- .inherited(subclass) ⇒ Object
- .setup(&block) ⇒ Object
-
.setup_once(&block) ⇒ Object
setup_once blocks are run just once for a context, and not on a per-test basis.
- .should(name, &block) ⇒ Object
- .teardown(&block) ⇒ Object
- .teardown_once(&block) ⇒ Object
Instance Method Summary collapse
-
#run(test_runner) ⇒ Object
run() is called by the MiniTest framework.
Class Method Details
.context(name, &block) ⇒ Object
34 35 36 37 38 39 40 41 |
# File 'lib/scope.rb', line 34 def self.context(name, &block) parent = @contexts.last new_context = Context.new(name, parent) parent.tests_and_subcontexts << new_context @contexts << new_context block.call @contexts.pop end |
.context_for_test ⇒ Object
A map of test name => Context.
8 |
# File 'lib/scope.rb', line 8 def self.context_for_test() @context_for_test end |
.focus ⇒ Object
“Focuses” the next test that’s defined after this method is called, ensuring that only that test is run.
67 68 69 70 71 72 73 74 |
# File 'lib/scope.rb', line 67 def self.focus # Since we're focusing only the next test, remove any tests which were already defined. context_for_test.values.uniq.each do |context| context.tests_and_subcontexts.reject! { |test| test.is_a?(String) } end @focus_enabled = true @focus_next_test = true end |
.inherited(subclass) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/scope.rb', line 10 def self.inherited(subclass) # Calling Unit::TestCase's inherited() method is important, as that's how it registers test suites. super subclass.instance_eval do # Pretend the whole test is wrapped in a context, so we can always code as if tests are in contexts. @contexts = [Context.new("")] @context_for_test = {} # The tests defined in this test case. MiniTest::Unit::TestCase sorts these methods randomly or # alphabetically. Let's run them in the order they were defined, as that's least surprising. def test_methods() tests = [] stack = [@contexts.first] until stack.empty? do item = stack.pop stack += item.tests_and_subcontexts.reverse if item.is_a?(Context) tests << item if item.is_a?(String) end tests end end end |
.setup(&block) ⇒ Object
58 |
# File 'lib/scope.rb', line 58 def self.setup(&block) @contexts.last.setup= block end |
.setup_once(&block) ⇒ Object
setup_once blocks are run just once for a context, and not on a per-test basis. They are useful for integration tests with costly setup.
63 |
# File 'lib/scope.rb', line 63 def self.setup_once(&block) @contexts.last.setup_once = block end |
.should(name, &block) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/scope.rb', line 43 def self.should(name, &block) # When focus_enabled is true, we'll only be running the next should() block that gets defined. if @focus_enabled return unless @focus_next_test @focus_next_test = false end context_name = @contexts[1..-1].map { |context| context.name }.join(" ") context_name += " " unless context_name.empty? test_method_name = "#{context_name}should #{name}" define_method test_method_name, block @contexts.last.tests_and_subcontexts << test_method_name @context_for_test[test_method_name] = @contexts.last end |
.teardown(&block) ⇒ Object
59 |
# File 'lib/scope.rb', line 59 def self.teardown(&block) @contexts.last.teardown = block end |
.teardown_once(&block) ⇒ Object
64 |
# File 'lib/scope.rb', line 64 def self.teardown_once(&block) @contexts.last.teardown_once = block end |
Instance Method Details
#run(test_runner) ⇒ Object
run() is called by the MiniTest framework. This TestCase class is instantiated once per test method defined, and then run() is called on each test case instance.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/scope.rb', line 78 def run(test_runner) test_name = self.__name__ context = self.class.context_for_test[test_name] result = nil begin # Unit::TestCase's implementation of run() invokes the test method with exception handling. context.run_setup_and_teardown(self, test_name) { result = super } rescue *MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS raise rescue Exception => error result = test_runner.puke(self.class, self.__name__, error) end result end |