Bring back yard coverage to 100%

Also do some minor refactorings
This commit is contained in:
Markus Schirp 2012-12-12 22:31:14 +01:00
parent 386a2bc2df
commit 93556763dd
17 changed files with 170 additions and 37 deletions

View file

@ -235,7 +235,7 @@ module Mutant
# Add mutation filter
#
# @param [Class<Mutant::Filter>]
# @param [Class<Mutant::Filter>] klass
#
# @return [undefined]
#
@ -283,7 +283,7 @@ module Mutant
# Set strategy
#
# @param [Strategy]
# @param [Strategy] strategy
#
# @api private
#

View file

@ -1,16 +1,44 @@
module Mutant
class Killer
# Killer that executes other killer in forked environment
class Forked < self
# Initialize object
#
# @param [Killer] killer
# @param [Strategy] strategy
# @param [Mutation] mutation
#
# @api private
#
def initialize(killer, strategy, mutation)
@killer = killer
super(strategy, mutation)
end
# Return killer type
#
# @return [String]
#
# @api private
#
def type
@killer.type
end
private
# Run killer
#
# @return [true]
# if mutant was killed
#
# @return [false]
# otherwise
#
# @api private
#
def run
fork do
killer = @killer.new(strategy, mutation)
@ -22,15 +50,40 @@ module Mutant
end
end
# A killer that executes other killer in forked environemnts
class Forking < self
include Equalizer.new(:killer)
# Return killer
#
# @return [Killer]
#
# @api private
#
attr_reader :killer
# Initalize killer
#
# @param [Killer] killer
# the killer that will be used
#
# @return [undefined]
#
# @api private
#
def initialize(killer)
@killer = killer
end
# Return killer instance
#
# @param [Strategy] strategy
# @param [Mutation] mutation
#
# @return [Killer::Forked]
#
# @api private
#
def new(strategy, mutation)
Forked.new(killer, strategy, mutation)
end

View file

@ -1,15 +1,29 @@
module Mutant
class Killer
# Abstract base class for killer with static result
class Static < self
# Return result
#
# @return [true]
# if mutation was killed
#
# @return [false]
# otherwise
#
# @api private
#
def run
self.class::RESULT
end
# Killer that is always successful
class Success < self
TYPE = 'success'.freeze
RESULT = true
end
# Killer that always fails
class Fail < self
TYPE = 'fail'.freeze
RESULT = false

View file

@ -43,6 +43,8 @@ module Mutant
# @return [nil]
# returns nil otherwise
#
# @api private
#
def self.from_string(input)
descendants.each do |descendant|
matcher = descendant.parse(input)

View file

@ -72,7 +72,7 @@ module Mutant
# @return [true]
# if method is public
#
# @retur [false]
# @return [false]
# otherwise
#
# @api private

View file

@ -98,7 +98,7 @@ module Mutant
# Yield scope if name matches pattern
#
# @param [::Module,::Class]
# @param [::Module,::Class] scope
#
# @return [undefined]
#

View file

@ -153,6 +153,8 @@ module Mutant
#
# @return [Enumerable<Symbol>]
#
# @api private
#
def method_names
scope = self.scope
return [] unless scope.kind_of?(Module)

View file

@ -6,7 +6,7 @@ module Mutant
# Test for match
#
# @param [Mutation]
# @param [Mutation] mutation
#
# @return [true]
# returns true if mutation matches whitelist

View file

@ -12,9 +12,9 @@ module Mutant
#
# @api private
#
def self.each(node, &block)
return to_enum(__method__, node) unless block_given?
Registry.lookup(node.class).new(node, block)
def self.each(input, &block)
return to_enum(__method__, input) unless block_given?
Registry.lookup(input.class).new(input, block)
self
end
@ -34,10 +34,12 @@ module Mutant
# Return identity of object (for deduplication)
#
# @param [Object]
# @param [Object] object
#
# @return [Object]
#
# @api private
#
def self.identity(object)
object
end
@ -105,6 +107,8 @@ module Mutant
# @return [false]
# otherwise
#
# @api private
#
def allow?(object)
true
end

View file

@ -11,13 +11,28 @@ module Mutant
#
# @return [String]
#
# @api private
#
def self.identity(node)
ToSource.to_source(node)
end
private
private
# Return mutated node
#
# @return [Rubinius::AST::Node]
#
# @api private
#
alias_method :node, :input
# Return duplicated node
#
# @return [Rubinius::AST::Node]
#
# @api private
#
alias_method :dup_node, :dup_input
# Emit a new AST node

View file

@ -16,28 +16,15 @@ module Mutant
#
def dispatch
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
emit_attribute_mutations(:array) do |mutation|
array = mutation.array
# Do not generate empty bodies
if array.empty?
array << new_nil
end
end
super
end
end
end
end

View file

@ -5,7 +5,13 @@ module Mutant
# Run ulitity mutator
#
# @param [Object]
# @param [Object] object
#
# @return [Enumerator<Object>]
# if no block given
#
# @return [self]
# otherwise
#
# @api private
#
@ -27,6 +33,8 @@ module Mutant
# @return [false]
# otherwise
#
# @api private
#
def new?(generated)
input != generated
end

View file

@ -123,7 +123,7 @@ module Mutant
# Report errors
#
# @param [Enumerable<Killer>]
# @param [Enumerable<Killer>] errors
#
# @api private
#
@ -164,7 +164,7 @@ module Mutant
# Initialize reporter
#
# @param [IO] io
# @param [Config] config
#
# @return [undefined]
#
@ -234,8 +234,7 @@ module Mutant
# Write colorized diff
#
# @param [String] original
# @param [String] current
# @param [Mutation] mutation
#
# @return [undefined]
#

View file

@ -44,30 +44,70 @@ module Mutant
#
attr_reader :time
# Initialize object
#
# @return [undefined]
#
# @api private
#
def initialize
@start = Time.now
@noop_fails = @subjects = @mutations = @kills = @time = 0
end
# Return runtime in seconds
#
# @return [Float]
#
# @api private
#
def runtime
Time.now - @start
end
# Count subject
#
# @return [self]
#
# @api private
#
def subject
@subjects +=1
self
end
# Return number of mutants alive
#
# @return [Fixnum]
#
# @api private
#
def alive
@mutations - @kills
end
# Count noop mutation fail
#
# @param [Killer] killer
#
# @return [self]
#
# @api private
#
def noop_fail(killer)
@noop_fails += 1
@time += killer.runtime
self
end
# Count killer
#
# @param [Killer] killer
#
# @return [self]
#
# @api private
#
def killer(killer)
@mutations +=1
@kills +=1 unless killer.fail?

View file

@ -44,7 +44,7 @@ module Mutant
# Kill mutation
#
# @param [Mutation]
# @param [Mutation] mutation
#
# @return [Killer]
#

View file

@ -50,6 +50,13 @@ module Mutant
# Run all specs per mutation
class Full < self
# Return spec files
#
# @return [Enumerable<String>]
#
# @api private
#
def spec_files(mutation)
Dir['spec/**/*_spec.rb']
end

View file

@ -8,7 +8,7 @@ module Mutant
# Perform example lookup
#
# @param [Mutation]
# @param [Mutation] mutation
#
# @return [Enumerable<String>]
#
@ -111,6 +111,8 @@ module Mutant
# @return [nil]
# otherwise
#
# @api private
#
def mapped_name
MAPPING[method_name]
end