diff --git a/e2e/__external-repos__/simple-project-references/jest.config.js b/e2e/__external-repos__/simple-project-references/jest.config.js index 1942d9a712..18ff5f36d5 100644 --- a/e2e/__external-repos__/simple-project-references/jest.config.js +++ b/e2e/__external-repos__/simple-project-references/jest.config.js @@ -1,12 +1,16 @@ /** @type {import('@jest/types').Config.InitialOptions} */ /** @typedef {import('ts-jest')} */ +const { pathsToModuleNameMapper } = require('ts-jest/utils'); +const { compilerOptions } = require('./tsconfig-base'); + module.exports = { preset: 'ts-jest', testEnvironment: 'node', // Ignore the TS project `outDir` // https://github.com/kulshekhar/ts-jest/issues/765 testPathIgnorePatterns: ['/target/'], + moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/' }), globals: { 'ts-jest': { isolatedModules: true, diff --git a/e2e/__external-repos__/simple-project-references/src/__tests__/divide.ts b/e2e/__external-repos__/simple-project-references/src/__tests__/divide.ts new file mode 100644 index 0000000000..a83fa96f0f --- /dev/null +++ b/e2e/__external-repos__/simple-project-references/src/__tests__/divide.ts @@ -0,0 +1,10 @@ +import { divide } from '~' +import { divide as _divide } from '~/divide' + +test('imports same divide function', () => { + expect(_divide).toBe(divide) +}) + +test('divides 3 / 2 to equal 1.5', () => { + expect(divide(3, 2)).toBe(1.5) +}) diff --git a/e2e/__external-repos__/simple-project-references/src/__tests__/multiply.ts b/e2e/__external-repos__/simple-project-references/src/__tests__/multiply.ts new file mode 100644 index 0000000000..2162500b7c --- /dev/null +++ b/e2e/__external-repos__/simple-project-references/src/__tests__/multiply.ts @@ -0,0 +1,5 @@ +import { multiply } from '@/multiply' + +test('multiplies 2 * 2 to equal 4', () => { + expect(multiply(2, 2)).toBe(4) +}) diff --git a/e2e/__external-repos__/simple-project-references/src/__tests__/subtract.ts b/e2e/__external-repos__/simple-project-references/src/__tests__/subtract.ts new file mode 100644 index 0000000000..9455bd3067 --- /dev/null +++ b/e2e/__external-repos__/simple-project-references/src/__tests__/subtract.ts @@ -0,0 +1,5 @@ +import { subtract } from '@/subtract' + +test('subtracts 3 - 1 to equal 2', () => { + expect(subtract(3, 1)).toBe(2) +}) diff --git a/e2e/__external-repos__/simple-project-references/src/math/divide.ts b/e2e/__external-repos__/simple-project-references/src/math/divide.ts new file mode 100644 index 0000000000..7e72575935 --- /dev/null +++ b/e2e/__external-repos__/simple-project-references/src/math/divide.ts @@ -0,0 +1,3 @@ +import divide from 'lodash/divide' + +export { divide } diff --git a/e2e/__external-repos__/simple-project-references/src/nested/src/multiply.ts b/e2e/__external-repos__/simple-project-references/src/nested/src/multiply.ts new file mode 100644 index 0000000000..eabf98d6ab --- /dev/null +++ b/e2e/__external-repos__/simple-project-references/src/nested/src/multiply.ts @@ -0,0 +1,3 @@ +import multiply from 'lodash/multiply' + +export { multiply } diff --git a/e2e/__external-repos__/simple-project-references/src/nested/subtract.ts b/e2e/__external-repos__/simple-project-references/src/nested/subtract.ts new file mode 100644 index 0000000000..f329a6fb22 --- /dev/null +++ b/e2e/__external-repos__/simple-project-references/src/nested/subtract.ts @@ -0,0 +1,3 @@ +import subtract from 'lodash/subtract' + +export { subtract } diff --git a/e2e/__external-repos__/simple-project-references/tsconfig-base.json b/e2e/__external-repos__/simple-project-references/tsconfig-base.json index 1a5cd690cb..5d975f771b 100644 --- a/e2e/__external-repos__/simple-project-references/tsconfig-base.json +++ b/e2e/__external-repos__/simple-project-references/tsconfig-base.json @@ -11,6 +11,19 @@ "rootDir": "./src/", "types": [], "allowSyntheticDefaultImports": true, - "esModuleInterop": true + "esModuleInterop": true, + "baseUrl": ".", + "paths": { + "@/*": [ + "src/nested/*", + "src/nested/src/*" + ], + "~": [ + "src/math/divide.ts" + ], + "~/*": [ + "src/math/*" + ] + } } } diff --git a/src/config/paths-to-module-name-mapper.spec.ts b/src/config/paths-to-module-name-mapper.spec.ts index 34b8210ad3..a88301355c 100644 --- a/src/config/paths-to-module-name-mapper.spec.ts +++ b/src/config/paths-to-module-name-mapper.spec.ts @@ -5,11 +5,12 @@ import { pathsToModuleNameMapper } from './paths-to-module-name-mapper' const tsconfigMap = { log: ['src/util/log'], server: ['src/server'], + client: ['src/client', 'src/client/index'], 'util/*': ['src/util/*'], 'api/*': ['src/api/*'], 'test/*': ['test/*'], 'mocks/*': ['test/mocks/*'], - 'test/*/mock': ['test/mocks/*'], + 'test/*/mock': ['test/mocks/*', 'test/__mocks__/*'], } describe('pathsToModuleNameMapper', () => { @@ -17,11 +18,18 @@ describe('pathsToModuleNameMapper', () => { expect(pathsToModuleNameMapper(tsconfigMap)).toMatchInlineSnapshot(` Object { "^api/(.*)$": "src/api/$1", + "^client$": Array [ + "src/client", + "src/client/index", + ], "^log$": "src/util/log", "^mocks/(.*)$": "test/mocks/$1", "^server$": "src/server", "^test/(.*)$": "test/$1", - "^test/(.*)/mock$": "test/mocks/$1", + "^test/(.*)/mock$": Array [ + "test/mocks/$1", + "test/__mocks__/$1", + ], "^util/(.*)$": "src/util/$1", } `) @@ -31,11 +39,18 @@ Object { expect(pathsToModuleNameMapper(tsconfigMap, { prefix: '/' })).toMatchInlineSnapshot(` Object { "^api/(.*)$": "/src/api/$1", + "^client$": Array [ + "/src/client", + "/src/client/index", + ], "^log$": "/src/util/log", "^mocks/(.*)$": "/test/mocks/$1", "^server$": "/src/server", "^test/(.*)$": "/test/$1", - "^test/(.*)/mock$": "/test/mocks/$1", + "^test/(.*)/mock$": Array [ + "/test/mocks/$1", + "/test/__mocks__/$1", + ], "^util/(.*)$": "/src/util/$1", } `) @@ -48,20 +63,16 @@ Object { pathsToModuleNameMapper({ kept: ['src/kept'], 'no-target': [], - 'too-many-target': ['one', 'two'], 'too/*/many/*/stars': ['to/*/many/*/stars'], }), ).toMatchInlineSnapshot(` Object { "^kept$": "src/kept", - "^too\\\\-many\\\\-target$": "one", } `) expect(log.lines.warn).toMatchInlineSnapshot(` Array [ "[level:40] Not mapping \\"no-target\\" because it has no target. -", - "[level:40] Mapping only to first target of \\"too-many-target\\" because it has more than one (2). ", "[level:40] Not mapping \\"too/*/many/*/stars\\" because it has more than one star (\`*\`). ", diff --git a/src/config/paths-to-module-name-mapper.ts b/src/config/paths-to-module-name-mapper.ts index d41f3fc322..e06a03831f 100644 --- a/src/config/paths-to-module-name-mapper.ts +++ b/src/config/paths-to-module-name-mapper.ts @@ -26,24 +26,18 @@ export const pathsToModuleNameMapper = ( if (toPaths.length === 0) { logger.warn(interpolate(Errors.NotMappingPathWithEmptyMap, { path: fromPath })) continue - } else if (toPaths.length > 1) { - logger.warn( - interpolate(Errors.MappingOnlyFirstTargetOfPath, { - path: fromPath, - count: toPaths.length, - }), - ) } - const target = toPaths[0] // split with '*' const segments = fromPath.split(/\*/g) if (segments.length === 1) { + const paths = toPaths.map((target) => `${prefix}${target}`) pattern = `^${escapeRegex(fromPath)}$` - jestMap[pattern] = `${prefix}${target}` + jestMap[pattern] = paths.length === 1 ? paths[0] : paths } else if (segments.length === 2) { + const paths = toPaths.map((target) => `${prefix}${target.replace(/\*/g, '$1')}`) pattern = `^${escapeRegex(segments[0])}(.*)${escapeRegex(segments[1])}$` - jestMap[pattern] = `${prefix}${target.replace(/\*/g, '$1')}` + jestMap[pattern] = paths.length === 1 ? paths[0] : paths } else { logger.warn(interpolate(Errors.NotMappingMultiStarPath, { path: fromPath })) continue diff --git a/src/util/messages.ts b/src/util/messages.ts index fc3873179a..b62fe8b8f8 100644 --- a/src/util/messages.ts +++ b/src/util/messages.ts @@ -12,7 +12,6 @@ export const enum Errors { UnableToCompileTypeScript = '{{diagnostics}}', NotMappingMultiStarPath = 'Not mapping "{{path}}" because it has more than one star (`*`).', NotMappingPathWithEmptyMap = 'Not mapping "{{path}}" because it has no target.', - MappingOnlyFirstTargetOfPath = 'Mapping only to first target of "{{path}}" because it has more than one ({{count}}).', GotJsFileButAllowJsFalse = 'Got a `.js` file to compile while `allowJs` option is not set to `true` (file: {{path}}). To fix this:\n - if you want TypeScript to process JS files, set `allowJs` to `true` in your TypeScript config (usually tsconfig.json)\n - if you do not want TypeScript to process your `.js` files, in your Jest config change the `transform` key which value is `ts-jest` so that it does not match `.js` files anymore', GotUnknownFileTypeWithoutBabel = 'Got a unknown file type to compile (file: {{path}}). To fix this, in your Jest config change the `transform` key which value is `ts-jest` so that it does not match this kind of files anymore.', GotUnknownFileTypeWithBabel = 'Got a unknown file type to compile (file: {{path}}). To fix this, in your Jest config change the `transform` key which value is `ts-jest` so that it does not match this kind of files anymore. If you still want Babel to process it, add another entry to the `transform` option with value `babel-jest` which key matches this type of files.',