Define expected mutations with less redundancy

The mutation examples are now introspectable, this allows to render nice
index or performing better automated analysis against the corpus.
This commit is contained in:
Markus Schirp 2014-06-02 12:57:14 +00:00
parent c75729ead2
commit 4a9ab9340e
95 changed files with 1751 additions and 2116 deletions

View file

@ -1,3 +1,3 @@
---
threshold: 18
total_score: 801
total_score: 848

View file

@ -10,7 +10,8 @@ ClassVariable:
exclude: []
ControlParameter:
enabled: true
exclude: []
exclude:
- Mutant::Expression#match_length
DataClump:
enabled: true
exclude: []
@ -33,6 +34,8 @@ FeatureEnvy:
# Nature of OptionParser :(
- Mutant::CLI#add_environmental_options
- Mutant::CLI#parse
# False positive, its a utility
- Mutant::Meta::Example::Verification#format_mutation
IrresponsibleModule:
enabled: true
exclude: []
@ -69,6 +72,7 @@ RepeatedConditional:
- Mutant::Mutator
- Mutant::Rspec::Strategy
- Mutant::Reporter::CLI
- Mutant::Meta::Example::DSL
max_ifs: 1
TooManyInstanceVariables:
enabled: true
@ -154,4 +158,5 @@ UtilityFunction:
- Mutant::Rspec::Strategy#options
- Mutant::Rspec::Strategy#world
- Mutant::Rspec::Strategy#rspec2
- Mutant::Meta::Example::Verification#format_mutation
max_helper_calls: 0

View file

@ -29,8 +29,8 @@ module Mutant
#
def matcher(cache)
methods_matcher = MATCHERS.fetch(scope_symbol).new(cache, scope)
method = methods_matcher.methods.detect do |method|
method.name == method_name
method = methods_matcher.methods.detect do |meth|
meth.name == method_name
end or raise NameError, "Cannot find method #{identifier}"
methods_matcher.matcher.build(cache, scope, method)
end

31
lib/mutant/meta.rb Normal file
View file

@ -0,0 +1,31 @@
module Mutant
# Namespace for mutant metadata
module Meta
require 'mutant/meta/example'
require 'mutant/meta/example/dsl'
# Mutation example
class Example
ALL = []
# Add example
#
# @return [undefined]
#
# @api private
#
def self.add(&block)
ALL << DSL.run(block)
end
Pathname.glob(Pathname.new(__FILE__).parent.parent.parent.join('meta', '**/*.rb'))
.sort
.each(&method(:require))
ALL.freeze
end # Example
end # Meta
end # Mutant

150
lib/mutant/meta/example.rb Normal file
View file

@ -0,0 +1,150 @@
# encoding: UTF-8
module Mutant
module Meta
class Example
include Adamantium, Concord::Public.new(:node, :mutations)
# Return a verification instance
#
# @return [Verification]
#
# @api private
#
def verification
Verification.new(self, generated)
end
# Return generated mutations
#
# @return [Emumerable<Parser::AST::Node>]
#
# @api private
#
def generated
Mutant::Mutator.each(node).to_a
end
memoize :generated
# Example verification
class Verification
include Adamantium::Flat, Concord.new(:example, :generated)
# Test if mutation was verified successfully
#
# @return [Boolean]
#
# @api private
#
def success?
unparser.success? && missing.empty? && unexpected.empty?
end
# Return error report
#
# @return [String]
#
# @api private
#
def error_report
unless unparser.success?
return unparser.report
end
mutation_report
end
private
# Return unexpected mutationso
#
# @return [Array<Parser::AST::Node>]
#
# @api private
#
def unexpected
generated - example.mutations
end
memoize :unexpected
# Return mutation report
#
# @return [String]
#
# @api private
#
def mutation_report
original_node = example.node
[
'Original-AST:',
original_node.inspect,
'Original-Source:',
Unparser.unparse(original_node),
*missing_report,
*unexpected_report
].join("\n======\n")
end
# Return missing report
#
# @return [Array, nil]
#
# @api private
#
def missing_report
if missing.any?
['Missing mutations:', missing.map(&method(:format_mutation)).join("\n-----\n")]
end
end
# Return unexpected report
#
# @return [Array, nil]
#
# @api private
#
def unexpected_report
if unexpected.any?
message << 'Unexpected mutations:'
message << unexpected.map(&method(:format_mutation)).join("\n-----\n")
end
end
# Format mutation
#
# @return [String]
#
# @api private
#
def format_mutation(node)
[
node.inspect,
Unparser.unparse(node)
].join("\n")
end
# Return missing mutationso
#
# @return [Array<Parser::AST::Node>]
#
# @api private
#
def missing
example.mutations - generated
end
memoize :missing
# Return unparser verifier
#
# @return [Unparser::CLI::Source]
#
# @api private
#
def unparser
Unparser::CLI::Source::Node.new(Unparser::Preprocessor.run(example.node))
end
memoize :unparser
end # Verification
end # Example
end # Meta
end # Mutant

View file

@ -0,0 +1,105 @@
module Mutant
module Meta
class Example
# Example DSL
class DSL
include NodeHelpers
# Run DSL on block
#
# @return [Example]
#
# @api private
#
def self.run(block)
instance = new
instance.instance_eval(&block)
instance.example
end
# Initialize DSL context
#
# @return [undefined]
#
# @api private
#
def initialize
@source = nil
@expected = []
end
# Return example
#
# @return [Example]
#
# @raise [RuntimeError]
# in case example cannot be build
#
# @api private
#
def example
raise 'source not defined' unless @source
Example.new(@source, @expected)
end
private
# Set original source
#
# @param [String,Parser::AST::Node] input
#
# @return [self]
#
def source(input)
raise 'source already defined' if @source
@source = node(input)
self
end
# Add expected mutation
#
# @param [String,Parser::AST::Node] input
#
# @return [self]
#
def mutation(input)
node = node(input)
if @expected.include?(node)
raise "Node for input: #{input.inspect} is already expected"
end
@expected << node
self
end
# Helper method to coerce input to node
#
# @param [String,Parser::AST::Node] input
#
# @return [Parser::AST::Node]
#
# @raise [RuntimeError]
# in case input cannot be coerced
#
# @api private
#
def node(input)
node =
case input
when String
Parser::CurrentRuby.parse(input)
when Parser::AST::Node
input
else
raise "Cannot coerce to node: #{source.inspect}"
end
Unparser::Preprocessor.run(node)
end
end # DSL
end # Example
end # Meta
end # Mutant

12
meta/and_asgn.rb Normal file
View file

@ -0,0 +1,12 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'a &&= 1'
mutation 'a__mutant__ &&= 1'
mutation 'a &&= nil'
mutation 'a &&= 0'
mutation 'a &&= -1'
mutation 'a &&= 2'
mutation 'nil'
end

15
meta/begin.rb Normal file
View file

@ -0,0 +1,15 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'true; false'
# Mutation of each statement in block
mutation 'true; true'
mutation 'false; false'
mutation 'nil; false'
mutation 'true; nil'
# Delete each statement
mutation 'true'
mutation 'false'
end

23
meta/binary.rb Normal file
View file

@ -0,0 +1,23 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'true and false'
mutation 'nil'
mutation 'true'
mutation 'false'
mutation 'true or false'
mutation '!true and false'
mutation '!(true and false)'
end
Mutant::Meta::Example.add do
source 'true or false'
mutation 'nil'
mutation 'true'
mutation 'false'
mutation 'true and false'
mutation '!true or false'
mutation '!(true or false)'
end

55
meta/block.rb Normal file
View file

