/
string-literal-mutator.ts
47 lines (41 loc) · 1.53 KB
/
string-literal-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
46
47
import { types, NodePath } from '@babel/core';
import { NodeMutation } from '../mutant';
import { NodeMutator } from './node-mutator';
export class StringLiteralMutator implements NodeMutator {
public name = 'StringLiteral';
public mutate(path: NodePath): NodeMutation[] {
if (path.isTemplateLiteral()) {
const replacement = path.node.quasis.length === 1 && path.node.quasis[0].value.raw.length === 0 ? 'Stryker was here!' : '';
return [
{
original: path.node,
replacement: types.templateLiteral([types.templateElement({ raw: replacement })], []),
},
];
}
if (path.isStringLiteral() && this.isValidParent(path)) {
return [
{
original: path.node,
replacement: types.stringLiteral(path.node.value.length === 0 ? 'Stryker was here!' : ''),
},
];
}
return [];
}
private isValidParent(child: NodePath<types.StringLiteral>): boolean {
const parent = child.parent;
return !(
types.isImportDeclaration(parent) ||
types.isExportDeclaration(parent) ||
types.isModuleDeclaration(parent) ||
types.isTSExternalModuleReference(parent) ||
types.isJSXAttribute(parent) ||
types.isExpressionStatement(parent) ||
types.isTSLiteralType(parent) ||
(types.isObjectProperty(parent) && parent.key === child.node) ||
(types.isClassProperty(parent) && parent.key === child.node) ||
(types.isCallExpression(parent) && types.isIdentifier(parent.callee, { name: 'require' }))
);
}
}