Refactor runner and fix integration spec

This commit is contained in:
Markus Schirp 2012-09-16 00:51:47 +02:00
parent 96beff82b9
commit cd35a6dcc6
9 changed files with 49 additions and 74 deletions

View file

@ -6,6 +6,7 @@ gem 'immutable', :git => 'https://github.com/dkubb/immutable.git', :br
gem 'descendants_tracker', :git => 'https://github.com/dkubb/descendants_tracker.git'
gem 'abstract_class', :git => 'https://github.com/dkubb/abstract_class.git'
gem 'equalizer', :git => 'https://github.com/dkubb/equalizer.git'
gem 'anima', :git => 'https://github.com/mbj/anima.git'
gem 'to_source', :git => 'https://github.com/mbj/to_source.git'
group :development do

View file

@ -8,6 +8,7 @@ require 'to_source'
require 'ice_nine'
require 'ice_nine/core_ext/object'
require 'backports'
require 'anima'
require 'diff/lcs'
require 'diff/lcs/hunk'

View file

@ -1,5 +1,5 @@
module Mutant
# Comandline adapter or mutant runner
# Comandline parser
class CLI
include Immutable
@ -16,17 +16,17 @@ module Mutant
# @api private
#
def self.run(*arguments)
error = Runner.run(new(*arguments).runner_options).fail?
error = Runner.run(new(*arguments).attributes).fail?
error ? 1 : 0
end
# Return options for runner
# Return attributes
#
# @return [Hash]
#
# @api private
#
def runner_options
def attributes
{
:mutation_filter => mutation_filter,
:matcher => matcher,
@ -34,12 +34,12 @@ module Mutant
:killer => Killer::Rspec::Forking
}
end
memoize :runner_options
memoize :attributes
private
OPTIONS = {
'--code' => [:add_filter, Mutation::Filter::Code].freeze
'--code' => [:add_filter, Mutation::Filter::Code]
}.deep_freeze
OPTION_PATTERN = %r(\A-(?:-)?[a-z0-9]+\z).freeze
@ -67,9 +67,7 @@ module Mutant
def initialize(arguments)
@filters, @matchers = [], []
@arguments = arguments
@index = 0
@arguments, @index = arguments, 0
while @index < @arguments.length
dispatch
@ -98,7 +96,7 @@ module Mutant
def current_option_value
@arguments.fetch(@index+1)
rescue IndexError
raise Error,"#{current_argument.inspect} is missing an argument"
raise Error, "#{current_argument.inspect} is missing an argument"
end
# Process current argument

View file

@ -1,9 +1,14 @@
module Mutant
# Runner that allows to mutate an entire project
class Runner
include Immutable
include Immutable, Anima
extend MethodObject
attribute :matcher
attribute :killer
attribute :reporter
attribute :mutation_filter
# Return killers with errors
#
# @return [Enumerable<Killer>]
@ -28,42 +33,25 @@ module Mutant
private
# Return reporter
# Initialize object
#
# @return [Reporter]
#
# @api private
#
def reporter; @reporter; end
# Initialize runner object
#
# @param [Hash] options
# @param [Hash] attributes
#
# @return [undefined]
#
# @api private
#
def initialize(options)
@killer = Helper.extract_option(options, :killer)
@matcher = Helper.extract_option(options, :matcher)
@reporter = options.fetch(:reporter, Reporter::Null)
@mutation_filter = options.fetch(:mutation_filter, Mutation::Filter::ALL)
def initialize(attributes)
attributes[:reporter] ||= Reporter::Null
attributes[:mutation_filter] ||= Mutation::Filter::ALL
super(attributes)
@errors = []
run
end
# Return subject enumerator
#
# @return [Enumerator<Subject>]
#
# @api private
#
def subjects
@matcher.each
end
# Run mutation killers on subjects
#
# @return [undefined]
@ -71,7 +59,7 @@ module Mutant
# @api private
#
def run
subjects.each do |subject|
matcher.each do |subject|
reporter.subject(subject)
run_subject(subject)
end
@ -111,13 +99,3 @@ module Mutant
end
end
end
# Return candiate matcher enumerator
#
# @return [Enumerable<Class<Matcher>>]
#
# @api private
#
def candidate_matchers
[Matcher::Method::Singleton, Matcher::Method::Instance].each
end

