@@ -30,6 +30,41 @@ describe('how_installed', ()=>{
3030 expect ( info . kind ) . toBe ( 'npm-local' ) ;
3131 } ) ;
3232
33+ it ( 'calls it local when the owning project is an ancestor of the working directory' , ( ) => {
34+ // node resolves upward, so a copy in /home/artem/app/node_modules is
35+ // this project's whether you stand in app or in app/src.
36+ const project = at ( 'home' , 'artem' , 'app' ) ;
37+ const info = how_installed ( {
38+ module_dir : path . join ( project , 'node_modules' , 'reply-cli' ) ,
39+ cwd : path . join ( project , 'src' , 'deep' ) ,
40+ read_package : pkg ( 'reply-cli' ) ,
41+ } ) ;
42+ expect ( info . kind ) . toBe ( 'npm-local' ) ;
43+ } ) ;
44+
45+ it ( 'still calls a version-manager install global from the home directory' , ( ) => {
46+ // The regression that matters: ~/.nvm/... is under $HOME, so asking
47+ // whether the module sits under cwd would call this project-local and
48+ // refuse to update the one install we can actually drive.
49+ const home = at ( 'home' , 'artem' ) ;
50+ const info = how_installed ( {
51+ module_dir : path . join ( home , '.nvm' , 'versions' , 'node' , 'v22.17.1' , 'lib' , 'node_modules' , 'reply-cli' ) ,
52+ cwd : home ,
53+ read_package : pkg ( 'reply-cli' ) ,
54+ } ) ;
55+ expect ( info . kind ) . toBe ( 'npm-global' ) ;
56+ } ) ;
57+
58+ it ( 'attributes a nested copy to the project that owns the tree' , ( ) => {
59+ const project = at ( 'home' , 'artem' , 'app' ) ;
60+ const info = how_installed ( {
61+ module_dir : path . join ( project , 'node_modules' , 'some-tool' , 'node_modules' , 'reply-cli' ) ,
62+ cwd : project ,
63+ read_package : pkg ( 'reply-cli' ) ,
64+ } ) ;
65+ expect ( info . kind ) . toBe ( 'npm-local' ) ;
66+ } ) ;
67+
3368 it ( 'recognises npx before node_modules, since an npx cache has both' , ( ) => {
3469 const info = how_installed ( {
3570 module_dir : at ( 'home' , 'artem' , '.npm' , '_npx' , 'a1b2' , 'node_modules' , 'reply-cli' ) ,
0 commit comments