From bb28849b091ca1e220c031699a775159aab867c4 Mon Sep 17 00:00:00 2001 From: Huafu Gandon Date: Sat, 22 Sep 2018 19:32:24 +0200 Subject: [PATCH] fix(diagnostics): throws only for category warning and error Diagnostics have a category. By default if warnOnly is not set, when diagnostic(s) of kind message or suggestion will be raised, ts-jest will log it but not throw. This also changes the category of the internal TS151000. Closes #748 --- src/config/config-set.spec.ts | 19 ++++++++++++------- src/config/config-set.ts | 24 +++++++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/config/config-set.spec.ts b/src/config/config-set.spec.ts index a357fc9bbe..eef9b851ae 100644 --- a/src/config/config-set.spec.ts +++ b/src/config/config-set.spec.ts @@ -1,6 +1,6 @@ import { testing } from 'bs-logger' import { resolve } from 'path' -import ts, { Diagnostic, ModuleKind, ScriptTarget } from 'typescript' +import ts, { Diagnostic, DiagnosticCategory, ModuleKind, ScriptTarget } from 'typescript' import * as _myModule from '..' import * as fakers from '../__helpers__/fakers' @@ -295,7 +295,7 @@ describe('typescript', () => { target.clear() const cs = createConfigSet({ tsJestConfig: { - tsConfig: { module: 'ES6', esModuleInterop: false, allowSyntheticDefaultImports: false } as any, + tsConfig: { module: 'ES6', esModuleInterop: false } as any, diagnostics: { warnOnly: true, pretty: false }, }, resolve: null, @@ -307,7 +307,7 @@ describe('typescript', () => { }) expect(target.lines.warn.join()).toMatchInlineSnapshot(` "[level:40] TypeScript diagnostics (customize using \`[jest-config].globals.ts-jest.diagnostics\` option): -warning TS151001: If you have issues related to imports, you should consider setting \`esModuleInterop\` to \`true\` in your TypeScript configuration file (usually \`tsconfig.json\`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information. +message TS151001: If you have issues related to imports, you should consider setting \`esModuleInterop\` to \`true\` in your TypeScript configuration file (usually \`tsconfig.json\`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information. " `) }) @@ -540,15 +540,20 @@ Object { describe('raiseDiagnostics', () => { const createTsError = jest.fn( - (list: Diagnostic[]) => new Error(list.map(d => `[${d.code}] ${d.messageText}`).join('\n')), + (list: Diagnostic[]) => new Error(list.map(d => `[TS${d.code}] ${d.messageText}`).join('\n')), ) const filterDiagnostics = jest.fn(list => list) const logger = testing.createLoggerMock() - const diagnostic: Diagnostic = { messageText: 'foo', code: 'TS9999' } as any + const makeDiagnostic = ({ + messageText = 'foo', + code = 9999, + category = DiagnosticCategory.Warning, + }: Partial = {}): Diagnostic => ({ messageText, code, category } as any) it('should throw when warnOnly is false', () => { const { raiseDiagnostics } = createConfigSet({ createTsError, filterDiagnostics }) expect(() => raiseDiagnostics([])).not.toThrow() - expect(() => raiseDiagnostics([diagnostic])).toThrowErrorMatchingInlineSnapshot(`"[TS9999] foo"`) + expect(() => raiseDiagnostics([makeDiagnostic()])).toThrowErrorMatchingInlineSnapshot(`"[TS9999] foo"`) + expect(() => raiseDiagnostics([makeDiagnostic({ category: DiagnosticCategory.Message })])).not.toThrow() }) it('should not throw when warnOnly is true', () => { const { raiseDiagnostics } = createConfigSet({ @@ -559,7 +564,7 @@ describe('raiseDiagnostics', () => { }) logger.target.clear() expect(() => raiseDiagnostics([])).not.toThrow() - expect(() => raiseDiagnostics([diagnostic])).not.toThrow() + expect(() => raiseDiagnostics([makeDiagnostic()])).not.toThrow() expect(logger.target.lines).toMatchInlineSnapshot(` Array [ "[level:40] [TS9999] foo diff --git a/src/config/config-set.ts b/src/config/config-set.ts index 4d1c1debfd..7642850e92 100644 --- a/src/config/config-set.ts +++ b/src/config/config-set.ts @@ -265,12 +265,17 @@ export class ConfigSet { tsJest: { diagnostics: { throws }, }, + compilerModule: { DiagnosticCategory }, } = this return (diagnostics: Diagnostic[], filePath?: string, logger: Logger = this.logger): void | never => { const filteredDiagnostics = filterDiagnostics(diagnostics, filePath) if (filteredDiagnostics.length === 0) return const error = createTsError(filteredDiagnostics) - if (throws) throw error + // only throw if `warnOnly` and it is a warning or error + const importantCategories = [DiagnosticCategory.Warning, DiagnosticCategory.Error] + if (throws && filteredDiagnostics.some(d => importantCategories.includes(d.category))) { + throw error + } logger.warn({ error }, error.message) } } @@ -621,10 +626,19 @@ export class ConfigSet { ? ts.ModuleKind.CommonJS : ts.ModuleKind.ESNext const moduleValue = finalOptions.module == null ? defaultModule : finalOptions.module - if (moduleValue !== forcedOptions.module && !finalOptions.esModuleInterop) { - result.errors.push(this.makeDiagnostic(DiagnosticCodes.ConfigModuleOption, Errors.ConfigNoModuleInterop)) - // at least enable synthetic default imports - finalOptions.allowSyntheticDefaultImports = true + if ( + moduleValue !== forcedOptions.module && + !(finalOptions.esModuleInterop || finalOptions.allowSyntheticDefaultImports) + ) { + result.errors.push( + this.makeDiagnostic(DiagnosticCodes.ConfigModuleOption, Errors.ConfigNoModuleInterop, { + category: ts.DiagnosticCategory.Message, + }), + ) + // at least enable synthetic default imports (except if it's set in the input config) + if (!('allowSyntheticDefaultImports' in config.compilerOptions)) { + finalOptions.allowSyntheticDefaultImports = true + } } // ensure undefined are removed and other values are overridden