Skip to content

Commit

Permalink
fix(typescript): don't mutate declare statements (#1458)
Browse files Browse the repository at this point in the history
Stop mutating `declare` expressions. Like `declare function notMutated(a: number, b: number);`
  • Loading branch information
Josh Goldberg authored and nicojs committed Mar 26, 2019
1 parent c010af3 commit aae3afe
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 7 deletions.
22 changes: 15 additions & 7 deletions packages/typescript/src/TypescriptMutator.ts
Expand Up @@ -30,12 +30,20 @@ export class TypescriptMutator {
}

private mutateForNode<T extends ts.Node>(node: T, sourceFile: ts.SourceFile): Mutant[] {
const targetMutators = this.mutators.filter(mutator => mutator.guard(node));
const mutants = flatMap(targetMutators, mutator => mutator.mutate(node, sourceFile));
node.forEachChild(child => {
// It is important that forEachChild does not return a true, otherwise node visiting is halted!
mutants.push(... this.mutateForNode(child, sourceFile));
});
return mutants;
if (shouldNodeBeSkipped(node)) {
return [];
} else {
const targetMutators = this.mutators.filter(mutator => mutator.guard(node));
const mutants = flatMap(targetMutators, mutator => mutator.mutate(node, sourceFile));
node.forEachChild(child => {
// It is important that forEachChild does not return a true, otherwise node visiting is halted!
mutants.push(... this.mutateForNode(child, sourceFile));
});
return mutants;
}
}
}

const shouldNodeBeSkipped = (node: ts.Node): boolean => {
return node.modifiers !== undefined && node.modifiers.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword);
};
62 changes: 62 additions & 0 deletions packages/typescript/test/unit/TypescriptMutator.spec.ts
Expand Up @@ -90,5 +90,67 @@ describe('TypescriptMutator', () => {
expect(mutants.filter(mutant => mutant.mutatorName === 'FunctionDeclarationForTest')).lengthOf(4);
});

describe('declaration nodes', () => {
beforeEach(() => {
sut = createSut();
});

it('should not skip a node when it does not have a declare modifier', () => {
// Arrange
file1 = new File(
'file1.ts',
`function mutated(a: number, b: number);`);

// Act
const mutants = sut.mutate([
file1,
]);

// Assert
expect(mutants).to.deep.equal([
{
fileName: 'file1.ts',
mutatorName: 'SourceFileForTest',
range: [0, 39],
replacement: '"stryker was here"'
},
{
fileName: 'file1.ts',
mutatorName: 'FunctionDeclarationForTest',
range: [0, 39],
replacement: '// Function declaration removed'
},
{
fileName: 'file1.ts',
mutatorName: 'FunctionDeclarationForTest',
range: [0, 39],
replacement: 'changedToOtherCall()'
}
]);
});

it('should skip a node when it has a declare modifier', () => {
// Arrange
file1 = new File(
'file1.ts',
`declare function notMutated(a: number, b: number);`);

// Act
const mutants = sut.mutate([
file1,
]);

// Assert
expect(mutants).to.deep.equal([
{
fileName: 'file1.ts',
mutatorName: 'SourceFileForTest',
range: [0, 50],
replacement: '"stryker was here"',
}
]);
});
});

});
});

0 comments on commit aae3afe

Please sign in to comment.