free_mutant/lib/mutant/strategy.rb
Markus Schirp a618d82fb1 Push down test selection and add framework for output capture
This clearly is a WIP. We know have the reporter granularity to capture
per mutation test outputs + per mutation test selections.

This adds all infrastructure to address:

* #185 we know which tests are run in reporter
* #180 fine grained information available for the reporter
* #178 minitest project integration only needs to return an enumerable
  with metadata
* #174 We can now "see" all test, allowing to generate a default
  matcher.
* #158 Ability to steer test selection centralized for all integrations
* #125 We have the required objects in graph
* #96 We have finer granularity in reporter graph

Because we know signal more complex state from killforks to parent I
need to bring back killfork partent signalling, but this time with
sending complex data around (Test::Report). Should be easy with
Marshal.{dump,load} but my OSS time budget is exhausted for now.
2014-04-28 19:17:29 +00:00

123 lines
2 KiB
Ruby

# encoding: utf-8
module Mutant
# Abstract base class for killing strategies
class Strategy
include AbstractType, Adamantium::Flat, Equalizer.new
REGISTRY = {}
# Lookup strategy for name
#
# @param [String] name
#
# @return [Strategy]
# if found
#
# @api private
#
def self.lookup(name)
REGISTRY.fetch(name)
end
# Register strategy
#
# @param [String] name
#
# @return [undefined]
#
# @api private
#
def self.register(name)
REGISTRY[name] = self
end
private_class_method :register
# Perform strategy setup
#
# @return [self]
#
# @api private
#
def setup
self
end
# Perform strategy teardown
#
# @return [self]
#
# @api private
#
def teardown
self
end
# Return all available tests by strategy
#
# @return [Enumerable<Test>]
#
# @api private
#
abstract_method :all_tests
# Return killers for mutation
#
# @param [Mutation] mutation
#
# @return [Enumerable<Killer>]
#
# @api private
#
def killers(mutation)
tests(mutation).map do |test|
Killer.new(
mutation: mutation,
test: test
)
end
end
# Return tests for mutation
#
# TODO: This logic is now centralized but still fucked.
#
# @param [Mutation] mutation
#
# @return [Enumerable<Test>]
#
# @api private
#
def tests(mutation)
mutation.subject.match_prefixes.map do |match_expression|
tests = all_tests.select do |test|
test.subject_identification.start_with?(match_expression)
end
return tests if tests.any?
end
[]
end
private
# Null strategy that never kills a mutation
class Null < self
register('null')
# Return all tests
#
# @return [Enumerable<Test>]
#
# @api private
#
def all_tests
[]
end
end # Null
end # Strategy
end # Mutant