From 772e5bcb126b4a44024921c31b760d57d92afd94 Mon Sep 17 00:00:00 2001 From: Nico Jansen Date: Thu, 30 Sep 2021 18:56:46 +0200 Subject: [PATCH] fix(typescript-checker): support TS 4.4 (#3178) TypeScript 4.4 also watches package.json files in node_modules for changes. I guess this is done to be able to reload the types when a node_module gets updated. However, the typescript-checker wasn't expecting those `watchFile` calls to come in. The checker was defensive programmed, meaning an error is thrown when something happens that it doesn't expect. This ended up being a simple fix. Simply ignoring `watchFile` of files that are not loaded seems to do the trick. --- e2e/package-lock.json | 6 +++--- e2e/package.json | 2 +- e2e/test/jest-with-ts/stryker.conf.json | 4 ++-- e2e/test/jest-with-ts/verify/verify.ts | 11 +++++------ packages/typescript-checker/.vscode/launch.json | 2 +- .../typescript-checker/src/fs/hybrid-file-system.ts | 7 +++---- .../test/unit/fs/hybrid-file-system.spec.ts | 12 +++++++++--- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/e2e/package-lock.json b/e2e/package-lock.json index 777ce12720..b0e0eabb20 100644 --- a/e2e/package-lock.json +++ b/e2e/package-lock.json @@ -13546,9 +13546,9 @@ } }, "typescript": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", - "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", "dev": true }, "ua-parser-js": { diff --git a/e2e/package.json b/e2e/package.json index a3715f4ff3..52dca7f125 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -39,7 +39,7 @@ "ts-jest": "~27.0.1", "ts-loader": "~8.0.3", "ts-node": "~7.0.0", - "typescript": "~4.3.2", + "typescript": "^4.4.3", "webpack": "~4.41.2", "webpack-cli": "~3.3.12" }, diff --git a/e2e/test/jest-with-ts/stryker.conf.json b/e2e/test/jest-with-ts/stryker.conf.json index 70b571e8c1..cb4bd35e26 100644 --- a/e2e/test/jest-with-ts/stryker.conf.json +++ b/e2e/test/jest-with-ts/stryker.conf.json @@ -13,8 +13,8 @@ ], "coverageAnalysis": "off", "reporters": [ - "event-recorder", "progress", - "html" + "html", + "json" ] } diff --git a/e2e/test/jest-with-ts/verify/verify.ts b/e2e/test/jest-with-ts/verify/verify.ts index b25649a10e..2dfbbe5570 100644 --- a/e2e/test/jest-with-ts/verify/verify.ts +++ b/e2e/test/jest-with-ts/verify/verify.ts @@ -1,16 +1,15 @@ -import { expectMetrics } from '../../../helpers'; +import { expectMetricsJson } from '../../../helpers'; describe('Verify stryker has ran correctly', () => { - it('should report correct score', async () => { - await expectMetrics({ + await expectMetricsJson({ ignored: 0, killed: 17, - mutationScore: 56.67, + mutationScore: 62.96, noCoverage: 0, - survived: 13, + survived: 10, timeout: 0, - compileErrors: 32 + compileErrors: 35, }); }); }); diff --git a/packages/typescript-checker/.vscode/launch.json b/packages/typescript-checker/.vscode/launch.json index cd597552b2..427d8e5417 100644 --- a/packages/typescript-checker/.vscode/launch.json +++ b/packages/typescript-checker/.vscode/launch.json @@ -4,7 +4,7 @@ { "type": "node", "request": "launch", - "name": "Unit / Integration tests", + "name": "💙 Unit / Integration tests", "program": "${workspaceRoot}/../../node_modules/mocha/bin/_mocha", "internalConsoleOptions": "openOnSessionStart", "outFiles": [ diff --git a/packages/typescript-checker/src/fs/hybrid-file-system.ts b/packages/typescript-checker/src/fs/hybrid-file-system.ts index 6b1c7c8331..0648f5349b 100644 --- a/packages/typescript-checker/src/fs/hybrid-file-system.ts +++ b/packages/typescript-checker/src/fs/hybrid-file-system.ts @@ -47,11 +47,10 @@ export class HybridFileSystem { public watchFile(fileName: string, watcher: ts.FileWatcherCallback): void { const file = this.getFile(fileName); - if (!file) { - throw new Error(`Cannot find file ${fileName} for watching`); + if (file) { + this.log.trace('Registering watcher for file "%s"', fileName); + file.watcher = watcher; } - this.log.trace('Registering watcher for file "%s"', fileName); - file.watcher = watcher; } public getFile(fileName: string): ScriptFile | undefined { diff --git a/packages/typescript-checker/test/unit/fs/hybrid-file-system.spec.ts b/packages/typescript-checker/test/unit/fs/hybrid-file-system.spec.ts index 335831f4fb..937c036909 100644 --- a/packages/typescript-checker/test/unit/fs/hybrid-file-system.spec.ts +++ b/packages/typescript-checker/test/unit/fs/hybrid-file-system.spec.ts @@ -1,7 +1,7 @@ import sinon from 'sinon'; import ts from 'typescript'; import { expect } from 'chai'; -import { testInjector } from '@stryker-mutator/test-helpers'; +import { factory, testInjector } from '@stryker-mutator/test-helpers'; import { HybridFileSystem } from '../../../src/fs'; @@ -106,8 +106,14 @@ describe('fs', () => { expect(helper.readFileStub).calledWith('test/foo/a.js'); }); - it("should throw if file doesn't exist", () => { - expect(() => sut.watchFile('not-exists.js', sinon.stub())).throws('Cannot find file not-exists.js for watching'); + it("should not throw if file isn't loaded", () => { + // Should ignore the file watch + const watchCallback = sinon.stub(); + sut.watchFile('node_modules/chai/package.json', watchCallback); + + // If it was successfully ignored, than `mutate` should throw + expect(() => sut.mutate(factory.mutant({ fileName: 'node_modules/chai/package.json' }))).throws(); + expect(watchCallback).not.called; }); it('should log that the file is watched', () => {