Skip to content

Commit

Permalink
fix(babel-transformer): respect top of the file comments/pragma
Browse files Browse the repository at this point in the history
This means that the stryker mutator hooks are no longer just
prepended to the beginning of file. Instead we also add the comments
which means things like flow should behave correctly
  • Loading branch information
swist committed Mar 7, 2021
1 parent 424aca4 commit 804c83e
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 2 deletions.
53 changes: 53 additions & 0 deletions e2e/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@babel/plugin-proposal-class-properties": "~7.8.3",
"@babel/plugin-proposal-pipeline-operator": "~7.8.3",
"@babel/preset-env": "~7.8.3",
"@babel/preset-flow": "7.12.13",
"@types/node": "^10.12.18",
"@types/semver": "~6.2.0",
"ajv": "~7.0.2",
Expand Down
16 changes: 16 additions & 0 deletions e2e/test/flow-test-project/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"presets": [
"@babel/preset-flow",
[
"@babel/preset-env",
{
"targets": {
"edge": "16",
"firefox": "57",
"chrome": "62",
"safari": "11"
}
}
]
]
}
5 changes: 5 additions & 0 deletions e2e/test/flow-test-project/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions e2e/test/flow-test-project/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "flow-jest-project",
"version": "0.0.0",
"private": true,
"description": "A module to test a flow project, see https://flow.org/",
"scripts": {
"test:unit": "jest",
"test": "stryker run",
"posttest": "mocha --no-config --require ../../tasks/ts-node-register.js verify/*.ts"
}
}
6 changes: 6 additions & 0 deletions e2e/test/flow-test-project/src/square.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// @flow
export function square(n: number): number {
const result: Array<?number> = [];
const cat = new Set<string>();
return n * n;
}
8 changes: 8 additions & 0 deletions e2e/test/flow-test-project/src/square.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { square } from './square';
import { expect } from 'chai';

describe('square', () => {
it('should provide 4 when given 2', () => {
expect(square(2)).eq(4);
});
});
13 changes: 13 additions & 0 deletions e2e/test/flow-test-project/stryker.conf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "../../node_modules/@stryker-mutator/core/schema/stryker-schema.json",
"reporters": [
"clear-text",
"event-recorder"
],
"concurrency": 2,
"commandRunner": {
"command": "npm run test:unit"
},
"symlinkNodeModules": false,
"fileLogLevel": "info"
}
16 changes: 16 additions & 0 deletions e2e/test/flow-test-project/verify/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"presets": [
"@babel/preset-flow",
[
"@babel/preset-env",
{
"targets": {
"edge": "16",
"firefox": "57",
"chrome": "62",
"safari": "11"
}
}
]
]
}
19 changes: 19 additions & 0 deletions e2e/test/flow-test-project/verify/verify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { expectMetrics } from '../../../helpers';

describe('After running stryker on jest-react project', () => {
it('should report expected scores', async () => {
await expectMetrics({
killed: 2,
ignored: 0,
survived: 1,
mutationScore: 66.67,
});
/*
-----------|---------|----------|-----------|------------|----------|---------|
File | % score | # killed | # timeout | # survived | # no cov | # error |
-----------|---------|----------|-----------|------------|----------|---------|
All files | 66.67 | 2 | 0 | 1 | 0 | 0 |
square.js | 66.67 | 2 | 0 | 1 | 0 | 0 |
-----------|---------|----------|-----------|------------|----------|---------|*/
});
});
5 changes: 5 additions & 0 deletions packages/instrumenter/src/transformers/babel-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export const transformBabel: AstTransformer<AstFormat.JS | AstFormat.TS> = ({ ro
},
});
if (mutantCollector.hasPlacedMutants(originFileName)) {
const innerComments = root.program.innerComments ?? [];
const leadingComments = root.program.body[0]?.leadingComments ?? [];
if (Array.isArray(leadingComments)) {
instrumentationBabelHeader[0].leadingComments = [...innerComments, ...leadingComments];
}
root.program.body.unshift(...instrumentationBabelHeader);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,26 @@ describe('babel-transformer', () => {
expect(mutantCollectorMock.markMutantsAsPlaced).calledWith([mutant]);
});

it('should add the global stuff on top', () => {
const ast = createJSAst({ rawContent: 'foo' });
it('should add the global stuff on top but after comments that are followed by newline', () => {
const ast = createJSAst({ rawContent: '// @flow\n// another comment\n\nconst foo="cat"' });
mutantCollectorMock.hasPlacedMutants.returns(true);
transformBabel(ast, mutantCollectorMock, context);

expect(ast.root.program.body[0].leadingComments![0].value).eq(' @flow');
expect(ast.root.program.body[0].leadingComments![1].value).eq(' another comment');

for (let i = 0; i < instrumentationBabelHeader.length; i++) {
expect(ast.root.program.body[i]).eq(instrumentationBabelHeader[i]);
}
});
it('should add the global stuff on top but after comments that are followed by a statement', () => {
const ast = createJSAst({ rawContent: '// @flow\n// another comment\nconst foo="cat"' });
mutantCollectorMock.hasPlacedMutants.returns(true);
transformBabel(ast, mutantCollectorMock, context);

expect(ast.root.program.body[0].leadingComments![0].value).eq(' @flow');
expect(ast.root.program.body[0].leadingComments![1].value).eq(' another comment');

for (let i = 0; i < instrumentationBabelHeader.length; i++) {
expect(ast.root.program.body[i]).eq(instrumentationBabelHeader[i]);
}
Expand Down

0 comments on commit 804c83e

Please sign in to comment.