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