Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(disable-checking): allow jest environment #2607

Merged
merged 1 commit into from Nov 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion e2e/test/jest-with-ts/package.json
Expand Up @@ -3,7 +3,7 @@
"description": "A test project for using stryker with jest and jest-ts preprocessor. Inspired by the stryker-dashboard source code.",
"scripts": {
"test": "stryker run",
"test:original": "jest",
"test:unit": "jest",
"posttest": "mocha --require ../../tasks/ts-node-register.js verify/verify.ts"
},
"dependencies": {
Expand Down
15 changes: 15 additions & 0 deletions e2e/test/jest-with-ts/src/components/hello-component.test.ts
@@ -0,0 +1,15 @@
/**
* @jest-environment jsdom
*/

import './hello-component';

describe('hello-component', () => {

fit('should show a "hello world" message', () => {
const element = document.createElement('jest-hello');
document.body.appendChild(element);
expect(element.innerText).toEqual('hello world');
document.body.removeChild(element);
});
});
7 changes: 7 additions & 0 deletions e2e/test/jest-with-ts/src/components/hello-component.ts
@@ -0,0 +1,7 @@

export class HelloComponent extends HTMLElement {
connectedCallback() {
this.innerText = 'hello world';
}
}
window.customElements.define('jest-hello', HelloComponent);
3 changes: 2 additions & 1 deletion e2e/test/jest-with-ts/stryker.conf.json
@@ -1,7 +1,8 @@
{
"$schema": "../../node_modules/@stryker-mutator/core/schema/stryker-schema.json",
"mutate": [
"src/data-access/mappers/TableStorageMapper.ts"
"src/data-access/mappers/TableStorageMapper.ts",
"src/components/hello-component.ts"
],
"packageManager": "npm",
"testRunner": "jest",
Expand Down
3 changes: 2 additions & 1 deletion e2e/test/jest-with-ts/tsconfig.json
Expand Up @@ -4,7 +4,8 @@
"esModuleInterop": true,
"module": "commonjs",
"lib": [
"es2017"
"es2017",
"DOM"
],
"types": [
"jest",
Expand Down
4 changes: 2 additions & 2 deletions e2e/test/jest-with-ts/verify/verify.ts
Expand Up @@ -5,8 +5,8 @@ describe('Verify stryker has ran correctly', () => {
it('should report correct score', async () => {
await expectMetrics({
ignored: 0,
killed: 15,
mutationScore: 53.57,
killed: 17,
mutationScore: 56.67,
noCoverage: 0,
survived: 13,
timeout: 0,
Expand Down
5 changes: 4 additions & 1 deletion packages/instrumenter/src/disable-type-checks.ts
Expand Up @@ -7,6 +7,7 @@ import { AstFormat, HtmlAst, JSAst, TSAst } from './syntax';

const commentDirectiveRegEx = /^(\s*)@(ts-[a-z-]+).*$/;
const tsDirectiveLikeRegEx = /@(ts-[a-z-]+)/;
const startingCommentRegex = /(^\s*\/\*.*?\*\/)/gs;

export async function disableTypeChecks(file: File, options: ParserOptions) {
if (isJSFileWithoutTSDirectives(file)) {
Expand Down Expand Up @@ -43,7 +44,9 @@ function prefixWithNoCheck(code: string): string {
return code;
}
} else {
return `// @ts-nocheck\n${code}`;
// We should leave comments, like `/** @jest-env jsdom */ at the top of the file, see #2569
const commentMatch = startingCommentRegex.exec(code);
return `${commentMatch?.[1].concat('\n') ?? ''}// @ts-nocheck\n${code.substr(commentMatch?.[1].length ?? 0)}`;
}
}

Expand Down
12 changes: 10 additions & 2 deletions packages/instrumenter/test/unit/disable-type-checks.spec.ts
Expand Up @@ -27,6 +27,14 @@ describe(disableTypeChecks.name, () => {
});
});

describe('with jest directive (`@jest-environment`)', () => {
it('should insert `// @ts-nocheck` after the jest directive', async () => {
const inputFile = new File('foo.js', '/**\n* @jest-environment jsdom\n*/\nfoo.bar();');
const actual = await disableTypeChecks(inputFile, { plugins: null });
assertions.expectTextFileEqual(actual, new File('foo.js', '/**\n* @jest-environment jsdom\n*/\n// @ts-nocheck\n\nfoo.bar();'));
});
});

it('should not even parse the file if "@ts-" can\'t be found anywhere in the file (performance optimization)', async () => {
const createParserSpy = sinon.spy(parsers, 'createParser');
const inputFile = new File('foo.js', 'foo.bar();');
Expand All @@ -47,15 +55,15 @@ describe(disableTypeChecks.name, () => {
});

it('should remove @ts directive from single line', async () => {
await arrangeActAssert('// @ts-check\nfoo.bar();', '// \nfoo.bar();');
await arrangeActAssert('baz();// @ts-check\nfoo.bar();', 'baz();// \nfoo.bar();');
});

it('should not remove @ts comments which occur later on the comment line (since then they are not considered a directive)', async () => {
await arrangeActAssert('// this should be ignored: @ts-expect-error\nfoo.bar();');
});

it('should remove @ts directive from multiline', async () => {
await arrangeActAssert('/* @ts-expect-error */\nfoo.bar();', '/* */\nfoo.bar();');
await arrangeActAssert('baz();/* @ts-expect-error */\nfoo.bar();', 'baz();/* */\nfoo.bar();');
});

describe('with string', () => {
Expand Down