Skip to content

Commit 1415c67

Browse files
committed
test(coverage): cover packageManager-field detection paths
Adds three tests for previously-untested branches in detectAndValidatePackageEnvironment: - packageManager: 'pnpm@8.15.7' → agent inferred from the field before lockfile lookup (lines 324-332) - packageManager without '@' → falls through to LOCKS lookup (npm) - yarn-classic with major > 1 → upgrades to yarn/berry (lines 348-349) environment.mts: 75.34% → 80.13% statements (+4.79%).
1 parent 52279a9 commit 1415c67

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

packages/cli/test/unit/utils/ecosystem/environment.test.mts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,5 +828,89 @@ describe('package-environment', () => {
828828
expect(result.message).toBe('Missing lockfile')
829829
}
830830
})
831+
832+
it('detects agent from packageManager field (lines 324-332)', async () => {
833+
// packageManager: "pnpm@8.15.7" → agent='pnpm' inferred from the field
834+
// before any lockfile lookup.
835+
mockFindUp.mockImplementation(async files => {
836+
if (Array.isArray(files) && files.includes('pnpm-lock.yaml')) {
837+
return '/project/pnpm-lock.yaml'
838+
}
839+
if (files === 'package.json') {
840+
return '/project/package.json'
841+
}
842+
return undefined
843+
})
844+
mockExistsSync.mockReturnValue(true)
845+
mockWhichBin.mockResolvedValue('/usr/local/bin/pnpm')
846+
mockReadPackageJson.mockResolvedValue({
847+
name: 'test-project',
848+
version: '1.0.0',
849+
packageManager: 'pnpm@8.15.7',
850+
})
851+
852+
const result = await detectAndValidatePackageEnvironment('/project')
853+
854+
expect(result.ok).toBe(true)
855+
if (result.ok) {
856+
expect(result.data.agent).toBe('pnpm')
857+
}
858+
})
859+
860+
it('falls back to npm when packageManager has no @ separator', async () => {
861+
mockFindUp.mockImplementation(async files => {
862+
if (Array.isArray(files) && files.includes('package-lock.json')) {
863+
return '/project/package-lock.json'
864+
}
865+
if (files === 'package.json') {
866+
return '/project/package.json'
867+
}
868+
return undefined
869+
})
870+
mockExistsSync.mockReturnValue(true)
871+
mockWhichBin.mockResolvedValue('/usr/local/bin/npm')
872+
mockReadPackageJson.mockResolvedValue({
873+
name: 'test-project',
874+
version: '1.0.0',
875+
// No '@' → atSignIndex < 0 → falls through to lockfile inference.
876+
packageManager: 'invalid-format',
877+
})
878+
879+
const result = await detectAndValidatePackageEnvironment('/project')
880+
881+
// Falls through to LOCKS lookup (package-lock.json → npm).
882+
expect(result.ok).toBe(true)
883+
if (result.ok) {
884+
expect(result.data.agent).toBe('npm')
885+
}
886+
})
887+
888+
it('detects yarn-berry when yarn-classic agent has major > 1 (lines 348-349)', async () => {
889+
mockFindUp.mockImplementation(async files => {
890+
if (Array.isArray(files) && files.includes('yarn.lock')) {
891+
return '/project/yarn.lock'
892+
}
893+
if (files === 'package.json') {
894+
return '/project/package.json'
895+
}
896+
return undefined
897+
})
898+
mockExistsSync.mockReturnValue(true)
899+
mockWhichBin.mockResolvedValue('/usr/local/bin/yarn')
900+
mockReadPackageJson.mockResolvedValue({
901+
name: 'test-project',
902+
version: '1.0.0',
903+
})
904+
// yarn version 4.x → coerced major 4 > 1 → upgrades classic to berry.
905+
mockSpawn.mockResolvedValue({ stdout: '4.5.0', stderr: '', code: 0 })
906+
907+
const result = await detectAndValidatePackageEnvironment('/project')
908+
909+
expect(result.ok).toBe(true)
910+
if (result.ok) {
911+
// Agent name uses '/' as the separator between flavor variants.
912+
expect(result.data.agent).toBe('yarn/berry')
913+
}
914+
})
831915
})
832916
})

0 commit comments

Comments
 (0)