@ -0,0 +1,55 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'foo() { a; b }'
mutation 'foo { a }'
mutation 'foo { b }'
mutation 'foo {}'
mutation 'foo { raise }'
mutation 'foo { a; nil }'
mutation 'foo { nil; b }'
mutation 'foo'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'foo { |a, b| }'
mutation 'foo'
mutation 'foo { |a, b| raise }'
mutation 'foo { |a, b__mutant__| }'
mutation 'foo { |a__mutant__, b| }'
mutation 'foo { |a| }'
mutation 'foo { |b| }'
mutation 'foo { || }'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'foo { |(a, b), c| }'
mutation 'nil'
mutation 'foo { || }'
mutation 'foo { |a, b, c| }'
mutation 'foo { |(a, b), c| raise }'
mutation 'foo { |(a), c| }'
mutation 'foo { |(b), c| }'
mutation 'foo { |(a, b)| }'
mutation 'foo { |c| }'
mutation 'foo { |(a__mutant__, b), c| }'
mutation 'foo { |(a, b__mutant__), c| }'
mutation 'foo { |(a, b), c__mutant__| }'
mutation 'foo'
end
Mutant::Meta::Example.add do
source 'foo { |(a)| }'
mutation 'foo { || }'
mutation 'foo { |a| }'
mutation 'foo { |(a)| raise }'
mutation 'foo { |(a__mutant__)| }'
mutation 'foo'
mutation 'nil'
end

8
meta/block_pass.rb Normal file
View file

@ -0,0 +1,8 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'foo(&bar)'
mutation 'foo'
mutation 'nil'
end

10
meta/blockarg.rb Normal file
View file

@ -0,0 +1,10 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'foo { |&bar| }'
mutation 'foo { |&bar| raise }'
mutation 'foo {}'
mutation 'foo'
mutation 'nil'
end

303
meta/case.rb Normal file
View file

@ -0,0 +1,303 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source <<-RUBY
case
when true
else
end
RUBY
mutation 'nil'
mutation <<-RUBY
case
when true
raise
else
end
RUBY
mutation <<-RUBY
case
when false
else
end
RUBY
mutation <<-RUBY
case
when nil
else
end
RUBY
end
Mutant::Meta::Example.add do
source <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz
else
:else
end
RUBY
# Presence of branches
mutation <<-RUBY
case :condition
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz
end
RUBY
# Mutations of condition
mutation <<-RUBY
case nil
when :foo
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition__mutant__
when :foo
when :bar, :baz
:barbaz
else
:else
end
RUBY
# Mutations of branch bodies
mutation <<-RUBY
case :condition
when :foo
raise
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz__mutant__
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar, :baz
nil
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz
else
:else__mutant__
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz
else
nil
end
RUBY
# Mutations of when conditions
mutation <<-RUBY
case :condition
when :foo__mutant__
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when nil
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar__mutant__, :baz
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when nil, :baz
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar, nil
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar, :baz__mutant__
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :baz
:barbaz
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
when :bar
:barbaz
else
:else
end
RUBY
mutation 'nil'
end
Mutant::Meta::Example.add do
source <<-RUBY
case :condition
when :foo
:foo
else
:else
end
RUBY
# Presence of branches
mutation <<-RUBY
case :condition
when :foo
:foo
end
RUBY
# Mutations of condition
mutation <<-RUBY
case nil
when :foo
:foo
else
:else
end
RUBY
mutation <<-RUBY
case :condition__mutant__
when :foo
:foo
else
:else
end
RUBY
# Mutations of branch bodies
mutation <<-RUBY
case :condition
when :foo
nil
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
:foo__mutant__
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when :foo
:foo
else
:else__mutant__
end
RUBY
mutation <<-RUBY
case :condition
when :foo
:foo
else
nil
end
RUBY
# Mutations of when conditions
mutation <<-RUBY
case :condition
when :foo__mutant__
:foo
else
:else
end
RUBY
mutation <<-RUBY
case :condition
when nil
:foo
else
:else
end
RUBY
mutation 'nil'
end

8
meta/cbase.rb Normal file
View file

@ -0,0 +1,8 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '::A'
mutation 'nil'
mutation 'A'
end

38
meta/conditional_loop.rb Normal file
View file

@ -0,0 +1,38 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'while true; end'
mutation 'while true; raise; end'
mutation 'while false; end'
mutation 'while nil; end'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'while true; foo; bar; end'
mutation 'while true; bar; end'
mutation 'while true; foo; end'
mutation 'while true; end'
mutation 'while false; foo; bar; end'
mutation 'while nil; foo; bar; end'
mutation 'while true; foo; nil; end'
mutation 'while true; nil; bar; end'
mutation 'while true; raise; end'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'until true; foo; bar; end'
mutation 'until true; bar; end'
mutation 'until true; foo; end'
mutation 'until true; end'
mutation 'until false; foo; bar; end'
mutation 'until nil; foo; bar; end'
mutation 'until true; foo; nil; end'
mutation 'until true; nil; bar; end'
mutation 'until true; raise; end'
mutation 'nil'
end

9
meta/const.rb Normal file
View file

@ -0,0 +1,9 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'A::B::C'
mutation 'nil'
mutation 'B::C'
mutation 'C'
end

118
meta/define.rb Normal file
View file

@ -0,0 +1,118 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'def foo; end'
mutation 'def foo; raise; end'
end
Mutant::Meta::Example.add do
source "def foo\nfoo\nrescue\nend"
mutation 'def foo; raise; end'
mutation 'def foo; nil; rescue; end'
mutation 'def foo; end'
end
Mutant::Meta::Example.add do
source 'def foo; true; false; end'
# Mutation of each statement in block
mutation 'def foo; true; true; end'
mutation 'def foo; false; false; end'
mutation 'def foo; true; nil; end'
mutation 'def foo; nil; false; end'
# Remove statement in block
mutation 'def foo; true; end'
mutation 'def foo; false; end'
# Remove all statements
mutation 'def foo; end'
mutation 'def foo; raise; end'
end
Mutant::Meta::Example.add do
source 'def foo(a, b); end'
# Deletion of each argument
mutation 'def foo(a); end'
mutation 'def foo(b); end'
# Deletion of all arguments
mutation 'def foo; end'
# Rename each argument
mutation 'def foo(a__mutant__, b); end'
mutation 'def foo(a, b__mutant__); end'
# Mutation of body
mutation 'def foo(a, b); raise; end'
end
Mutant::Meta::Example.add do
source 'def foo(_unused); end'
mutation 'def foo(_unused); raise; end'
mutation 'def foo; end'
end
Mutant::Meta::Example.add do
source 'def foo(_unused = true); end'
mutation 'def foo(_unused = nil); end'
mutation 'def foo(_unused = false); end'
mutation 'def foo(_unused = true); raise; end'
mutation 'def foo(_unused); end'
mutation 'def foo; end'
end
Mutant::Meta::Example.add do
source 'def foo(a = true); end'
mutation 'def foo(a); end'
mutation 'def foo(); end'
mutation 'def foo(a = false); end'
mutation 'def foo(a = nil); end'
mutation 'def foo(a__mutant__ = true); end'
mutation 'def foo(a = true); raise; end'
end
Mutant::Meta::Example.add do
source 'def self.foo; true; false; end'
# Body presence mutation
mutation 'def self.foo; false; false; end'
mutation 'def self.foo; true; true; end'
mutation 'def self.foo; true; nil; end'
mutation 'def self.foo; nil; false; end'
# Body presence mutation
mutation 'def self.foo; true; end'
mutation 'def self.foo; false; end'
# Remove all statements
mutation 'def self.foo; end'
mutation 'def self.foo; raise; end'
end
Mutant::Meta::Example.add do
source 'def self.foo(a, b); end'
# Deletion of each argument
mutation 'def self.foo(a); end'
mutation 'def self.foo(b); end'
# Deletion of all arguments
mutation 'def self.foo; end'
# Rename each argument
mutation 'def self.foo(a__mutant__, b); end'
mutation 'def self.foo(a, b__mutant__); end'
# Mutation of body
mutation 'def self.foo(a, b); raise; end'
end

7
meta/defined.rb Normal file
View file

@ -0,0 +1,7 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'defined?(foo)'
mutation 'defined?(nil)'
end

10
meta/dstr.rb Normal file
View file

@ -0,0 +1,10 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '"foo#{bar}baz"'
mutation 'nil'
mutation '"#{nil}#{bar}baz"'
mutation '"foo#{bar}#{nil}"'
mutation '"foo#{nil}baz"'
end

11
meta/dsym.rb Normal file
View file

@ -0,0 +1,11 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source ':"foo#{bar}baz"'
mutation ':"#{nil}#{bar}baz"'
mutation ':"foo#{bar}#{nil}"'
mutation ':"foo#{nil}baz"'
mutation 'nil'
end

