From b5430e2000d83517119b7a1b85e487cb18e4b25c Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Fri, 7 Dec 2012 23:27:21 +0100 Subject: [PATCH] Cleanup crashes and invalid mutants --- Changelog.md | 5 ++ Gemfile | 2 +- lib/mutant.rb | 4 +- lib/mutant/matcher/method.rb | 41 ++++++----- lib/mutant/matcher/method/classifier.rb | 27 ++++++-- lib/mutant/matcher/method/instance.rb | 11 --- lib/mutant/matcher/method/singleton.rb | 11 --- lib/mutant/matcher/scope_methods.rb | 69 +++++++++++++++---- lib/mutant/mutator/node/block.rb | 20 ++++++ lib/mutant/mutator/node/if_statement.rb | 4 +- lib/mutant/mutator/node/literal/range.rb | 2 +- lib/mutant/strategy/rspec.rb | 8 +-- lib/mutant/strategy/rspec/example_lookup.rb | 16 ++++- spec/shared/method_filter_parse_behavior.rb | 16 ----- spec/shared/mutator_behavior.rb | 28 +++++--- .../classifier/class_methods/run_spec.rb | 38 +++++++--- .../unit/mutant/matcher/method/method_spec.rb | 11 --- .../mutator/node/block/mutation_spec.rb | 17 ++--- .../mutator/node/define/mutation_spec.rb | 4 +- .../node/if_statement/mutation_spec.rb | 64 ++++++++++++----- .../mutant/mutator/node/literal/array_spec.rb | 2 +- .../mutator/node/literal/empty_array_spec.rb | 2 +- .../mutator/node/literal/fixnum_spec.rb | 2 +- .../mutant/mutator/node/literal/float_spec.rb | 4 +- .../mutant/mutator/node/literal/hash_spec.rb | 26 +++---- .../mutant/mutator/node/literal/range_spec.rb | 4 +- .../rspec/example_lookup/spec_file_spec.rb | 15 ++++ 27 files changed, 291 insertions(+), 162 deletions(-) delete mode 100644 spec/shared/method_filter_parse_behavior.rb delete mode 100644 spec/unit/mutant/matcher/method/method_spec.rb diff --git a/Changelog.md b/Changelog.md index 868dd841..d489e2b2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,10 @@ # v0.2.1 xxx +* [fixed] Crash on unavailable source location +* [fixed] Incorrect handling of if and unless statements +* [fixed] Expand Foo#initialize to spec/unit/foo in rspec dm2 strategy +* [fixed] Correctly expand [] to element_reader_spec.rb in rspec dm2 strategy +* [fixed] Correctly expand []= to element_writer_spec.rb in rspec dm2 strategy * [fixed] Correctly expand foo= to foo_writer_spec.rb in rspec dm2 strategy [Compare v0.2.0..v0.2.1](https://github.com/mbj/mutant/compare/v0.2.0...v0.2.1) diff --git a/Gemfile b/Gemfile index 21f4562d..8a136bfc 100644 --- a/Gemfile +++ b/Gemfile @@ -2,5 +2,5 @@ source 'https://rubygems.org' gemspec -gem 'devtools', :git => 'https://github.com/mbj/devtools.git', :branch => :'rspec-2-mutant' +gem 'devtools', :git => 'https://github.com/mbj/devtools.git' eval(File.read(File.join(File.dirname(__FILE__),'Gemfile.devtools'))) diff --git a/lib/mutant.rb b/lib/mutant.rb index 81e2eb01..4cadb4c0 100644 --- a/lib/mutant.rb +++ b/lib/mutant.rb @@ -41,6 +41,8 @@ module Mutant self end + PID = Process.pid + end require 'mutant/support/method_object' @@ -84,8 +86,8 @@ require 'mutant/matcher/object_space' require 'mutant/matcher/method' require 'mutant/matcher/method/singleton' require 'mutant/matcher/method/instance' -require 'mutant/matcher/method/classifier' require 'mutant/matcher/scope_methods' +require 'mutant/matcher/method/classifier' require 'mutant/killer' require 'mutant/killer/static' require 'mutant/killer/rspec' diff --git a/lib/mutant/matcher/method.rb b/lib/mutant/matcher/method.rb index c38373d5..458f8691 100644 --- a/lib/mutant/matcher/method.rb +++ b/lib/mutant/matcher/method.rb @@ -28,6 +28,12 @@ module Mutant # def each(&block) return to_enum unless block_given? + + unless source_location + $stderr.puts "#{method.inspect} does not have source location unable to emit matcher" + return self + end + subject.tap do |subject| yield subject if subject end @@ -35,6 +41,14 @@ module Mutant self end + # Return method + # + # @return [UnboundMethod, Method] + # + # @api private + # + attr_reader :method + # Return scope # # @return [Class|Module] @@ -43,21 +57,15 @@ module Mutant # attr_reader :scope - # Return context - # - # @return [Context::Scope] - # - # @api private - # - attr_reader :context - # Return method name # # @return [String] # # @api private # - attr_reader :method_name + def method_name + method.name + end # Test if method is public # @@ -76,26 +84,27 @@ module Mutant # Initialize method filter # # @param [Class|Module] scope - # @param [Symbol] method_name + # @param [Method, UnboundMethod] method # # @return [undefined] # # @api private # - def initialize(scope, method_name) - @scope, @method_name = scope, method_name.to_sym - @context = Context::Scope.build(scope, source_path) + def initialize(scope, method) + @scope, @method = scope, method # FIXME: cache public private should not be needed, loader should not override visibility! (But does currently) :( public? end - # Return method + # Return context # - # @return [UnboundMethod, Method] + # @return [Context::Scope] # # @api private # - abstract_method :method + def context + Context::Scope.build(scope, source_path) + end # Return full ast # diff --git a/lib/mutant/matcher/method/classifier.rb b/lib/mutant/matcher/method/classifier.rb index eb2a833c..a3cc763a 100644 --- a/lib/mutant/matcher/method/classifier.rb +++ b/lib/mutant/matcher/method/classifier.rb @@ -6,15 +6,15 @@ module Mutant include Adamantium::Flat TABLE = { - '.' => Matcher::Method::Singleton, - '#' => Matcher::Method::Instance + '.' => Matcher::ScopeMethods::Singleton, + '#' => Matcher::ScopeMethods::Instance }.freeze SCOPE_FORMAT = /\A([^#.]+)(\.|#)(.+)\z/.freeze # Positions of captured regexp groups # Freezing fixnums to avoid their singleton classes are patched. - SCOPE_NAME_POSITION = 1.freeze + SCOPE_NAME_POSITION = 1.freeze SCOPE_SYMBOL_POSITION = 2.freeze METHOD_NAME_POSITION = 3.freeze @@ -45,8 +45,22 @@ module Mutant # @api private # def matcher - matcher_class.new(scope, method_name) + scope_matcher.matcher.new(scope, method) end + memoize :matcher + + # Return method + # + # @return [Method, UnboundMethod] + # + # @api private + # + def method + scope_matcher.methods.detect do |method| + method.name == method_name + end || raise("Cannot find #{method_name} for #{scope}") + end + memoize :method, :freezer => :noop # Return match # @@ -117,9 +131,10 @@ module Mutant # # @api private # - def matcher_class - TABLE.fetch(scope_symbol) + def scope_matcher + TABLE.fetch(scope_symbol).new(scope) end + memoize :scope_matcher end end end diff --git a/lib/mutant/matcher/method/instance.rb b/lib/mutant/matcher/method/instance.rb index df6c2911..0dd0d50d 100644 --- a/lib/mutant/matcher/method/instance.rb +++ b/lib/mutant/matcher/method/instance.rb @@ -50,17 +50,6 @@ module Mutant node.name == method_name end - # Return method instance - # - # @return [UnboundMethod] - # - # @api private - # - def method - scope.instance_method(method_name) - end - memoize :method, :freezer => :noop - end end end diff --git a/lib/mutant/matcher/method/singleton.rb b/lib/mutant/matcher/method/singleton.rb index f941d9fd..c46ef0a2 100644 --- a/lib/mutant/matcher/method/singleton.rb +++ b/lib/mutant/matcher/method/singleton.rb @@ -33,17 +33,6 @@ module Mutant private - # Return method instance - # - # @return [UnboundMethod] - # - # @api private - # - def method - scope.method(method_name) - end - memoize :method, :freezer => :noop - # Test for node match # # @param [Rubinius::AST::Node] node diff --git a/lib/mutant/matcher/scope_methods.rb b/lib/mutant/matcher/scope_methods.rb index 97fcfb05..24d82fcb 100644 --- a/lib/mutant/matcher/scope_methods.rb +++ b/lib/mutant/matcher/scope_methods.rb @@ -24,6 +24,7 @@ module Mutant # def each(&block) return to_enum unless block_given? + methods.each do |method| emit_matches(method, &block) end @@ -31,6 +32,29 @@ module Mutant self end + # Return methods + # + # @return [Enumerable] + # + # @api private + # + def methods + method_names.map do |name| + access(name) + end + end + memoize :methods + + # Return method matcher class + # + # @return [Class:Matcher::Method] + # + # @api private + # + def matcher + self.class::MATCHER + end + private # Initialize object @@ -47,7 +71,7 @@ module Mutant # Emit matches for method # - # @param [UnboundMethod] method + # @param [UnboundMethod, Method] method # # @return [undefined] # @@ -59,22 +83,29 @@ module Mutant end end - - abstract_method :methods - - # Return method matcher class + # Return method names # - # @return [Class:Matcher::Method] + # @return [Enumerable] # # @api private # - def matcher - self.class::MATCHER - end + abstract_method :method_names class Singleton < self MATCHER = Mutant::Matcher::Method::Singleton + # Return method for name + # + # @param [Symbol] method_name + # + # @return [Method] + # + # @api private + # + def access(method_name) + scope.method(method_name) + end + private # Return singleton methods defined on scope @@ -85,7 +116,7 @@ module Mutant # # @api private # - def methods + def method_names singleton_class = scope.singleton_class names = @@ -93,7 +124,7 @@ module Mutant singleton_class.private_instance_methods(false) + singleton_class.protected_instance_methods(false) - names.map(&:to_sym).sort.reject do |name| + names.sort.reject do |name| name.to_sym == :__class_init__ end end @@ -102,6 +133,18 @@ module Mutant class Instance < self MATCHER = Mutant::Matcher::Method::Instance + # Return method for name + # + # @param [Symbol] method_name + # + # @return [UnboundMethod] + # + # @api private + # + def access(method_name) + scope.instance_method(method_name) + end + private # Return instance methods names of scope @@ -110,7 +153,7 @@ module Mutant # # @return [Enumerable] # - def methods + def method_names scope = self.scope return [] unless scope.kind_of?(Module) @@ -119,7 +162,7 @@ module Mutant scope.private_instance_methods(false) + scope.protected_instance_methods(false) - names.uniq.map(&:to_sym).sort + names.uniq.sort end end end diff --git a/lib/mutant/mutator/node/block.rb b/lib/mutant/mutator/node/block.rb index 24193c88..e2214116 100644 --- a/lib/mutant/mutator/node/block.rb +++ b/lib/mutant/mutator/node/block.rb @@ -18,6 +18,26 @@ module Mutant array = input.array emit_attribute_mutations(:array) end + + # Test if node is new + # + # FIXME: Remove this hack and make sure empty bodies are not generated + # + # @param [Rubinius::AST::Node] + # + # @return [true] + # if node is new + # + # @return [false] + # otherwise + # + def new?(node) + if node.array.empty? + node.array << new_nil + end + + super + end end end end diff --git a/lib/mutant/mutator/node/if_statement.rb b/lib/mutant/mutator/node/if_statement.rb index 3f5ef8e4..1cd1fd06 100644 --- a/lib/mutant/mutator/node/if_statement.rb +++ b/lib/mutant/mutator/node/if_statement.rb @@ -16,8 +16,8 @@ module Mutant # def dispatch emit_attribute_mutations(:condition) - emit_attribute_mutations(:body) - emit_attribute_mutations(:else) if node.else + emit_attribute_mutations(:body) if node.body.class != Rubinius::AST::NilLiteral + emit_attribute_mutations(:else) if node.else.class != Rubinius::AST::NilLiteral emit_inverted_condition emit_deleted_if_branch emit_deleted_else_branch diff --git a/lib/mutant/mutator/node/literal/range.rb b/lib/mutant/mutator/node/literal/range.rb index 5dc037b6..50684c83 100644 --- a/lib/mutant/mutator/node/literal/range.rb +++ b/lib/mutant/mutator/node/literal/range.rb @@ -49,7 +49,7 @@ module Mutant # def emit_finish_mutations finish = node.finish - emit_self(negative_infinity, finish) + #emit_self(negative_infinity, finish) emit_self(nan, finish) end diff --git a/lib/mutant/strategy/rspec.rb b/lib/mutant/strategy/rspec.rb index e3cb9bf4..a44e0ea2 100644 --- a/lib/mutant/strategy/rspec.rb +++ b/lib/mutant/strategy/rspec.rb @@ -11,7 +11,7 @@ module Mutant # Return filename pattern # - # @return [String] + # @return [Enumerable] # # @api private # @@ -25,17 +25,17 @@ module Mutant # Return file name pattern for mutation # - # @return [Mutation] + # @return [Enumerable] # # @api private # def self.spec_files(mutation) - Dir['spec/unit/**/*_spec.rb'] + ['spec/unit'] end end # Run all integration specs per mutation - class Unit < self + class Integration < self # Return file name pattern for mutation # diff --git a/lib/mutant/strategy/rspec/example_lookup.rb b/lib/mutant/strategy/rspec/example_lookup.rb index 3be01587..bc8aff57 100644 --- a/lib/mutant/strategy/rspec/example_lookup.rb +++ b/lib/mutant/strategy/rspec/example_lookup.rb @@ -63,13 +63,25 @@ module Mutant # @api private # def spec_file - matcher.method_name.to_s. + method_name.to_s. + gsub(/\A\[\]\z/, 'element_reader'). + gsub(/\A\[\]=\z/, 'element_writer'). gsub(/\?\z/, '_predicate'). gsub(/=\z/, '_writer'). gsub(/!\z/, '_bang') + '_spec.rb' end memoize :spec_file + # Return method name + # + # @return [Symbol] + # + # @api private + # + def method_name + matcher.method_name + end + # Return glob expression # # @return [String] @@ -77,6 +89,8 @@ module Mutant # @api private # def glob_expression + return base_path if method_name == :initialize + if mutation.subject.matcher.public? "#{base_path}/#{spec_file}" else diff --git a/spec/shared/method_filter_parse_behavior.rb b/spec/shared/method_filter_parse_behavior.rb deleted file mode 100644 index 7a80294e..00000000 --- a/spec/shared/method_filter_parse_behavior.rb +++ /dev/null @@ -1,16 +0,0 @@ -shared_examples_for 'a method filter parse result' do - before do - expected_class.stub(:new => response) - end - - let(:response) { mock('Response') } - - it { should be(response) } - - it 'should initialize method filter with correct arguments' do - expected_class.should_receive(:new).with(TestApp::Literal, :string).and_return(response) - subject - end -end - - diff --git a/spec/shared/mutator_behavior.rb b/spec/shared/mutator_behavior.rb index 78c41aea..d3ee4536 100644 --- a/spec/shared/mutator_behavior.rb +++ b/spec/shared/mutator_behavior.rb @@ -15,25 +15,31 @@ shared_examples_for 'a mutator' do it { should be_instance_of(to_enum.class) } - let(:expected_mutations) do - mutations.map do |mutation| - if mutation.respond_to?(:to_ast) - mutation.to_ast.to_sexp - else - mutation - end - end.to_set + unless instance_methods.include?(:expected_mutations) + let(:expected_mutations) do + mutations.map do |mutation| + case mutation + when String + mutation.to_ast + when Rubinius::AST::Node + mutation + else + raise + end + end.map do |node| + ToSource.to_source(node) + end.to_set + end end it 'generates the expected mutations' do - generated = self.subject.map(&:to_sexp).to_set + generated = self.subject.map { |mutation| ToSource.to_source(mutation) }.to_set missing = (expected_mutations - generated).to_a unexpected = (generated - expected_mutations).to_a unless generated == expected_mutations - message = "Missing mutations: %s\nUnexpected mutations: %s" % [missing, unexpected].map(&:inspect) - fail message + fail "Missing mutations:\n%s\nUnexpected mutations:\n%s" % [missing.join("\n----\n"), unexpected.join("\n----\n")] end end end diff --git a/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb b/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb index 5ef10b10..a6aef20d 100644 --- a/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb +++ b/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb @@ -3,25 +3,43 @@ require 'spec_helper' describe Mutant::Matcher::Method::Classifier, '.run' do subject { described_class.run(input) } - context 'with explicit toplevel scope' do - let(:input) { '::TestApp::Literal#string' } - let(:expected_class) { Mutant::Matcher::Method::Instance } + shared_examples_for 'Mutant::Matcher::Method::Classifier.run' do + before do + expected_class.stub(:new => response) + end - it_should_behave_like 'a method filter parse result' + let(:response) { :Response } + + it { should be(response) } + + it 'should initialize method filter with correct arguments' do + expected_class.should_receive(:new).with(TestApp::Literal, expected_method).and_return(response) + subject + end + end + + context 'with explicit toplevel scope' do + let(:input) { '::TestApp::Literal#string' } + let(:expected_class) { Mutant::Matcher::Method::Instance } + let(:expected_method) { TestApp::Literal.instance_method(:string) } + + it_should_behave_like 'Mutant::Matcher::Method::Classifier.run' end context 'with instance method notation' do - let(:input) { 'TestApp::Literal#string' } - let(:expected_class) { Mutant::Matcher::Method::Instance } + let(:input) { 'TestApp::Literal#string' } + let(:expected_method) { TestApp::Literal.instance_method(:string) } + let(:expected_class) { Mutant::Matcher::Method::Instance } - it_should_behave_like 'a method filter parse result' + it_should_behave_like 'Mutant::Matcher::Method::Classifier.run' end context 'with singleton method notation' do - let(:input) { 'TestApp::Literal.string' } - let(:expected_class) { Mutant::Matcher::Method::Singleton } + let(:input) { 'TestApp::Literal.string' } + let(:expected_method) { TestApp::Literal.method(:string) } + let(:expected_class) { Mutant::Matcher::Method::Singleton } - it_should_behave_like 'a method filter parse result' + it_should_behave_like 'Mutant::Matcher::Method::Classifier.run' end context 'with invalid notation' do diff --git a/spec/unit/mutant/matcher/method/method_spec.rb b/spec/unit/mutant/matcher/method/method_spec.rb deleted file mode 100644 index b00c47be..00000000 --- a/spec/unit/mutant/matcher/method/method_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'spec_helper' - -describe Mutant::Matcher::Method, '#method' do - subject { object.send(:method) } - - let(:object) { described_class.allocate } - - it 'should raise error' do - expect { subject }.to raise_error(NotImplementedError, 'Mutant::Matcher::Method#method is not implemented') - end -end diff --git a/spec/unit/mutant/mutator/node/block/mutation_spec.rb b/spec/unit/mutant/mutator/node/block/mutation_spec.rb index 0d618c26..617b52fe 100644 --- a/spec/unit/mutant/mutator/node/block/mutation_spec.rb +++ b/spec/unit/mutant/mutator/node/block/mutation_spec.rb @@ -9,26 +9,27 @@ describe Mutant::Mutator, 'block' do mutations = [] # Mutation of each statement in block - mutations << "foo\nself.bar" - mutations << "self.foo\nbar" + mutations << "foo\nself.bar".to_ast + mutations << "self.foo\nbar".to_ast - ## Remove statement in block - mutations << [:block, 'self.foo'.to_sexp] - mutations << [:block, 'self.bar'.to_sexp] - mutations << [:block] + # Remove statement in block + mutations << Rubinius::AST::Block.new(1, ['self.foo'.to_ast]) + mutations << Rubinius::AST::Block.new(1, ['self.bar'.to_ast]) + mutations << Rubinius::AST::Block.new(1, ['nil'.to_ast]) end it_should_behave_like 'a mutator' end + 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] - mutations << [:block] + mutations << Rubinius::AST::Block.new(1, ['foo'.to_ast]) + mutations << Rubinius::AST::Block.new(1, ['nil'.to_ast]) end it_should_behave_like 'a mutator' diff --git a/spec/unit/mutant/mutator/node/define/mutation_spec.rb b/spec/unit/mutant/mutator/node/define/mutation_spec.rb index 787f2732..84b5aa41 100644 --- a/spec/unit/mutant/mutator/node/define/mutation_spec.rb +++ b/spec/unit/mutant/mutator/node/define/mutation_spec.rb @@ -17,7 +17,7 @@ describe Mutant::Mutator, 'define' do mutations << 'def foo; self.bar; end' # Remove all statements - mutations << [:defn, :foo, [:args], [:scope, [:block]]] + mutations << 'def foo; end' end it_should_behave_like 'a mutator' @@ -38,7 +38,7 @@ describe Mutant::Mutator, 'define' do mutations << 'def self.foo; self.baz; end' # Remove all statements - mutations << [:defs, [:self], :foo, [:args], [:scope, [:block]]] + mutations << 'def self.foo; end' end it_should_behave_like 'a mutator' diff --git a/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb b/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb index 44cbbc0d..4902b5cb 100644 --- a/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb +++ b/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb @@ -1,30 +1,60 @@ require 'spec_helper' describe Mutant::Mutator, 'if statement' do - let(:source) { 'if self.condition; true; else false; end' } - let(:mutations) do - mutants = [] + context 'if with two branches' do + let(:source) { 'if self.condition; true; else false; end' } - # mutations of condition - mutants << 'if condition; true; else false; end' + let(:mutations) do + mutants = [] - mutants << 'if !self.condition; true; else false; end' + # mutations of condition + mutants << 'if condition; true; else false; end' - # Deleted else branch - mutants << 'if self.condition; true end' + mutants << 'if !self.condition; true; else false; end' - # Deleted if branch with promoting else branch to if branch - mutants << 'if self.condition; false end' + # Deleted else branch + mutants << 'if self.condition; true end' - # mutations of body - mutants << 'if self.condition; false; else false; end' - mutants << 'if self.condition; nil; else false; end' + # Deleted if branch with promoting else branch to if branch + mutants << 'if self.condition; false end' - # mutations of else body - mutants << 'if self.condition; true; else true; end' - mutants << 'if self.condition; true; else nil; end' + # mutations of body + mutants << 'if self.condition; false; else false; end' + mutants << 'if self.condition; nil; else false; end' + + # mutations of else body + mutants << 'if self.condition; true; else true; end' + mutants << 'if self.condition; true; else nil; end' + end + + it_should_behave_like 'a mutator' end - it_should_behave_like 'a mutator' + context 'unless with one branch' do + let(:source) { 'unless condition; true; end' } + + let(:mutations) do + mutants = [] + mutants << 'unless !condition; true; end' + mutants << 'if condition; true; end' + mutants << 'unless condition; false; end' + mutants << 'unless condition; nil; end' + end + + it_should_behave_like 'a mutator' + end + + context 'if with one branch' do + let(:source) { 'if condition; true; end' } + + let(:mutations) do + mutants = [] + mutants << 'if !condition; true; end' + mutants << 'if condition; false; end' + mutants << 'if condition; nil; end' + end + + it_should_behave_like 'a mutator' + end end diff --git a/spec/unit/mutant/mutator/node/literal/array_spec.rb b/spec/unit/mutant/mutator/node/literal/array_spec.rb index 02c78995..a4e913fe 100644 --- a/spec/unit/mutant/mutator/node/literal/array_spec.rb +++ b/spec/unit/mutant/mutator/node/literal/array_spec.rb @@ -7,7 +7,7 @@ describe Mutant::Mutator::Node::Literal, 'array' do mutations = [] # Literal replaced with nil - mutations << [:nil] + mutations << 'nil' # Mutation of each element in array mutations << '[nil, false]' diff --git a/spec/unit/mutant/mutator/node/literal/empty_array_spec.rb b/spec/unit/mutant/mutator/node/literal/empty_array_spec.rb index e95b8a71..f2cdb4aa 100644 --- a/spec/unit/mutant/mutator/node/literal/empty_array_spec.rb +++ b/spec/unit/mutant/mutator/node/literal/empty_array_spec.rb @@ -7,7 +7,7 @@ describe Mutant::Mutator::Node::Literal, 'empty array' do mutations = [] # Literal replaced with nil - mutations << [:nil] + mutations << 'nil' # Extra element mutations << '[nil]' diff --git a/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb b/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb index 4fec9f60..cf79aae7 100644 --- a/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +++ b/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb @@ -6,7 +6,7 @@ describe Mutant::Mutator::Node::Literal, 'fixnum' do let(:source) { '10' } let(:mutations) do - %W(nil 0 1 #{random_fixnum}) << [:lit, -10] + %W(nil 0 1 #{random_fixnum} -10) end before do diff --git a/spec/unit/mutant/mutator/node/literal/float_spec.rb b/spec/unit/mutant/mutator/node/literal/float_spec.rb index 8f09f122..3d4ad0d0 100644 --- a/spec/unit/mutant/mutator/node/literal/float_spec.rb +++ b/spec/unit/mutant/mutator/node/literal/float_spec.rb @@ -11,8 +11,8 @@ describe Mutant::Mutator::Node::Literal, 'float' do mutations << random_float.to_s mutations << '0.0/0.0' mutations << '1.0/0.0' - mutations << [:negate, [:call, [:lit, 1.0], :/, [:arglist, [:lit, 0.0]]]] - mutations << [:lit, -10.0] + mutations << '-1.0 / 0.0' + mutations << '-10.0' end let(:random_float) { 7.123 } diff --git a/spec/unit/mutant/mutator/node/literal/hash_spec.rb b/spec/unit/mutant/mutator/node/literal/hash_spec.rb index e02b11e2..8e0f41be 100644 --- a/spec/unit/mutant/mutator/node/literal/hash_spec.rb +++ b/spec/unit/mutant/mutator/node/literal/hash_spec.rb @@ -7,27 +7,27 @@ describe Mutant::Mutator::Node::Literal, 'hash' do mutations = [] # Literal replaced with nil - mutations << [:nil] + mutations << 'nil' # Mutation of each key and value in hash - mutations << [:hash, [:false ], [:true ], [:false], [:false]] - mutations << [:hash, [:nil ], [:true ], [:false], [:false]] - mutations << [:hash, [:true ], [:false], [:false], [:false]] - mutations << [:hash, [:true ], [:nil ], [:false], [:false]] - mutations << [:hash, [:true ], [:true ], [:true ], [:false]] - mutations << [:hash, [:true ], [:true ], [:nil ], [:false]] - mutations << [:hash, [:true ], [:true ], [:false], [:true ]] - mutations << [:hash, [:true ], [:true ], [:false], [:nil ]] + mutations << '{ false => true , false => false }' + mutations << '{ nil => true , false => false }' + mutations << '{ true => false , false => false }' + mutations << '{ true => nil , false => false }' + mutations << '{ true => true , true => false }' + mutations << '{ true => true , nil => false }' + mutations << '{ true => true , false => true }' + mutations << '{ true => true , false => nil }' # Remove each key once - mutations << [:hash, [:true ], [:true ]] - mutations << [:hash, [:false ], [:false ]] + mutations << '{ true => true }' + mutations << '{ false => false }' # Empty hash - mutations << [:hash] + mutations << '{}' # Extra element - mutations << [:hash, [:true ], [:true ], [:false], [:false ], [:nil], [:nil] ] + mutations << '{true => true, false => false, nil => nil}' end it_should_behave_like 'a mutator' diff --git a/spec/unit/mutant/mutator/node/literal/range_spec.rb b/spec/unit/mutant/mutator/node/literal/range_spec.rb index 1b004305..c89f9b41 100644 --- a/spec/unit/mutant/mutator/node/literal/range_spec.rb +++ b/spec/unit/mutant/mutator/node/literal/range_spec.rb @@ -9,7 +9,7 @@ describe Mutant::Mutator::Node::Literal, 'range' do mutations << 'nil' mutations << '1...100' mutations << '(0.0/0.0)..100' - mutations << [:dot2, [:negate, [:call, [:lit, 1.0], :/, [:arglist, [:lit, 0.0]]]], [:lit, 100]] + #mutations << [:dot2, [:negate, [:call, [:lit, 1.0], :/, [:arglist, [:lit, 0.0]]]], [:lit, 100]] mutations << '1..(1.0/0.0)' mutations << '1..(0.0/0.0)' end @@ -25,7 +25,7 @@ describe Mutant::Mutator::Node::Literal, 'range' do mutations << 'nil' mutations << '1..100' mutations << '(0.0/0.0)...100' - mutations << [:dot3, [:negate, [:call, [:lit, 1.0], :/, [:arglist, [:lit, 0.0]]]], [:lit, 100]] + #mutations << [:dot3, [:negate, [:call, [:lit, 1.0], :/, [:arglist, [:lit, 0.0]]]], [:lit, 100]] mutations << '1...(1.0/0.0)' mutations << '1...(0.0/0.0)' end diff --git a/spec/unit/mutant/strategy/rspec/example_lookup/spec_file_spec.rb b/spec/unit/mutant/strategy/rspec/example_lookup/spec_file_spec.rb index 1e3fbe55..790ae899 100644 --- a/spec/unit/mutant/strategy/rspec/example_lookup/spec_file_spec.rb +++ b/spec/unit/mutant/strategy/rspec/example_lookup/spec_file_spec.rb @@ -16,6 +16,21 @@ describe Mutant::Strategy::Rspec::ExampleLookup, '#spec_file' do it { should be_frozen } end + context 'with element reader method' do + let(:method_name) { '[]' } + let(:expected_spec_file) { 'element_reader_spec.rb' } + + it_should_behave_like 'Mutant::Strategy::Rspec::ExampleLookup#spec_file' + end + + context 'with element writer method' do + let(:method_name) { '[]=' } + + let(:expected_spec_file) { 'element_writer_spec.rb' } + + it_should_behave_like 'Mutant::Strategy::Rspec::ExampleLookup#spec_file' + end + context 'with writer method' do let(:method_name) { 'foo=' } let(:expected_spec_file) { 'foo_writer_spec.rb' }