@@ -378,6 +378,80 @@ describe('PackageManager', () => {
378378 } ) ;
379379 } ) ;
380380
381+ describe ( 'getCurrentPackageName' , ( ) => {
382+ it ( 'should return the name from package.json without running the package manager command' , async ( ) => {
383+ const pm = new PackageManager ( host , '/repo/app' , descriptor ) ;
384+ const readFileSpy = spyOn ( host , 'readFile' ) . and . resolveTo ( '{"name": "app"}' ) ;
385+
386+ expect ( await pm . getCurrentPackageName ( ) ) . toBe ( 'app' ) ;
387+ expect ( readFileSpy ) . toHaveBeenCalledWith ( jasmine . stringMatching ( / p a c k a g e \. j s o n $ / ) ) ;
388+ expect ( runCommandSpy ) . not . toHaveBeenCalled ( ) ;
389+ } ) ;
390+
391+ it ( 'should fall back to the package manager command when reading package.json fails' , async ( ) => {
392+ const pm = new PackageManager ( host , '/repo/app/src' , descriptor ) ;
393+ spyOn ( host , 'readFile' ) . and . rejectWith ( new Error ( 'ENOENT' ) ) ;
394+ runCommandSpy . and . resolveTo ( { stdout : '"app"' , stderr : '' } ) ;
395+
396+ expect ( await pm . getCurrentPackageName ( ) ) . toBe ( 'app' ) ;
397+ expect ( runCommandSpy ) . toHaveBeenCalledWith (
398+ descriptor . binary ,
399+ descriptor . getPackageNameCommand ,
400+ jasmine . objectContaining ( { cwd : '/repo/app/src' } ) ,
401+ ) ;
402+ } ) ;
403+
404+ it ( 'should extract the package name when npm prints a single-entry workspace object' , async ( ) => {
405+ const pm = new PackageManager ( host , '/repo/apps/app/src' , descriptor ) ;
406+ spyOn ( host , 'readFile' ) . and . rejectWith ( new Error ( 'ENOENT' ) ) ;
407+ // Inside a workspace member, `npm pkg get name` prints `{ "app": "app" }` instead of `"app"`.
408+ runCommandSpy . and . resolveTo ( { stdout : '{\n "app": "app"\n}' , stderr : '' } ) ;
409+
410+ expect ( await pm . getCurrentPackageName ( ) ) . toBe ( 'app' ) ;
411+ } ) ;
412+
413+ it ( 'should return undefined when npm prints multiple workspace entries and package.json is unavailable' , async ( ) => {
414+ const pm = new PackageManager ( host , '/repo' , descriptor ) ;
415+ spyOn ( host , 'readFile' ) . and . rejectWith ( new Error ( 'ENOENT' ) ) ;
416+ runCommandSpy . and . resolveTo ( {
417+ stdout : '{\n "app-a": "app-a",\n "app-b": "app-b"\n}' ,
418+ stderr : '' ,
419+ } ) ;
420+
421+ expect ( await pm . getCurrentPackageName ( ) ) . toBeUndefined ( ) ;
422+ } ) ;
423+ } ) ;
424+
425+ describe ( 'getProjectDependencies' , ( ) => {
426+ it ( 'should list the dependencies of an npm workspace member' , async ( ) => {
427+ const pm = new PackageManager ( host , '/repo/apps/app' , descriptor ) ;
428+ runCommandSpy . and . callFake ( ( _binary : string , args : readonly string [ ] ) =>
429+ Promise . resolve ( {
430+ stdout :
431+ args [ 0 ] === 'pkg'
432+ ? '{\n "app": "app"\n}'
433+ : JSON . stringify ( {
434+ name : 'monorepo' ,
435+ dependencies : {
436+ app : {
437+ version : '0.0.0' ,
438+ resolved : 'file:../apps/app' ,
439+ dependencies : { '@angular/core' : { version : '22.0.0' } } ,
440+ } ,
441+ } ,
442+ } ) ,
443+ stderr : '' ,
444+ } ) ,
445+ ) ;
446+ spyOn ( host , 'readFile' ) . and . resolveTo ( '{"name": "app"}' ) ;
447+
448+ const dependencies = await pm . getProjectDependencies ( ) ;
449+
450+ expect ( [ ...dependencies . keys ( ) ] ) . toEqual ( [ '@angular/core' ] ) ;
451+ expect ( dependencies . get ( '@angular/core' ) ?. version ) . toBe ( '22.0.0' ) ;
452+ } ) ;
453+ } ) ;
454+
381455 describe ( 'initializationError' , ( ) => {
382456 it ( 'should throw initializationError when running commands' , async ( ) => {
383457 const error = new Error ( 'Not installed' ) ;
0 commit comments