/
arithmetic-operator-mutator.ts
45 lines (34 loc) · 1.25 KB
/
arithmetic-operator-mutator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import { NodePath, types } from '@babel/core';
import { NodeMutation } from '../mutant';
import { NodeMutator } from './node-mutator';
enum ArithmeticOperators {
'+' = '-',
'-' = '+',
'*' = '/',
'/' = '*',
'%' = '*',
}
export class ArithmeticOperatorMutator implements NodeMutator {
private readonly operators = ArithmeticOperators;
public name = 'ArithmeticOperator';
public mutate(path: NodePath): NodeMutation[] {
if (path.isBinaryExpression() && this.isSupported(path.node.operator, path.node)) {
const mutatedOperator = this.operators[path.node.operator];
const replacement = types.cloneNode(path.node, false);
replacement.operator = mutatedOperator;
return [{ original: path.node, replacement }];
}
return [];
}
private isSupported(operator: string, node: types.BinaryExpression): operator is keyof typeof ArithmeticOperators {
if (!Object.keys(this.operators).includes(operator)) {
return false;
}
const stringTypes = ['StringLiteral', 'TemplateLiteral'];
const leftType = node.left.type === 'BinaryExpression' ? node.left.right.type : node.left.type;
if (stringTypes.includes(node.right.type) || stringTypes.includes(leftType)) {
return false;
}
return true;
}
}