Class: Mutineer::Mutators::OperandRemoval

Inherits:
Base
  • Object
show all
Defined in:
lib/mutineer/mutators/operand_removal.rb

Overview

Operand-removal mutator (Tier-2).

Replaces a boolean expression with one of its operands, two mutations per &&, ||, and or or: a && b becomes (a) and (b). The parentheses keep the precedence of and and or. A surviving mutant shows that no test needs the operand that was removed.

Constant Summary collapse

JUMPS =

Node types for jumps. A jump in a value context does not parse, so the operator never keeps a jump alone.

[Prism::ReturnNode, Prism::BreakNode, Prism::NextNode, Prism::RedoNode, Prism::RetryNode].freeze

Instance Method Summary collapse

Methods inherited from Base

#heredoc?, #mutations_for

Instance Method Details

#emit(node) ⇒ void (private)

This method returns an undefined value.

Emits one mutation that keeps the left operand, then one that keeps the right operand. The order is fixed, because the two mutants share a token and their occurrence ordinals tell them apart.

Parameters:

  • node (Prism::AndNode, Prism::OrNode) —

    connector node.



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/mutineer/mutators/operand_removal.rb', line 51

def emit(node)
  [[node.left, node.right], [node.right, node.left]].each do |kept, removed|
    next if JUMPS.any? { |type| kept.is_a?(type) } || heredoc?(removed)

    @mutations << Mutation.new(
      start_offset: node.location.start_offset,
      end_offset: node.location.end_offset,
      replacement: "(#{kept.slice})",
      operator: :operand_removal
    )
  end
end

#visit_and_node(node) ⇒ void

This method returns an undefined value.

Visits and nodes.

Parameters:

  • node (Prism::AndNode) —

    node to inspect.



22
23
24
25
# File 'lib/mutineer/mutators/operand_removal.rb', line 22

def visit_and_node(node)
  emit(node)
  super # nested connectors (a && b && c) each get their own mutations
end

#visit_def_node(node) ⇒ void

This method returns an undefined value.

Skips a nested method definition. The project finds it as a subject of its own, so a visit here counts its connectors twice.

Parameters:

  • node (Prism::DefNode) —

    nested definition node.



41
# File 'lib/mutineer/mutators/operand_removal.rb', line 41

def visit_def_node(node); end

#visit_or_node(node) ⇒ void

This method returns an undefined value.

Visits or nodes.

Parameters:

  • node (Prism::OrNode) —

    node to inspect.



31
32
33
34
# File 'lib/mutineer/mutators/operand_removal.rb', line 31

def visit_or_node(node)
  emit(node)
  super
end