@@ -392,3 +392,152 @@ func TestFindAppHost(t *testing.T) {
392392 t .Error ("FindAppHost() ProjectFile is empty, expected .csproj path" )
393393 }
394394}
395+
396+ func TestGetPackageManagerFromPackageJson (t * testing.T ) {
397+ tests := []struct {
398+ name string
399+ content string
400+ expected string
401+ }{
402+ {
403+ name : "packageManager field with npm" ,
404+ content : `{"name": "test", "packageManager": "npm@10.5.0"}` ,
405+ expected : "npm" ,
406+ },
407+ {
408+ name : "packageManager field with yarn" ,
409+ content : `{"name": "test", "packageManager": "yarn@4.1.0"}` ,
410+ expected : "yarn" ,
411+ },
412+ {
413+ name : "packageManager field with pnpm" ,
414+ content : `{"name": "test", "packageManager": "pnpm@8.15.0"}` ,
415+ expected : "pnpm" ,
416+ },
417+ {
418+ name : "no packageManager field" ,
419+ content : `{"name": "test", "version": "1.0.0"}` ,
420+ expected : "" ,
421+ },
422+ {
423+ name : "empty packageManager field" ,
424+ content : `{"name": "test", "packageManager": ""}` ,
425+ expected : "" ,
426+ },
427+ {
428+ name : "unsupported package manager" ,
429+ content : `{"name": "test", "packageManager": "bun@1.0.0"}` ,
430+ expected : "" ,
431+ },
432+ {
433+ name : "invalid JSON" ,
434+ content : `{invalid json}` ,
435+ expected : "" ,
436+ },
437+ {
438+ name : "packageManager without version" ,
439+ content : `{"name": "test", "packageManager": "pnpm"}` ,
440+ expected : "pnpm" ,
441+ },
442+ }
443+
444+ for _ , tt := range tests {
445+ t .Run (tt .name , func (t * testing.T ) {
446+ // Create temporary directory
447+ tmpDir , err := os .MkdirTemp ("" , "detector-test-*" )
448+ if err != nil {
449+ t .Fatalf ("failed to create temp dir: %v" , err )
450+ }
451+ defer func () { _ = os .RemoveAll (tmpDir ) }()
452+
453+ // Create package.json
454+ packageJsonPath := filepath .Join (tmpDir , "package.json" )
455+ if err := os .WriteFile (packageJsonPath , []byte (tt .content ), 0600 ); err != nil {
456+ t .Fatalf ("failed to create package.json: %v" , err )
457+ }
458+
459+ // Test detection
460+ result := getPackageManagerFromPackageJson (tmpDir )
461+ if result != tt .expected {
462+ t .Errorf ("getPackageManagerFromPackageJson() = %q, want %q" , result , tt .expected )
463+ }
464+ })
465+ }
466+ }
467+
468+ func TestDetectNodePackageManagerWithPackageManagerField (t * testing.T ) {
469+ tests := []struct {
470+ name string
471+ packageJson string
472+ lockFiles []string
473+ expected string
474+ }{
475+ {
476+ name : "packageManager field takes priority over lock files" ,
477+ packageJson : `{"name": "test", "packageManager": "yarn@4.1.0"}` ,
478+ lockFiles : []string {"pnpm-lock.yaml" , "package-lock.json" },
479+ expected : "yarn" ,
480+ },
481+ {
482+ name : "fallback to pnpm lock file when no packageManager field" ,
483+ packageJson : `{"name": "test"}` ,
484+ lockFiles : []string {"pnpm-lock.yaml" },
485+ expected : "pnpm" ,
486+ },
487+ {
488+ name : "fallback to yarn lock file when no packageManager field" ,
489+ packageJson : `{"name": "test"}` ,
490+ lockFiles : []string {"yarn.lock" },
491+ expected : "yarn" ,
492+ },
493+ {
494+ name : "fallback to npm lock file when no packageManager field" ,
495+ packageJson : `{"name": "test"}` ,
496+ lockFiles : []string {"package-lock.json" },
497+ expected : "npm" ,
498+ },
499+ {
500+ name : "default to npm when no packageManager field and no lock files" ,
501+ packageJson : `{"name": "test"}` ,
502+ lockFiles : []string {},
503+ expected : "npm" ,
504+ },
505+ {
506+ name : "packageManager field with pnpm overrides yarn lock" ,
507+ packageJson : `{"name": "test", "packageManager": "pnpm@8.15.0"}` ,
508+ lockFiles : []string {"yarn.lock" },
509+ expected : "pnpm" ,
510+ },
511+ }
512+
513+ for _ , tt := range tests {
514+ t .Run (tt .name , func (t * testing.T ) {
515+ // Create temporary directory
516+ tmpDir , err := os .MkdirTemp ("" , "detector-test-*" )
517+ if err != nil {
518+ t .Fatalf ("failed to create temp dir: %v" , err )
519+ }
520+ defer func () { _ = os .RemoveAll (tmpDir ) }()
521+
522+ // Create package.json
523+ packageJsonPath := filepath .Join (tmpDir , "package.json" )
524+ if err := os .WriteFile (packageJsonPath , []byte (tt .packageJson ), 0600 ); err != nil {
525+ t .Fatalf ("failed to create package.json: %v" , err )
526+ }
527+
528+ // Create lock files
529+ for _ , lockFile := range tt .lockFiles {
530+ lockPath := filepath .Join (tmpDir , lockFile )
531+ if err := os .WriteFile (lockPath , []byte ("" ), 0600 ); err != nil {
532+ t .Fatalf ("failed to create lock file %s: %v" , lockFile , err )
533+ }
534+ }
535+
536+ // Test detection
537+ result := DetectNodePackageManagerWithBoundary (tmpDir , "" )
538+ if result != tt .expected {
539+ t .Errorf ("DetectNodePackageManagerWithBoundary() = %q, want %q" , result , tt .expected )
540+ }
541+ })
542+ }
543+ }
0 commit comments