Refactor runner and fix integration spec
This commit is contained in:
parent
96beff82b9
commit
cd35a6dcc6
9 changed files with 49 additions and 74 deletions
1
Gemfile
1
Gemfile
|
|
@ -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 'descendants_tracker', :git => 'https://github.com/dkubb/descendants_tracker.git'
|
||||||
gem 'abstract_class', :git => 'https://github.com/dkubb/abstract_class.git'
|
gem 'abstract_class', :git => 'https://github.com/dkubb/abstract_class.git'
|
||||||
gem 'equalizer', :git => 'https://github.com/dkubb/equalizer.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'
|
gem 'to_source', :git => 'https://github.com/mbj/to_source.git'
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ require 'to_source'
|
||||||
require 'ice_nine'
|
require 'ice_nine'
|
||||||
require 'ice_nine/core_ext/object'
|
require 'ice_nine/core_ext/object'
|
||||||
require 'backports'
|
require 'backports'
|
||||||
|
require 'anima'
|
||||||
require 'diff/lcs'
|
require 'diff/lcs'
|
||||||
require 'diff/lcs/hunk'
|
require 'diff/lcs/hunk'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
module Mutant
|
module Mutant
|
||||||
# Comandline adapter or mutant runner
|
# Comandline parser
|
||||||
class CLI
|
class CLI
|
||||||
include Immutable
|
include Immutable
|
||||||
|
|
||||||
|
|
@ -16,17 +16,17 @@ module Mutant
|
||||||
# @api private
|
# @api private
|
||||||
#
|
#
|
||||||
def self.run(*arguments)
|
def self.run(*arguments)
|
||||||
error = Runner.run(new(*arguments).runner_options).fail?
|
error = Runner.run(new(*arguments).attributes).fail?
|
||||||
error ? 1 : 0
|
error ? 1 : 0
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return options for runner
|
# Return attributes
|
||||||
#
|
#
|
||||||
# @return [Hash]
|
# @return [Hash]
|
||||||
#
|
#
|
||||||
# @api private
|
# @api private
|
||||||
#
|
#
|
||||||
def runner_options
|
def attributes
|
||||||
{
|
{
|
||||||
:mutation_filter => mutation_filter,
|
:mutation_filter => mutation_filter,
|
||||||
:matcher => matcher,
|
:matcher => matcher,
|
||||||
|
|
@ -34,12 +34,12 @@ module Mutant
|
||||||
:killer => Killer::Rspec::Forking
|
:killer => Killer::Rspec::Forking
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
memoize :runner_options
|
memoize :attributes
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
OPTIONS = {
|
OPTIONS = {
|
||||||
'--code' => [:add_filter, Mutation::Filter::Code].freeze
|
'--code' => [:add_filter, Mutation::Filter::Code]
|
||||||
}.deep_freeze
|
}.deep_freeze
|
||||||
|
|
||||||
OPTION_PATTERN = %r(\A-(?:-)?[a-z0-9]+\z).freeze
|
OPTION_PATTERN = %r(\A-(?:-)?[a-z0-9]+\z).freeze
|
||||||
|
|
@ -67,9 +67,7 @@ module Mutant
|
||||||
def initialize(arguments)
|
def initialize(arguments)
|
||||||
@filters, @matchers = [], []
|
@filters, @matchers = [], []
|
||||||
|
|
||||||
@arguments = arguments
|
@arguments, @index = arguments, 0
|
||||||
|
|
||||||
@index = 0
|
|
||||||
|
|
||||||
while @index < @arguments.length
|
while @index < @arguments.length
|
||||||
dispatch
|
dispatch
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
module Mutant
|
module Mutant
|
||||||
# Runner that allows to mutate an entire project
|
# Runner that allows to mutate an entire project
|
||||||
class Runner
|
class Runner
|
||||||
include Immutable
|
include Immutable, Anima
|
||||||
extend MethodObject
|
extend MethodObject
|
||||||
|
|
||||||
|
attribute :matcher
|
||||||
|
attribute :killer
|
||||||
|
attribute :reporter
|
||||||
|
attribute :mutation_filter
|
||||||
|
|
||||||
# Return killers with errors
|
# Return killers with errors
|
||||||
#
|
#
|
||||||
# @return [Enumerable<Killer>]
|
# @return [Enumerable<Killer>]
|
||||||
|
|
@ -28,42 +33,25 @@ module Mutant
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Return reporter
|
# Initialize object
|
||||||
#
|
#
|
||||||
# @return [Reporter]
|
# @param [Hash] attributes
|
||||||
#
|
|
||||||
# @api private
|
|
||||||
#
|
|
||||||
def reporter; @reporter; end
|
|
||||||
|
|
||||||
# Initialize runner object
|
|
||||||
#
|
|
||||||
# @param [Hash] options
|
|
||||||
#
|
#
|
||||||
# @return [undefined]
|
# @return [undefined]
|
||||||
#
|
#
|
||||||
# @api private
|
# @api private
|
||||||
#
|
#
|
||||||
def initialize(options)
|
def initialize(attributes)
|
||||||
@killer = Helper.extract_option(options, :killer)
|
attributes[:reporter] ||= Reporter::Null
|
||||||
@matcher = Helper.extract_option(options, :matcher)
|
attributes[:mutation_filter] ||= Mutation::Filter::ALL
|
||||||
@reporter = options.fetch(:reporter, Reporter::Null)
|
|
||||||
@mutation_filter = options.fetch(:mutation_filter, Mutation::Filter::ALL)
|
super(attributes)
|
||||||
|
|
||||||
@errors = []
|
@errors = []
|
||||||
|
|
||||||
run
|
run
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return subject enumerator
|
|
||||||
#
|
|
||||||
# @return [Enumerator<Subject>]
|
|
||||||
#
|
|
||||||
# @api private
|
|
||||||
#
|
|
||||||
def subjects
|
|
||||||
@matcher.each
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run mutation killers on subjects
|
# Run mutation killers on subjects
|
||||||
#
|
#
|
||||||
# @return [undefined]
|
# @return [undefined]
|
||||||
|
|
@ -71,7 +59,7 @@ module Mutant
|
||||||
# @api private
|
# @api private
|
||||||
#
|
#
|
||||||
def run
|
def run
|
||||||
subjects.each do |subject|
|
matcher.each do |subject|
|
||||||
reporter.subject(subject)
|
reporter.subject(subject)
|
||||||
run_subject(subject)
|
run_subject(subject)
|
||||||
end
|
end
|
||||||
|
|
@ -111,13 +99,3 @@ module Mutant
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return candiate matcher enumerator
|
|
||||||
#
|
|
||||||
# @return [Enumerable<Class<Matcher>>]
|
|
||||||
#
|
|
||||||
# @api private
|
|
||||||
#
|
|
||||||
def candidate_matchers
|
|
||||||
[Matcher::Method::Singleton, Matcher::Method::Instance].each
|
|
||||||
end
|
|
||||||
|
|
|
||||||
|
|
@ -23,5 +23,6 @@ Gem::Specification.new do |gem|
|
||||||
gem.add_runtime_dependency('immutable', '~> 0.0.1')
|
gem.add_runtime_dependency('immutable', '~> 0.0.1')
|
||||||
gem.add_runtime_dependency('equalizer', '~> 0.0.1')
|
gem.add_runtime_dependency('equalizer', '~> 0.0.1')
|
||||||
gem.add_runtime_dependency('abstract_class', '~> 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')
|
gem.add_runtime_dependency('diff-lcs', '~> 1.1.3')
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Mutant, 'runner' do
|
describe Mutant, 'runner' do
|
||||||
before do
|
|
||||||
pending
|
|
||||||
end
|
|
||||||
|
|
||||||
around do |example|
|
around do |example|
|
||||||
Dir.chdir(TestApp.root) do
|
Dir.chdir(TestApp.root) do
|
||||||
example.run
|
example.run
|
||||||
|
|
@ -14,13 +10,13 @@ describe Mutant, 'runner' do
|
||||||
it 'allows to run mutant over a project' do
|
it 'allows to run mutant over a project' do
|
||||||
output = StringIO.new
|
output = StringIO.new
|
||||||
runner = Mutant::Runner.run(
|
runner = Mutant::Runner.run(
|
||||||
:pattern => /\ATestApp::/,
|
|
||||||
:killer => Mutant::Killer::Rspec,
|
:killer => Mutant::Killer::Rspec,
|
||||||
|
:matcher => Mutant::Matcher::ObjectSpace.new(/\ATestApp::/),
|
||||||
:reporter => Mutant::Reporter::CLI.new(output)
|
:reporter => Mutant::Reporter::CLI.new(output)
|
||||||
)
|
)
|
||||||
runner.fail?.should be(true)
|
runner.fail?.should be(true)
|
||||||
runner.errors.size.should be(22)
|
runner.errors.size.should be(22)
|
||||||
output.rewind
|
output.rewind
|
||||||
output.lines.grep(/Mutation/).size.should be(22)
|
output.lines.grep(/Mutant alive:/).size.should be(22)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ shared_examples_for 'an invalid cli run' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Mutant::CLI, '#runner_options' do
|
describe Mutant::CLI, '#attributes' do
|
||||||
subject { object.runner_options }
|
subject { object.attributes }
|
||||||
|
|
||||||
let(:object) { described_class.new(arguments) }
|
let(:object) { described_class.new(arguments) }
|
||||||
|
|
||||||
|
|
@ -5,22 +5,22 @@ describe Mutant::CLI, '.run' do
|
||||||
|
|
||||||
let(:object) { described_class }
|
let(:object) { described_class }
|
||||||
let(:argv) { mock('ARGV') }
|
let(:argv) { mock('ARGV') }
|
||||||
let(:options) { mock('Options') }
|
let(:attributes) { mock('Options') }
|
||||||
let(:runner) { mock('Runner', :fail? => failure) }
|
let(:runner) { mock('Runner', :fail? => failure) }
|
||||||
let(:instance) { mock(described_class.name, :runner_options => options) }
|
let(:instance) { mock(described_class.name, :attributes => attributes) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
described_class.stub(:new => instance)
|
described_class.stub(:new => instance)
|
||||||
Mutant::Runner.stub(:run => runner)
|
Mutant::Runner.stub(:run => runner)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when runner NOT fails' do
|
context 'when runner does NOT fail' do
|
||||||
let(:failure) { false }
|
let(:failure) { false }
|
||||||
|
|
||||||
it { should be(0) }
|
it { should be(0) }
|
||||||
|
|
||||||
it 'should run with options' do
|
it 'should run with attributes' do
|
||||||
Mutant::Runner.should_receive(:run).with(options).and_return(runner)
|
Mutant::Runner.should_receive(:run).with(attributes).and_return(runner)
|
||||||
should be(0)
|
should be(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -30,8 +30,8 @@ describe Mutant::CLI, '.run' do
|
||||||
|
|
||||||
it { should be(1) }
|
it { should be(1) }
|
||||||
|
|
||||||
it 'should run with options' do
|
it 'should run with attributes' do
|
||||||
Mutant::Runner.should_receive(:run).with(options).and_return(runner)
|
Mutant::Runner.should_receive(:run).with(attributes).and_return(runner)
|
||||||
should be(1)
|
should be(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ describe Mutant::Matcher, '.from_string' do
|
||||||
it_should_behave_like 'an idempotent method'
|
it_should_behave_like 'an idempotent method'
|
||||||
end
|
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') }
|
let(:matcher_b) { mock('Matcher B') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue