From 27d8387795321fa301626f6d8cf51cb9baf0ee52 Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Sun, 1 Dec 2013 22:42:52 +0100 Subject: [PATCH] Add explicit resbody mutator Closes: #117 --- lib/mutant.rb | 1 + lib/mutant/mutator/node/generic.rb | 2 +- lib/mutant/mutator/node/resbody.rb | 45 ++++++++++++ .../mutator/node/rescue/mutation_spec.rb | 71 ++++++++++++++++--- 4 files changed, 107 insertions(+), 12 deletions(-) create mode 100644 lib/mutant/mutator/node/resbody.rb diff --git a/lib/mutant.rb b/lib/mutant.rb index c5cecf4d..3cf79b92 100644 --- a/lib/mutant.rb +++ b/lib/mutant.rb @@ -92,6 +92,7 @@ require 'mutant/mutator/node/block' require 'mutant/mutator/node/if' require 'mutant/mutator/node/case' require 'mutant/mutator/node/splat' +require 'mutant/mutator/node/resbody' require 'mutant/config' require 'mutant/loader' require 'mutant/context' diff --git a/lib/mutant/mutator/node/generic.rb b/lib/mutant/mutator/node/generic.rb index fccafb27..33cd6ebb 100644 --- a/lib/mutant/mutator/node/generic.rb +++ b/lib/mutant/mutator/node/generic.rb @@ -12,7 +12,7 @@ module Mutant handle( :ensure, :rescue, :redo, :defined?, - :regopt, :resbody, :retry, :arg_expr, + :regopt, :retry, :arg_expr, :kwrestarg, :kwoptarg, :kwarg, :undef, :module, :empty, :alias, :for, :xstr, :back_ref, :class, :sclass, :match_with_lvasgn, :match_current_line diff --git a/lib/mutant/mutator/node/resbody.rb b/lib/mutant/mutator/node/resbody.rb new file mode 100644 index 00000000..c91babfa --- /dev/null +++ b/lib/mutant/mutator/node/resbody.rb @@ -0,0 +1,45 @@ +module Mutant + class Mutator + class Node + # Mutator for resbody nodes + class Resbody < self + + handle(:resbody) + + children :captures, :assignment, :block + + private + + # Emit mutations + # + # @return [undefined] + # + # @api private + # + def dispatch + emit_assignment(nil) + emit_block_mutations if block + mutate_captures + end + + # Mutate captures + # + # @return [undefined] + # + # @api private + # + def mutate_captures + return unless captures + emit_captures(nil) + Util::Array.each(captures.children, self) do |matchers| + next if matchers.empty? + emit_captures(s(:array, *matchers)) + # p capture + # emit_captures(s(:array, *capture)) + end + end + + end # Resbody + end # Node + end # Mutator +end # Mutant diff --git a/spec/unit/mutant/mutator/node/rescue/mutation_spec.rb b/spec/unit/mutant/mutator/node/rescue/mutation_spec.rb index 25fbf5fd..504f404c 100644 --- a/spec/unit/mutant/mutator/node/rescue/mutation_spec.rb +++ b/spec/unit/mutant/mutator/node/rescue/mutation_spec.rb @@ -3,22 +3,71 @@ require 'spec_helper' describe Mutant::Mutator::Node::Generic, 'rescue' do - let(:source) { 'begin; rescue Exception => e; true end' } - - let(:mutations) do - mutations = [] - mutations << 'begin; rescue Exception => srandom; true; end' - mutations << 'begin; rescue Exception => e; false; end' - mutations << 'begin; rescue Exception => e; nil; end' - mutations << 'begin; rescue nil => e; true; end' -# mutations << 'begin; rescue => e; true; end' # FIXME - end before do Mutant::Random.stub(hex_string: 'random') end - pending do + context 'multiple exception selectors and assignment' do + let(:source) { 'begin; rescue ExceptionA, ExceptionB => error; true; end' } + + let(:mutations) do + mutations = [] + mutations << 'nil' + # mutations << 'begin; rescue ExceptionA, ExceptionB => error; true; end' + mutations << 'begin; rescue ExceptionA, ExceptionB; true; end' + mutations << 'begin; rescue ExceptionA, ExceptionB => error; false; end' + mutations << 'begin; rescue ExceptionA, ExceptionB => error; nil; end' + mutations << 'begin; rescue ExceptionA, nil => error; true; end' + mutations << 'begin; rescue ExceptionA => error; true; end' + mutations << 'begin; rescue ExceptionB => error; true; end' + mutations << 'begin; rescue nil, ExceptionB => error; true; end' + mutations << 'begin; rescue => error; true; end' + end + + it_should_behave_like 'a mutator' + end + + context 'single exception selector and assignment' do + let(:source) { 'begin; rescue Exception => error; true; end' } + + let(:mutations) do + mutations = [] + mutations << 'nil' + mutations << 'begin; rescue Exception; true; end' + mutations << 'begin; rescue Exception => error; false; end' + mutations << 'begin; rescue Exception => error; nil; end' + mutations << 'begin; rescue nil => error; true; end' + mutations << 'begin; rescue => error; true; end' + end + + it_should_behave_like 'a mutator' + end + + context 'no exection selector and assignment' do + let(:source) { 'begin; rescue => error; true end' } + + let(:mutations) do + mutations = [] + mutations << 'nil' + mutations << 'begin; rescue => error; false; end' + mutations << 'begin; rescue => error; nil; end' + mutations << 'begin; rescue; true; end' + end + + it_should_behave_like 'a mutator' + end + + context 'no exection selector and no assignment' do + let(:source) { 'begin; rescue; true end' } + + let(:mutations) do + mutations = [] + mutations << 'nil' + mutations << 'begin; rescue; false; end' + mutations << 'begin; rescue; nil; end' + end + it_should_behave_like 'a mutator' end end