-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathjest.config.ts
More file actions
131 lines (116 loc) · 4.25 KB
/
Copy pathjest.config.ts
File metadata and controls
131 lines (116 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import type { Config } from 'jest'
import { readFileSync, existsSync } from 'fs'
import { join } from 'path'
// list of patterns for which no transformation/transpiling should be made
const ignoredModulePatterns: string = ['d3-.*', '(.*.mjs$)'].join('|')
// list of patterns excluded by testing/coverage (default: node_modules)
const ignoredPathPatterns: string[] = [
'<rootDir>/pre_loaders/',
'<rootDir>/src/main.ts',
'<rootDir>/src/bootstrap.ts',
'<rootDir>/src/scope-polyfill',
'<rootDir>/src/app/shared/generated'
]
/**
* Scans installed packages for subpath exports that lack physical directories.
* Generates tsconfig paths (for TS compilation) and moduleNameMapper entries (for Jest runtime).
* This avoids manually adding path mappings whenever a new subpath import is used.
*/
function resolvePackageExports(rootDir: string) {
const pkgJson = JSON.parse(readFileSync(join(rootDir, 'package.json'), 'utf-8'))
const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies }
const tsPaths: Record<string, string[]> = {}
const moduleNameMapper: Record<string, string> = {}
for (const pkgName of Object.keys(allDeps)) {
let depPkg: any
try {
depPkg = JSON.parse(readFileSync(join(rootDir, 'node_modules', pkgName, 'package.json'), 'utf-8'))
} catch {
continue
}
const exports = depPkg.exports
if (!exports || typeof exports !== 'object') continue
for (const [subpath, mapping] of Object.entries(exports)) {
if (subpath === '.' || subpath === './package.json' || subpath.includes('*')) continue
const subpathClean = subpath.replace(/^\.\//, '')
const importSpecifier = `${pkgName}/${subpathClean}`
// Only generate mappings when there is no physical path (standard resolution would fail)
const physicalPath = join(rootDir, 'node_modules', pkgName, subpathClean)
if (existsSync(physicalPath) || existsSync(physicalPath + '.js') || existsSync(physicalPath + '.d.ts')) {
continue
}
let types: string | undefined
let defaultExport: string | undefined
if (typeof mapping === 'string') {
defaultExport = mapping
} else if (mapping && typeof mapping === 'object') {
const m = mapping as Record<string, any>
types = m['types']
defaultExport = m['default']
}
if (types) {
tsPaths[importSpecifier] = [`./node_modules/${pkgName}/${types.replace(/^\.\//, '')}`]
}
if (defaultExport) {
const escaped = importSpecifier.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
moduleNameMapper[`^${escaped}$`] = `<rootDir>/node_modules/${pkgName}/${defaultExport.replace(/^\.\//, '')}`
}
}
}
return { tsPaths, moduleNameMapper }
}
const { tsPaths, moduleNameMapper: exportMapper } = resolvePackageExports(process.cwd())
const config: Config = {
displayName: 'onecx-shell-ui',
silent: true,
verbose: false,
testEnvironment: 'jsdom',
preset: './jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment'
],
testMatch: ['<rootDir>/src/app/**/*.spec.ts'],
testPathIgnorePatterns: ignoredPathPatterns,
// transformation
moduleNameMapper: {
...exportMapper
},
transformIgnorePatterns: [`node_modules/(?!${ignoredModulePatterns})`],
transform: {
'^.+\\.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: {
esModuleInterop: true,
outDir: './dist/out-tsc',
target: 'es2016',
module: 'esnext',
types: ['jest', 'node'],
paths: tsPaths
},
stringifyContentPathRegex: '\\.(html|svg)$'
}
]
},
// reporting
collectCoverage: true,
coverageDirectory: '<rootDir>/reports/coverage/',
coveragePathIgnorePatterns: ignoredPathPatterns,
coverageReporters: ['json', 'text', 'lcov', 'text-summary', 'html'],
testResultsProcessor: 'jest-sonar-reporter',
reporters: [
'default',
[
'jest-sonar',
{
outputDirectory: 'reports',
outputName: 'sonarqube_report.xml',
reportedFilePath: 'absolute'
}
]
]
}
export default config