Add Mutant::Runner::Subject

The idea is to break up the big fat and ugly Runner class into dedicated
pices with a single reponsibility.
This commit is contained in:
Markus Schirp 2013-02-01 23:06:07 +01:00
parent 6fe8b1181c
commit 2b6470f223
4 changed files with 74 additions and 112 deletions

View file

@ -107,6 +107,8 @@ require 'mutant/strategy/rspec/dm2'
require 'mutant/strategy/rspec/dm2/lookup'
require 'mutant/strategy/rspec/dm2/lookup/method'
require 'mutant/runner'
require 'mutant/runner/subject'
require 'mutant/runner/mutation'
require 'mutant/cli'
require 'mutant/cli/classifier'
require 'mutant/cli/classifier/namespace'

View file

@ -1,22 +1,7 @@
module Mutant
# Runner that allows to mutate an entire project
class Runner
include Adamantium::Flat, Equalizer.new(:config)
extend MethodObject
# Test for succcess
#
# @return [true]
# when there are subjects and no failures
#
# @return [false]
# otherwise
#
# @api private
#
def success?
reporter.success?
end
include Adamantium::Flat, AbstractType
# Return config
#
@ -26,8 +11,6 @@ module Mutant
#
attr_reader :config
private
# Initialize object
#
# @param [Config] config
@ -41,106 +24,15 @@ module Mutant
run
end
# Return strategy
#
# @return [Strategy]
#
# @api private
#
def strategy
config.strategy
end
private
# Return reporter
#
# @return [Reporter]
#
# @api private
#
def reporter
config.reporter
end
# Run mutation killers on subjects
# Perform operation
#
# @return [undefined]
#
# @api private
#
def run
reporter.start(config)
util = strategy
util.setup
config.matcher.each do |subject|
reporter.subject(subject)
run_subject(subject)
end
util.teardown
reporter.stop
end
abstract_method :run
# Run mutation killers on subject
#
# @param [Subject] subject
#
# @return [undefined]
#
# @api private
#
def run_subject(subject)
return unless test_noop(subject)
subject.each do |mutation|
next unless config.filter.match?(mutation)
reporter.mutation(mutation)
kill(mutation)
end
end
# Test noop mutation
#
# @return [true]
# if noop mutation is alive
#
# @return [false]
# otherwise
#
# @api private
#
def test_noop(subject)
noop = subject.noop
unless kill(noop)
reporter.noop(noop)
return false
end
true
end
# Run killer on mutation
#
# @param [Mutation] mutation
#
# @return [true]
# if killer was successful
#
# @return [false]
# otherwise
#
# @api private
#
def kill(mutation)
killer = killer(mutation)
reporter.report_killer(killer)
killer.success?
end
# Return killer for mutation
#
# @return [Killer]
#
# @api private
#
def killer(mutation)
strategy.kill(mutation)
end
end
end

View file

@ -0,0 +1,41 @@
module Mutant
class Runner
# Subject specific runner
class Subject < self
# Return mutation runners
#
# @return [Enumerable<Runner::Mutation>]
#
# @api private
#
attr_reader :mutations
# Initialize object
#
# @param [Configuration] config
# @param [Subject] subject
#
# @return [undefined]
#
# @api private
#
def initialize(config, subject)
@subject = subject
super(config)
end
private
# Perform operation
#
# @return [undefined]
#
# @api private
#
def run
end
end
end
end

View file

@ -0,0 +1,27 @@
require 'spec_helper'
describe Mutant::Runner::Subject do
let(:object) { described_class }
let(:config) { mock('Config') }
let(:mutation) { mock('Mutation') }
let(:mutation_subject) { [mutation] }
class DummyRunner
include Equalizer.new(:config, :mutation)
attr_reader :mutation
def initialize(config, mutation)
@config, @mutation = config, mutation
end
end
before do
stub_const('Mutant::Runner::Mutation', DummyRunner)
end
subject { object.new(config, mutation_subject) }
its(:mutations) { eql([DummyRunner.new(config, mutation)]) }
end