mirror of
https://github.com/pnpm/pnpm.git
synced 2026-06-29 18:35:18 -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 fs from 'node:fs'
|
||||||
import path from 'node:path'
|
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 { readEnvLockfile } from '@pnpm/lockfile.fs'
|
||||||
import { prepare } from '@pnpm/prepare'
|
import { prepare } from '@pnpm/prepare'
|
||||||
import { getIntegrity } from '@pnpm/registry-mock'
|
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()
|
expect(envLockfile!.importers['.'].packageManagerDependencies).toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('packageManagerDependencies is refreshed when pnpm is invoked via corepack (#11397)', async () => {
|
// These tests resolve the running pnpm version's integrity from registry-mock,
|
||||||
const pnpmVersion = JSON.parse(fs.readFileSync(path.join(path.dirname(pnpmBinLocation), '..', 'package.json'), 'utf8')).version as string
|
// which proxies pnpm to npmjs. They fail between a release commit and the
|
||||||
prepare({
|
// matching npm publish ("No matching version found for pnpm@<version>"), and
|
||||||
devEngines: {
|
// pass again once the version lands on npmjs.
|
||||||
packageManager: {
|
describe('release-brittle: may fail until current version is published to npm', () => {
|
||||||
name: 'pnpm',
|
test('packageManagerDependencies is refreshed when pnpm is invoked via corepack (#11397)', async () => {
|
||||||
version: pnpmVersion,
|
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
|
// Seed the lockfile with a stale packageManagerDependencies entry that no
|
||||||
// longer satisfies devEngines.packageManager. Multi-document YAML: env
|
// longer satisfies devEngines.packageManager. Multi-document YAML: env
|
||||||
// lockfile is the first doc, the (empty) installer lockfile is the second.
|
// lockfile is the first doc, the (empty) installer lockfile is the second.
|
||||||
fs.writeFileSync('pnpm-lock.yaml', `---
|
fs.writeFileSync('pnpm-lock.yaml', `---
|
||||||
lockfileVersion: '9.0'
|
lockfileVersion: '9.0'
|
||||||
importers:
|
importers:
|
||||||
'.':
|
'.':
|
||||||
@@ -178,16 +183,17 @@ snapshots: {}
|
|||||||
---
|
---
|
||||||
`)
|
`)
|
||||||
|
|
||||||
// COREPACK_ROOT used to skip the entire pm-handling block, leaving the stale
|
// COREPACK_ROOT used to skip the entire pm-handling block, leaving the
|
||||||
// 0.0.1 entry untouched. The sync must run regardless of how pnpm was
|
// stale 0.0.1 entry untouched. The sync must run regardless of how pnpm
|
||||||
// invoked.
|
// was invoked.
|
||||||
await execPnpm(['install'], {
|
await execPnpm(['install'], {
|
||||||
env: { COREPACK_ROOT: '/fake/corepack' },
|
env: { COREPACK_ROOT: '/fake/corepack' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const envLockfile = await readEnvLockfile(process.cwd())
|
const envLockfile = await readEnvLockfile(process.cwd())
|
||||||
expect(envLockfile).not.toBeNull()
|
expect(envLockfile).not.toBeNull()
|
||||||
expect(envLockfile!.importers['.'].packageManagerDependencies?.['pnpm'].version).toBe(pnpmVersion)
|
expect(envLockfile!.importers['.'].packageManagerDependencies?.['pnpm'].version).toBe(pnpmVersion)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('installing a new configurational dependency', async () => {
|
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 { prepare, prepareEmpty } from '@pnpm/prepare'
|
||||||
import { writeYamlFileSync } from 'write-yaml-file'
|
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')
|
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 () => {
|
test('devEngines.packageManager array selects the pnpm entry', async () => {
|
||||||
prepare({
|
prepare({
|
||||||
devEngines: {
|
devEngines: {
|
||||||
@@ -251,22 +219,6 @@ test('devEngines.packageManager array defaults onFail to ignore for non-last ele
|
|||||||
expect(status).toBe(0)
|
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 () => {
|
test('devEngines.packageManager takes precedence over packageManager field', async () => {
|
||||||
const versionProcess = execPnpmSync(['--version'])
|
const versionProcess = execPnpmSync(['--version'])
|
||||||
const pnpmVersion = versionProcess.stdout.toString().trim()
|
const pnpmVersion = versionProcess.stdout.toString().trim()
|
||||||
@@ -476,3 +428,57 @@ test.each([
|
|||||||
expect(status).toBe(0)
|
expect(status).toBe(0)
|
||||||
expect(stderr.toString()).not.toContain('configured to use 0.0.1')
|
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