-
-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
318 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,8 @@ def zombie? | |
false | ||
end | ||
|
||
abstract_method :action | ||
|
||
private | ||
|
||
def subcommands | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# frozen_string_literal: true | ||
|
||
module Mutant | ||
module CLI | ||
class Command | ||
class Util < self | ||
NAME = 'util' | ||
SHORT_DESCRIPTION = 'Utility subcommands' | ||
|
||
class Mutation < self | ||
NAME = 'mutation' | ||
SHORT_DESCRIPTION = 'Print mutations of a code snippet' | ||
SUBCOMMANDS = [].freeze | ||
OPTIONS = %i[add_target_options].freeze | ||
|
||
def action | ||
@targets.each(&method(:print_mutations)) | ||
Either::Right.new(nil) | ||
end | ||
|
||
private | ||
|
||
class Target | ||
include Adamantium | ||
|
||
def node | ||
Unparser.parse(source) | ||
end | ||
memoize :node | ||
|
||
class File < self | ||
include Concord.new(:pathname, :source) | ||
|
||
public :source | ||
|
||
def identification | ||
"file:#{pathname}" | ||
end | ||
end # File | ||
|
||
class Source < self | ||
include Concord::Public.new(:source) | ||
|
||
def identification | ||
'<cli-source>' | ||
end | ||
end # source | ||
end # Target | ||
|
||
def initialize(_arguments) | ||
super | ||
|
||
@targets = [] | ||
end | ||
|
||
def add_target_options(parser) | ||
parser.on('-e', '--evaluate SOURCE') do |source| | ||
@targets << Target::Source.new(source) | ||
end | ||
end | ||
|
||
def print_mutations(target) | ||
world.stdout.puts(target.identification) | ||
Mutator.mutate(target.node).each do |mutation| | ||
Reporter::CLI::Printer::Mutation.call( | ||
world.stdout, | ||
Mutant::Mutation::Evil.new(target, mutation) | ||
) | ||
end | ||
end | ||
|
||
def parse_remaining_arguments(arguments) | ||
@targets.concat( | ||
arguments.map do |argument| | ||
parse_pathname(argument) | ||
.bind(&method(:read_file)) | ||
.from_right { |error| return Either::Left.new(error) } | ||
end | ||
) | ||
|
||
Either::Right.new(self) | ||
end | ||
|
||
def read_file(pathname) | ||
source = | ||
begin | ||
pathname.read | ||
rescue Exception => exception | ||
return Either::Left.new("Cannot read file: #{exception}") | ||
end | ||
|
||
Either::Right.new(Target::File.new(pathname, source)) | ||
end | ||
|
||
def parse_pathname(input) | ||
Either.wrap_error(ArgumentError) { Pathname.new(input) } | ||
.lmap(&:message) | ||
end | ||
end # Mutation | ||
|
||
SUBCOMMANDS = [Mutation] | ||
end # Util | ||
end # Command | ||
end # CLI | ||
end # Mutant |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# frozen_string_literal: true | ||
|
||
module Mutant | ||
class Reporter | ||
class CLI | ||
class Printer | ||
# Reporter for mutations | ||
class Mutation < self | ||
NO_DIFF_MESSAGE = <<~'MESSAGE' | ||
--- Internal failure --- | ||
BUG: A generted mutation did not result in exactly one diff hunk! | ||
This is an invariant violation by the mutation generation engine. | ||
Please report a reproduction to https://github.com/mbj/mutant | ||
Original unparsed source: | ||
%s | ||
Original AST: | ||
%s | ||
Mutated unparsed source: | ||
%s | ||
Mutated AST: | ||
%s | ||
MESSAGE | ||
|
||
SEPARATOR = '-----------------------' | ||
|
||
# Run report printer | ||
# | ||
# @return [undefined] | ||
def run | ||
diff = object.diff | ||
diff = color? ? diff.colorized_diff : diff.diff | ||
|
||
if diff | ||
output.write(diff) | ||
else | ||
print_no_diff_message | ||
end | ||
end | ||
|
||
def print_no_diff_message | ||
info( | ||
NO_DIFF_MESSAGE, | ||
object.original_source, | ||
original_node.inspect, | ||
object.source, | ||
object.node.inspect | ||
) | ||
end | ||
|
||
def original_node | ||
object.subject.node | ||
end | ||
|
||
end # MutationResult | ||
end # Printer | ||
end # CLI | ||
end # Reporter | ||
end # Mutant |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.