Skip to content

Commit f2f99c3

Browse files
authored
feat(config): replace pathRegex with exclude (#2295)
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
1 parent d5ef413 commit f2f99c3

File tree

8 files changed

+62
-51
lines changed

8 files changed

+62
-51
lines changed

src/compiler/__snapshots__/ts-compiler.spec.ts.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ exports[`TsCompiler isolatedModule false should compile codes with useESM true 1
5353
//# "
5454
`;
5555

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

58-
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."`;
58+
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."`;
5959

6060
exports[`TsCompiler isolatedModule true jsx option should compile tsx file for jsx preserve 1`] = `
6161
"\\"use strict\\";

src/compiler/ts-compiler.spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ const v: boolean = t
130130
).not.toThrowError()
131131
})
132132

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

136136
expect(() =>
@@ -145,9 +145,9 @@ const t: string = f(5)
145145
).toThrowErrorMatchingSnapshot()
146146
})
147147

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

153153
expect(() =>
@@ -162,9 +162,9 @@ const t: string = f(5)
162162
).toThrowErrorMatchingSnapshot()
163163
})
164164

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

170170
expect(() =>
@@ -410,7 +410,7 @@ const t: string = f(5)
410410
{
411411
tsJestConfig: {
412412
...baseTsJestConfig,
413-
diagnostics: { pathRegex: 'foo.spec.ts' },
413+
diagnostics: { exclude: ['foo.spec.ts'] },
414414
},
415415
},
416416
jestCacheFS,

src/config/config-set.spec.ts

+23-21
Original file line numberDiff line numberDiff line change
@@ -432,13 +432,20 @@ describe('isTestFile', () => {
432432

433433
describe('shouldStringifyContent', () => {
434434
it('should return correct value is defined', () => {
435-
const cs = createConfigSet({ tsJestConfig: { tsconfig: false, stringifyContentPathRegex: '\\.str$' } as any })
436-
expect(cs.shouldStringifyContent('/foo/bar.ts')).toBe(false)
437-
expect(cs.shouldStringifyContent('/foo/bar.str')).toBe(true)
435+
const cs1 = createConfigSet({ tsJestConfig: { tsconfig: false, stringifyContentPathRegex: '\\.str$' } as any })
436+
437+
expect(cs1.shouldStringifyContent('/foo/bar.ts')).toBe(false)
438+
expect(cs1.shouldStringifyContent('/foo/bar.str')).toBe(true)
439+
440+
const cs2 = createConfigSet({ tsJestConfig: { tsconfig: false, stringifyContentPathRegex: /\.str$/ } as any })
441+
442+
expect(cs2.shouldStringifyContent('/foo/bar.ts')).toBe(false)
443+
expect(cs2.shouldStringifyContent('/foo/bar.str')).toBe(true)
438444
})
439445

440446
it('should return correct value when stringifyContentPathRegex is undefined', () => {
441447
const cs = createConfigSet({ tsJestConfig: { tsconfig: false } as any })
448+
442449
expect(cs.shouldStringifyContent('/foo/bar.ts')).toBe(false)
443450
})
444451
}) // shouldStringifyContent
@@ -487,10 +494,10 @@ describe('raiseDiagnostics', () => {
487494
code = 9999,
488495
category = ts.DiagnosticCategory.Warning,
489496
}: Partial<ts.Diagnostic> = {}): ts.Diagnostic => ({ messageText, code, category } as any)
490-
it('should throw when diagnostics contains file path and pathRegex config matches file path', () => {
497+
it('should throw when diagnostics contains file path and exclude config matches file path', () => {
491498
const cs = createConfigSet({
492499
logger,
493-
tsJestConfig: { diagnostics: { pathRegex: 'src/__mocks__/index.ts', pretty: false } },
500+
tsJestConfig: { diagnostics: { exclude: ['src/__mocks__/index.ts'], pretty: false } },
494501
})
495502
logger.target.clear()
496503

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

502-
it("should not throw when diagnostics contains file path and pathRegex config doesn't match file path", () => {
509+
it("should not throw when diagnostics contains file path and exclude config doesn't match file path", () => {
503510
const cs = createConfigSet({
504511
logger,
505-
tsJestConfig: { diagnostics: { warnOnly: true, pathRegex: '/bar/', pretty: false } },
512+
tsJestConfig: { diagnostics: { warnOnly: true, exclude: ['/bar/'], pretty: false } },
506513
})
507514
logger.target.clear()
508515

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

527-
it("should not throw when pathRegex config doesn't match source file path", () => {
534+
it("should not throw when exclude config doesn't match source file path", () => {
528535
const cs = createConfigSet({
529536
logger,
530-
tsJestConfig: { diagnostics: { pathRegex: '/foo/', pretty: false, ignoreCodes: [1111] } },
537+
tsJestConfig: { diagnostics: { exclude: ['/foo/'], pretty: false, ignoreCodes: [1111] } },
531538
})
532539
logger.target.clear()
533540

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

537-
it("should throw when pathRegex config doesn't match source file path", () => {
544+
it("should throw when exclude config doesn't match source file path", () => {
538545
const cs = createConfigSet({
539546
logger,
540-
tsJestConfig: { diagnostics: { pathRegex: 'src/__mocks__/index.ts', pretty: false } },
547+
tsJestConfig: { diagnostics: { exclude: ['src/__mocks__/index.ts'], pretty: false } },
541548
})
542549
logger.target.clear()
543550

@@ -553,7 +560,7 @@ describe('shouldReportDiagnostics', () => {
553560
let cs = createConfigSet({
554561
tsJestConfig: {
555562
tsconfig: false,
556-
diagnostics: { pathRegex: '/foo/' },
563+
diagnostics: { exclude: ['**/foo/*.ts', '**/foo/*.tsx'] },
557564
} as any,
558565
})
559566

@@ -570,7 +577,7 @@ describe('shouldReportDiagnostics', () => {
570577
let cs = createConfigSet({
571578
tsJestConfig: {
572579
tsconfig: { checkJs: false },
573-
diagnostics: { pathRegex: '/foo/' },
580+
diagnostics: { exclude: ['foo/*'] },
574581
},
575582
})
576583

@@ -580,17 +587,12 @@ describe('shouldReportDiagnostics', () => {
580587
cs = createConfigSet({
581588
tsJestConfig: {
582589
tsconfig: { checkJs: true },
583-
diagnostics: { pathRegex: '/foo/' },
590+
diagnostics: { exclude: ['**/foo/*.js', '**/foo/*.jsx'] },
584591
},
585592
})
586593

587594
expect(cs.shouldReportDiagnostics('/foo/index.js')).toBe(true)
588595
expect(cs.shouldReportDiagnostics('/foo/index.jsx')).toBe(true)
589-
590-
cs = createConfigSet({ tsJestConfig: { tsconfig: { checkJs: true } } })
591-
592-
expect(cs.shouldReportDiagnostics('/foo/index.js')).toBe(true)
593-
expect(cs.shouldReportDiagnostics('/foo/index.jsx')).toBe(true)
594596
})
595597
}) // shouldReportDiagnostics
596598

@@ -950,15 +952,15 @@ describe('diagnostics', () => {
950952
{
951953
diagnostics: {
952954
ignoreCodes: '10, 25',
953-
pathRegex: '\\.test\\.ts',
955+
exclude: ['\\.test\\.ts'],
954956
pretty: false,
955957
},
956958
},
957959
{
958960
diagnostics: {
959961
ignoreCodes: ['10', 25],
960962
pretty: false,
961-
pathRegex: RegExp('\\.test\\.ts'),
963+
exclude: ['\\.test\\.ts'],
962964
},
963965
},
964966
{ diagnostics: { warnOnly: true } },

src/config/config-set.ts

+18-12
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ export class ConfigSet {
147147
/**
148148
* @internal
149149
*/
150-
private readonly _isMatch: (str: Config.Path) => boolean
150+
private readonly _matchTestFilePath: (filePath: string) => boolean
151+
/**
152+
* @internal
153+
*/
154+
private _shouldGetDiagnosticsForFile!: (filePath: string) => boolean
151155
/**
152156
* @internal
153157
*/
@@ -201,7 +205,7 @@ export class ConfigSet {
201205
if (!this._matchablePatterns.length) {
202206
this._matchablePatterns.push(...DEFAULT_JEST_TEST_MATCH)
203207
}
204-
this._isMatch = globsToMatcher(
208+
this._matchTestFilePath = globsToMatcher(
205209
this._matchablePatterns.filter((pattern: any) => typeof pattern === 'string') as string[],
206210
)
207211
}
@@ -270,17 +274,21 @@ export class ConfigSet {
270274
}
271275
this._diagnostics = {
272276
pretty: diagnosticsOpt.pretty ?? true,
277+
exclude: diagnosticsOpt.exclude ?? [],
273278
ignoreCodes: toDiagnosticCodeList(ignoreList),
274-
pathRegex: normalizeRegex(diagnosticsOpt.pathRegex),
275279
throws: !diagnosticsOpt.warnOnly,
276280
}
277281
} else {
278282
this._diagnostics = {
279283
ignoreCodes: diagnosticsOpt ? toDiagnosticCodeList(ignoreList) : [],
284+
exclude: [],
280285
pretty: true,
281286
throws: diagnosticsOpt,
282287
}
283288
}
289+
this._shouldGetDiagnosticsForFile = this._diagnostics.exclude.length
290+
? globsToMatcher(this._diagnostics.exclude)
291+
: () => true
284292

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

@@ -377,6 +385,9 @@ export class ConfigSet {
377385
}
378386
}
379387

388+
/**
389+
* @internal
390+
*/
380391
private _getAndResolveTsConfig(compilerOptions?: CompilerOptions, resolvedConfigFile?: string): ParsedCommandLine {
381392
const result = this._resolveTsConfig(compilerOptions, resolvedConfigFile) as ParsedCommandLine
382393
const { _overriddenCompilerOptions: forcedOptions } = this
@@ -494,7 +505,7 @@ export class ConfigSet {
494505

495506
isTestFile(fileName: string): boolean {
496507
return this._matchablePatterns.some((pattern) =>
497-
typeof pattern === 'string' ? this._isMatch(fileName) : pattern.test(fileName),
508+
typeof pattern === 'string' ? this._matchTestFilePath(fileName) : pattern.test(fileName),
498509
)
499510
}
500511

@@ -527,16 +538,11 @@ export class ConfigSet {
527538
}
528539

529540
shouldReportDiagnostics(filePath: string): boolean {
530-
const { pathRegex } = this._diagnostics
531541
const fileExtension = extname(filePath)
532-
const { checkJs } = this.parsedTsConfig.options
533-
if (pathRegex) {
534-
const regex = new RegExp(pathRegex)
535542

536-
return JS_JSX_EXTENSIONS.includes(fileExtension) ? checkJs && regex.test(filePath) : regex.test(filePath)
537-
} else {
538-
return JS_JSX_EXTENSIONS.includes(fileExtension) ? checkJs : true
539-
}
543+
return JS_JSX_EXTENSIONS.includes(fileExtension)
544+
? this.parsedTsConfig.options.checkJs && this._shouldGetDiagnosticsForFile(filePath)
545+
: this._shouldGetDiagnosticsForFile(filePath)
540546
}
541547

542548
/**

src/types.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,9 @@ export interface TsJestGlobalOptions {
102102
*/
103103
ignoreCodes?: number | string | (number | string)[]
104104
/**
105-
* If specified, diagnostics of source files which path does **not** match
106-
* will be ignored
105+
* If specified, diagnostics of source files which path **matches** will be ignored
107106
*/
108-
pathRegex?: RegExp | string
107+
exclude?: Config.Glob[]
109108
/**
110109
* Logs TypeScript errors to stderr instead of throwing exceptions
111110
*
@@ -152,7 +151,7 @@ type TsJestConfig$tsConfig = TsJestConfig$tsConfig$file | TsJestConfig$tsConfig$
152151
export interface TsJestDiagnosticsCfg {
153152
pretty: boolean
154153
ignoreCodes: number[]
155-
pathRegex?: string | undefined
154+
exclude: Config.Glob[]
156155
throws: boolean
157156
warnOnly?: boolean
158157
}

src/utils/__snapshots__/backports.spec.ts.snap

+3-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ Object {
9898
"globals": Object {
9999
"ts-jest": Object {
100100
"diagnostics": Object {
101-
"pathRegex": "\\\\.spec\\\\.ts$",
101+
"exclude": Array [
102+
"\\\\.spec\\\\.ts$",
103+
],
102104
"warnOnly": true,
103105
},
104106
},

src/utils/backports.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const backportJestConfig = <T extends Config.InitialOptions | Config.Proj
6464
warnConfig('globals.ts-jest.enableTsDiagnostics', 'globals.ts-jest.diagnostics')
6565
if (tsJest.enableTsDiagnostics) {
6666
mergeTsJest.diagnostics = { warnOnly: true }
67-
if (typeof tsJest.enableTsDiagnostics === 'string') mergeTsJest.diagnostics.pathRegex = tsJest.enableTsDiagnostics
67+
if (typeof tsJest.enableTsDiagnostics === 'string') mergeTsJest.diagnostics.exclude = [tsJest.enableTsDiagnostics]
6868
} else {
6969
mergeTsJest.diagnostics = false
7070
}

website/docs/options/diagnostics.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ The `diagnostics` option's value can also accept an object for more advanced con
2020
- **`warnOnly`**: If specified and `true`, diagnostics will be reported but won't stop compilation (default: _disabled_).
2121
- **`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:
2222
- `6059`: _'rootDir' is expected to contain all source files._
23-
- `18002`: _The 'files' list in config file is empty._ (it is strongly recommended to include this one)
23+
- `18002`: _The 'files' list in config file is empty._ (it is strongly recommended including this one)
2424
- `18003`: _No inputs were found in config file._
25-
- **`pathRegex`**: If specified, diagnostics of source files which path does **not** match will be ignored.
25+
- **`exclude`**: If specified, diagnostics of source files which path **matches** will be ignored. This works a bit
26+
similar to `tsconfig` option [exclude](https://www.typescriptlang.org/tsconfig#exclude) with the only difference is that
27+
in TypeScript, `exclude` will also exclude files from compilation process.
2628
- **`pretty`**: Enables/disables colorful and pretty output of errors (default: _enabled_).
2729

2830
### Examples
@@ -68,7 +70,7 @@ module.exports = {
6870
globals: {
6971
'ts-jest': {
7072
diagnostics: {
71-
pathRegex: /\.(spec|test)\.ts$/,
73+
exclude: ['**/*.spec.ts'],
7274
},
7375
},
7476
},
@@ -83,7 +85,7 @@ module.exports = {
8385
"globals": {
8486
"ts-jest": {
8587
"diagnostics": {
86-
"pathRegex": "\\.(spec|test)\\.ts$"
88+
"exclude": ["**/*.spec.ts"]
8789
}
8890
}
8991
}

0 commit comments

Comments
 (0)