mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-31 12:10:49 -04:00
test(pnpm): group release-brittle tests under a shared describe block (#11767)
Three tests resolve the running pnpm version's integrity from registry-mock,
which proxies pnpm to npmjs. They fail every release between the version
bump commit and the matching npm publish ("No matching version found for
pnpm@<version>"), then pass again once the version lands on npmjs. Group
them under a 'release-brittle' describe in each file so the failure mode
is obvious from the test name and only stated once.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
import { expect, test } from '@jest/globals'
|
||||
import { describe, expect, test } from '@jest/globals'
|
||||
import { readEnvLockfile } from '@pnpm/lockfile.fs'
|
||||
import { prepare } from '@pnpm/prepare'
|
||||
import { getIntegrity } from '@pnpm/registry-mock'
|
||||
@@ -149,21 +149,26 @@ test('package manager from the packageManager field is not saved into the lockfi
|
||||
expect(envLockfile!.importers['.'].packageManagerDependencies).toBeUndefined()
|
||||
})
|
||||
|
||||
test('packageManagerDependencies is refreshed when pnpm is invoked via corepack (#11397)', async () => {
|
||||
const pnpmVersion = JSON.parse(fs.readFileSync(path.join(path.dirname(pnpmBinLocation), '..', 'package.json'), 'utf8')).version as string
|
||||
prepare({
|
||||
devEngines: {
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: pnpmVersion,
|
||||
// These tests resolve the running pnpm version's integrity from registry-mock,
|
||||
// which proxies pnpm to npmjs. They fail between a release commit and the
|
||||
// matching npm publish ("No matching version found for pnpm@<version>"), and
|
||||
// pass again once the version lands on npmjs.
|
||||
describe('release-brittle: may fail until current version is published to npm', () => {
|
||||
test('packageManagerDependencies is refreshed when pnpm is invoked via corepack (#11397)', async () => {
|
||||
const pnpmVersion = JSON.parse(fs.readFileSync(path.join(path.dirname(pnpmBinLocation), '..', 'package.json'), 'utf8')).version as string
|
||||
prepare({
|
||||
devEngines: {
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: pnpmVersion,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// Seed the lockfile with a stale packageManagerDependencies entry that no
|
||||
// longer satisfies devEngines.packageManager. Multi-document YAML: env
|
||||
// lockfile is the first doc, the (empty) installer lockfile is the second.
|
||||
fs.writeFileSync('pnpm-lock.yaml', `---
|
||||
// Seed the lockfile with a stale packageManagerDependencies entry that no
|
||||
// longer satisfies devEngines.packageManager. Multi-document YAML: env
|
||||
// lockfile is the first doc, the (empty) installer lockfile is the second.
|
||||
fs.writeFileSync('pnpm-lock.yaml', `---
|
||||
lockfileVersion: '9.0'
|
||||
importers:
|
||||
'.':
|
||||
@@ -178,16 +183,17 @@ snapshots: {}
|
||||
---
|
||||
`)
|
||||
|
||||
// COREPACK_ROOT used to skip the entire pm-handling block, leaving the stale
|
||||
// 0.0.1 entry untouched. The sync must run regardless of how pnpm was
|
||||
// invoked.
|
||||
await execPnpm(['install'], {
|
||||
env: { COREPACK_ROOT: '/fake/corepack' },
|
||||
})
|
||||
// COREPACK_ROOT used to skip the entire pm-handling block, leaving the
|
||||
// stale 0.0.1 entry untouched. The sync must run regardless of how pnpm
|
||||
// was invoked.
|
||||
await execPnpm(['install'], {
|
||||
env: { COREPACK_ROOT: '/fake/corepack' },
|
||||
})
|
||||
|
||||
const envLockfile = await readEnvLockfile(process.cwd())
|
||||
expect(envLockfile).not.toBeNull()
|
||||
expect(envLockfile!.importers['.'].packageManagerDependencies?.['pnpm'].version).toBe(pnpmVersion)
|
||||
const envLockfile = await readEnvLockfile(process.cwd())
|
||||
expect(envLockfile).not.toBeNull()
|
||||
expect(envLockfile!.importers['.'].packageManagerDependencies?.['pnpm'].version).toBe(pnpmVersion)
|
||||
})
|
||||
})
|
||||
|
||||
test('installing a new configurational dependency', async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect, test } from '@jest/globals'
|
||||
import { describe, expect, test } from '@jest/globals'
|
||||
import { prepare, prepareEmpty } from '@pnpm/prepare'
|
||||
import { writeYamlFileSync } from 'write-yaml-file'
|
||||
|
||||
@@ -185,38 +185,6 @@ test('devEngines.packageManager with a different PM name should fail with onFail
|
||||
expect(stderr.toString()).toContain('This project is configured to use yarn')
|
||||
})
|
||||
|
||||
test('pnpm --version exits promptly when devEngines.packageManager matches the running pnpm', async () => {
|
||||
// Regression test: main.ts's `--version` short-circuit returned before
|
||||
// the command-handler `finally` that calls finishWorkers(), and
|
||||
// switchCliVersion had already spawned workers during integrity
|
||||
// resolution. The worker pool then kept the Node event loop alive long
|
||||
// past the version print.
|
||||
// Read the running pnpm version from a fresh empty dir — the previous
|
||||
// test's prepare() leaves cwd in a manifest with a failing pm check, and
|
||||
// checkPackageManager runs before the --version short-circuit.
|
||||
prepareEmpty()
|
||||
const versionProcess = execPnpmSync(['--version'])
|
||||
const pnpmVersion = versionProcess.stdout.toString().trim()
|
||||
|
||||
prepare({
|
||||
devEngines: {
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: pnpmVersion,
|
||||
onFail: 'download',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// 30 s is comfortably above the post-fix exit time (~3 s) and far below
|
||||
// the pre-fix hang. If the regression returns, spawnSync's timeout kicks
|
||||
// in and execPnpmSync throws from its `error`/`signal` checks.
|
||||
const { status, stdout } = execPnpmSync(['--version'], { timeout: 30_000 })
|
||||
|
||||
expect(status).toBe(0)
|
||||
expect(stdout.toString().trim()).toBe(pnpmVersion)
|
||||
})
|
||||
|
||||
test('devEngines.packageManager array selects the pnpm entry', async () => {
|
||||
prepare({
|
||||
devEngines: {
|
||||
@@ -251,22 +219,6 @@ test('devEngines.packageManager array defaults onFail to ignore for non-last ele
|
||||
expect(status).toBe(0)
|
||||
})
|
||||
|
||||
test('devEngines.packageManager with version range should match current version', async () => {
|
||||
prepare({
|
||||
devEngines: {
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '>=1.0.0',
|
||||
onFail: 'error',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const { status } = execPnpmSync(['install'])
|
||||
|
||||
expect(status).toBe(0)
|
||||
})
|
||||
|
||||
test('devEngines.packageManager takes precedence over packageManager field', async () => {
|
||||
const versionProcess = execPnpmSync(['--version'])
|
||||
const pnpmVersion = versionProcess.stdout.toString().trim()
|
||||
@@ -476,3 +428,57 @@ test.each([
|
||||
expect(status).toBe(0)
|
||||
expect(stderr.toString()).not.toContain('configured to use 0.0.1')
|
||||
})
|
||||
|
||||
// These tests resolve the running pnpm version's integrity from registry-mock,
|
||||
// which proxies pnpm to npmjs. They fail between a release commit and the
|
||||
// matching npm publish ("No matching version found for pnpm@<version>"), and
|
||||
// pass again once the version lands on npmjs.
|
||||
describe('release-brittle: may fail until current version is published to npm', () => {
|
||||
test('pnpm --version exits promptly when devEngines.packageManager matches the running pnpm', async () => {
|
||||
// Regression test: main.ts's `--version` short-circuit returned before
|
||||
// the command-handler `finally` that calls finishWorkers(), and
|
||||
// switchCliVersion had already spawned workers during integrity
|
||||
// resolution. The worker pool then kept the Node event loop alive long
|
||||
// past the version print.
|
||||
// Read the running pnpm version from a fresh empty dir — the previous
|
||||
// test's prepare() leaves cwd in a manifest with a failing pm check, and
|
||||
// checkPackageManager runs before the --version short-circuit.
|
||||
prepareEmpty()
|
||||
const versionProcess = execPnpmSync(['--version'])
|
||||
const pnpmVersion = versionProcess.stdout.toString().trim()
|
||||
|
||||
prepare({
|
||||
devEngines: {
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: pnpmVersion,
|
||||
onFail: 'download',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// 30 s is comfortably above the post-fix exit time (~3 s) and far below
|
||||
// the pre-fix hang. If the regression returns, spawnSync's timeout kicks
|
||||
// in and execPnpmSync throws from its `error`/`signal` checks.
|
||||
const { status, stdout } = execPnpmSync(['--version'], { timeout: 30_000 })
|
||||
|
||||
expect(status).toBe(0)
|
||||
expect(stdout.toString().trim()).toBe(pnpmVersion)
|
||||
})
|
||||
|
||||
test('devEngines.packageManager with version range should match current version', async () => {
|
||||
prepare({
|
||||
devEngines: {
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '>=1.0.0',
|
||||
onFail: 'error',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const { status } = execPnpmSync(['install'])
|
||||
|
||||
expect(status).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user