Class: Henitai::Operator
- Inherits:
-
Object
- Object
- Henitai::Operator
- Defined in:
- lib/henitai/operator.rb,
sig/henitai.rbs
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,
EqualityIdentityOperator
Each operator subclass must implement:
- .node_types → Array<Symbol> AST node types this operator handles
- #mutate(node, subject:) → Array<Mutant>
Direct Known Subclasses
Henitai::Operators::ArithmeticOperator, Henitai::Operators::ArrayDeclaration, Henitai::Operators::AssignmentExpression, Henitai::Operators::BlockStatement, Henitai::Operators::BooleanLiteral, Henitai::Operators::ConditionalExpression, Henitai::Operators::EqualityIdentityOperator, Henitai::Operators::EqualityOperator, Henitai::Operators::HashLiteral, Henitai::Operators::LogicalOperator, Henitai::Operators::MethodChainUnwrap, Henitai::Operators::MethodExpression, Henitai::Operators::PatternMatch, Henitai::Operators::RangeLiteral, Henitai::Operators::RegexMutator, Henitai::Operators::ReturnValue, Henitai::Operators::SafeNavigation, Henitai::Operators::StringLiteral, Henitai::Operators::UnaryOperator, Henitai::Operators::UpdateOperator
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 EqualityIdentityOperator ]).freeze
Class Method Summary collapse
-
.for_set(set) ⇒ Array<Operator>
Operator instances for the given set.
-
.node_types ⇒ Array[Symbol]
Subclasses must declare which AST node types they handle.
Instance Method Summary collapse
- #build_mutant(subject:, original_node:, mutated_node:, description:) ⇒ Mutant
- #mutate(node, subject:) ⇒ Array<Mutant>
-
#name ⇒ String
Operator name as used in the Stryker JSON schema.
- #node_location(node) ⇒ Hash[Symbol, untyped]
Class Method Details
.for_set(set) ⇒ Array<Operator>
Returns operator instances for the given set.
52 53 54 55 |
# File 'lib/henitai/operator.rb', line 52 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_types ⇒ Array[Symbol]
Subclasses must declare which AST node types they handle.
58 59 60 |
# File 'lib/henitai/operator.rb', line 58 def self.node_types raise NotImplementedError, "#{name}.node_types must be defined" end |
Instance Method Details
#build_mutant(subject:, original_node:, mutated_node:, description:) ⇒ Mutant
76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/henitai/operator.rb', line 76 def build_mutant(subject:, original_node:, mutated_node:, description:) loc = node_location(original_node) Mutant.new( subject:, operator: name, nodes: { original: original_node, mutated: mutated_node }, description:, location: loc ) end |
#mutate(node, subject:) ⇒ Array<Mutant>
65 66 67 |
# File 'lib/henitai/operator.rb', line 65 def mutate(node, subject:) raise NotImplementedError, "#{self.class}#mutate must be implemented" end |
#name ⇒ String
Operator name as used in the Stryker JSON schema.
70 71 72 |
# File 'lib/henitai/operator.rb', line 70 def name self.class.name.split("::").last end |
#node_location(node) ⇒ Hash[Symbol, untyped]
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/henitai/operator.rb', line 90 def node_location(node) exp = node.location.expression return {} unless exp { file: exp.source_buffer.name, start_line: exp.line, end_line: exp.last_line, start_col: exp.column, end_col: exp.last_column } end |