@@ -116,14 +116,18 @@ describe('ng-add', () => {
116116 ) ;
117117 } ) ;
118118
119- it ( 'should throw if app does not have architect configured' , async ( ) => {
119+ it ( 'should throw if app does not have build target configured' , async ( ) => {
120120 const tree = Tree . empty ( ) ;
121121 tree . create (
122122 'angular.json' ,
123123 JSON . stringify ( {
124124 version : 1 ,
125125 projects : {
126- [ PROJECT_NAME ] : { projectType : 'application' , root : PROJECT_NAME }
126+ [ PROJECT_NAME ] : {
127+ projectType : 'application' ,
128+ root : PROJECT_NAME ,
129+ architect : { }
130+ }
127131 }
128132 } )
129133 ) ;
@@ -133,7 +137,135 @@ describe('ng-add', () => {
133137 project : PROJECT_NAME
134138 } ) ( tree , { } as SchematicContext )
135139 ) . rejects . toThrowError (
136- 'Cannot read the output path (architect.build.options.outputPath) of the Angular project "THEPROJECT" in angular.json'
140+ / C a n n o t f i n d b u i l d t a r g e t f o r t h e A n g u l a r p r o j e c t /
141+ ) ;
142+ } ) ;
143+ } ) ;
144+
145+ describe ( 'Angular 17+ outputPath formats' , ( ) => {
146+ it ( 'should accept Angular 20+ projects without outputPath (uses default)' , async ( ) => {
147+ const tree = Tree . empty ( ) ;
148+ tree . create (
149+ 'angular.json' ,
150+ JSON . stringify ( {
151+ version : 1 ,
152+ projects : {
153+ [ PROJECT_NAME ] : {
154+ projectType : 'application' ,
155+ root : PROJECT_ROOT ,
156+ architect : {
157+ build : {
158+ builder : '@angular/build:application' ,
159+ options : {
160+ // Angular 20+ omits outputPath - uses sensible default
161+ }
162+ }
163+ }
164+ }
165+ }
166+ } )
167+ ) ;
168+
169+ const result = await ngAdd ( { project : PROJECT_NAME } ) (
170+ tree ,
171+ { } as SchematicContext
172+ ) ;
173+
174+ const resultConfig = readJSONFromTree ( result , 'angular.json' ) ;
175+ const deployTarget = resultConfig . projects [ PROJECT_NAME ] . architect . deploy ;
176+ expect ( deployTarget . builder ) . toBe ( 'angular-cli-ghpages:deploy' ) ;
177+ } ) ;
178+
179+ it ( 'should accept outputPath as object with base property' , async ( ) => {
180+ const tree = Tree . empty ( ) ;
181+ tree . create (
182+ 'angular.json' ,
183+ JSON . stringify ( {
184+ version : 1 ,
185+ projects : {
186+ [ PROJECT_NAME ] : {
187+ projectType : 'application' ,
188+ root : PROJECT_ROOT ,
189+ architect : {
190+ build : {
191+ options : {
192+ outputPath : { base : 'dist/my-app' , browser : '' }
193+ }
194+ }
195+ }
196+ }
197+ }
198+ } )
199+ ) ;
200+
201+ const result = await ngAdd ( { project : PROJECT_NAME } ) (
202+ tree ,
203+ { } as SchematicContext
204+ ) ;
205+
206+ const resultConfig = readJSONFromTree ( result , 'angular.json' ) ;
207+ const deployTarget = resultConfig . projects [ PROJECT_NAME ] . architect . deploy ;
208+ expect ( deployTarget . builder ) . toBe ( 'angular-cli-ghpages:deploy' ) ;
209+ } ) ;
210+
211+ it ( 'should accept outputPath object with base and browser properties' , async ( ) => {
212+ const tree = Tree . empty ( ) ;
213+ tree . create (
214+ 'angular.json' ,
215+ JSON . stringify ( {
216+ version : 1 ,
217+ projects : {
218+ [ PROJECT_NAME ] : {
219+ projectType : 'application' ,
220+ root : PROJECT_ROOT ,
221+ architect : {
222+ build : {
223+ options : {
224+ outputPath : { base : 'dist/app' , browser : 'browser' , server : 'server' }
225+ }
226+ }
227+ }
228+ }
229+ }
230+ } )
231+ ) ;
232+
233+ const result = await ngAdd ( { project : PROJECT_NAME } ) (
234+ tree ,
235+ { } as SchematicContext
236+ ) ;
237+
238+ const resultConfig = readJSONFromTree ( result , 'angular.json' ) ;
239+ const deployTarget = resultConfig . projects [ PROJECT_NAME ] . architect . deploy ;
240+ expect ( deployTarget . builder ) . toBe ( 'angular-cli-ghpages:deploy' ) ;
241+ } ) ;
242+
243+ it ( 'should reject invalid outputPath object without base property' , async ( ) => {
244+ const tree = Tree . empty ( ) ;
245+ tree . create (
246+ 'angular.json' ,
247+ JSON . stringify ( {
248+ version : 1 ,
249+ projects : {
250+ [ PROJECT_NAME ] : {
251+ projectType : 'application' ,
252+ root : PROJECT_ROOT ,
253+ architect : {
254+ build : {
255+ options : {
256+ outputPath : { browser : 'browser' } // missing base - invalid
257+ }
258+ }
259+ }
260+ }
261+ }
262+ } )
263+ ) ;
264+
265+ await expect (
266+ ngAdd ( { project : PROJECT_NAME } ) ( tree , { } as SchematicContext )
267+ ) . rejects . toThrowError (
268+ / I n v a l i d o u t p u t P a t h c o n f i g u r a t i o n .* E x p e c t e d u n d e f i n e d .* a s t r i n g .* a n o b j e c t w i t h a " b a s e " p r o p e r t y /
137269 ) ;
138270 } ) ;
139271 } ) ;
0 commit comments