Class: Henitai::Operator

Inherits:
Object
  • Object
show all
Defined in:
lib/henitai/operator.rb

Overview

Base class for all mutation operators.

An Operator receives an AST node and produces zero or more Mutant objects. Operator names follow the Stryker-compatible naming convention so that the JSON report is compatible with stryker-dashboard filters and HTML reports.

Built-in operators (light set):

ArithmeticOperator, EqualityOperator, LogicalOperator, BooleanLiteral,
ConditionalExpression, StringLiteral, ReturnValue

Additional operators (full set):

ArrayDeclaration, HashLiteral, RangeLiteral, SafeNavigation,
PatternMatch, BlockStatement, MethodExpression, AssignmentExpression,
UnaryOperator, UpdateOperator, RegexMutator, MethodChainUnwrap

Each operator subclass must implement:

- .node_types  → Array<Symbol>  AST node types this operator handles
- #mutate(node, subject:) → Array<Mutant>

Constant Summary collapse

LIGHT_SET =
%w[
  ArithmeticOperator
  EqualityOperator
  LogicalOperator
  BooleanLiteral
  ConditionalExpression
  StringLiteral
  ReturnValue
].freeze
FULL_SET =
(LIGHT_SET + %w[
  ArrayDeclaration
  HashLiteral
  MethodChainUnwrap
  RangeLiteral
  RegexMutator
  SafeNavigation
  PatternMatch
  BlockStatement
  MethodExpression
  AssignmentExpression
  UnaryOperator
  UpdateOperator
]).freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.for_set(set) ⇒ Array<Operator>

Returns operator instances for the given set.

Parameters:

  • set (Symbol)

    :light or :full

Returns:

  • (Array<Operator>)

    operator instances for the given set



50
51
52
53
# File 'lib/henitai/operator.rb', line 50

def self.for_set(set)
  names = set.to_sym == :full ? FULL_SET : LIGHT_SET
  names.map { |name| Henitai::Operators.const_get(name).new }
end

.node_typesObject

Subclasses must declare which AST node types they handle.

Raises:

  • (NotImplementedError)


56
57
58
# File 'lib/henitai/operator.rb', line 56

def self.node_types
  raise NotImplementedError, "#{name}.node_types must be defined"
end

Instance Method Details

#mutate(node, subject:) ⇒ Array<Mutant>

Parameters:

  • node (Parser::AST::Node)
  • subject (Subject)

Returns:

Raises:

  • (NotImplementedError)


63
64
65
# File 'lib/henitai/operator.rb', line 63

def mutate(node, subject:)
  raise NotImplementedError, "#{self.class}#mutate must be implemented"
end

#nameObject

Operator name as used in the Stryker JSON schema.



68
69
70
# File 'lib/henitai/operator.rb', line 68

def name
  self.class.name.split("::").last
end