9
meta/ensure.rb Normal file
View file

@ -0,0 +1,9 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'begin; rescue; ensure; true; end'
mutation 'begin; rescue; ensure; false; end'
mutation 'begin; rescue; ensure; nil; end'
mutation 'nil'
end

57
meta/if.rb Normal file
View file

@ -0,0 +1,57 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'if :condition; true; else false; end'
# mutation of condition
mutation 'if :condition__mutant__; true; else false; end'
mutation 'if !:condition; true; else false; end'
mutation 'if nil; true; else false; end'
mutation 'if true; true; else false; end'
mutation 'if false; true; else false; end'
# Deleted else branch
mutation 'if :condition; true end'
# Deleted if branch resuting in unless rendering
mutation 'unless :condition; false; end'
# Deleted if branch with promoting else branch to if branch
mutation 'if :condition; false end'
# mutation of if body
mutation 'if :condition; false; else false; end'
mutation 'if :condition; nil; else false; end'
# mutation of else body
mutation 'if :condition; true; else true; end'
mutation 'if :condition; true; else nil; end'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'if condition; true; end'
mutation 'if !condition; true; end'
mutation 'if condition; false; end'
mutation 'if condition; nil; end'
mutation 'if true; true; end'
mutation 'if false; true; end'
mutation 'if nil; true; end'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'unless :condition; true; end'
mutation 'unless !:condition; true; end'
mutation 'unless :condition__mutant__; true; end'
mutation 'unless nil; true; end'
mutation 'unless :condition; false; end'
mutation 'unless :condition; nil; end'
mutation 'unless true; true; end'
mutation 'unless false; true; end'
mutation 'if :condition; true; end'
mutation 'nil'
end

9
meta/kwbegin.rb Normal file
View file

@ -0,0 +1,9 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'begin; true; end'
mutation 'begin; false; end'
mutation 'begin; nil; end'
mutation 'nil'
end

30
meta/literal/array.rb Normal file
View file

@ -0,0 +1,30 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '[true]'
mutation 'nil'
mutation 'true'
mutation '[false]'
mutation '[nil]'
mutation '[]'
end
Mutant::Meta::Example.add do
source '[true, false]'
mutation 'nil'
# Mutation of each element in array
mutation '[nil, false]'
mutation '[false, false]'
mutation '[true, nil]'
mutation '[true, true]'
# Remove each element of array once
mutation '[true]'
mutation '[false]'
# Empty array
mutation '[]'
end

15
meta/literal/boolean.rb Normal file
View file

@ -0,0 +1,15 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'true'
mutation 'nil'
mutation 'false'
end
Mutant::Meta::Example.add do
source 'false'
mutation 'nil'
mutation 'true'
end

19
meta/literal/fixnum.rb Normal file
View file

@ -0,0 +1,19 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '10'
# generic
mutation 'nil'
# edge cases
mutation '0'
mutation '1'
# negative
mutation '-10'
# scalar boundary
mutation '9'
mutation '11'
end

38
meta/literal/float.rb Normal file
View file

@ -0,0 +1,38 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '10.0'
# generic
mutation 'nil'
# edge cases
mutation '0.0'
mutation '1.0'
mutation '(0.0 / 0.0)'
mutation '(1.0 / 0.0)'
mutation '(-1.0 / 0.0)'
# negative
mutation '-10.0'
end
Mutant::Meta::Example.add do
source '0.0'
mutation 'nil'
mutation '1.0'
mutation '(0.0 / 0.0)'
mutation '(1.0 / 0.0)'
mutation '(-1.0 / 0.0)'
end
Mutant::Meta::Example.add do
source '-0.0'
mutation 'nil'
mutation '1.0'
mutation '(0.0 / 0.0)'
mutation '(1.0 / 0.0)'
mutation '(-1.0 / 0.0)'
end

25
meta/literal/hash.rb Normal file
View file

@ -0,0 +1,25 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '{true => true, false => false}'
# Literal replaced with nil
mutation 'nil'
# Mutation of each key and value in hash
mutation '{ false => true , false => false }'
mutation '{ nil => true , false => false }'
mutation '{ true => false , false => false }'
mutation '{ true => nil , false => false }'
mutation '{ true => true , true => false }'
mutation '{ true => true , nil => false }'
mutation '{ true => true , false => true }'
mutation '{ true => true , false => nil }'
# Remove each key once
mutation '{ true => true }'
mutation '{ false => false }'
# Empty hash
mutation '{}'
end

5
meta/literal/nil.rb Normal file
View file

@ -0,0 +1,5 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'nil'
end

41
meta/literal/range.rb Normal file
View file

@ -0,0 +1,41 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '1..100'
mutation 'nil'
mutation '1...100'
mutation '(0.0 / 0.0)..100'
mutation '1..(1.0 / 0.0)'
mutation '1..(0.0 / 0.0)'
mutation '-1..100'
mutation '0..100'
mutation '2..100'
mutation 'nil..100'
mutation '1..nil'
mutation '1..0'
mutation '1..1'
mutation '1..99'
mutation '1..101'
mutation '1..-100'
end
Mutant::Meta::Example.add do
source '1...100'
mutation 'nil'
mutation '1..100'
mutation '(0.0 / 0.0)...100'
mutation '1...(1.0 / 0.0)'
mutation '1...(0.0 / 0.0)'
mutation '-1...100'
mutation '0...100'
mutation '2...100'
mutation 'nil...100'
mutation '1...nil'
mutation '1...0'
mutation '1...1'
mutation '1...99'
mutation '1...101'
mutation '1...-100'
end

20
meta/literal/regex.rb Normal file
View file

@ -0,0 +1,20 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '/foo/'
mutation '//' # match all
mutation '/a\A/' # match nothing
mutation 'nil'
end
Mutant::Meta::Example.add do
source '/#{foo.bar}n/'
mutation '//' # match all
mutation '/#{foo}n/'
mutation '/a\A/' # match nothing
mutation '/#{nil.bar}n/'
mutation '/#{nil}n/'
mutation 'nil'
end

7
meta/literal/string.rb Normal file
View file

@ -0,0 +1,7 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '"foo"'
mutation 'nil'
end

8
meta/literal/symbol.rb Normal file
View file

@ -0,0 +1,8 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source ':foo'
mutation 'nil'
mutation ':foo__mutant__'
end

21
meta/loop_ctrl.rb Normal file
View file

@ -0,0 +1,21 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'break true'
mutation 'break false'
mutation 'break nil'
mutation 'break'
mutation 'nil'
mutation 'next true'
end
Mutant::Meta::Example.add do
source 'next true'
mutation 'next false'
mutation 'next nil'
mutation 'next'
mutation 'nil'
mutation 'break true'
end

7
meta/masgn.rb Normal file
View file

@ -0,0 +1,7 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'a, b = c, d'
mutation 'nil'
end

View file

@ -0,0 +1,14 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'true if /foo/'
mutation 'false if /foo/'
mutation 'true if //'
mutation 'nil if /foo/'
mutation 'true if true'
mutation 'true if false'
mutation 'true if nil'
mutation 'true if /a\A/'
mutation 'nil'
end

View file

@ -0,0 +1,50 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '$a = nil; $a'
mutation '$a = nil; nil'
mutation '$a = nil'
mutation '$a'
mutation '$a__mutant__ = nil; $a'
mutation 'nil; $a'
end
Mutant::Meta::Example.add do
source '@@a = nil; @@a'
mutation '@@a = nil; nil'
mutation '@@a = nil'
mutation '@@a'
mutation '@@a__mutant__ = nil; @@a'
mutation 'nil; @@a'
end
Mutant::Meta::Example.add do
source '@a = nil; @a'
mutation '@a = nil; nil'
mutation '@a = nil'
mutation '@a'
mutation '@a__mutant__ = nil; @a'
mutation 'nil; @a'
end
Mutant::Meta::Example.add do
source 'a = nil; a'
mutation 'a = nil; nil'
mutation 'a = nil'
# TODO: fix invalid AST
# These ASTs are not valid and should NOT be emitted
# Mutations of lvarasgn need to be special cased to avoid this.
mutation s(:begin, s(:lvasgn, :a__mutant__, s(:nil)), s(:lvar, :a))
mutation s(:begin, s(:nil), s(:lvar, :a))
mutation s(:lvar, :a)
end
Mutant::Meta::Example.add do
source 'self'
mutation 'nil'
end

