From 71c4a1999702428a38b2b9b904218e0168366444 Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Sat, 2 Feb 2013 16:56:48 +0100 Subject: [PATCH] Move CLI parsing specific stuff in subclass Not ideal, but a first step to improve SRP here. --- lib/mutant.rb | 1 + lib/mutant/cli.rb | 122 ++++-------------- lib/mutant/cli_parser.rb | 87 +++++++++++++ .../unit/mutant/cli/class_methods/new_spec.rb | 2 +- 4 files changed, 117 insertions(+), 95 deletions(-) create mode 100644 lib/mutant/cli_parser.rb diff --git a/lib/mutant.rb b/lib/mutant.rb index 80afe777..7d376f5e 100644 --- a/lib/mutant.rb +++ b/lib/mutant.rb @@ -111,6 +111,7 @@ require 'mutant/runner' require 'mutant/runner/config' require 'mutant/runner/subject' require 'mutant/runner/mutation' +require 'mutant/cli_parser' require 'mutant/cli' require 'mutant/cli/classifier' require 'mutant/cli/classifier/namespace' diff --git a/lib/mutant/cli.rb b/lib/mutant/cli.rb index 484ec836..9ca5755c 100644 --- a/lib/mutant/cli.rb +++ b/lib/mutant/cli.rb @@ -1,27 +1,9 @@ module Mutant + # Comandline parser - class CLI + class CLI < CLIParser include Adamantium::Flat, Equalizer.new(:matcher, :filter, :strategy, :reporter) - # Error raised when CLI argv is inalid - Error = Class.new(RuntimeError) - - EXIT_FAILURE = 1 - EXIT_SUCCESS = 0 - - OPTIONS = { - '--code' => [:add_filter, Mutation::Filter::Code ], - '--debug' => [:set_debug ], - '-d' => [:set_debug ], - '--rspec-unit' => [:set_strategy, Strategy::Rspec::Unit ], - '--rspec-full' => [:set_strategy, Strategy::Rspec::Full ], - '--rspec-dm2' => [:set_strategy, Strategy::Rspec::DM2 ], - '--static-fail' => [:set_strategy, Strategy::Static::Fail ], - '--static-success' => [:set_strategy, Strategy::Static::Success ] - }.freeze - - OPTION_PATTERN = %r(\A-(?:-)?[a-zA-Z0-9\-]+\z).freeze - # Run cli with arguments # # @param [Array] arguments @@ -40,23 +22,29 @@ module Mutant EXIT_FAILURE end - # Return matcher + OPTIONS = { + '--code' => [:add_filter, Mutation::Filter::Code ], + '--debug' => [:set_debug ], + '-d' => [:set_debug ], + '--rspec-unit' => [:set_strategy, Strategy::Rspec::Unit ], + '--rspec-full' => [:set_strategy, Strategy::Rspec::Full ], + '--rspec-dm2' => [:set_strategy, Strategy::Rspec::DM2 ] + }.freeze + + # Initialize objecct # - # @return [Mutant::Matcher] + # @param [Array] # - # @raise [CLI::Error] - # raises error when matcher is not given + # @return [undefined] # # @api private # - def matcher - if @matchers.empty? - raise Error, 'No matchers given' - end - - Mutant::Matcher::Chain.build(@matchers) + def initialize(arguments) + @filters, @matchers = [], [] + super(arguments) + strategy + matcher end - memoize :matcher # Test for running in debug mode # @@ -112,77 +100,23 @@ module Mutant private - # Initialize CLI + # Return matcher # - # @param [Array] arguments - # - # @return [undefined] - # - # @api private - # - def initialize(arguments) - @filters, @matchers = [], [] - - @arguments, @index = arguments, 0 - - while @index < @arguments.length - dispatch - end - - strategy - matcher - end - - # Return option for argument with index - # - # @param [Fixnum] index - # - # @return [String] - # - # @api private - # - def option(index) - @arguments.fetch(index+1) - end - - # Return current argument - # - # @return [String] - # - # @api private - # - def current_argument - @arguments.fetch(@index) - end - - # Return current option value - # - # @return [String] + # @return [Mutant::Matcher] # # @raise [CLI::Error] - # raises error when option is missing + # raises error when matcher is not given # # @api private # - def current_option_value - @arguments.fetch(@index+1) - rescue IndexError - raise Error, "#{current_argument.inspect} is missing an argument" - end - - # Process current argument - # - # @return [undefined] - # - # @api private - # - def dispatch - if OPTION_PATTERN =~ current_argument - dispatch_option - else - dispatch_matcher + def matcher + if @matchers.empty? + raise Error, 'No matchers given' end + + Mutant::Matcher::Chain.build(@matchers) end + memoize :matcher # Move processed argument by amount # diff --git a/lib/mutant/cli_parser.rb b/lib/mutant/cli_parser.rb new file mode 100644 index 00000000..3e3c7957 --- /dev/null +++ b/lib/mutant/cli_parser.rb @@ -0,0 +1,87 @@ +module Mutant + # Base class for cli parsers + # + # I hate base classes for reusable functionallity. + # But could not come up with a nice composition/instantiation + # solution. + # + class CLIParser + + # Error raised when CLI argv is inalid + Error = Class.new(RuntimeError) + + EXIT_FAILURE = 1 + EXIT_SUCCESS = 0 + + OPTION_PATTERN = %r(\A-(?:-)?[a-zA-Z0-9\-]+\z).freeze + + # Initialize CLI + # + # @param [Array] arguments + # + # @return [undefined] + # + # @api private + # + def initialize(arguments) + @arguments, @index = arguments, 0 + while @index < @arguments.length + dispatch + end + end + + private + + # Return option for argument with index + # + # @param [Fixnum] index + # + # @return [String] + # + # @api private + # + def option(index) + @arguments.fetch(index+1) + end + + # Return current argument + # + # @return [String] + # + # @api private + # + def current_argument + @arguments.fetch(@index) + end + + # Return current option value + # + # @return [String] + # + # @raise [CLI::Error] + # raises error when option is missing + # + # @api private + # + def current_option_value + @arguments.fetch(@index+1) + rescue IndexError + raise Error, "#{current_argument.inspect} is missing an argument" + end + + # Process current argument + # + # @return [undefined] + # + # @api private + # + def dispatch + if OPTION_PATTERN =~ current_argument + dispatch_option + else + dispatch_matcher + end + 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 79d1fc4e..82b8942b 100644 --- a/spec/unit/mutant/cli/class_methods/new_spec.rb +++ b/spec/unit/mutant/cli/class_methods/new_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' shared_examples_for 'an invalid cli run' do it 'should raise error' do - expect { subject }.to raise_error(described_class::Error, expected_message) + expect { subject }.to raise_error(Mutant::CLIParser::Error, expected_message) end end