Skip to content

Commit

Permalink
Fix coverage of Mutant::Mutator namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
mbj committed Mar 22, 2016
1 parent f0ae1d1 commit 41c41b2
Show file tree
Hide file tree
Showing 51 changed files with 331 additions and 265 deletions.
3 changes: 1 addition & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ namespace :metrics do
task mutant: :coverage do
arguments = %w[
bundle exec mutant
--ignore-subject Mutant::Meta*
--include lib
--since HEAD~1
--require mutant
--use rspec
--zombie
]
arguments.concat(%w[--jobs 4]) if ENV.key?('CIRCLE_CI')
arguments.concat(%w[--jobs 4]) if ENV.key?('CIRCLECI')

arguments.concat(%w[-- Mutant*])

Expand Down
4 changes: 2 additions & 2 deletions config/flay.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
threshold: 18
total_score: 1162
threshold: 16
total_score: 1160
2 changes: 0 additions & 2 deletions lib/mutant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ def self.ci?
require 'mutant/mutator/node/literal/nil'
require 'mutant/mutator/node/argument'
require 'mutant/mutator/node/arguments'
require 'mutant/mutator/node/blockarg'
require 'mutant/mutator/node/begin'
require 'mutant/mutator/node/binary'
require 'mutant/mutator/node/const'
Expand All @@ -112,7 +111,6 @@ def self.ci?
require 'mutant/mutator/node/yield'
require 'mutant/mutator/node/super'
require 'mutant/mutator/node/zsuper'
require 'mutant/mutator/node/restarg'
require 'mutant/mutator/node/send'
require 'mutant/mutator/node/send/binary'
require 'mutant/mutator/node/send/conditional'
Expand Down
1 change: 1 addition & 0 deletions lib/mutant/ast/meta/send.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Send
#
# @return [Enumerable<Parser::AST::Node>]
alias_method :arguments, :remaining_children

public :arguments

# Test if AST node is a valid assignment target
Expand Down
2 changes: 1 addition & 1 deletion lib/mutant/meta/example.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def source
#
# @return [Enumerable<Mutant::Mutation>]
def generated
Mutator.each(node).map do |node|
Mutator::REGISTRY.call(node).map do |node|
Mutation::Evil.new(self, node)
end
end
Expand Down
66 changes: 13 additions & 53 deletions lib/mutant/mutator.rb
Original file line number Diff line number Diff line change
@@ -1,42 +1,22 @@
module Mutant
# Generator for mutations
class Mutator
include Adamantium::Flat, AbstractType

# Run mutator on input
#
# @param [Object] input
# the input to mutate
#
# @param [Mutator] parent
#
# @return [self]
def self.each(input, parent = nil, &block)
return to_enum(__method__, input, parent) unless block_given?
REGISTRY.lookup(input).new(input, parent, block)

self
end
include Adamantium::Flat, Concord.new(:input, :parent), AbstractType, Procto.call(:output)

# Register node class handler
#
# @return [undefined]
def self.handle(*types)
types.each do |type|
REGISTRY.register(type, self)
self::REGISTRY.register(type, self)
end
end
private_class_method :handle

# Mutation input
#
# @return [Object]
attr_reader :input

# Parent context of input
# Return output
#
# @return [Object]
attr_reader :parent
# @return [Set<Parser::AST::Node>]
attr_reader :output

private

Expand All @@ -47,10 +27,11 @@ def self.handle(*types)
# @param [#call(node)] block
#
# @return [undefined]
def initialize(input, parent, block)
@input, @parent, @block = input, parent, block
@seen = Set.new
guard(input)
def initialize(_input, _parent = nil)
super

@output = Set.new

dispatch
end

Expand All @@ -60,16 +41,7 @@ def initialize(input, parent, block)
#
# @return [Boolean]
def new?(object)
!@seen.include?(object)
end

# Add object to guarded values
#
# @param [Object] object
#
# @return [undefined]
def guard(object)
@seen << object
!object.eql?(input)
end

# Dispatch node generations
Expand All @@ -85,26 +57,14 @@ def guard(object)
def emit(object)
return unless new?(object)

guard(object)

emit!(object)
end

# Call block with node
#
# @param [Parser::AST::Node] node
#
# @return [self]
def emit!(node)
@block.call(node)
self
output << object
end

# Run input with mutator
#
# @return [undefined]
def run(mutator)
mutator.new(input, self, method(:emit))
mutator.call(input).each(&method(:emit))
end

# Shortcut to create a new unfrozen duplicate of input
Expand Down
34 changes: 15 additions & 19 deletions lib/mutant/mutator/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ class Node < self
def self.define_named_child(name, index)
super

define_method("emit_#{name}_mutations") do |&block|
define_method(:"emit_#{name}_mutations") do |&block|
mutate_child(index, &block)
end

define_method("emit_#{name}") do |node|
define_method(:"emit_#{name}") do |node|
emit_child_update(index, node)
end
end
Expand Down Expand Up @@ -56,10 +56,9 @@ def children
# @return [undefined]
#
# rubocop:disable RedundantBlockCall - its not redundant here
def mutate_child(index, mutator = Mutator, &block)
def mutate_child(index, &block)
block ||= TAUTOLOGY
child = children.at(index)
mutator.each(child, self) do |mutation|
REGISTRY.call(children.fetch(index), self).each do |mutation|
next unless block.call(mutation)
emit_child_update(index, mutation)
end
Expand Down Expand Up @@ -119,17 +118,6 @@ def emit_nil
emit(N_NIL) unless asgn_left?
end