View file

@ -16,12 +16,13 @@ Gem::Specification.new do |gem|
gem.test_files = `git ls-files -- spec`.split("\n")
gem.extra_rdoc_files = %w[TODO]
gem.add_runtime_dependency('to_source', '~> 0.1.3')
gem.add_runtime_dependency('ice_nine', '~> 0.4.0')
gem.add_runtime_dependency('descendants_tracker', '~> 0.0.1')
gem.add_runtime_dependency('backports', '~> 2.6')
gem.add_runtime_dependency('immutable', '~> 0.0.1')
gem.add_runtime_dependency('equalizer', '~> 0.0.1')
gem.add_runtime_dependency('abstract_class', '~> 0.0.1')
gem.add_runtime_dependency('diff-lcs', '~> 1.1.3')
gem.add_runtime_dependency('to_source', '~> 0.1.3')
gem.add_runtime_dependency('ice_nine', '~> 0.4.0')
gem.add_runtime_dependency('descendants_tracker', '~> 0.0.1')
gem.add_runtime_dependency('backports', '~> 2.6')
gem.add_runtime_dependency('immutable', '~> 0.0.1')
gem.add_runtime_dependency('equalizer', '~> 0.0.1')
gem.add_runtime_dependency('abstract_class', '~> 0.0.1')
gem.add_runtime_dependency('anima', '~> 0.0.1')
gem.add_runtime_dependency('diff-lcs', '~> 1.1.3')
end

View file

@ -1,10 +1,6 @@
require 'spec_helper'
describe Mutant, 'runner' do
before do
pending
end
around do |example|
Dir.chdir(TestApp.root) do
example.run
@ -14,13 +10,13 @@ describe Mutant, 'runner' do
it 'allows to run mutant over a project' do
output = StringIO.new
runner = Mutant::Runner.run(
:pattern => /\ATestApp::/,
:killer => Mutant::Killer::Rspec,
:matcher => Mutant::Matcher::ObjectSpace.new(/\ATestApp::/),
:reporter => Mutant::Reporter::CLI.new(output)
)
runner.fail?.should be(true)
runner.errors.size.should be(22)
output.rewind
output.lines.grep(/Mutation/).size.should be(22)
output.lines.grep(/Mutant alive:/).size.should be(22)
end
end

View file

@ -6,8 +6,8 @@ shared_examples_for 'an invalid cli run' do
end
end
describe Mutant::CLI, '#runner_options' do
subject { object.runner_options }
describe Mutant::CLI, '#attributes' do
subject { object.attributes }
let(:object) { described_class.new(arguments) }

View file

@ -3,24 +3,24 @@ require 'spec_helper'
describe Mutant::CLI, '.run' do
subject { object.run(argv) }
let(:object) { described_class }
let(:argv) { mock('ARGV') }
let(:options) { mock('Options') }
let(:runner) { mock('Runner', :fail? => failure) }
let(:instance) { mock(described_class.name, :runner_options => options) }
let(:object) { described_class }
let(:argv) { mock('ARGV') }
let(:attributes) { mock('Options') }
let(:runner) { mock('Runner', :fail? => failure) }
let(:instance) { mock(described_class.name, :attributes => attributes) }
before do
described_class.stub(:new => instance)
Mutant::Runner.stub(:run => runner)
end
context 'when runner NOT fails' do
context 'when runner does NOT fail' do
let(:failure) { false }
it { should be(0) }
it 'should run with options' do
Mutant::Runner.should_receive(:run).with(options).and_return(runner)
it 'should run with attributes' do
Mutant::Runner.should_receive(:run).with(attributes).and_return(runner)
should be(0)
end
end
@ -30,8 +30,8 @@ describe Mutant::CLI, '.run' do
it { should be(1) }
it 'should run with options' do
Mutant::Runner.should_receive(:run).with(options).and_return(runner)
it 'should run with attributes' do
Mutant::Runner.should_receive(:run).with(attributes).and_return(runner)
should be(1)
end
end

View file

@ -31,7 +31,7 @@ describe Mutant::Matcher, '.from_string' do
it_should_behave_like 'an idempotent method'
end
pending 'when more than one descendant handles input' do
context 'when more than one descendant handles input' do
let(:matcher_b) { mock('Matcher B') }
before do