|
8 | 8 |
|
9 | 9 | import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
|
10 | 10 | import { execFile as execFileCb } from 'child_process';
|
| 11 | +import { promises as fs } from 'fs'; |
11 | 12 | import * as path from 'path';
|
12 | 13 | import { promisify } from 'util';
|
13 | 14 | import { colors } from '../../utils/color';
|
@@ -54,8 +55,25 @@ export default createBuilder(
|
54 | 55 | };
|
55 | 56 | }
|
56 | 57 |
|
| 58 | + const [testFiles, customConfig] = await Promise.all([ |
| 59 | + findTestFiles(options.include, options.exclude, context.workspaceRoot), |
| 60 | + findCustomJestConfig(context.workspaceRoot), |
| 61 | + ]); |
| 62 | + |
| 63 | + // Warn if a custom Jest configuration is found. We won't use it, so if a developer is trying to use a custom config, this hopefully |
| 64 | + // makes a better experience than silently ignoring the configuration. |
| 65 | + // Ideally, this would be a hard error. However a Jest config could exist for testing other files in the workspace outside of Angular |
| 66 | + // CLI, so we likely can't produce a hard error in this situation without an opt-out. |
| 67 | + if (customConfig) { |
| 68 | + context.logger.warn( |
| 69 | + 'A custom Jest config was found, but this is not supported by `@angular-devkit/build-angular:jest` and will be' + |
| 70 | + ` ignored: ${customConfig}. This is an experiment to see if completely abstracting away Jest's configuration is viable. Please` + |
| 71 | + ` consider if your use case can be met without directly modifying the Jest config. If this is a major obstacle for your use` + |
| 72 | + ` case, please post it in this issue so we can collect feedback and evaluate: https://github.com/angular/angular-cli/issues/25434.`, |
| 73 | + ); |
| 74 | + } |
| 75 | + |
57 | 76 | // Build all the test files.
|
58 |
| - const testFiles = await findTestFiles(options.include, options.exclude, context.workspaceRoot); |
59 | 77 | const jestGlobal = path.join(__dirname, 'jest-global.mjs');
|
60 | 78 | const initTestBed = path.join(__dirname, 'init-test-bed.mjs');
|
61 | 79 | const buildResult = await build(context, {
|
@@ -85,6 +103,7 @@ export default createBuilder(
|
85 | 103 | jest,
|
86 | 104 |
|
87 | 105 | `--rootDir="${path.join(testOut, 'browser')}"`,
|
| 106 | + `--config=${path.join(__dirname, 'jest.config.mjs')}`, |
88 | 107 | '--testEnvironment=jsdom',
|
89 | 108 |
|
90 | 109 | // TODO(dgp1130): Enable cache once we have a mechanism for properly clearing / disabling it.
|
@@ -162,3 +181,17 @@ function resolveModule(module: string): string | undefined {
|
162 | 181 | return undefined;
|
163 | 182 | }
|
164 | 183 | }
|
| 184 | + |
| 185 | +/** Returns whether or not the provided directory includes a Jest configuration file. */ |
| 186 | +async function findCustomJestConfig(dir: string): Promise<string | undefined> { |
| 187 | + const entries = await fs.readdir(dir, { withFileTypes: true }); |
| 188 | + |
| 189 | + // Jest supports many file extensions (`js`, `ts`, `cjs`, `cts`, `json`, etc.) Just look |
| 190 | + // for anything with that prefix. |
| 191 | + const config = entries.find((entry) => entry.isFile() && entry.name.startsWith('jest.config.')); |
| 192 | + if (!config) { |
| 193 | + return undefined; |
| 194 | + } |
| 195 | + |
| 196 | + return path.join(dir, config.name); |
| 197 | +} |
0 commit comments