2013-07-28 19:03:06 -04:00
|
|
|
# encoding: utf-8
|
|
|
|
|
2013-02-02 10:32:13 -05:00
|
|
|
module Mutant
|
|
|
|
class Runner
|
2013-04-20 14:50:36 -04:00
|
|
|
# Runner for object config
|
2013-02-02 10:32:13 -05:00
|
|
|
class Config < self
|
|
|
|
|
2014-05-11 10:27:40 -04:00
|
|
|
# The expected coverage precision
|
|
|
|
COVERAGE_PRECISION = 1
|
|
|
|
|
2013-07-14 19:17:15 -04:00
|
|
|
register Mutant::Config
|
|
|
|
|
|
|
|
# Run runner for object
|
|
|
|
#
|
|
|
|
# @param [Config] config
|
|
|
|
# @param [Object] object
|
|
|
|
#
|
|
|
|
# @return [Runner]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def self.run(config)
|
|
|
|
handler = lookup(config.class)
|
|
|
|
handler.new(config)
|
|
|
|
end
|
|
|
|
|
2013-02-02 10:32:13 -05:00
|
|
|
# Return subject runners
|
|
|
|
#
|
|
|
|
# @return [Enumerable<Runner::Subject>]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
attr_reader :subjects
|
|
|
|
|
2013-03-27 10:52:02 -04:00
|
|
|
# Return failed subjects
|
|
|
|
#
|
|
|
|
# @return [Enumerable<Subject>]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def failed_subjects
|
2013-07-14 19:17:15 -04:00
|
|
|
subjects.reject(&:success?)
|
2013-03-27 10:52:02 -04:00
|
|
|
end
|
|
|
|
memoize :failed_subjects
|
|
|
|
|
|
|
|
# Test if run was successful
|
|
|
|
#
|
|
|
|
# @return [true]
|
|
|
|
# if run was successful
|
|
|
|
#
|
|
|
|
# @return [false]
|
|
|
|
# otherwise
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def success?
|
2014-01-18 18:06:40 -05:00
|
|
|
coverage.round(COVERAGE_PRECISION) == config.expected_coverage.round(COVERAGE_PRECISION)
|
2013-03-27 10:52:02 -04:00
|
|
|
end
|
|
|
|
memoize :success?
|
|
|
|
|
2013-04-20 14:50:36 -04:00
|
|
|
# Return strategy
|
|
|
|
#
|
|
|
|
# @return [Strategy]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def strategy
|
|
|
|
config.strategy
|
|
|
|
end
|
|
|
|
|
2014-01-18 18:06:40 -05:00
|
|
|
# Return coverage
|
|
|
|
#
|
|
|
|
# @return [Float]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def coverage
|
2014-03-07 08:03:42 -05:00
|
|
|
return 0.0 if amount_mutations.zero? && amount_kills.zero?
|
|
|
|
(amount_kills.to_f / amount_mutations) * 100
|
2014-01-18 18:06:40 -05:00
|
|
|
end
|
|
|
|
memoize :coverage
|
|
|
|
|
|
|
|
# Return amount of kills
|
|
|
|
#
|
|
|
|
# @return [Fixnum]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def amount_kills
|
|
|
|
mutations.select(&:success?).length
|
|
|
|
end
|
|
|
|
memoize :amount_kills
|
|
|
|
|
|
|
|
# Return mutations
|
|
|
|
#
|
|
|
|
# @return [Array<Mutation>]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def mutations
|
|
|
|
subjects.map(&:mutations).flatten
|
|
|
|
end
|
|
|
|
memoize :mutations
|
|
|
|
|
|
|
|
# Return amount of mutations
|
|
|
|
#
|
|
|
|
# @return [Fixnum]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def amount_mutations
|
|
|
|
mutations.length
|
|
|
|
end
|
|
|
|
|
2013-02-02 10:32:13 -05:00
|
|
|
private
|
|
|
|
|
2013-03-27 10:52:02 -04:00
|
|
|
# Run config
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2013-04-20 20:48:58 -04:00
|
|
|
def run_subjects
|
2013-04-20 14:50:36 -04:00
|
|
|
strategy = self.strategy
|
2013-03-27 10:52:02 -04:00
|
|
|
strategy.setup
|
2014-05-11 10:25:11 -04:00
|
|
|
@subjects = visit_collection(config.subjects)
|
2013-03-27 10:52:02 -04:00
|
|
|
strategy.teardown
|
2013-04-20 20:48:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
# Run with strategy management
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def run
|
|
|
|
run_subjects
|
2013-04-20 20:20:18 -04:00
|
|
|
@end = Time.now
|
2014-05-12 09:48:15 -04:00
|
|
|
reporter.report(self)
|
2013-02-02 10:32:13 -05:00
|
|
|
end
|
|
|
|
|
2013-06-14 14:54:02 -04:00
|
|
|
end # Config
|
|
|
|
end # Runner
|
|
|
|
end # Mutant
|