View file

@ -0,0 +1,9 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'A = true'
mutation 'A__MUTANT__ = true'
mutation 'A = false'
mutation 'A = nil'
end

View file

@ -0,0 +1,37 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '$a = true'
mutation '$a__mutant__ = true'
mutation '$a = false'
mutation '$a = nil'
mutation 'nil'
end
Mutant::Meta::Example.add do
source '@@a = true'
mutation '@@a__mutant__ = true'
mutation '@@a = false'
mutation '@@a = nil'
mutation 'nil'
end
Mutant::Meta::Example.add do
source '@a = true'
mutation '@a__mutant__ = true'
mutation '@a = false'
mutation '@a = nil'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'a = true'
mutation 'a__mutant__ = true'
mutation 'a = false'
mutation 'a = nil'
mutation 'nil'
end

14
meta/nthref.rb Normal file
View file

@ -0,0 +1,14 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '$1'
mutation '$2'
end
Mutant::Meta::Example.add do
source '$2'
mutation '$3'
mutation '$1'
end

15
meta/op_assgn.rb Normal file
View file

@ -0,0 +1,15 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source '@a.b += 1'
mutation '@a.b += -1'
mutation '@a.b += 2'
mutation '@a.b += 0'
mutation '@a.b += nil'
mutation 'nil.b += 1'
mutation 'nil'
# TODO: fix invalid AST
# This should not get emitted as invalid AST with valid unparsed source
mutation s(:op_asgn, s(:ivar, :@a), :+, s(:int, 1))
end

12
meta/or_asgn.rb Normal file
View file

@ -0,0 +1,12 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'a ||= 1'
mutation 'a__mutant__ ||= 1'
mutation 'a ||= nil'
mutation 'a ||= 0'
mutation 'a ||= -1'
mutation 'a ||= 2'
mutation 'nil'
end

5
meta/redo.rb Normal file
View file

@ -0,0 +1,5 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'redo'
end

38
meta/rescue.rb Normal file
View file

@ -0,0 +1,38 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'begin; rescue ExceptionA, ExceptionB => error; true; end'
mutation 'nil'
mutation 'begin; rescue ExceptionA, ExceptionB; true; end'
mutation 'begin; rescue ExceptionA, ExceptionB => error; false; end'
mutation 'begin; rescue ExceptionA, ExceptionB => error; nil; end'
mutation 'begin; rescue ExceptionA => error; true; end'
mutation 'begin; rescue ExceptionB => error; true; end'
end
Mutant::Meta::Example.add do
source 'begin; rescue SomeException => error; true; end'
mutation 'nil'
mutation 'begin; rescue SomeException; true; end'
mutation 'begin; rescue SomeException => error; false; end'
mutation 'begin; rescue SomeException => error; nil; end'
end
Mutant::Meta::Example.add do
source 'begin; rescue => error; true end'
mutation 'nil'
mutation 'begin; rescue => error; false; end'
mutation 'begin; rescue => error; nil; end'
mutation 'begin; rescue; true; end'
end
Mutant::Meta::Example.add do
source 'begin; rescue; true end'
mutation 'nil'
mutation 'begin; rescue; false; end'
mutation 'begin; rescue; nil; end'
end

11
meta/restarg.rb Normal file
View file

@ -0,0 +1,11 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'foo(*bar)'
mutation 'foo'
mutation 'foo(nil)'
mutation 'foo(bar)'
mutation 'foo(*nil)'
mutation 'nil'
end

15
meta/return.rb Normal file
View file

@ -0,0 +1,15 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'return'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'return foo'
mutation 'foo'
mutation 'return nil'
mutation 'nil'
end

240
meta/send.rb Normal file
View file

@ -0,0 +1,240 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'reverse_each'
mutation 'nil'
mutation 'each'
end
Mutant::Meta::Example.add do
source 'reverse_map'
mutation 'nil'
mutation 'map'
mutation 'each'
end
Mutant::Meta::Example.add do
source 'map'
mutation 'nil'
mutation 'each'
end
Mutant::Meta::Example.add do
source 'foo == bar'
mutation 'foo'
mutation 'bar'
mutation 'nil == bar'
mutation 'foo == nil'
mutation 'nil'
mutation 'foo.eql?(bar)'
mutation 'foo.equal?(bar)'
end
Mutant::Meta::Example.add do
source 'foo.gsub(a, b)'
mutation 'foo'
mutation 'foo.gsub(a)'
mutation 'foo.gsub(b)'
mutation 'foo.gsub'
mutation 'foo.sub(a, b)'
mutation 'foo.gsub(a, nil)'
mutation 'foo.gsub(nil, b)'
mutation 'nil.gsub(a, b)'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'foo.send(bar)'
mutation 'foo.send'
mutation 'foo.public_send(bar)'
mutation 'bar'
mutation 'foo'
mutation 'foo.send(nil)'
mutation 'nil.send(bar)'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'self.foo ||= expression'
mutation 'self.foo ||= nil'
mutation 'nil.foo ||= expression'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'self.bar=baz'
mutation 'nil'
mutation 'self.bar=nil'
mutation 'self'
mutation 'self.bar'
mutation 'baz'
# This one could probably be removed
mutation 'nil.bar=baz'
end
Mutant::Meta::Example.add do
source 'foo.bar=baz'
mutation 'foo'
mutation 'nil'
mutation 'foo.bar=nil'
mutation 'foo.bar'
mutation 'baz'
# This one could probably be removed
mutation 'nil.bar=baz'
end
Mutant::Meta::Example.add do
source 'foo[bar]=baz'
mutation 'foo'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'foo(*bar)'
mutation 'foo'
mutation 'foo(nil)'
mutation 'foo(bar)'
mutation 'foo(*nil)'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'foo(&bar)'
mutation 'foo'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'foo[*bar]'
mutation 'foo'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'foo'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'self.foo'
mutation 'foo'
mutation 'self'
mutation 'nil.foo'
mutation 'nil'
end
Unparser::Constants::KEYWORDS.each do |keyword|
Mutant::Meta::Example.add do
source "self.#{keyword}"
mutation "nil.#{keyword}"
mutation 'nil'
mutation 'self'
end
end
Mutant::Meta::Example.add do
source 'foo.bar'
mutation 'foo'
mutation 'nil.bar'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'self.class.foo'
mutation 'self.class'
mutation 'self.foo'
mutation 'nil.class.foo'
mutation 'nil.foo'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'foo(nil)'
mutation 'foo'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'self.foo(nil)'
mutation 'self'
mutation 'self.foo'
mutation 'foo(nil)'
mutation 'nil'
mutation 'nil.foo(nil)'
end
Unparser::Constants::KEYWORDS.each do |keyword|
Mutant::Meta::Example.add do
source "foo.#{keyword}(nil)"
mutation "foo.#{keyword}"
mutation 'foo'
mutation "nil.#{keyword}(nil)"
mutation 'nil'
end
end
Mutant::Meta::Example.add do
source 'foo(nil, nil)'
mutation 'foo()'
mutation 'foo(nil)'
mutation 'nil'
end
Mutant::Meta::Example.add do
source '(left - right) / foo'
mutation 'foo'
mutation '(left - right)'
mutation 'left / foo'
mutation 'right / foo'
mutation '(left - right) / nil'
mutation '(left - nil) / foo'
mutation '(nil - right) / foo'
mutation 'nil / foo'
mutation 'nil'
end
(Mutant::BINARY_METHOD_OPERATORS - [:==, :eql?]).each do |operator|
Mutant::Meta::Example.add do
source "true #{operator} false"
mutation "false #{operator} false"
mutation "nil #{operator} false"
mutation "true #{operator} true"
mutation "true #{operator} nil"
mutation 'true'
mutation 'false'
mutation 'nil'
end
Mutant::Meta::Example.add do
source "left #{operator} right"
mutation 'left'
mutation 'right'
mutation "left #{operator} nil"
mutation "nil #{operator} right"
mutation 'nil'
end
end

