Skip to content

Commit

Permalink
feat(config): replace pathRegex with exclude (#2295)
Browse files Browse the repository at this point in the history
Replace `pathRegex` by `exclude` which uses Glob patterns, similar to tsconfig `exclude` option. This will make it easier to configure files to exclude from type checking.

BREAKING CHANGE
One is currently using `pathRegex` should use `exclude` with Glob patterns
  • Loading branch information
ahnpnl authored Jan 21, 2021
1 parent d5ef413 commit f2f99c3
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 51 deletions.
4 changes: 2 additions & 2 deletions src/compiler/__snapshots__/ts-compiler.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ exports[`TsCompiler isolatedModule false should compile codes with useESM true 1
//# "
`;

exports[`TsCompiler isolatedModule true diagnostics should report diagnostics related to codes with pathRegex config is undefined 1`] = `"foo.ts(2,23): error TS1005: '=>' expected."`;
exports[`TsCompiler isolatedModule true diagnostics should report diagnostics related to codes with exclude config is undefined 1`] = `"foo.ts(2,23): error TS1005: '=>' expected."`;

exports[`TsCompiler isolatedModule true diagnostics should report diagnostics related to codes with pathRegex config matches file name 1`] = `"foo.ts(2,23): error TS1005: '=>' expected."`;
exports[`TsCompiler isolatedModule true diagnostics should report diagnostics related to codes with exclude config matches file name 1`] = `"foo.ts(2,23): error TS1005: '=>' expected."`;

exports[`TsCompiler isolatedModule true jsx option should compile tsx file for jsx preserve 1`] = `
"\\"use strict\\";
Expand Down
12 changes: 6 additions & 6 deletions src/compiler/ts-compiler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const v: boolean = t
).not.toThrowError()
})

it('should report diagnostics related to codes with pathRegex config is undefined', () => {
it('should report diagnostics related to codes with exclude config is undefined', () => {
const compiler = makeCompiler({ tsJestConfig: { ...baseTsJestConfig, tsconfig: false } })

expect(() =>
Expand All @@ -145,9 +145,9 @@ const t: string = f(5)
).toThrowErrorMatchingSnapshot()
})

it('should report diagnostics related to codes with pathRegex config matches file name', () => {
it('should report diagnostics related to codes with exclude config matches file name', () => {
const compiler = makeCompiler({
tsJestConfig: { ...baseTsJestConfig, tsconfig: false, diagnostics: { pathRegex: 'foo.ts' } },
tsJestConfig: { ...baseTsJestConfig, tsconfig: false, diagnostics: { exclude: ['foo.ts'] } },
})

expect(() =>
Expand All @@ -162,9 +162,9 @@ const t: string = f(5)
).toThrowErrorMatchingSnapshot()
})

it('should not report diagnostics related to codes with pathRegex config does not match file name', () => {
it('should not report diagnostics related to codes with exclude config does not match file name', () => {
const compiler = makeCompiler({
tsJestConfig: { ...baseTsJestConfig, tsconfig: false, diagnostics: { pathRegex: 'bar.ts' } },
tsJestConfig: { ...baseTsJestConfig, tsconfig: false, diagnostics: { exclude: ['bar.ts'] } },
})

expect(() =>
Expand Down Expand Up @@ -410,7 +410,7 @@ const t: string = f(5)
{
tsJestConfig: {
...baseTsJestConfig,
diagnostics: { pathRegex: 'foo.spec.ts' },
diagnostics: { exclude: ['foo.spec.ts'] },
},
},
jestCacheFS,
Expand Down
44 changes: 23 additions & 21 deletions src/config/config-set.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,13 +432,20 @@ describe('isTestFile', () => {

describe('shouldStringifyContent', () => {
it('should return correct value is defined', () => {
const cs = createConfigSet({ tsJestConfig: { tsconfig: false, stringifyContentPathRegex: '\\.str$' } as any })
expect(cs.shouldStringifyContent('/foo/bar.ts')).toBe(false)
expect(cs.shouldStringifyContent('/foo/bar.str')).toBe(true)
const cs1 = createConfigSet({ tsJestConfig: { tsconfig: false, stringifyContentPathRegex: '\\.str$' } as any })

expect(cs1.shouldStringifyContent('/foo/bar.ts')).toBe(false)
expect(cs1.shouldStringifyContent('/foo/bar.str')).toBe(true)

const cs2 = createConfigSet({ tsJestConfig: { tsconfig: false, stringifyContentPathRegex: /\.str$/ } as any })

expect(cs2.shouldStringifyContent('/foo/bar.ts')).toBe(false)
expect(cs2.shouldStringifyContent('/foo/bar.str')).toBe(true)
})

it('should return correct value when stringifyContentPathRegex is undefined', () => {
const cs = createConfigSet({ tsJestConfig: { tsconfig: false } as any })

expect(cs.shouldStringifyContent('/foo/bar.ts')).toBe(false)
})
}) // shouldStringifyContent
Expand Down Expand Up @@ -487,10 +494,10 @@ describe('raiseDiagnostics', () => {
code = 9999,
category = ts.DiagnosticCategory.Warning,
}: Partial<ts.Diagnostic> = {}): ts.Diagnostic => ({ messageText, code, category } as any)
it('should throw when diagnostics contains file path and pathRegex config matches file path', () => {
it('should throw when diagnostics contains file path and exclude config matches file path', () => {
const cs = createConfigSet({
logger,
tsJestConfig: { diagnostics: { pathRegex: 'src/__mocks__/index.ts', pretty: false } },
tsJestConfig: { diagnostics: { exclude: ['src/__mocks__/index.ts'], pretty: false } },
})
logger.target.clear()

Expand All @@ -499,10 +506,10 @@ describe('raiseDiagnostics', () => {
).toThrowErrorMatchingInlineSnapshot(`"warning TS9999: foo"`)
})

it("should not throw when diagnostics contains file path and pathRegex config doesn't match file path", () => {
it("should not throw when diagnostics contains file path and exclude config doesn't match file path", () => {
const cs = createConfigSet({
logger,
tsJestConfig: { diagnostics: { warnOnly: true, pathRegex: '/bar/', pretty: false } },
tsJestConfig: { diagnostics: { warnOnly: true, exclude: ['/bar/'], pretty: false } },
})
logger.target.clear()

Expand All @@ -524,20 +531,20 @@ describe('raiseDiagnostics', () => {
file = program.getSourceFiles().find((sourceFile) => sourceFile.fileName === 'src/__mocks__/index.ts'),
}: Partial<ts.Diagnostic> = {}): ts.Diagnostic => ({ messageText, code, category, file } as any)

it("should not throw when pathRegex config doesn't match source file path", () => {
it("should not throw when exclude config doesn't match source file path", () => {
const cs = createConfigSet({
logger,
tsJestConfig: { diagnostics: { pathRegex: '/foo/', pretty: false, ignoreCodes: [1111] } },
tsJestConfig: { diagnostics: { exclude: ['/foo/'], pretty: false, ignoreCodes: [1111] } },
})
logger.target.clear()

expect(() => cs.raiseDiagnostics([makeDiagnostic()])).not.toThrow()
})

it("should throw when pathRegex config doesn't match source file path", () => {
it("should throw when exclude config doesn't match source file path", () => {
const cs = createConfigSet({
logger,
tsJestConfig: { diagnostics: { pathRegex: 'src/__mocks__/index.ts', pretty: false } },
tsJestConfig: { diagnostics: { exclude: ['src/__mocks__/index.ts'], pretty: false } },
})
logger.target.clear()

Expand All @@ -553,7 +560,7 @@ describe('shouldReportDiagnostics', () => {
let cs = createConfigSet({
tsJestConfig: {
tsconfig: false,
diagnostics: { pathRegex: '/foo/' },
diagnostics: { exclude: ['**/foo/*.ts', '**/foo/*.tsx'] },
} as any,
})

Expand All @@ -570,7 +577,7 @@ describe('shouldReportDiagnostics', () => {
let cs = createConfigSet({
tsJestConfig: {
tsconfig: { checkJs: false },
diagnostics: { pathRegex: '/foo/' },
diagnostics: { exclude: ['foo/*'] },
},
})

Expand All @@ -580,17 +587,12 @@ describe('shouldReportDiagnostics', () => {
cs = createConfigSet({
tsJestConfig: {
tsconfig: { checkJs: true },
diagnostics: { pathRegex: '/foo/' },
diagnostics: { exclude: ['**/foo/*.js', '**/foo/*.jsx'] },
},
})

expect(cs.shouldReportDiagnostics('/foo/index.js')).toBe(true)
expect(cs.shouldReportDiagnostics('/foo/index.jsx')).toBe(true)

cs = createConfigSet({ tsJestConfig: { tsconfig: { checkJs: true } } })

expect(cs.shouldReportDiagnostics('/foo/index.js')).toBe(true)
expect(cs.shouldReportDiagnostics('/foo/index.jsx')).toBe(true)
})
}) // shouldReportDiagnostics

Expand Down Expand Up @@ -950,15 +952,15 @@ describe('diagnostics', () => {
{
diagnostics: {
ignoreCodes: '10, 25',
pathRegex: '\\.test\\.ts',
exclude: ['\\.test\\.ts'],
pretty: false,
},
},
{
diagnostics: {
ignoreCodes: ['10', 25],
pretty: false,
pathRegex: RegExp('\\.test\\.ts'),
exclude: ['\\.test\\.ts'],
},
},
{ diagnostics: { warnOnly: true } },
Expand Down
30 changes: 18 additions & 12 deletions src/config/config-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,11 @@ export class ConfigSet {
/**
* @internal
*/
private readonly _isMatch: (str: Config.Path) => boolean
private readonly _matchTestFilePath: (filePath: string) => boolean
/**
* @internal
*/
private _shouldGetDiagnosticsForFile!: (filePath: string) => boolean
/**
* @internal
*/
Expand Down Expand Up @@ -201,7 +205,7 @@ export class ConfigSet {
if (!this._matchablePatterns.length) {
this._matchablePatterns.push(...DEFAULT_JEST_TEST_MATCH)
}
this._isMatch = globsToMatcher(
this._matchTestFilePath = globsToMatcher(
this._matchablePatterns.filter((pattern: any) => typeof pattern === 'string') as string[],
)
}
Expand Down Expand Up @@ -270,17 +274,21 @@ export class ConfigSet {
}
this._diagnostics = {
pretty: diagnosticsOpt.pretty ?? true,
exclude: diagnosticsOpt.exclude ?? [],
ignoreCodes: toDiagnosticCodeList(ignoreList),
pathRegex: normalizeRegex(diagnosticsOpt.pathRegex),
throws: !diagnosticsOpt.warnOnly,
}
} else {
this._diagnostics = {
ignoreCodes: diagnosticsOpt ? toDiagnosticCodeList(ignoreList) : [],
exclude: [],
pretty: true,
throws: diagnosticsOpt,
}
}
this._shouldGetDiagnosticsForFile = this._diagnostics.exclude.length
? globsToMatcher(this._diagnostics.exclude)
: () => true

this.logger.debug({ diagnostics: this._diagnostics }, 'normalized diagnostics config via ts-jest option')

Expand Down Expand Up @@ -377,6 +385,9 @@ export class ConfigSet {
}
}

/**
* @internal
*/
private _getAndResolveTsConfig(compilerOptions?: CompilerOptions, resolvedConfigFile?: string): ParsedCommandLine {
const result = this._resolveTsConfig(compilerOptions, resolvedConfigFile) as ParsedCommandLine
const { _overriddenCompilerOptions: forcedOptions } = this
Expand Down Expand Up @@ -494,7 +505,7 @@ export class ConfigSet {

isTestFile(fileName: string): boolean {
return this._matchablePatterns.some((pattern) =>
typeof pattern === 'string' ? this._isMatch(fileName) : pattern.test(fileName),
typeof pattern === 'string' ? this._matchTestFilePath(fileName) : pattern.test(fileName),
)
}

Expand Down Expand Up @@ -527,16 +538,11 @@ export class ConfigSet {
}

shouldReportDiagnostics(filePath: string): boolean {
const { pathRegex } = this._diagnostics
const fileExtension = extname(filePath)
const { checkJs } = this.parsedTsConfig.options
if (pathRegex) {
const regex = new RegExp(pathRegex)

return JS_JSX_EXTENSIONS.includes(fileExtension) ? checkJs && regex.test(filePath) : regex.test(filePath)
} else {
return JS_JSX_EXTENSIONS.includes(fileExtension) ? checkJs : true
}
return JS_JSX_EXTENSIONS.includes(fileExtension)
? this.parsedTsConfig.options.checkJs && this._shouldGetDiagnosticsForFile(filePath)
: this._shouldGetDiagnosticsForFile(filePath)
}

/**
Expand Down
7 changes: 3 additions & 4 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,9 @@ export interface TsJestGlobalOptions {
*/
ignoreCodes?: number | string | (number | string)[]
/**
* If specified, diagnostics of source files which path does **not** match
* will be ignored
* If specified, diagnostics of source files which path **matches** will be ignored
*/
pathRegex?: RegExp | string
exclude?: Config.Glob[]
/**
* Logs TypeScript errors to stderr instead of throwing exceptions
*
Expand Down Expand Up @@ -152,7 +151,7 @@ type TsJestConfig$tsConfig = TsJestConfig$tsConfig$file | TsJestConfig$tsConfig$
export interface TsJestDiagnosticsCfg {
pretty: boolean
ignoreCodes: number[]
pathRegex?: string | undefined
exclude: Config.Glob[]
throws: boolean
warnOnly?: boolean
}
Expand Down
4 changes: 3 additions & 1 deletion src/utils/__snapshots__/backports.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ Object {
"globals": Object {
"ts-jest": Object {
"diagnostics": Object {
"pathRegex": "\\\\.spec\\\\.ts$",
"exclude": Array [
"\\\\.spec\\\\.ts$",
],
"warnOnly": true,
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/utils/backports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const backportJestConfig = <T extends Config.InitialOptions | Config.Proj
warnConfig('globals.ts-jest.enableTsDiagnostics', 'globals.ts-jest.diagnostics')
if (tsJest.enableTsDiagnostics) {
mergeTsJest.diagnostics = { warnOnly: true }
if (typeof tsJest.enableTsDiagnostics === 'string') mergeTsJest.diagnostics.pathRegex = tsJest.enableTsDiagnostics
if (typeof tsJest.enableTsDiagnostics === 'string') mergeTsJest.diagnostics.exclude = [tsJest.enableTsDiagnostics]
} else {
mergeTsJest.diagnostics = false
}
Expand Down
10 changes: 6 additions & 4 deletions website/docs/options/diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ The `diagnostics` option's value can also accept an object for more advanced con
- **`warnOnly`**: If specified and `true`, diagnostics will be reported but won't stop compilation (default: _disabled_).
- **`ignoreCodes`**: List of TypeScript error codes to ignore. Complete list can be found [there](https://github.com/Microsoft/TypeScript/blob/master/src/compiler/diagnosticMessages.json). By default here are the ones ignored:
- `6059`: _'rootDir' is expected to contain all source files._
- `18002`: _The 'files' list in config file is empty._ (it is strongly recommended to include this one)
- `18002`: _The 'files' list in config file is empty._ (it is strongly recommended including this one)
- `18003`: _No inputs were found in config file._
- **`pathRegex`**: If specified, diagnostics of source files which path does **not** match will be ignored.
- **`exclude`**: If specified, diagnostics of source files which path **matches** will be ignored. This works a bit
similar to `tsconfig` option [exclude](https://www.typescriptlang.org/tsconfig#exclude) with the only difference is that
in TypeScript, `exclude` will also exclude files from compilation process.
- **`pretty`**: Enables/disables colorful and pretty output of errors (default: _enabled_).

### Examples
Expand Down Expand Up @@ -68,7 +70,7 @@ module.exports = {
globals: {
'ts-jest': {
diagnostics: {
pathRegex: /\.(spec|test)\.ts$/,
exclude: ['**/*.spec.ts'],
},
},
},
Expand All @@ -83,7 +85,7 @@ module.exports = {
"globals": {
"ts-jest": {
"diagnostics": {
"pathRegex": "\\.(spec|test)\\.ts$"
"exclude": ["**/*.spec.ts"]
}
}
}
Expand Down

0 comments on commit f2f99c3

Please sign in to comment.