Add runner objects for config and mutation

This commit is contained in:
Markus Schirp 2013-02-02 16:32:13 +01:00
parent 732ece42c3
commit 2b01374d3a
10 changed files with 135 additions and 6 deletions

View file

@ -108,6 +108,7 @@ require 'mutant/strategy/rspec/dm2'
require 'mutant/strategy/rspec/dm2/lookup'
require 'mutant/strategy/rspec/dm2/lookup/method'
require 'mutant/runner'
require 'mutant/runner/config'
require 'mutant/runner/subject'
require 'mutant/runner/mutation'
require 'mutant/cli'

View file

@ -32,7 +32,9 @@ module Mutant
# @api private
#
def self.run(*arguments)
Runner.run(new(*arguments)).success? ? EXIT_SUCCESS : EXIT_FAILURE
config = new(*arguments)
runner = Runner::Config.run(config)
runner.success? ? EXIT_SUCCESS : EXIT_FAILURE
rescue Error => exception
$stderr.puts(exception.message)
EXIT_FAILURE

View file

@ -2,6 +2,7 @@ module Mutant
# Runner that allows to mutate an entire project
class Runner
include Adamantium::Flat, AbstractType
extend MethodObject
# Return config
#

View file

@ -0,0 +1,23 @@
module Mutant
class Runner
class Config < self
# Return subject runners
#
# @return [Enumerable<Runner::Subject>]
#
# @api private
#
attr_reader :subjects
private
def run
@subjects = config.subjects.map do |subject|
Subject.run(config, subject)
end
end
end
end
end

View file

@ -0,0 +1,42 @@
module Mutant
class Runner
# Mutation runner
class Mutation < self
# Return killer instance
#
# @return [Killer]
#
# @api private
#
attr_reader :killer
# Initialize object
#
# @param [Configuration] config
# @param [Mutation] mutation
#
# @return [undefined]
#
# @api private
#
def initialize(config, mutation)
@mutation = mutation
super(config)
end
private
# Perform operation
#
# @return [undefined]
#
# @api private
#
def run
@killer = config.strategy(@mutation).kill(@mutation)
end
end
end
end

View file

@ -1,6 +1,7 @@
module Mutant
# A mixing to create method object semantics
module MethodObject
# Hook called when descendant is extended
#
# @param [Module|Class] descendant
@ -27,5 +28,6 @@ module Mutant
def run(*args)
new(*args)
end
end
end

View file

@ -11,7 +11,7 @@ describe Mutant::CLI, '.run' do
before do
described_class.stub(:new => instance)
Mutant::Runner.stub(:run => runner)
Mutant::Runner::Config.stub(:run => runner)
end
context 'when runner is successful' do
@ -20,7 +20,7 @@ describe Mutant::CLI, '.run' do
it { should be(0) }
it 'should run with attributes' do
Mutant::Runner.should_receive(:run).with(instance).and_return(runner)
Mutant::Runner::Config.should_receive(:run).with(instance).and_return(runner)
should be(0)
end
end
@ -31,7 +31,7 @@ describe Mutant::CLI, '.run' do
it { should be(1) }
it 'should run with attributes' do
Mutant::Runner.should_receive(:run).with(instance).and_return(runner)
Mutant::Runner::Config.should_receive(:run).with(instance).and_return(runner)
should be(1)
end
end

View file

@ -0,0 +1,24 @@
require 'spec_helper'
describe Mutant::Runner::Config, '#subjects' do
let(:object) { described_class.run(config) }
subject { object.subjects }
let(:config) { mock('Config', :subjects => [mutation_subject]) }
let(:mutation_subject) { mock('Mutation subject') }
let(:subject_runner) { mock('Subject runner') }
class DummySubjectRunner
include Composition.new(:config, :mutation)
def self.run(*args); new(*args); end
end
before do
stub_const('Mutant::Runner::Subject', DummySubjectRunner)
end
it { should eql([DummySubjectRunner.new(config, mutation_subject)]) }
it_should_behave_like 'an idempotent method'
end

View file

@ -0,0 +1,31 @@
require 'spec_helper'
describe Mutant::Runner::Mutation, '#killer' do
let(:object) { described_class.run(config, mutation) }
let(:config) { mock('Config') }
let(:mutation) { mock('Mutation') }
let(:strategy) { mock('Strategy') }
let(:killer) { mock('Killer') }
subject { object.killer }
before do
config.stub(:strategy => strategy)
strategy.stub(:kill => killer)
end
it 'should call configuration to identify strategy' do
config.should_receive(:strategy).with(mutation).and_return(strategy)
should be(killer)
end
it 'should run killer' do
strategy.should_receive(:kill).with(mutation).and_return(killer)
should be(killer)
end
it { should be(killer) }
it_should_behave_like 'an idempotent method'
end

View file

@ -1,16 +1,17 @@
require 'spec_helper'
describe Mutant::Runner::Subject, '#mutations' do
let(:object) { described_class.new(config, mutation_subject) }
let(:object) { described_class.run(config, mutation_subject) }
subject { object.mutations }
let(:config) { mock('Config') }
let(:config) { mock('Config') }
let(:mutation) { mock('Mutation') }
let(:mutation_subject) { [mutation] }
class DummyRunner
include Composition.new(:config, :mutation)
def self.run(*args); new(*args); end
end
before do
@ -18,4 +19,6 @@ describe Mutant::Runner::Subject, '#mutations' do
end
it { should eql([DummyRunner.new(config, mutation)]) }
it_should_behave_like 'an idempotent method'
end