26
meta/super.rb Normal file
View file

@ -0,0 +1,26 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'super'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'super()'
mutation 'super'
mutation 'nil'
end
Mutant::Meta::Example.add do
source 'super(foo, bar)'
mutation 'super'
mutation 'super()'
mutation 'super(foo)'
mutation 'super(bar)'
mutation 'super(foo, nil)'
mutation 'super(nil, bar)'
mutation 'nil'
end

10
meta/yield.rb Normal file
View file

@ -0,0 +1,10 @@
# encoding: utf-8
Mutant::Meta::Example.add do
source 'yield true'
mutation 'yield false'
mutation 'yield nil'
mutation 'yield'
mutation 'nil'
end

View file

@ -14,6 +14,7 @@ if ENV['COVERAGE'] == 'true'
add_filter 'spec'
add_filter 'vendor'
add_filter 'test_app'
add_filter 'lib/mutant/meta/**/*.rb'
minimum_coverage 89.77 # TODO: raise this to 100, then mutation test
end
@ -24,6 +25,7 @@ require 'adamantium'
require 'devtools/spec_helper'
require 'unparser/cli'
require 'mutant'
require 'mutant/meta'
$LOAD_PATH << File.join(TestApp.root, 'lib')

View file

@ -33,7 +33,12 @@ describe Mutant::Expression::Method do
context 'with an instance method' do
let(:input) { instance_method }
it { should eql(Mutant::Matcher::Method::Instance.new(cache, TestApp::Literal, TestApp::Literal.instance_method(:string))) }
it 'returns correct matcher' do
should eql(Mutant::Matcher::Method::Instance.new(
cache,
TestApp::Literal, TestApp::Literal.instance_method(:string)
))
end
end
context 'with a singleton method' do

View file

