Finish cli reporter refactoring
Readds mutation reporting
This commit is contained in:
parent
20418d0969
commit
dbc6455ae1
9 changed files with 556 additions and 385 deletions
|
@ -107,3 +107,7 @@ require 'mutant/reporter'
|
|||
require 'mutant/reporter/null'
|
||||
require 'mutant/reporter/cli'
|
||||
require 'mutant/reporter/cli/printer'
|
||||
require 'mutant/reporter/cli/printer/config'
|
||||
require 'mutant/reporter/cli/printer/subject'
|
||||
require 'mutant/reporter/cli/printer/killer'
|
||||
require 'mutant/reporter/cli/printer/mutation'
|
||||
|
|
|
@ -79,7 +79,7 @@ module Mutant
|
|||
# @api private
|
||||
#
|
||||
def source
|
||||
ToSource.to_source(node)
|
||||
Unparser.unparse(node)
|
||||
end
|
||||
memoize :source
|
||||
|
||||
|
|
|
@ -2,40 +2,10 @@ module Mutant
|
|||
class Reporter
|
||||
# Reporter that reports in human readable format
|
||||
class CLI < self
|
||||
include Concord::Public.new(:io)
|
||||
include Concord::Public.new(:output)
|
||||
|
||||
NL = "\n".freeze
|
||||
|
||||
ACTIONS = {
|
||||
Config => :config,
|
||||
Subject => :subject,
|
||||
Killer => :killer,
|
||||
Runner::Subject => :subject_results,
|
||||
Runner::Config => :config_results
|
||||
}.freeze
|
||||
|
||||
# Perform lookup
|
||||
#
|
||||
# @param [Object] object
|
||||
#
|
||||
# @return [Symbol]
|
||||
# if found
|
||||
#
|
||||
# @raise [RuntimeError]
|
||||
# otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def self.lookup(object)
|
||||
current = klass = object.class
|
||||
begin
|
||||
symbol = ACTIONS[current]
|
||||
return symbol if symbol
|
||||
current = current.superclass
|
||||
end while current < ::Object
|
||||
raise "No reporter for #{klass}"
|
||||
end
|
||||
|
||||
# Report object
|
||||
#
|
||||
# @param [Object] object
|
||||
|
@ -45,188 +15,10 @@ module Mutant
|
|||
# @api private
|
||||
#
|
||||
def report(object)
|
||||
method = self.class.lookup(object)
|
||||
send(method, object)
|
||||
Printer.visit(object, output)
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Report subject
|
||||
#
|
||||
# @param [Subject] subject
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def subject(subject)
|
||||
puts
|
||||
puts(subject.identification)
|
||||
end
|
||||
# Report subject results
|
||||
#
|
||||
# @param [Subject] runner
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def subject_results(runner)
|
||||
Printer::Subject.run(io, runner)
|
||||
end
|
||||
|
||||
# Report mutation
|
||||
#
|
||||
# @param [Mutation] _mutation
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def mutation(_mutation)
|
||||
end
|
||||
|
||||
# Report configuration
|
||||
#
|
||||
# @param [Mutant::Config] config
|
||||
#
|
||||
# @return [self]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def config(config)
|
||||
puts 'Mutant configuration:'
|
||||
puts "Matcher: #{config.matcher.inspect }"
|
||||
puts "Filter: #{config.filter.inspect }"
|
||||
puts "Strategy: #{config.strategy.inspect}"
|
||||
end
|
||||
|
||||
# Report configuration results
|
||||
#
|
||||
# TODO: Break this stuff into smaller methods or factor out in a subclass
|
||||
#
|
||||
# @param [Reporter::Config] runner
|
||||
#
|
||||
# @return [self]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def config_results(runner)
|
||||
Printer::Config.run(io, runner)
|
||||
end
|
||||
|
||||
|
||||
# Report killer
|
||||
#
|
||||
# @param [Killer] killer
|
||||
#
|
||||
# @return [self]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def killer(killer)
|
||||
if killer.success?
|
||||
char('.', Color::GREEN)
|
||||
return
|
||||
end
|
||||
char('F', Color::RED)
|
||||
self
|
||||
end
|
||||
|
||||
# Write colorized char
|
||||
#
|
||||
# @param [String] char
|
||||
# @param [Color]
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def char(char, color)
|
||||
io = self.io
|
||||
io.write(colorize(color, char))
|
||||
io.flush
|
||||
end
|
||||
|
||||
# Test for colored output
|
||||
#
|
||||
# @return [true]
|
||||
# returns true if output is colored
|
||||
#
|
||||
# @return [false]
|
||||
# returns false otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def color?
|
||||
tty?
|
||||
end
|
||||
|
||||
# Colorize message
|
||||
#
|
||||
# @param [Color] color
|
||||
# @param [String] message
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
# @return [String]
|
||||
# returns colorized string if color is enabled
|
||||
# returns unmodified message otherwise
|
||||
#
|
||||
def colorize(color, message)
|
||||
color = Color::NONE unless color?
|
||||
color.format(message)
|
||||
end
|
||||
|
||||
# Write string to io
|
||||
#
|
||||
# @param [String] string
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def puts(string=NL)
|
||||
io.puts(string)
|
||||
end
|
||||
|
||||
# Write colorized diff
|
||||
#
|
||||
# @param [Mutation] mutation
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def colorized_diff(mutation)
|
||||
original, current = mutation.original_source, mutation.source
|
||||
differ = Differ.new(original, current)
|
||||
diff = color? ? differ.colorized_diff : differ.diff
|
||||
|
||||
if diff.empty?
|
||||
raise 'Unable to create a diff, so ast mutant or to_source does something strange!!'
|
||||
end
|
||||
|
||||
puts(diff)
|
||||
self
|
||||
end
|
||||
|
||||
# Test for output to tty
|
||||
#
|
||||
# @return [true]
|
||||
# returns true if output is a tty
|
||||
#
|
||||
# @return [false]
|
||||
# returns false otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def tty?
|
||||
@io.respond_to?(:tty?) && @io.tty?
|
||||
end
|
||||
memoize :tty?
|
||||
|
||||
end # CLI
|
||||
end # Reporter
|
||||
end # Mutant
|
||||
|
|
|
@ -2,197 +2,163 @@ module Mutant
|
|||
class Reporter
|
||||
class CLI
|
||||
|
||||
# CLI printer base class
|
||||
# CLI runner status printer base class
|
||||
class Printer
|
||||
include AbstractType, Adamantium::Flat, Concord.new(:output, :runner)
|
||||
include AbstractType, Adamantium::Flat, Concord.new(:object, :output)
|
||||
|
||||
def self.run(*args)
|
||||
new(*args).run
|
||||
REGISTRY = {}
|
||||
|
||||
# Registre handler for class
|
||||
#
|
||||
# @param [Class] klass
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def self.handle(klass)
|
||||
REGISTRY[klass] = self
|
||||
end
|
||||
|
||||
private
|
||||
# Finalize CLI reporter
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def self.finalize
|
||||
REGISTRY.freeze
|
||||
end
|
||||
|
||||
def puts(string = NL)
|
||||
output.puts(string)
|
||||
# Run printer
|
||||
#
|
||||
# @return [self]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def self.run(*args)
|
||||
new(*args).run
|
||||
self
|
||||
end
|
||||
|
||||
# Visit object
|
||||
#
|
||||
# @param [Object] object
|
||||
# @param [IO] output
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def self.visit(object, output)
|
||||
printer = REGISTRY.fetch(object.class)
|
||||
printer.run(object, output)
|
||||
end
|
||||
|
||||
abstract_method :run
|
||||
|
||||
# Config results printer
|
||||
class Config < self
|
||||
private
|
||||
|
||||
# Run printer
|
||||
#
|
||||
# @return [self]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def run
|
||||
puts "Subjects: #{subjects.length}"
|
||||
puts "Mutations: #{amount_mutations}"
|
||||
puts "Kills: #{amount_kills}"
|
||||
puts 'Runtime: %0.2fs' % runtime
|
||||
puts 'Killtime: %0.2fs' % killtime
|
||||
puts 'Overhead: %0.2f%%' % overhead
|
||||
puts 'Coverage: %0.2f%%' % coverage
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
# Return status color
|
||||
#
|
||||
# @return [Color]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def color
|
||||
success? ? Color::GREEN : Color::RED
|
||||
end
|
||||
|
||||
# Return subjects
|
||||
#
|
||||
# @return [Array<Subject>]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def subjects
|
||||
runner.subjects
|
||||
end
|
||||
# Print an info line to output
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def info(string, *arguments)
|
||||
puts(sprintf(string, *arguments))
|
||||
end
|
||||
|
||||
# Return mutations
|
||||
#
|
||||
# @return [Array<Mutation>]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def mutations
|
||||
subjects.map(&:mutations).flatten
|
||||
end
|
||||
memoize :mutations
|
||||
# Print a status line to output
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def status(string, *arguments)
|
||||
puts(colorize(color, sprintf(string, *arguments)))
|
||||
end
|
||||
|
||||
# Return amount of mutations
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_mutations
|
||||
mutations.length
|
||||
end
|
||||
# Print a line to output
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def puts(string = NL)
|
||||
output.puts(string)
|
||||
end
|
||||
|
||||
# Return amount of time in killers
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def killtime
|
||||
mutations.map(&:runtime).inject(0, :+)
|
||||
end
|
||||
memoize :killtime
|
||||
# Test if runner was successful
|
||||
#
|
||||
# @return [true]
|
||||
# if runner is successful
|
||||
#
|
||||
# @return [false]
|
||||
# otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def success?
|
||||
object.success?
|
||||
end
|
||||
|
||||
# Return amount of kills
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_kills
|
||||
mutations.select(&:success?).length
|
||||
end
|
||||
# Test for colored output
|
||||
#
|
||||
# @return [true]
|
||||
# returns true if output is colored
|
||||
#
|
||||
# @return [false]
|
||||
# returns false otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def color?
|
||||
tty?
|
||||
end
|
||||
|
||||
# Return mutant overhead
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def overhead
|
||||
(runtime - killtime) / runtime * 100
|
||||
end
|
||||
# Colorize message
|
||||
#
|
||||
# @param [Color] color
|
||||
# @param [String] message
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
# @return [String]
|
||||
# returns colorized string if color is enabled
|
||||
# returns unmodified message otherwise
|
||||
#
|
||||
def colorize(color, message)
|
||||
color = Color::NONE unless tty?
|
||||
color.format(message)
|
||||
end
|
||||
|
||||
# Return runtime
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def runtime
|
||||
runner.runtime
|
||||
end
|
||||
# Test for output to tty
|
||||
#
|
||||
# @return [true]
|
||||
# returns true if output is a tty
|
||||
#
|
||||
# @return [false]
|
||||
# returns false otherwise
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def tty?
|
||||
output.respond_to?(:tty?) && output.tty?
|
||||
end
|
||||
memoize :tty?
|
||||
|
||||
# Return coverage
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def coverage
|
||||
amount_kills / amount_mutations * 100
|
||||
end
|
||||
end # Config
|
||||
|
||||
# Subject results printer
|
||||
class Subject < self
|
||||
|
||||
# Run printer
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def run
|
||||
puts
|
||||
puts('(%02d/%02d) %3d%% - %0.02fs' % [amount_kills, amount_mutations, coverage, time])
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Return mutation time on subject
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def time
|
||||
mutations.map(&:runtime).inject(0, :+)
|
||||
end
|
||||
|
||||
# Return kills
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_kills
|
||||
fails = runner.failed_mutations
|
||||
fails = fails.length
|
||||
amount_mutations - fails
|
||||
end
|
||||
|
||||
# Return amount of mutations
|
||||
#
|
||||
# @return [Array<Mutation>]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_mutations
|
||||
mutations.length
|
||||
end
|
||||
|
||||
# Return mutations
|
||||
#
|
||||
# @return [Array<Mutation>]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def mutations
|
||||
runner.mutations
|
||||
end
|
||||
|
||||
# Return suject coverage
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def coverage
|
||||
coverage = amount_kills.to_f / amount_mutations * 100
|
||||
end
|
||||
|
||||
end # Subject
|
||||
end # Printer
|
||||
end # CLI
|
||||
end # Reporter
|
||||
|
|
172
lib/mutant/reporter/cli/printer/config.rb
Normal file
172
lib/mutant/reporter/cli/printer/config.rb
Normal file
|
@ -0,0 +1,172 @@
|
|||
module Mutant
|
||||
class Reporter
|
||||
class CLI
|
||||
class Printer
|
||||
|
||||
# Printer for configuration
|
||||
class Config < self
|
||||
|
||||
handle(Mutant::Config)
|
||||
|
||||
# Report configuration
|
||||
#
|
||||
# @param [Mutant::Config] config
|
||||
#
|
||||
# @return [self]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def run
|
||||
info 'Mutant configuration:'
|
||||
info 'Matcher: %s', object.matcher.inspect
|
||||
info 'Filter: %s', object.filter.inspect
|
||||
info 'Strategy: %s', object.strategy.inspect
|
||||
self
|
||||
end
|
||||
|
||||
# Config results printer
|
||||
class Runner < self
|
||||
|
||||
handle(Mutant::Runner::Config)
|
||||
|
||||
# Run printer
|
||||
#
|
||||
# @return [self]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def run
|
||||
print_mutations
|
||||
info 'Subjects: %s', amount_subjects
|
||||
info 'Mutations: %s', amount_mutations
|
||||
info 'Kills: %s', amount_kills
|
||||
info 'Runtime: %0.2fs', runtime
|
||||
info 'Killtime: %0.2fs', killtime
|
||||
info 'Overhead: %0.2f%%', overhead
|
||||
status 'Coverage: %0.2f%%', coverage
|
||||
status 'Alive: %s', amount_alive
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Return subjects
|
||||
#
|
||||
# @return [Array<Subject>]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def subjects
|
||||
object.subjects
|
||||
end
|
||||
|
||||
# Return amount of subjects
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_subjects
|
||||
subjects.length
|
||||
end
|
||||
|
||||
# Print mutations
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def print_mutations
|
||||
object.failed_subjects.each do |subject|
|
||||
Subject::Runner::Details.run(subject, output)
|
||||
end
|
||||
end
|
||||
|
||||
# Return mutations
|
||||
#
|
||||
# @return [Array<Mutation>]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def mutations
|
||||
subjects.map(&:mutations).flatten
|
||||
end
|
||||
memoize :mutations
|
||||
|
||||
# Return amount of mutations
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_mutations
|
||||
mutations.length
|
||||
end
|
||||
|
||||
# Return amount of time in killers
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def killtime
|
||||
mutations.map(&:runtime).inject(0, :+)
|
||||
end
|
||||
memoize :killtime
|
||||
|
||||
# Return amount of kills
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_kills
|
||||
mutations.select(&:success?).length
|
||||
end
|
||||
|
||||
# Return mutant overhead
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def overhead
|
||||
(runtime - killtime) / runtime * 100
|
||||
end
|
||||
|
||||
# Return runtime
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def runtime
|
||||
object.runtime
|
||||
end
|
||||
|
||||
# Return coverage
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def coverage
|
||||
amount_kills / amount_mutations * 100
|
||||
end
|
||||
|
||||
# Return amount of alive mutations
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_alive
|
||||
amount_mutations - amount_kills
|
||||
end
|
||||
|
||||
end # Runner
|
||||
end # Config
|
||||
end # Printer
|
||||
end # Cli
|
||||
end # Reporter
|
||||
end # Mutant
|
42
lib/mutant/reporter/cli/printer/killer.rb
Normal file
42
lib/mutant/reporter/cli/printer/killer.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
module Mutant
|
||||
class Reporter
|
||||
class CLI
|
||||
class Printer
|
||||
|
||||
# Printer for killer results
|
||||
class Killer < self
|
||||
|
||||
handle(Mutant::Killer::Forked)
|
||||
|
||||
# Run printer
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def run
|
||||
if success?
|
||||
char('.', Color::GREEN)
|
||||
return
|
||||
end
|
||||
char('F', Color::RED)
|
||||
end
|
||||
|
||||
# Write colorized char
|
||||
#
|
||||
# @param [String] char
|
||||
# @param [Color]
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def char(char, color)
|
||||
output.write(colorize(color, char))
|
||||
output.flush
|
||||
end
|
||||
end # Killer
|
||||
end # Printer
|
||||
end # CLI
|
||||
end # Reporter
|
||||
end # Mutant
|
55
lib/mutant/reporter/cli/printer/mutation.rb
Normal file
55
lib/mutant/reporter/cli/printer/mutation.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
module Mutant
|
||||
class Reporter
|
||||
class CLI
|
||||
class Printer
|
||||
# Mutation printer
|
||||
class Mutation < self
|
||||
|
||||
# Run mutation printer
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def run
|
||||
status(mutation.identification)
|
||||
puts(colorized_diff)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Return mutation
|
||||
#
|
||||
# @return [Mutation]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def mutation
|
||||
object.mutation
|
||||
end
|
||||
|
||||
# Return colorized diff
|
||||
#
|
||||
# @param [Mutation] mutation
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def colorized_diff
|
||||
original, current = mutation.original_source, mutation.source
|
||||
differ = Differ.new(original, current)
|
||||
diff = color? ? differ.colorized_diff : differ.diff
|
||||
|
||||
if diff.empty?
|
||||
raise 'Unable to create a diff, so ast mutant or unparser does something strange!!'
|
||||
end
|
||||
|
||||
diff
|
||||
end
|
||||
|
||||
end # Mutantion
|
||||
end # Printer
|
||||
end # CLI
|
||||
end # Reporter
|
||||
end # Mutant
|
140
lib/mutant/reporter/cli/printer/subject.rb
Normal file
140
lib/mutant/reporter/cli/printer/subject.rb
Normal file
|
@ -0,0 +1,140 @@
|
|||
module Mutant
|
||||
class Reporter
|
||||
class CLI
|
||||
class Printer
|
||||
|
||||
# Subject results printer
|
||||
class Subject < self
|
||||
|
||||
handle(Mutant::Subject::Method::Instance)
|
||||
handle(Mutant::Subject::Method::Singleton)
|
||||
|
||||
# Run subject results printer
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def run
|
||||
info(object.identification)
|
||||
end
|
||||
|
||||
class Runner < self
|
||||
|
||||
handle(Mutant::Runner::Subject)
|
||||
|
||||
# Run printer
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def run
|
||||
print_progress_bar_finish
|
||||
print_stats
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Return mutation time on subject
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def time
|
||||
mutations.map(&:runtime).inject(0, :+)
|
||||
end
|
||||
|
||||
# Return subject
|
||||
#
|
||||
# @return [Subject]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def subject
|
||||
object.subject
|
||||
end
|
||||
|
||||
# Print stats
|
||||
#
|
||||
# @return [undefned
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def print_stats
|
||||
status('(%02d/%02d) %3d%% - %0.02fs', amount_kills, amount_mutations, coverage, time)
|
||||
end
|
||||
|
||||
# Print progress bar finish
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def print_progress_bar_finish
|
||||
puts unless amount_mutations.zero?
|
||||
end
|
||||
|
||||
# Return kills
|
||||
#
|
||||
# @return [Fixnum]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_kills
|
||||
fails = object.failed_mutations
|
||||
fails = fails.length
|
||||
amount_mutations - fails
|
||||
end
|
||||
|
||||
# Return amount of mutations
|
||||
#
|
||||
# @return [Array<Mutation>]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def amount_mutations
|
||||
mutations.length
|
||||
end
|
||||
|
||||
# Return mutations
|
||||
#
|
||||
# @return [Array<Mutation>]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def mutations
|
||||
object.mutations
|
||||
end
|
||||
|
||||
# Return suject coverage
|
||||
#
|
||||
# @return [Float]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def coverage
|
||||
coverage = amount_kills.to_f / amount_mutations * 100
|
||||
end
|
||||
|
||||
# Detailed subject printer
|
||||
class Details < self
|
||||
|
||||
def run
|
||||
puts(subject.identification)
|
||||
object.failed_mutations.each do |mutation|
|
||||
Mutation.run(mutation, output)
|
||||
end
|
||||
print_stats
|
||||
end
|
||||
|
||||
end # Details
|
||||
end # Runner
|
||||
end # Subject
|
||||
end # Printer
|
||||
end # CLI
|
||||
end # Reporter
|
||||
end # Mutant
|
||||
|
|
@ -66,12 +66,12 @@ module Mutant
|
|||
|
||||
# Return source representation of ast
|
||||
#
|
||||
# @return [Source]
|
||||
# @return [String]
|
||||
#
|
||||
# @api private
|
||||
#
|
||||
def source
|
||||
ToSource.to_source(node)
|
||||
Unparser.unparse(node)
|
||||
end
|
||||
memoize :source
|
||||
|
||||
|
|
Loading…
Reference in a new issue