2014-06-02 08:57:14 -04:00
|
|
|
# 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
|
|
|
|
|
2014-06-09 10:56:13 -04:00
|
|
|
# Return source
|
|
|
|
#
|
|
|
|
# @return [String]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def source
|
|
|
|
Unparser.unparse(node)
|
|
|
|
end
|
|
|
|
memoize :source
|
|
|
|
|
2014-06-02 08:57:14 -04:00
|
|
|
# Return generated mutations
|
|
|
|
#
|
2014-06-09 10:56:13 -04:00
|
|
|
# @return [Emumerable<Mutant::Mutation>]
|
2014-06-02 08:57:14 -04:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def generated
|
2014-06-09 10:56:13 -04:00
|
|
|
Mutant::Mutator.each(node).map do |node|
|
|
|
|
Mutant::Mutation::Evil.new(self, node)
|
|
|
|
end
|
2014-06-02 08:57:14 -04:00
|
|
|
end
|
|
|
|
memoize :generated
|
|
|
|
|
|
|
|
# Example verification
|
|
|
|
class Verification
|
2014-06-09 10:56:13 -04:00
|
|
|
include Adamantium::Flat, Concord.new(:example, :mutations)
|
2014-06-02 08:57:14 -04:00
|
|
|
|
|
|
|
# Test if mutation was verified successfully
|
|
|
|
#
|
|
|
|
# @return [Boolean]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def success?
|
2014-06-09 10:56:13 -04:00
|
|
|
unparser.success? && missing.empty? && unexpected.empty? && no_diffs.empty?
|
2014-06-02 08:57:14 -04:00
|
|
|
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
|
2014-06-09 10:56:13 -04:00
|
|
|
mutations.map(&:node) - example.mutations
|
2014-06-02 08:57:14 -04:00
|
|
|
end
|
|
|
|
memoize :unexpected
|
|
|
|
|
2014-06-09 10:56:13 -04:00
|
|
|
# Return mutations with no diff to original
|
|
|
|
#
|
|
|
|
# @return [Enumerable<Mutation>]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def no_diffs
|
|
|
|
mutations.select { |mutation| mutation.source.eql?(example.source) }
|
|
|
|
end
|
|
|
|
memoize :no_diffs
|
|
|
|
|
2014-06-02 08:57:14 -04:00
|
|
|
# Return mutation report
|
|
|
|
#
|
|
|
|
# @return [String]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def mutation_report
|
|
|
|
original_node = example.node
|
|
|
|
[
|
|
|
|
'Original-AST:',
|
|
|
|
original_node.inspect,
|
|
|
|
'Original-Source:',
|
2014-06-09 10:56:13 -04:00
|
|
|
example.source,
|
2014-06-02 08:57:14 -04:00
|
|
|
*missing_report,
|
2014-06-09 10:56:13 -04:00
|
|
|
*unexpected_report,
|
2014-06-09 22:07:50 -04:00
|
|
|
*no_diff_report
|
2014-06-02 08:57:14 -04:00
|
|
|
].join("\n======\n")
|
|
|
|
end
|
|
|
|
|
|
|
|
# Return missing report
|
|
|
|
#
|
|
|
|
# @return [Array, nil]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def missing_report
|
2014-06-08 09:01:26 -04:00
|
|
|
[
|
|
|
|
'Missing mutations:',
|
|
|
|
missing.map(&method(:format_mutation)).join("\n-----\n")
|
|
|
|
] if missing.any?
|
2014-06-02 08:57:14 -04:00
|
|
|
end
|
|
|
|
|
2014-06-09 10:56:13 -04:00
|
|
|
# Return no diff report
|
|
|
|
#
|
|
|
|
# @return [Array, nil]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def no_diff_report
|
|
|
|
[
|
|
|
|
'No source diffs to original:',
|
|
|
|
no_diffs.map do |mutation|
|
|
|
|
"#{mutation.node.inspect}\n#{mutation.source}"
|
|
|
|
end
|
|
|
|
] if no_diffs.any?
|
|
|
|
end
|
|
|
|
|
2014-06-02 08:57:14 -04:00
|
|
|
# Return unexpected report
|
|
|
|
#
|
|
|
|
# @return [Array, nil]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def unexpected_report
|
2014-06-08 09:01:26 -04:00
|
|
|
[
|
|
|
|
'Unexpected mutations:',
|
|
|
|
unexpected.map(&method(:format_mutation)).join("\n-----\n")
|
|
|
|
] if unexpected.any?
|
2014-06-02 08:57:14 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
# Format mutation
|
|
|
|
#
|
|
|
|
# @return [String]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def format_mutation(node)
|
|
|
|
[
|
|
|
|
node.inspect,
|
|
|
|
Unparser.unparse(node)
|
|
|
|
].join("\n")
|
|
|
|
end
|
|
|
|
|
2014-06-09 10:56:13 -04:00
|
|
|
# Return missing mutations
|
2014-06-02 08:57:14 -04:00
|
|
|
#
|
|
|
|
# @return [Array<Parser::AST::Node>]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def missing
|
2014-06-09 10:56:13 -04:00
|
|
|
example.mutations - mutations.map(&:node)
|
2014-06-02 08:57:14 -04:00
|
|
|
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
|