# Emit values
#
# @param [Array<Object>] values
#
# @return [undefined]
def emit_values(values)
values.each do |value|
emit_type(value)
end
end

# Parent node
#
# @return [Parser::AST::Node] node
Expand Down Expand Up @@ -165,9 +153,17 @@ def asgn_left?
#
# @return [Enumerable<Fixnum>]
def children_indices(range)
range_end = range.end
last_index = range_end >= 0 ? range_end : children.length + range_end
range.begin.upto(last_index)
range.begin.upto(children.length + range.end)
end

# Emit single child mutation
#
# @return [undefined]
def mutate_single_child
children.each_with_index do |child, index|
mutate_child(index)
yield child, index unless children.one?
end
end

end # Node
Expand Down
12 changes: 4 additions & 8 deletions lib/mutant/mutator/node/arguments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def dispatch
# @return [undefined]
def emit_argument_presence
emit_type
Mutator::Util::Array::Presence.each(children, self) do |children|
Util::Array::Presence.call(children).each do |children|
emit_type(*children)
end
end
Expand All @@ -32,7 +32,7 @@ def emit_argument_presence
# @return [undefined]
def emit_argument_mutations
children.each_with_index do |child, index|
Mutator.each(child) do |mutant|
REGISTRY.call(child).each do |mutant|
next if invalid_argument_replacement?(mutant, index)
emit_child_update(index, mutant)
end
Expand All @@ -45,11 +45,7 @@ def emit_argument_mutations
#
# @return [Boolean]
def invalid_argument_replacement?(mutant, index)
original = children.fetch(index)

n_optarg?(original) &&
n_arg?(mutant) &&
children[0...index].any?(&method(:n_optarg?))
n_arg?(mutant) && children[0...index].any?(&method(:n_optarg?))
end

# Emit mlhs expansions
Expand All @@ -59,7 +55,7 @@ def emit_mlhs_expansion
mlhs_childs_with_index.each do |child, index|
dup_children = children.dup
dup_children.delete_at(index)
dup_children.insert(index, *child.children)
dup_children.insert(index, *child)
emit_type(*dup_children)
end
end
Expand Down
17 changes: 2 additions & 15 deletions lib/mutant/mutator/node/begin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,10 @@ class Begin < self
#
# @return [undefined]
def dispatch
Util::Array.each(children, self, &method(:emit_child_subset))
children.each_with_index do |child, index|
mutate_child(index)
emit(child) unless children.eql?([child])
mutate_single_child do |child|
emit(child)
end
end

# Emit child subset
#
# @param [Array<Parser::AST::Node>] children
#
# @return [undefined]
def emit_child_subset(children)
return if children.length < 2
emit_type(*children)
end

end # Block
end # Node
end # Mutator
Expand Down
13 changes: 0 additions & 13 deletions lib/mutant/mutator/node/blockarg.rb

This file was deleted.

2 changes: 1 addition & 1 deletion lib/mutant/mutator/node/break.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Break < Generic
#
# @return [undefined]
def dispatch
super
super()
emit_singletons
children.each_index(&method(:delete_child))
end
Expand Down
2 changes: 1 addition & 1 deletion lib/mutant/mutator/node/dstr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Dstr < Generic
#
# @return [undefined]
def dispatch
super
super()
emit_singletons
end

Expand Down
2 changes: 1 addition & 1 deletion lib/mutant/mutator/node/dsym.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Dsym < Generic
#
# @return [undefined]
def dispatch
super
super()
emit_singletons
end

Expand Down
4 changes: 2 additions & 2 deletions lib/mutant/mutator/node/generic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ class Generic < self
# These nodes still need a dedicated mutator,
# your contribution is that close!
handle(
:ensure, :redo, :regopt, :retry, :arg_expr,
:ensure, :redo, :regopt, :retry, :arg_expr, :blockarg,
:kwrestarg, :kwoptarg, :kwarg, :undef, :module, :empty,
:alias, :for, :xstr, :back_ref, :class,
:alias, :for, :xstr, :back_ref, :class, :restarg,
:sclass, :match_with_lvasgn, :while_post,
:until_post, :preexe, :postexe, :iflipflop, :eflipflop, :kwsplat,
:shadowarg, :rational, :complex, :__FILE__, :__LINE__
Expand Down
2 changes: 1 addition & 1 deletion lib/mutant/mutator/node/kwbegin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Kwbegin < Generic
#
# @return [undefined]
def dispatch
super
super()
emit_singletons
end

Expand Down
9 changes: 9 additions & 0 deletions lib/mutant/mutator/node/literal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ class Node
# Abstract mutator for literal AST nodes
class Literal < self
include AbstractType

private

# Emit values
#
# @return [undefined]
def emit_values
values.each(&method(:emit_type))
end
end # Literal
end # Node
end # Mutator
Expand Down
2 changes: 1 addition & 1 deletion lib/mutant/mutator/node/literal/fixnum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Fixnum < self
# @return [undefined]
def dispatch
emit_singletons
emit_values(values)
emit_values
end

# Values to mutate to
Expand Down
Loading

0 comments on commit 41c41b2

Please sign in to comment.