@ -1,19 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::OpAsgn, 'and_asgn' do
let(:source) { 'a &&= 1' }
let(:mutations) do
mutations = []
mutations << 'a__mutant__ &&= 1'
mutations << 'a &&= nil'
mutations << 'a &&= 0'
mutations << 'a &&= -1'
mutations << 'a &&= 2'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,32 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator, 'begin' do
# This mutation and only this mutation can result in
# and empty emit that is parsed into nil, unparser cannot
# handle this so we guard this here!
def generate(node)
return '' if node.nil?
super
end
let(:source) { "true\nfalse" }
let(:mutations) do
mutations = []
# Mutation of each statement in block
mutations << "true\ntrue"
mutations << "false\nfalse"
mutations << "nil\nfalse"
mutations << "true\nnil"
# Remove statement in block
mutations << 'true'
mutations << 'false'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,41 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Binary, 'mutations' do
context 'and' do
let(:source) { 'true and false' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'true'
mutations << 'false'
mutations << 'true or false'
mutations << 'not true and false'
mutations << 'not(true and false)'
end
it_should_behave_like 'a mutator'
end
context 'or' do
let(:source) { 'true or false' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'true'
mutations << 'false'
mutations << 'true and false'
mutations << 'not true or false'
mutations << 'not(true or false)'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,15 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::NamedValue::Access, 'block_pass' do
let(:source) { 'foo(&bar)' }
let(:mutations) do
mutants = []
mutants << 'foo'
mutants << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,83 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator, 'block' do
context 'with block' do
let(:source) { 'foo() { a; b }' }
let(:mutations) do
mutations = []
mutations << 'foo { a }'
mutations << 'foo { b }'
mutations << 'foo {}'
mutations << 'foo { raise }'
mutations << 'foo { a; nil }'
mutations << 'foo { nil; b }'
mutations << 'foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with block args' do
let(:source) { 'foo { |a, b| }' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'foo { |a, b| raise }'
mutations << 'foo { |a, b__mutant__| }'
mutations << 'foo { |a__mutant__, b| }'
mutations << 'foo { |a| }'
mutations << 'foo { |b| }'
mutations << 'foo { || }'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with block pattern args' do
let(:source) { 'foo { |(a, b), c| }' }
let(:mutations) do
mutations = []
mutations << 'foo { || }'
mutations << 'foo { |a, b, c| }'
mutations << 'foo { |(a, b), c| raise }'
mutations << 'foo { |(a), c| }'
mutations << 'foo { |(b), c| }'
mutations << 'foo { |(a, b)| }'
mutations << 'foo { |c| }'
mutations << 'foo { |(a__mutant__, b), c| }'
mutations << 'foo { |(a, b__mutant__), c| }'
mutations << 'foo { |(a, b), c__mutant__| }'
mutations << 'foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with mini block pattern arg' do
let(:source) { 'foo { |(a)| }' }
let(:mutations) do
mutations = []
mutations << 'foo { || }'
mutations << 'foo { |a| }'
mutations << 'foo { |(a)| raise }'
mutations << 'foo { |(a__mutant__)| }'
mutations << 'foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,17 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Blockarg, 'blockarg' do
let(:source) { 'foo { |&bar| }' }
let(:mutations) do
mutations = []
mutations << 'foo { |&bar| raise }'
mutations << 'foo {}'
mutations << 'foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,329 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Case do
context 'without condition' do
let(:source) do
<<-RUBY
case
when true
else
end
RUBY
end
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << <<-RUBY
case
when true
raise
else
end
RUBY
mutations << <<-RUBY
case
when false
else
end
RUBY
mutations << <<-RUBY
case
when nil
else
end
RUBY
end
it_should_behave_like 'a mutator'
end
context 'with multiple when branches' do
let(:source) do
<<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz
else
:else
end
RUBY
end
let(:mutations) do
mutations = []
# Presence of branches
mutations << <<-RUBY
case :condition
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz
end
RUBY
# Mutations of condition
mutations << <<-RUBY
case nil
when :foo
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition__mutant__
when :foo
when :bar, :baz
:barbaz
else
:else
end
RUBY
# Mutations of branch bodies
mutations << <<-RUBY
case :condition
when :foo
raise
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz__mutant__
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar, :baz
nil
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz
else
:else__mutant__
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar, :baz
:barbaz
else
nil
end
RUBY
# Mutations of when conditions
mutations << <<-RUBY
case :condition
when :foo__mutant__
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when nil
when :bar, :baz
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar__mutant__, :baz
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when nil, :baz
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar, nil
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar, :baz__mutant__
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :baz
:barbaz
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
when :bar
:barbaz
else
:else
end
RUBY
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with one when branch' do
let(:source) do
<<-RUBY
case :condition
when :foo
:foo
else
:else
end
RUBY
end
let(:mutations) do
mutations = []
# Presence of branches
mutations << <<-RUBY
case :condition
when :foo
:foo
end
RUBY
# Mutations of condition
mutations << <<-RUBY
case nil
when :foo
:foo
else
:else
end
RUBY
mutations << <<-RUBY
case :condition__mutant__
when :foo
:foo
else
:else
end
RUBY
# Mutations of branch bodies
mutations << <<-RUBY
case :condition
when :foo
nil
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
:foo__mutant__
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
:foo
else
:else__mutant__
end
RUBY
mutations << <<-RUBY
case :condition
when :foo
:foo
else
nil
end
RUBY
# Mutations of when conditions
mutations << <<-RUBY
case :condition
when :foo__mutant__
:foo
else
:else
end
RUBY
mutations << <<-RUBY
case :condition
when nil
:foo
else
:else
end
RUBY
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,15 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Noop, 'cbase' do
let(:source) { '::A' }
let(:mutations) do
mutants = []
mutants << 'nil'
mutants << 'A'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,58 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::ConditionalLoop do
context 'with empty body' do
let(:source) { 'while true; end' }
let(:mutations) do
mutations = []
mutations << 'while true; raise; end'
mutations << 'while false; end'
mutations << 'while nil; end'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with while statement' do
let(:source) { 'while true; foo; bar; end' }
let(:mutations) do
mutations = []
mutations << 'while true; bar; end'
mutations << 'while true; foo; end'
mutations << 'while true; end'
mutations << 'while false; foo; bar; end'
mutations << 'while nil; foo; bar; end'
mutations << 'while true; foo; nil; end'
mutations << 'while true; nil; bar; end'
mutations << 'while true; raise; end'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with until statement' do
let(:source) { 'until true; foo; bar; end' }
let(:mutations) do
mutations = []
mutations << 'until true; bar; end'
mutations << 'until true; foo; end'
mutations << 'until true; end'
mutations << 'until false; foo; bar; end'
mutations << 'until nil; foo; bar; end'
mutations << 'until true; foo; nil; end'
mutations << 'until true; nil; bar; end'
mutations << 'until true; raise; end'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,16 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Const, 'const' do
let(:source) { 'A::B::C' }
let(:mutations) do
mutants = []
mutants << 'nil'
mutants << 'B::C'
mutants << 'C'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,171 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator, 'def' do
context 'empty' do
let(:source) { 'def foo; end' }
let(:mutations) do
mutations = []
mutations << 'def foo; raise; end'
end
it_should_behave_like 'a mutator'
end
context 'empty rescue body' do
let(:source) { "def foo\nfoo\nrescue\nend" }
let(:mutations) do
mutations = []
mutations << 'def foo; raise; end'
mutations << 'def foo; nil; rescue; end'
mutations << 'def foo; end'
end
it_should_behave_like 'a mutator'
end
context 'with no arguments' do
let(:source) { 'def foo; true; false; end' }
let(:mutations) do
mutations = []
# Mutation of each statement in block
mutations << 'def foo; true; true; end'
mutations << 'def foo; false; false; end'
mutations << 'def foo; true; nil; end'
mutations << 'def foo; nil; false; end'
# Remove statement in block
mutations << 'def foo; true; end'
mutations << 'def foo; false; end'
# Remove all statements
mutations << 'def foo; end'
mutations << 'def foo; raise; end'
end
it_should_behave_like 'a mutator'
end
context 'with arguments' do
let(:source) { 'def foo(a, b); end' }
let(:mutations) do
mutations = []
# Deletion of each argument
mutations << 'def foo(a); end'
mutations << 'def foo(b); end'
# Deletion of all arguments
mutations << 'def foo; end'
# Rename each argument
mutations << 'def foo(a__mutant__, b); end'
mutations << 'def foo(a, b__mutant__); end'
# Mutation of body
mutations << 'def foo(a, b); raise; end'
end
it_should_behave_like 'a mutator'
end
context 'with argument beginning in an underscore' do
let(:source) { 'def foo(_unused); end' }
let(:mutations) do
mutations = []
mutations << 'def foo(_unused); raise; end'
mutations << 'def foo; end'
end
it_should_behave_like 'a mutator'
end
context 'with optional argument beginning in an underscore' do
let(:source) { 'def foo(_unused = true); end' }
let(:mutations) do
mutations = []
mutations << 'def foo(_unused = nil); end'
mutations << 'def foo(_unused = false); end'
mutations << 'def foo(_unused = true); raise; end'
mutations << 'def foo(_unused); end'
mutations << 'def foo; end'
end
it_should_behave_like 'a mutator'
end
context 'default argument' do
let(:source) { 'def foo(a = true); end' }
let(:mutations) do
mutations = []
mutations << 'def foo(a); end'
mutations << 'def foo(); end'
mutations << 'def foo(a = false); end'
mutations << 'def foo(a = nil); end'
mutations << 'def foo(a__mutant__ = true); end'
mutations << 'def foo(a = true); raise; end'
end
it_should_behave_like 'a mutator'
end
context 'define on singleton' do
let(:source) { 'def self.foo; true; false; end' }
let(:mutations) do
mutations = []
# Body presence mutations
mutations << 'def self.foo; false; false; end'
mutations << 'def self.foo; true; true; end'
mutations << 'def self.foo; true; nil; end'
mutations << 'def self.foo; nil; false; end'
# Body presence mutations
mutations << 'def self.foo; true; end'
mutations << 'def self.foo; false; end'
# Remove all statements
mutations << 'def self.foo; end'
mutations << 'def self.foo; raise; end'
end
it_should_behave_like 'a mutator'
end
context 'define on singleton with argument' do
let(:source) { 'def self.foo(a, b); end' }
let(:mutations) do
mutations = []
# Deletion of each argument
mutations << 'def self.foo(a); end'
mutations << 'def self.foo(b); end'
# Deletion of all arguments
mutations << 'def self.foo; end'
# Rename each argument
mutations << 'def self.foo(a__mutant__, b); end'
mutations << 'def self.foo(a, b__mutant__); end'
# Mutation of body
mutations << 'def self.foo(a, b); raise; end'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,14 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Generic, 'defined?' do
let(:source) { 'defined?(foo)' }
let(:mutations) do
mutations = []
mutations << 'defined?(nil)'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,17 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Dstr, 'dstr' do
let(:source) { '"foo#{bar}baz"' }
let(:mutations) do
mutations = []
mutations << '"#{nil}#{bar}baz"'
mutations << '"foo#{bar}#{nil}"'
mutations << '"foo#{nil}baz"'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,18 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Dsym, 'dsym' do
let(:source) { ':"foo#{bar}baz"' }
let(:mutations) do
mutations = []
mutations << ':"#{nil}#{bar}baz"'
mutations << ':"foo#{bar}#{nil}"'
mutations << ':"foo#{nil}baz"'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,16 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Generic, 'ensure' do
let(:source) { 'begin; rescue; ensure; true; end' }
let(:mutations) do
mutations = []
mutations << 'begin; rescue; ensure; false; end'
mutations << 'begin; rescue; ensure; nil; end'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,77 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator, 'if' do
context 'with if and else branches' do
let(:source) { 'if :condition; true; else false; end' }
let(:mutations) do
mutants = []
# mutations of condition
mutants << 'if :condition__mutant__; true; else false; end'
mutants << 'if !:condition; true; else false; end'
mutants << 'if nil; true; else false; end'
mutants << 'if true; true; else false; end'
mutants << 'if false; true; else false; end'
# Deleted else branch
mutants << 'if :condition; true end'
# Deleted if branch resuting in unless rendering
mutants << 'unless :condition; false; end'
# Deleted if branch with promoting else branch to if branch
mutants << 'if :condition; false end'
# mutations of if body
mutants << 'if :condition; false; else false; end'
mutants << 'if :condition; nil; else false; end'
# mutations of else body
mutants << 'if :condition; true; else true; end'
mutants << 'if :condition; true; else nil; end'
mutants << 'nil'
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'
mutants << 'if true; true; end'
mutants << 'if false; true; end'
mutants << 'if nil; true; end'
mutants << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'unless with one branch' do
let(:source) { 'unless :condition; true; end' }
let(:mutations) do
mutants = []
mutants << 'unless !:condition; true; end'
mutants << 'unless :condition__mutant__; true; end'
mutants << 'unless nil; true; end'
mutants << 'unless :condition; false; end'
mutants << 'unless :condition; nil; end'
mutants << 'unless true; true; end'
mutants << 'unless false; true; end'
mutants << 'if :condition; true; end'
mutants << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,16 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Kwbegin, 'kwbegin' do
let(:source) { 'begin; true; end' }
let(:mutations) do
mutations = []
mutations << 'begin; false; end'
mutations << 'begin; nil; end'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,47 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'array' do
context 'on one item' do
let(:source) { '[true]' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'true'
mutations << '[false]'
mutations << '[nil]'
mutations << '[]'
end
it_should_behave_like 'a mutator'
end
context 'on arrays with more than one item' do
let(:source) { '[true, false]' }
let(:mutations) do
mutations = []
# Literal replaced with nil
mutations << 'nil'
# Mutation of each element in array
mutations << '[nil, false]'
mutations << '[false, false]'
mutations << '[true, nil]'
mutations << '[true, true]'
# Remove each element of array once
mutations << '[true]'
mutations << '[false]'
# Empty array
mutations << '[]'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,25 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'boolean' do
context 'true literal' do
let(:source) { 'true' }
let(:mutations) do
%w[nil false]
end
it_should_behave_like 'a mutator'
end
context 'false literal' do
let(:source) { 'false' }
let(:mutations) do
%w[nil true]
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,13 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'fixnum' do
let(:source) { '10' }
let(:mutations) do
%w[nil 0 1 -10 9 11]
end
it_should_behave_like 'a mutator'
end

View file

@ -1,53 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'float' do
context 'positive number' do
let(:source) { '10.0' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << '0.0'
mutations << '1.0'
mutations << '(0.0 / 0.0)'
mutations << '(1.0 / 0.0)'
mutations << '(-1.0 / 0.0)'
mutations << '-10.0'
end
it_should_behave_like 'a mutator'
end
context '0.0' do
let(:source) { '0.0' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << '1.0'
mutations << '(0.0 / 0.0)'
mutations << '(1.0 / 0.0)'
mutations << '(-1.0 / 0.0)'
end
it_should_behave_like 'a mutator'
end
context '-0.0' do
let(:source) { '-0.0' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << '1.0'
mutations << '(0.0 / 0.0)'
mutations << '(1.0 / 0.0)'
mutations << '(-1.0 / 0.0)'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,33 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'hash' do
let(:source) { '{true => true, false => false}' }
let(:mutations) do
mutations = []
# Literal replaced with nil
mutations << 'nil'
# Mutation of each key and value in hash
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 << '{ true => true }'
mutations << '{ false => false }'
# Empty hash
mutations << '{}'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,10 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'nil' do
let(:source) { 'nil' }
let(:mutations) { [] }
it_should_behave_like 'a mutator'
end

View file

@ -1,56 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'range' do
context 'inclusive range literal' do
let(:source) { '1..100' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << '1...100'
mutations << '(0.0 / 0.0)..100'
mutations << '1..(1.0 / 0.0)'
mutations << '1..(0.0 / 0.0)'
mutations << '-1..100'
mutations << '0..100'
mutations << '2..100'
mutations << 'nil..100'
mutations << '1..nil'
mutations << '1..0'
mutations << '1..1'
mutations << '1..99'
mutations << '1..101'
mutations << '1..-100'
end
it_should_behave_like 'a mutator'
end
context 'exclusive range literal' do
let(:source) { '1...100' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << '1..100'
mutations << '(0.0 / 0.0)...100'
mutations << '1...(1.0 / 0.0)'
mutations << '1...(0.0 / 0.0)'
mutations << '-1...100'
mutations << '0...100'
mutations << '2...100'
mutations << 'nil...100'
mutations << '1...nil'
mutations << '1...0'
mutations << '1...1'
mutations << '1...99'
mutations << '1...101'
mutations << '1...-100'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,36 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'regex' do
context 'literal' do
let(:source) { '/foo/' }
let(:mutations) do
mutations = []
mutations << '//' # match all
mutations << '/a\A/' # match nothing
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'interpolated' do
let(:source) { '/#{foo.bar}n/' }
let(:mutations) do
mutations = []
mutations << '//' # match all
mutations << '/#{foo}n/' # match all
mutations << '/a\A/' # match nothing
mutations << '/#{nil.bar}n/'
mutations << '/#{nil}n/'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,15 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'string' do
let(:random_string) { 'bar' }
let(:source) { '"foo"' }
let(:mutations) do
%w[nil]
end
it_should_behave_like 'a mutator'
end

View file

@ -1,15 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Literal, 'symbol' do
let(:random_string) { 'bar' }
let(:source) { ':foo' }
let(:mutations) do
%w[nil :foo__mutant__]
end
it_should_behave_like 'a mutator'
end

View file

@ -1,37 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::LoopControl do
context 'with break node' do
let(:source) { 'break true' }
let(:mutations) do
mutations = []
mutations << 'break false'
mutations << 'break nil'
mutations << 'break'
mutations << 'nil'
mutations << 'next true'
end
it_should_behave_like 'a mutator'
end
context 'with next node' do
let(:source) { 'next true' }
let(:mutations) do
mutations = []
mutations << 'next false'
mutations << 'next nil'
mutations << 'next'
mutations << 'nil'
mutations << 'break true'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,14 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator, 'masgn' do
let(:source) { 'a, b = c, d' }
let(:mutations) do
mutations = []
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,21 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Generic, 'match_current_line' do
let(:source) { 'true if /foo/' }
let(:mutations) do
mutations = []
mutations << 'false if /foo/'
mutations << 'true if //'
mutations << 'nil if /foo/'
mutations << 'true if true'
mutations << 'true if false'
mutations << 'true if nil'
mutations << 'true if /a\A/'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,78 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::NamedValue::Access, 'mutations' do
context 'global variable' do
let(:source) { '$a = nil; $a' }
let(:mutations) do
mutants = []
mutants << '$a = nil; nil'
mutants << '$a = nil'
mutants << '$a'
mutants << '$a__mutant__ = nil; $a'
mutants << 'nil; $a'
end
it_should_behave_like 'a mutator'
end
context 'class variable' do
let(:source) { '@@a = nil; @@a' }
let(:mutations) do
mutants = []
mutants << '@@a = nil; nil'
mutants << '@@a = nil'
mutants << '@@a'
mutants << '@@a__mutant__ = nil; @@a'
mutants << 'nil; @@a'
end
end
context 'instance variable' do
let(:source) { '@a = nil; @a' }
let(:mutations) do
mutants = []
mutants << '@a = nil; nil'
mutants << '@a = nil'
mutants << '@a'
mutants << '@a__mutant__ = nil; @a'
mutants << 'nil; @a'
end
it_should_behave_like 'a mutator'
end
context 'local variable' do
let(:source) { 'a = nil; a' }
let(:mutations) do
mutants = []
mutants << 'a = nil; nil'
mutants << 'a = nil'
# TODO: fix invalid AST
# These ASTs are not valid and should NOT be emitted
# Mutations of lvarasgn need to be special cased to avoid this.
mutants << s(:begin, s(:lvasgn, :a__mutant__, s(:nil)), s(:lvar, :a))
mutants << s(:begin, s(:nil), s(:lvar, :a))
mutants << s(:lvar, :a)
end
it_should_behave_like 'a mutator'
end
context 'self' do
let(:source) { 'self' }
let(:mutations) do
mutants = []
mutants << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,16 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::NamedValue::VariableAssignment, 'mutations' do
let(:source) { 'A = true' }
let(:mutations) do
mutations = []
mutations << 'A__MUTANT__ = true'
mutations << 'A = false'
mutations << 'A = nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,61 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::NamedValue::VariableAssignment, 'mutations' do
context 'global variable' do
let(:source) { '$a = true' }
let(:mutations) do
mutations = []
mutations << '$a__mutant__ = true'
mutations << '$a = false'
mutations << '$a = nil'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'class variable' do
let(:source) { '@@a = true' }
let(:mutations) do
mutations = []
mutations << '@@a__mutant__ = true'
mutations << '@@a = false'
mutations << '@@a = nil'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'instance variable' do
let(:source) { '@a = true' }
let(:mutations) do
mutations = []
mutations << '@a__mutant__ = true'
mutations << '@a = false'
mutations << '@a = nil'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'local variable' do
let(:source) { 'a = true' }
let(:mutations) do
mutations = []
mutations << 'a__mutant__ = true'
mutations << 'a = false'
mutations << 'a = nil'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,19 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator, 'nthref' do
context '$1' do
let(:source) { '$1' }
let(:mutations) { ['$2'] }
it_should_behave_like 'a mutator'
end
context '$2' do
let(:source) { '$2' }
let(:mutations) { ['$3', '$1'] }
it_should_behave_like 'a mutator'
end
end

View file

@ -1,22 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Generic, 'op_asgn' do
let(:source) { '@a.b += 1' }
let(:mutations) do
mutations = []
mutations << '@a.b += -1'
mutations << '@a.b += 2'
mutations << '@a.b += 0'
mutations << '@a.b += nil'
mutations << 'nil.b += 1'
mutations << 'nil'
# TODO: fix invalid AST
# This should not get emitted as invalid AST with valid unparsed source
mutations << s(:op_asgn, s(:ivar, :@a), :+, s(:int, 1))
end
it_should_behave_like 'a mutator'
end

View file

@ -1,19 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::OpAsgn, 'or_asgn' do
let(:source) { 'a ||= 1' }
let(:mutations) do
mutations = []
mutations << 'a__mutant__ ||= 1'
mutations << 'a ||= nil'
mutations << 'a ||= 0'
mutations << 'a ||= -1'
mutations << 'a ||= 2'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,10 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Generic, 'redo' do
let(:source) { 'redo' }
let(:mutations) { [] }
it_should_behave_like 'a mutator'
end

View file

@ -1,63 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Generic, 'rescue' 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; true; end'
mutations << 'begin; rescue ExceptionA, ExceptionB => error; false; end'
mutations << 'begin; rescue ExceptionA, ExceptionB => error; nil; end'
mutations << 'begin; rescue ExceptionA => error; true; end'
mutations << 'begin; rescue ExceptionB => error; true; end'
end
it_should_behave_like 'a mutator'
end
context 'single exception selector and assignment' do
let(:source) { 'begin; rescue SomeException => error; true; end' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'begin; rescue SomeException; true; end'
mutations << 'begin; rescue SomeException => error; false; end'
mutations << 'begin; rescue SomeException => error; nil; 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

View file

@ -1,18 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Restarg, 'restarg' do
let(:source) { 'foo(*bar)' }
let(:mutations) do
mutants = []
mutants << 'foo'
mutants << 'foo(nil)'
mutants << 'foo(bar)'
mutants << 'foo(*nil)'
mutants << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -1,31 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator, 'return' do
context 'return without value' do
let(:source) { 'return' }
let(:mutations) do
mutations = []
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'return with value' do
let(:source) { 'return foo' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'return nil'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,382 +0,0 @@
# encoding: utf-8
require 'spec_helper'
# FIXME: This spec needs to be structured better!
describe Mutant::Mutator, 'send' do
context 'when using #reverse_each' do
let(:source) { 'reverse_each' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'each'
end
it_should_behave_like 'a mutator'
end
context 'when using #reverse_map' do
let(:source) { 'reverse_map' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'map'
mutations << 'each'
end
it_should_behave_like 'a mutator'
end
context 'when using #map' do
let(:source) { 'map' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'each'
end
it_should_behave_like 'a mutator'
end
context 'when using #==' do
let(:source) { 'foo == bar' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'bar'
mutations << 'nil == bar'
mutations << 'foo == nil'
mutations << 'nil'
mutations << 'foo.eql?(bar)'
mutations << 'foo.equal?(bar)'
end
it_should_behave_like 'a mutator'
end
context 'when using #gsub' do
let(:source) { 'foo.gsub(a, b)' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'foo.gsub(a)'
mutations << 'foo.gsub(b)'
mutations << 'foo.gsub'
mutations << 'foo.sub(a, b)'
mutations << 'foo.gsub(a, nil)'
mutations << 'foo.gsub(nil, b)'
mutations << 'nil.gsub(a, b)'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'when using Kernel#send' do
let(:source) { 'foo.send(bar)' }
let(:mutations) do
mutations = []
mutations << 'foo.send'
mutations << 'foo.public_send(bar)'
mutations << 'bar'
mutations << 'foo'
mutations << 'foo.send(nil)'
mutations << 'nil.send(bar)'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'inside op assign' do
let(:source) { 'self.foo ||= expression' }
let(:mutations) do
mutations = []
mutations << 'self.foo ||= nil'
mutations << 'nil.foo ||= expression'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'attribute assign' do
context 'to self' do
let(:source) { 'self.bar=baz' }
let(:mutations) do
mutations = []
mutations << 'nil'
mutations << 'self.bar=nil'
mutations << 'self'
mutations << 'self.bar'
mutations << 'baz'
# This one could probably be removed
mutations << 'nil.bar=baz'
end
it_should_behave_like 'a mutator'
end
context 'to other object' do
let(:source) { 'foo.bar=baz' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'nil'
mutations << 'foo.bar=nil'
mutations << 'foo.bar'
mutations << 'baz'
# This one could probably be removed
mutations << 'nil.bar=baz'
end
it_should_behave_like 'a mutator'
end
end
context 'index assign' do
let(:source) { 'foo[bar]=baz' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with only a splat arg' do
let(:source) { 'foo(*bar)' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'foo(nil)'
mutations << 'foo(bar)'
mutations << 'foo(*nil)'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with only a block arg' do
let(:source) { 'foo(&bar)' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'single splat arg splat' do
let(:source) { 'foo[*bar]' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with self as' do
context 'implicit' do
let(:source) { 'foo' }
let(:mutations) do
mutations = []
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'explict receiver' do
let(:source) { 'self.foo' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'self'
mutations << 'nil.foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'explicit receiver with keyword message name' do
Unparser::Constants::KEYWORDS.each do |keyword|
context "with keyword: #{keyword}" do
let(:source) { "self.#{keyword}" }
let(:mutations) do
['self']
end
end
end
end
end
context 'without arguments' do
context 'to some object' do
let(:source) { 'foo.bar' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'nil.bar'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'to self.class.foo' do
let(:source) { 'self.class.foo' }
let(:mutations) do
mutations = []
mutations << 'self.class'
mutations << 'self.foo'
mutations << 'nil.class.foo'
mutations << 'nil.foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end
context 'with arguments' do
context 'one argument' do
let(:source) { 'foo(nil)' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with explicit self as receiver' do
let(:source) { 'self.foo(nil)' }
let(:mutations) do
mutations = []
mutations << 'self'
mutations << 'self.foo'
mutations << 'foo(nil)'
mutations << 'nil'
mutations << 'nil.foo(nil)'
end
it_should_behave_like 'a mutator'
end
context 'to some object with keyword in method name' do
Unparser::Constants::KEYWORDS.each do |keyword|
context "with keyword #{keyword}" do
let(:source) { "foo.#{keyword}(nil)" }
let(:mutations) do
mutations = []
mutations << "foo.#{keyword}"
mutations << 'foo'
mutations << "nil.#{keyword}(nil)"
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end
end
context 'two arguments' do
let(:source) { 'foo(nil, nil)' }
let(:mutations) do
mutations = []
mutations << 'foo()'
mutations << 'foo(nil)'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'binary operator methods' do
context 'nested' do
let(:source) { '(left - right) / foo' }
let(:mutations) do
mutations = []
mutations << 'foo'
mutations << '(left - right)'
mutations << 'left / foo'
mutations << 'right / foo'
mutations << '(left - right) / nil'
mutations << '(left - nil) / foo'
mutations << '(nil - right) / foo'
mutations << 'nil / foo'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
(Mutant::BINARY_METHOD_OPERATORS - [:==, :eql?]).each do |operator|
context 'on literal scalar arguments' do
let(:source) { "true #{operator} false" }
let(:mutations) do
mutations = []
mutations << "false #{operator} false"
mutations << "nil #{operator} false"
mutations << "true #{operator} true"
mutations << "true #{operator} nil"
mutations << 'true'
mutations << 'false'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'on non literal scalar arguments' do
let(:source) { "left #{operator} right" }
let(:mutations) do
mutations = []
mutations << 'left'
mutations << 'right'
mutations << "left #{operator} nil"
mutations << "nil #{operator} right"
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end
end
end
end

View file

@ -1,46 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator, 'super' do
context 'with no arguments' do
let(:source) { 'super' }
let(:mutations) do
mutations = []
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'with explicit empty arguments' do
let(:source) { 'super()' }
let(:mutations) do
mutations = []
mutations << 'super'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
context 'super with arguments' do
let(:source) { 'super(foo, bar)' }
let(:mutations) do
mutations = []
mutations << 'super'
mutations << 'super()'
mutations << 'super(foo)'
mutations << 'super(bar)'
mutations << 'super(foo, nil)'
mutations << 'super(nil, bar)'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end
end

View file

@ -1,17 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Mutator::Node::Yield, 'yield' do
let(:source) { 'yield true' }
let(:mutations) do
mutations = []
mutations << 'yield false'
mutations << 'yield nil'
mutations << 'yield'
mutations << 'nil'
end
it_should_behave_like 'a mutator'
end

View file

@ -0,0 +1,14 @@
require 'spec_helper'
describe Mutant::Mutator::Node do
Mutant::Meta::Example::ALL.each do |example|
context "on #{example.node.type.inspect}" do
it 'generates the correct mutations' do
verification = example.verification
unless verification.success?
fail verification.error_report
end
end
end
end
end