-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
feat(config): if process.features.typescript
is set, load jest.config.ts
without external loader
#15480
feat(config): if process.features.typescript
is set, load jest.config.ts
without external loader
#15480
Changes from 11 commits
248c584
f1802d4
db76b55
7cd7501
77711d4
d499556
adab654
26957cf
f274a59
fb5e770
de1796d
a797b6c
924fa02
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
|
||
import * as path from 'path'; | ||
import * as fs from 'graceful-fs'; | ||
import {onNodeVersions} from '@jest/test-utils'; | ||
import {cleanup, extractSummary, writeFiles} from '../Utils'; | ||
import runJest from '../runJest'; | ||
|
||
|
@@ -23,7 +24,9 @@ test('works with jest.config.ts', () => { | |
'package.json': '{}', | ||
}); | ||
|
||
const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false']); | ||
const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false'], { | ||
nodeOptions: '--no-warnings', | ||
}); | ||
const {rest, summary} = extractSummary(stderr); | ||
expect(exitCode).toBe(0); | ||
expect(rest).toMatchSnapshot(); | ||
|
@@ -39,7 +42,9 @@ test('works with tsconfig.json', () => { | |
'tsconfig.json': '{ "compilerOptions": { "module": "esnext" } }', | ||
}); | ||
|
||
const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false']); | ||
const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false'], { | ||
nodeOptions: '--no-warnings', | ||
}); | ||
const {rest, summary} = extractSummary(stderr); | ||
expect(exitCode).toBe(0); | ||
expect(rest).toMatchSnapshot(); | ||
|
@@ -62,62 +67,95 @@ test('traverses directory tree up until it finds jest.config', () => { | |
const {stderr, exitCode, stdout} = runJest( | ||
path.join(DIR, 'some', 'nested', 'directory'), | ||
['-w=1', '--ci=false'], | ||
{skipPkgJsonCheck: true}, | ||
{nodeOptions: '--no-warnings', skipPkgJsonCheck: true}, | ||
); | ||
|
||
// Snapshot the console.logged `process.cwd()` and make sure it stays the same | ||
expect(stdout.replaceAll(/^\W+(.*)e2e/gm, '<<REPLACED>>')).toMatchSnapshot(); | ||
expect( | ||
stdout | ||
.replaceAll(/^\W+(.*)e2e/gm, '<<REPLACED>>') | ||
// slightly different log in node versions >= 23 | ||
.replace('at Object.log', 'at Object.<anonymous>'), | ||
).toMatchSnapshot(); | ||
|
||
const {rest, summary} = extractSummary(stderr); | ||
expect(exitCode).toBe(0); | ||
expect(rest).toMatchSnapshot(); | ||
expect(summary).toMatchSnapshot(); | ||
}); | ||
|
||
const jestPath = require.resolve('jest'); | ||
const jestTypesPath = jestPath.replace(/\.js$/, '.d.ts'); | ||
const jestTypesExists = fs.existsSync(jestTypesPath); | ||
onNodeVersions('<23.6', () => { | ||
const jestPath = require.resolve('jest'); | ||
const jestTypesPath = jestPath.replace(/\.js$/, '.d.ts'); | ||
const jestTypesExists = fs.existsSync(jestTypesPath); | ||
|
||
(jestTypesExists ? test : test.skip).each([true, false])( | ||
'check the config disabled (skip type check: %p)', | ||
skipTypeCheck => { | ||
writeFiles(DIR, { | ||
'__tests__/a-giraffe.js': "test('giraffe', () => expect(1).toBe(1));", | ||
'jest.config.ts': ` | ||
/**@jest-config-loader-options {"transpileOnly":${!!skipTypeCheck}}*/ | ||
import {Config} from 'jest'; | ||
const config: Config = { testTimeout: "10000" }; | ||
export default config; | ||
`, | ||
'package.json': '{}', | ||
}); | ||
|
||
const typeErrorString = | ||
"TS2322: Type 'string' is not assignable to type 'number'."; | ||
const runtimeErrorString = 'Option "testTimeout" must be of type:'; | ||
|
||
const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false']); | ||
|
||
if (skipTypeCheck) { | ||
expect(stderr).not.toMatch(typeErrorString); | ||
expect(stderr).toMatch(runtimeErrorString); | ||
} else { | ||
expect(stderr).toMatch(typeErrorString); | ||
expect(stderr).not.toMatch(runtimeErrorString); | ||
} | ||
|
||
expect(exitCode).toBe(1); | ||
}, | ||
); | ||
|
||
(jestTypesExists ? test : test.skip).each([true, false])( | ||
'check the config disabled (skip type check: %p)', | ||
skipTypeCheck => { | ||
test('invalid JS in jest.config.ts', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The diff is a bit weird here - this test is duplicated into a pre-23.6 and post-23.6 version now. |
||
writeFiles(DIR, { | ||
'__tests__/a-giraffe.js': "test('giraffe', () => expect(1).toBe(1));", | ||
'jest.config.ts': ` | ||
/**@jest-config-loader-options {"transpileOnly":${!!skipTypeCheck}}*/ | ||
import {Config} from 'jest'; | ||
const config: Config = { testTimeout: "10000" }; | ||
export default config; | ||
`, | ||
'jest.config.ts': "export default i'll break this file yo", | ||
'package.json': '{}', | ||
}); | ||
|
||
const typeErrorString = | ||
"TS2322: Type 'string' is not assignable to type 'number'."; | ||
const runtimeErrorString = 'Option "testTimeout" must be of type:'; | ||
|
||
const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false']); | ||
expect(stderr).toMatch('TSError: ⨯ Unable to compile TypeScript:'); | ||
expect(exitCode).toBe(1); | ||
}); | ||
}); | ||
|
||
if (skipTypeCheck) { | ||
expect(stderr).not.toMatch(typeErrorString); | ||
expect(stderr).toMatch(runtimeErrorString); | ||
} else { | ||
expect(stderr).toMatch(typeErrorString); | ||
expect(stderr).not.toMatch(runtimeErrorString); | ||
} | ||
onNodeVersions('>=23.6', () => { | ||
test('invalid JS in jest.config.ts (node with native TS support)', () => { | ||
writeFiles(DIR, { | ||
'__tests__/a-giraffe.js': "test('giraffe', () => expect(1).toBe(1));", | ||
'jest.config.ts': "export default i'll break this file yo", | ||
'package.json': '{}', | ||
}); | ||
|
||
const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false'], { | ||
nodeOptions: '--no-warnings', | ||
}); | ||
expect( | ||
stderr | ||
// Remove the stack trace from the error message | ||
.slice(0, Math.max(0, stderr.indexOf('Caused by'))) | ||
.trim() | ||
// Replace the path to the config file with a placeholder | ||
.replace( | ||
/(Error: Jest: Failed to parse the TypeScript config file).*$/m, | ||
'$1 <<REPLACED>>', | ||
), | ||
).toMatchSnapshot(); | ||
expect(exitCode).toBe(1); | ||
}, | ||
); | ||
|
||
test('invalid JS in jest.config.ts', () => { | ||
writeFiles(DIR, { | ||
'__tests__/a-giraffe.js': "test('giraffe', () => expect(1).toBe(1));", | ||
'jest.config.ts': "export default i'll break this file yo", | ||
'package.json': '{}', | ||
}); | ||
|
||
const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false']); | ||
expect(stderr).toMatch('TSError: ⨯ Unable to compile TypeScript:'); | ||
expect(exitCode).toBe(1); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,10 +7,14 @@ | |
|
||
import {tmpdir} from 'os'; | ||
import * as path from 'path'; | ||
import * as semver from 'semver'; | ||
import {onNodeVersions} from '@jest/test-utils'; | ||
import {cleanup, writeFiles} from '../Utils'; | ||
import runJest, {getConfig} from '../runJest'; | ||
|
||
const DIR = path.resolve(tmpdir(), 'typescript-config-file'); | ||
const useNativeTypeScript = semver.satisfies(process.versions.node, '>=23.6.0'); | ||
const importFileExtension = useNativeTypeScript ? '.ts' : ''; | ||
|
||
beforeEach(() => cleanup(DIR)); | ||
afterEach(() => cleanup(DIR)); | ||
|
@@ -20,7 +24,7 @@ test('works with single typescript config that imports something', () => { | |
'__tests__/mytest.alpha.js': "test('alpha', () => expect(1).toBe(1));", | ||
'__tests__/mytest.common.js': "test('common', () => expect(1).toBe(1));", | ||
'alpha.config.ts': ` | ||
import commonRegex from './common'; | ||
import commonRegex from './common${importFileExtension}'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. transpiled resolution is fine with |
||
export default { | ||
testRegex: [ commonRegex, '__tests__/mytest.alpha.js' ] | ||
};`, | ||
|
@@ -77,12 +81,12 @@ test('works with multiple typescript configs that import something', () => { | |
'__tests__/mytest.beta.js': "test('beta', () => expect(1).toBe(1));", | ||
'__tests__/mytest.common.js': "test('common', () => expect(1).toBe(1));", | ||
'alpha.config.ts': ` | ||
import commonRegex from './common'; | ||
import commonRegex from './common${importFileExtension}'; | ||
export default { | ||
testRegex: [ commonRegex, '__tests__/mytest.alpha.js' ] | ||
};`, | ||
'beta.config.ts': ` | ||
import commonRegex from './common'; | ||
import commonRegex from './common${importFileExtension}'; | ||
export default { | ||
testRegex: [ commonRegex, '__tests__/mytest.beta.js' ] | ||
};`, | ||
|
@@ -108,18 +112,20 @@ test('works with multiple typescript configs that import something', () => { | |
expect(stdout).toBe(''); | ||
}); | ||
|
||
test("works with single typescript config that does not import anything with project's moduleResolution set to Node16", () => { | ||
const {configs} = getConfig( | ||
'typescript-config/modern-module-resolution', | ||
[], | ||
{ | ||
skipPkgJsonCheck: true, | ||
}, | ||
); | ||
onNodeVersions('<=23.6', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Node resolution modes cannot be configured via This test fails anyways, because it requires transpilation to happen - the |
||
test("works with single typescript config that does not import anything with project's moduleResolution set to Node16", () => { | ||
const {configs} = getConfig( | ||
'typescript-config/modern-module-resolution', | ||
[], | ||
{ | ||
skipPkgJsonCheck: true, | ||
}, | ||
); | ||
|
||
expect(configs).toHaveLength(1); | ||
expect(configs[0].displayName).toEqual({ | ||
color: 'white', | ||
name: 'Config from modern ts file', | ||
expect(configs).toHaveLength(1); | ||
expect(configs[0].displayName).toEqual({ | ||
color: 'white', | ||
name: 'Config from modern ts file', | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Skipping this test in new node versions since the node feature only transpiles and doesn't type check.