Skip to content

Commit a727bd5

Browse files
feat(config): support multiple paths for pathsToModuleNameMapper (#1690)
1 parent 6f059b4 commit a727bd5

11 files changed

Lines changed: 69 additions & 19 deletions

File tree

e2e/__external-repos__/simple-project-references/jest.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
/** @type {import('@jest/types').Config.InitialOptions} */
22
/** @typedef {import('ts-jest')} */
33

4+
const { pathsToModuleNameMapper } = require('ts-jest/utils');
5+
const { compilerOptions } = require('./tsconfig-base');
6+
47
module.exports = {
58
preset: 'ts-jest',
69
testEnvironment: 'node',
710
// Ignore the TS project `outDir`
811
// https://github.com/kulshekhar/ts-jest/issues/765
912
testPathIgnorePatterns: ['<rootDir>/target/'],
13+
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/' }),
1014
globals: {
1115
'ts-jest': {
1216
isolatedModules: true,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { divide } from '~'
2+
import { divide as _divide } from '~/divide'
3+
4+
test('imports same divide function', () => {
5+
expect(_divide).toBe(divide)
6+
})
7+
8+
test('divides 3 / 2 to equal 1.5', () => {
9+
expect(divide(3, 2)).toBe(1.5)
10+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { multiply } from '@/multiply'
2+
3+
test('multiplies 2 * 2 to equal 4', () => {
4+
expect(multiply(2, 2)).toBe(4)
5+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { subtract } from '@/subtract'
2+
3+
test('subtracts 3 - 1 to equal 2', () => {
4+
expect(subtract(3, 1)).toBe(2)
5+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import divide from 'lodash/divide'
2+
3+
export { divide }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import multiply from 'lodash/multiply'
2+
3+
export { multiply }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import subtract from 'lodash/subtract'
2+
3+
export { subtract }

e2e/__external-repos__/simple-project-references/tsconfig-base.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@
1111
"rootDir": "./src/",
1212
"types": [],
1313
"allowSyntheticDefaultImports": true,
14-
"esModuleInterop": true
14+
"esModuleInterop": true,
15+
"baseUrl": ".",
16+
"paths": {
17+
"@/*": [
18+
"src/nested/*",
19+
"src/nested/src/*"
20+
],
21+
"~": [
22+
"src/math/divide.ts"
23+
],
24+
"~/*": [
25+
"src/math/*"
26+
]
27+
}
1528
}
1629
}

src/config/paths-to-module-name-mapper.spec.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,31 @@ import { pathsToModuleNameMapper } from './paths-to-module-name-mapper'
55
const tsconfigMap = {
66
log: ['src/util/log'],
77
server: ['src/server'],
8+
client: ['src/client', 'src/client/index'],
89
'util/*': ['src/util/*'],
910
'api/*': ['src/api/*'],
1011
'test/*': ['test/*'],
1112
'mocks/*': ['test/mocks/*'],
12-
'test/*/mock': ['test/mocks/*'],
13+
'test/*/mock': ['test/mocks/*', 'test/__mocks__/*'],
1314
}
1415

1516
describe('pathsToModuleNameMapper', () => {
1617
it('should convert tsconfig mapping', () => {
1718
expect(pathsToModuleNameMapper(tsconfigMap)).toMatchInlineSnapshot(`
1819
Object {
1920
"^api/(.*)$": "src/api/$1",
21+
"^client$": Array [
22+
"src/client",
23+
"src/client/index",
24+
],
2025
"^log$": "src/util/log",
2126
"^mocks/(.*)$": "test/mocks/$1",
2227
"^server$": "src/server",
2328
"^test/(.*)$": "test/$1",
24-
"^test/(.*)/mock$": "test/mocks/$1",
29+
"^test/(.*)/mock$": Array [
30+
"test/mocks/$1",
31+
"test/__mocks__/$1",
32+
],
2533
"^util/(.*)$": "src/util/$1",
2634
}
2735
`)
@@ -31,11 +39,18 @@ Object {
3139
expect(pathsToModuleNameMapper(tsconfigMap, { prefix: '<rootDir>/' })).toMatchInlineSnapshot(`
3240
Object {
3341
"^api/(.*)$": "<rootDir>/src/api/$1",
42+
"^client$": Array [
43+
"<rootDir>/src/client",
44+
"<rootDir>/src/client/index",
45+
],
3446
"^log$": "<rootDir>/src/util/log",
3547
"^mocks/(.*)$": "<rootDir>/test/mocks/$1",
3648
"^server$": "<rootDir>/src/server",
3749
"^test/(.*)$": "<rootDir>/test/$1",
38-
"^test/(.*)/mock$": "<rootDir>/test/mocks/$1",
50+
"^test/(.*)/mock$": Array [
51+
"<rootDir>/test/mocks/$1",
52+
"<rootDir>/test/__mocks__/$1",
53+
],
3954
"^util/(.*)$": "<rootDir>/src/util/$1",
4055
}
4156
`)
@@ -48,20 +63,16 @@ Object {
4863
pathsToModuleNameMapper({
4964
kept: ['src/kept'],
5065
'no-target': [],
51-
'too-many-target': ['one', 'two'],
5266
'too/*/many/*/stars': ['to/*/many/*/stars'],
5367
}),
5468
).toMatchInlineSnapshot(`
5569
Object {
5670
"^kept$": "src/kept",
57-
"^too\\\\-many\\\\-target$": "one",
5871
}
5972
`)
6073
expect(log.lines.warn).toMatchInlineSnapshot(`
6174
Array [
6275
"[level:40] Not mapping \\"no-target\\" because it has no target.
63-
",
64-
"[level:40] Mapping only to first target of \\"too-many-target\\" because it has more than one (2).
6576
",
6677
"[level:40] Not mapping \\"too/*/many/*/stars\\" because it has more than one star (\`*\`).
6778
",

src/config/paths-to-module-name-mapper.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,18 @@ export const pathsToModuleNameMapper = (
2626
if (toPaths.length === 0) {
2727
logger.warn(interpolate(Errors.NotMappingPathWithEmptyMap, { path: fromPath }))
2828
continue
29-
} else if (toPaths.length > 1) {
30-
logger.warn(
31-
interpolate(Errors.MappingOnlyFirstTargetOfPath, {
32-
path: fromPath,
33-
count: toPaths.length,
34-
}),
35-
)
3629
}
37-
const target = toPaths[0]
3830

3931
// split with '*'
4032
const segments = fromPath.split(/\*/g)
4133
if (segments.length === 1) {
34+
const paths = toPaths.map((target) => `${prefix}${target}`)
4235
pattern = `^${escapeRegex(fromPath)}$`
43-
jestMap[pattern] = `${prefix}${target}`
36+
jestMap[pattern] = paths.length === 1 ? paths[0] : paths
4437
} else if (segments.length === 2) {
38+
const paths = toPaths.map((target) => `${prefix}${target.replace(/\*/g, '$1')}`)
4539
pattern = `^${escapeRegex(segments[0])}(.*)${escapeRegex(segments[1])}$`
46-
jestMap[pattern] = `${prefix}${target.replace(/\*/g, '$1')}`
40+
jestMap[pattern] = paths.length === 1 ? paths[0] : paths
4741
} else {
4842
logger.warn(interpolate(Errors.NotMappingMultiStarPath, { path: fromPath }))
4943
continue

0 commit comments

Comments
 (0)