@@ -47,49 +47,88 @@ async function addBrowserslistConfig(projectRoot: string): Promise<Rule> {
4747}
4848
4949function addKarmaConfig ( options : ConfigOptions ) : Rule {
50- return updateWorkspace ( ( workspace ) => {
51- const project = workspace . projects . get ( options . project ) ;
52- if ( ! project ) {
53- throw new SchematicsException ( `Project name "${ options . project } " doesn't not exist.` ) ;
54- }
50+ return ( _ , context ) =>
51+ updateWorkspace ( ( workspace ) => {
52+ const project = workspace . projects . get ( options . project ) ;
53+ if ( ! project ) {
54+ throw new SchematicsException ( `Project name "${ options . project } " doesn't not exist.` ) ;
55+ }
5556
56- const testTarget = project . targets . get ( 'test' ) ;
57- if ( ! testTarget ) {
58- throw new SchematicsException (
59- `No "test" target found for project "${ options . project } ".` +
60- ' A "test" target is required to generate a karma configuration.' ,
61- ) ;
62- }
57+ const testTarget = project . targets . get ( 'test' ) ;
58+ if ( ! testTarget ) {
59+ throw new SchematicsException (
60+ `No "test" target found for project "${ options . project } ".` +
61+ ' A "test" target is required to generate a karma configuration.' ,
62+ ) ;
63+ }
6364
64- if (
65- testTarget . builder !== AngularBuilder . Karma &&
66- testTarget . builder !== AngularBuilder . BuildKarma
67- ) {
68- throw new SchematicsException (
69- `Cannot add a karma configuration as builder for "test" target in project does not` +
70- ` use "${ AngularBuilder . Karma } " or "${ AngularBuilder . BuildKarma } ".` ,
71- ) ;
72- }
65+ if (
66+ testTarget . builder !== AngularBuilder . Karma &&
67+ testTarget . builder !== AngularBuilder . BuildKarma &&
68+ testTarget . builder !== AngularBuilder . BuildUnitTest
69+ ) {
70+ throw new SchematicsException (
71+ `Cannot add a karma configuration as builder for "test" target in project does not` +
72+ ` use "${ AngularBuilder . Karma } ", "${ AngularBuilder . BuildKarma } ", or ${ AngularBuilder . BuildUnitTest } .` ,
73+ ) ;
74+ }
75+
76+ testTarget . options ??= { } ;
77+ if ( testTarget . builder !== AngularBuilder . BuildUnitTest ) {
78+ testTarget . options . karmaConfig = path . join ( project . root , 'karma.conf.js' ) ;
79+ } else {
80+ // `unit-test` uses the `runnerConfig` option which has configuration discovery if enabled
81+ testTarget . options . runnerConfig = true ;
7382
74- testTarget . options ??= { } ;
75- testTarget . options . karmaConfig = path . join ( project . root , 'karma.conf.js' ) ;
83+ let isKarmaRunnerConfigured = false ;
84+ // Check runner option
85+ if ( testTarget . options . runner ) {
86+ if ( testTarget . options . runner === 'karma' ) {
87+ isKarmaRunnerConfigured = true ;
88+ } else {
89+ context . logger . warn (
90+ `The "test" target is configured to use a runner other than "karma" in the main options.` +
91+ ' The generated "karma.conf.js" file may not be used.' ,
92+ ) ;
93+ }
94+ }
7695
77- // If scoped project (i.e. "@foo/bar"), convert dir to "foo/bar".
78- let folderName = options . project . startsWith ( '@' ) ? options . project . slice ( 1 ) : options . project ;
79- if ( / [ A - Z ] / . test ( folderName ) ) {
80- folderName = strings . dasherize ( folderName ) ;
81- }
96+ for ( const [ name , config ] of Object . entries ( testTarget . configurations ?? { } ) ) {
97+ if ( config && typeof config === 'object' && 'runner' in config ) {
98+ if ( config . runner !== 'karma' ) {
99+ context . logger . warn (
100+ `The "test" target's "${ name } " configuration is configured to use a runner other than "karma".` +
101+ ' The generated "karma.conf.js" file may not be used for that configuration.' ,
102+ ) ;
103+ } else {
104+ isKarmaRunnerConfigured = true ;
105+ }
106+ }
107+ }
82108
83- return mergeWith (
84- apply ( url ( './files' ) , [
85- filter ( ( p ) => p . endsWith ( 'karma.conf.js.template' ) ) ,
86- applyTemplates ( {
87- relativePathToWorkspaceRoot : relativePathToWorkspaceRoot ( project . root ) ,
88- folderName,
89- needDevkitPlugin : testTarget . builder === AngularBuilder . Karma ,
90- } ) ,
91- move ( project . root ) ,
92- ] ) ,
93- ) ;
94- } ) ;
109+ if ( ! isKarmaRunnerConfigured ) {
110+ context . logger . warn (
111+ `The "test" target is not explicitly configured to use the "karma" runner.` +
112+ ' The generated "karma.conf.js" file may not be used as the default runner is "vitest".' ,
113+ ) ;
114+ }
115+ }
116+ // If scoped project (i.e. "@foo/bar"), convert dir to "foo/bar".
117+ let folderName = options . project . startsWith ( '@' ) ? options . project . slice ( 1 ) : options . project ;
118+ if ( / [ A - Z ] / . test ( folderName ) ) {
119+ folderName = strings . dasherize ( folderName ) ;
120+ }
121+
122+ return mergeWith (
123+ apply ( url ( './files' ) , [
124+ filter ( ( p ) => p . endsWith ( 'karma.conf.js.template' ) ) ,
125+ applyTemplates ( {
126+ relativePathToWorkspaceRoot : relativePathToWorkspaceRoot ( project . root ) ,
127+ folderName,
128+ needDevkitPlugin : testTarget . builder === AngularBuilder . Karma ,
129+ } ) ,
130+ move ( project . root ) ,
131+ ] ) ,
132+ ) ;
133+ } ) ;
95134}
0 commit comments