Module: Mutineer::MinitestIntegration::StopAtFirstFailure
- Defined in:
- lib/mutineer/minitest_integration/stop_at_first_failure.rb
Overview
Stops a Minitest run at the first failing test: one failure already kills the mutant. Child-process only, like MinitestIntegration.
It sets a flag instead of unwinding the stack, so that class-level
wrappers (after_all, a block-form transaction) still finish. The
remaining tests and classes then return before they start.
Minitest 5 and 6 need different hook points. An unknown shape installs no hook, and the run is a full run.
Defined Under Namespace
Modules: OuterReporter5, OuterReporter6, RecordFailure, SkipAfterStop5, SkipAfterStop6
Class Attribute Summary collapse
-
.armed_pid ⇒ Integer?
The pid of the armed process.
-
.armed_reporter ⇒ Minitest::CompositeReporter?
The outer reporter of the armed run.
-
.stopped ⇒ Boolean?
True after the outer reporter records a failure or an error.
Class Method Summary collapse
-
.arm!(runnables) ⇒ Boolean
Installs the hooks and arms the stop for this process.
-
.armed_here? ⇒ Boolean
True when the run is armed in this process.
-
.disarm! ⇒ void
Clears the armed state.
-
.hooks_for_loaded_minitest ⇒ Array(Module, Module)?
private
Picks the hook modules for the loaded Minitest.
-
.prepend_once(target, mod) ⇒ void
private
Prepends
modontargetonce. -
.stopped_here? ⇒ Boolean
True when the armed run in this process has stopped.
Class Attribute Details
.armed_pid ⇒ Integer?
The pid of the armed process. Forked workers inherit the other state, and the pid keeps them from acting on it.
117 118 119 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 117 def armed_pid @armed_pid end |
.armed_reporter ⇒ Minitest::CompositeReporter?
The outer reporter of the armed run.
122 123 124 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 122 def armed_reporter @armed_reporter end |
.stopped ⇒ Boolean?
True after the outer reporter records a failure or an error.
127 128 129 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 127 def stopped @stopped end |
Class Method Details
.arm!(runnables) ⇒ Boolean
Installs the hooks and arms the stop for this process. Call it after the test files load, so that every test class gets its prepend.
134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 134 def arm!(runnables) outer, skip = hooks_for_loaded_minitest return false unless outer prepend_once(::Minitest::CompositeReporter, RecordFailure) prepend_once(::Minitest.singleton_class, outer) runnables.each { |klass| prepend_once(klass.singleton_class, skip) } self.armed_pid = Process.pid self.armed_reporter = nil self.stopped = false true end |
.armed_here? ⇒ Boolean
True when the run is armed in this process.
159 160 161 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 159 def armed_here? armed_pid == Process.pid end |
.disarm! ⇒ void
This method returns an undefined value.
Clears the armed state.
150 151 152 153 154 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 150 def disarm! self.armed_pid = nil self.armed_reporter = nil self.stopped = false end |
.hooks_for_loaded_minitest ⇒ Array(Module, Module)? (private)
Picks the hook modules for the loaded Minitest.
176 177 178 179 180 181 182 183 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 176 def hooks_for_loaded_minitest runnable = ::Minitest::Runnable if ::Minitest.respond_to?(:run_all_suites) && runnable.respond_to?(:run_suite) [OuterReporter6, SkipAfterStop6] elsif ::Minitest.respond_to?(:__run) && runnable.respond_to?(:run_one_method) [OuterReporter5, SkipAfterStop5] end end |
.prepend_once(target, mod) ⇒ void (private)
This method returns an undefined value.
Prepends mod on target once. A copy on a superclass does not
count, because it comes after the own methods of target.
191 192 193 194 195 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 191 def prepend_once(target, mod) return if target.ancestors.take_while { |a| !a.equal?(target) }.include?(mod) target.prepend(mod) end |
.stopped_here? ⇒ Boolean
True when the armed run in this process has stopped.
166 167 168 |
# File 'lib/mutineer/minitest_integration/stop_at_first_failure.rb', line 166 def stopped_here? stopped == true && armed_here? end |