From 6f8d4e1cfa2346992e7414e3d314dc514725842f Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Mon, 13 Aug 2012 20:40:00 +0200 Subject: [PATCH] Do not create empty blocks on mutations --- lib/mutant/mutator/block.rb | 8 +++- spec/shared/mutator_behavior.rb | 5 ++- .../mutant/mutator/block/mutation_spec.rb | 38 +++++++++++++------ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/mutant/mutator/block.rb b/lib/mutant/mutator/block.rb index 7153af1a..68994bee 100644 --- a/lib/mutant/mutator/block.rb +++ b/lib/mutant/mutator/block.rb @@ -3,7 +3,7 @@ module Mutant # Mutator on AST blocks class Block < self - handle Rubinius::AST::Block + handle(Rubinius::AST::Block) private @@ -16,7 +16,11 @@ module Mutant def dispatch array = node.array emit_elements(array) - emit_element_presence(array) + if array.length > 1 + emit_element_presence(array) + else + emit_self([new_nil]) + end end end end diff --git a/spec/shared/mutator_behavior.rb b/spec/shared/mutator_behavior.rb index 9cfa8e44..f6eacd30 100644 --- a/spec/shared/mutator_behavior.rb +++ b/spec/shared/mutator_behavior.rb @@ -3,7 +3,10 @@ shared_examples_for 'a mutator' do let(:yields) { [] } let(:object) { described_class } - let(:node) { source.to_ast } + + unless instance_methods.map(&:to_s).include?('node') + let(:node) { source.to_ast } + end it_should_behave_like 'a command method' diff --git a/spec/unit/mutant/mutator/block/mutation_spec.rb b/spec/unit/mutant/mutator/block/mutation_spec.rb index 98deae8f..9551f94a 100644 --- a/spec/unit/mutant/mutator/block/mutation_spec.rb +++ b/spec/unit/mutant/mutator/block/mutation_spec.rb @@ -1,20 +1,36 @@ require 'spec_helper' describe Mutant::Mutator, 'block' do - # Two send operations - let(:source) { "self.foo\nself.bar" } - let(:mutations) do - mutations = [] + context 'with more than one statement' do + let(:source) { "self.foo\nself.bar" } - # Mutation of each statement in block - mutations << "foo\nself.bar" - mutations << "self.foo\nbar" + let(:mutations) do + mutations = [] - ## Remove statement in block - mutations << [:block, 'self.foo'.to_sexp] - mutations << [:block, 'self.bar'.to_sexp] + # Mutation of each statement in block + mutations << "foo\nself.bar" + mutations << "self.foo\nbar" + + ## Remove statement in block + mutations << [:block, 'self.foo'.to_sexp] + mutations << [:block, 'self.bar'.to_sexp] + end + + it_should_behave_like 'a mutator' end - it_should_behave_like 'a mutator' + + context 'with one statement' do + let(:node) { Rubinius::AST::Block.new(1, ['self.foo'.to_ast]) } + + let(:mutations) do + mutations = [] + mutations << [:block, 'foo'.to_sexp] + # Empty blocks result in stack verification error + mutations << [:block, 'nil'.to_sexp] + end + + it_should_behave_like 'a mutator' + end end