From 3224789680c21ce14c28eafdb9126b4a29611325 Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Mon, 2 Sep 2013 00:07:55 +0200 Subject: [PATCH] Refactor strategy CLI parsing * Add CLI::Builder::Rspec * Remove defunct static stragies * Add --rspec-level argument --- lib/mutant.rb | 2 +- lib/mutant/cli.rb | 57 +++++++------------ lib/mutant/cli/builder.rb | 21 ++++++- lib/mutant/strategy/rspec.rb | 2 +- spec/unit/mutant/cli/builder/rspec_spec.rb | 33 ++++++++++- .../unit/mutant/cli/class_methods/new_spec.rb | 6 +- 6 files changed, 75 insertions(+), 46 deletions(-) diff --git a/lib/mutant.rb b/lib/mutant.rb index a2116e5c..25708235 100644 --- a/lib/mutant.rb +++ b/lib/mutant.rb @@ -105,7 +105,6 @@ require 'mutant/killer/rspec' require 'mutant/killer/forking' require 'mutant/killer/forked' require 'mutant/strategy' -require 'mutant/strategy/static' require 'mutant/strategy/rspec' require 'mutant/runner' require 'mutant/runner/config' @@ -115,6 +114,7 @@ require 'mutant/cli' require 'mutant/cli/classifier' require 'mutant/cli/classifier/namespace' require 'mutant/cli/classifier/method' +require 'mutant/cli/builder' require 'mutant/color' require 'mutant/differ' require 'mutant/reporter' diff --git a/lib/mutant/cli.rb b/lib/mutant/cli.rb index 7641ae62..8a096c4e 100644 --- a/lib/mutant/cli.rb +++ b/lib/mutant/cli.rb @@ -42,12 +42,11 @@ module Mutant # def initialize(arguments = []) @filters, @matchers = [], [] - + @debug = @fail_fast = @zombie = false @cache = Mutant::Cache.new parse(arguments) - strategy - matcher + config # trigger lazyness end # Return config @@ -72,6 +71,8 @@ module Mutant private + attr_writer :strategy_builder + # Test for running in debug mode # # @return [true] @@ -99,7 +100,6 @@ module Mutant Mutation::Filter::Whitelist.new(@filters) end end - memoize :filter # Return stratety # @@ -108,9 +108,11 @@ module Mutant # @api private # def strategy - @strategy or raise(Error, 'No strategy was set!') + unless @strategy_builder + raise(Error, 'No strategy was set!') + end + @strategy_builder.strategy end - memoize :strategy # Return reporter # @@ -121,7 +123,6 @@ module Mutant def reporter Reporter::CLI.new($stdout) end - memoize :reporter # Return matcher # @@ -134,12 +135,11 @@ module Mutant # def matcher if @matchers.empty? - raise Error, 'No matchers given' + raise(Error, 'No matchers given') end Matcher::Chain.build(@matchers) end - memoize :matcher # Add mutation filter # @@ -155,18 +155,6 @@ module Mutant @filters << klass.new(filter) end - # Set strategy - # - # @param [Strategy] strategy - # - # @api private - # - # @return [undefined] - # - def set_strategy(strategy) - @strategy = strategy - end - # Parse the command-line options # # @param [Array] arguments @@ -182,9 +170,7 @@ module Mutant def parse(arguments) opts = OptionParser.new do |builder| builder.banner = 'usage: mutant STRATEGY [options] MATCHERS ...' - builder.separator '' - builder.separator 'Strategies:' - + builder.separator('') add_strategies(builder) add_environmental_options(builder) add_options(builder) @@ -217,24 +203,20 @@ module Mutant # Add strategies # - # @param [Object] opts + # @param [OptionParser] parser # # @return [undefined] # # @api private # - def add_strategies(opts) - opts.separator '' - opts.separator 'Strategies:' + def add_strategies(parser) + parser.separator(EMPTY_STRING) + parser.separator('Strategies:') - opts.on('--static-success', 'does succeed on all mutations') do - set_strategy Strategy::Static::Success.new - end - opts.on('--static-fail', 'does fail on all mutations') do - set_strategy Strategy::Static::Fail.new - end - opts.on('--rspec', 'kills mutations with rspec') do - set_strategy Strategy::Rspec.new + [ + Builder::Rspec + ].each do |builder| + builder.add_options(parser, &method(:strategy_builder=)) end end @@ -252,7 +234,7 @@ module Mutant end.on('-I', 'Add directory to $LOAD_PATH') do |directory| $LOAD_PATH << directory end.on('-r', '--require NAME', 'Require file with NAME') do |name| - require name + require(name) end end @@ -282,6 +264,5 @@ module Mutant exit end end - end # CLI end # Mutant diff --git a/lib/mutant/cli/builder.rb b/lib/mutant/cli/builder.rb index 6c51d117..fc120657 100644 --- a/lib/mutant/cli/builder.rb +++ b/lib/mutant/cli/builder.rb @@ -2,9 +2,10 @@ module Mutant class CLI # Abstract base class for strategy builders class Builder + include AbstractType # Rspec strategy builder - class Rspec + class Rspec < self # Initialize object # @@ -37,6 +38,24 @@ module Mutant Strategy::Rspec.new(@level) end + # Add cli options + # + # @param [OptionParser] parser + # + # @return [undefined] + # + # @api private + # + def self.add_options(parser) + builder = new + parser.on('--rspec', 'kills mutations with rspec') do + yield builder + end + parser.on('--rspec-level LEVEL', 'set rspec expansion level') do |level| + builder.set_level(level.to_i) + end + end + end # Rspec end # Builder end # CLI diff --git a/lib/mutant/strategy/rspec.rb b/lib/mutant/strategy/rspec.rb index 7376122f..c8060e66 100644 --- a/lib/mutant/strategy/rspec.rb +++ b/lib/mutant/strategy/rspec.rb @@ -4,7 +4,7 @@ module Mutant class Strategy # Rspec killer strategy class Rspec < self - include Equalizer.new + include Concord.new(:level) KILLER = Killer::Forking.new(Killer::Rspec) diff --git a/spec/unit/mutant/cli/builder/rspec_spec.rb b/spec/unit/mutant/cli/builder/rspec_spec.rb index 42d49f02..155e0b79 100644 --- a/spec/unit/mutant/cli/builder/rspec_spec.rb +++ b/spec/unit/mutant/cli/builder/rspec_spec.rb @@ -1,11 +1,40 @@ require 'spec_helper' describe Mutant::CLI::Builder::Rspec do + let(:object) { described_class.new } + let(:level) { double('Level') } + + let(:default_strategy) do + Mutant::Strategy::Rspec.new(0) + end + + let(:altered_strategy) do + Mutant::Strategy::Rspec.new(level) + end + + describe '#set_level' do + subject { object.set_level(level) } + + specify do + expect { subject }.to change { object.strategy }.from(default_strategy).to(altered_strategy) + end + end describe '#strategy' do - let(:level) { double('Level') } + subject { object.strategy } - it { should eql(Mutant::Strategy::Rspec.new(level)) } + context 'without setting a level' do + it { should eql(Mutant::Strategy::Rspec.new(0)) } + end + + context 'with setting a level' do + + before do + object.set_level(level) + end + + it { should eql(Mutant::Strategy::Rspec.new(level)) } + end end end diff --git a/spec/unit/mutant/cli/class_methods/new_spec.rb b/spec/unit/mutant/cli/class_methods/new_spec.rb index 1c719fd9..b712efcb 100644 --- a/spec/unit/mutant/cli/class_methods/new_spec.rb +++ b/spec/unit/mutant/cli/class_methods/new_spec.rb @@ -29,7 +29,7 @@ describe Mutant::CLI, '.new' do # Defaults let(:expected_filter) { Mutant::Mutation::Filter::ALL } - let(:expected_strategy) { Mutant::Strategy::Rspec.new } + let(:expected_strategy) { Mutant::Strategy::Rspec.new(0) } let(:expected_reporter) { Mutant::Reporter::CLI.new($stdout) } let(:ns) { Mutant::CLI::Classifier } @@ -56,7 +56,7 @@ describe Mutant::CLI, '.new' do end context 'with many strategy flags' do - let(:arguments) { %w(--static-fail --rspec TestApp) } + let(:arguments) { %w(--rspec --rspec TestApp) } let(:expected_matcher) { Mutant::CLI::Classifier::Namespace::Flat.new(Mutant::Cache.new, 'TestApp') } it_should_behave_like 'a cli parser' @@ -65,7 +65,7 @@ describe Mutant::CLI, '.new' do context 'without arguments' do let(:arguments) { [] } - let(:expected_message) { 'No strategy was set!' } + let(:expected_message) { 'No matchers given' } it_should_behave_like 'an invalid cli run' end