From 12f1c31a0decb867f91f31ffb0cadf34ce9f0673 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 12 Feb 2024 23:33:51 +0100 Subject: [PATCH] chore(tests): use separate envs for each tests (#371) --- tests/Disable.test.ts | 27 ++-- tests/Enable.test.ts | 35 ++--- tests/Up.test.ts | 1 + tests/Use.test.ts | 1 + tests/main.test.ts | 240 ++++++++++++++------------------- tests/npmRegistryUtils.test.ts | 15 +-- tests/setupTests.js | 56 ++++---- 7 files changed, 166 insertions(+), 209 deletions(-) diff --git a/tests/Disable.test.ts b/tests/Disable.test.ts index 9c93f9d7b..682a6817c 100644 --- a/tests/Disable.test.ts +++ b/tests/Disable.test.ts @@ -12,6 +12,7 @@ import {runCli} from './_runCli'; const engine = new Engine(); beforeEach(async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_HOME = npath.fromPortablePath(await xfs.mktempPromise()); }); @@ -26,15 +27,10 @@ describe(`DisableCommand`, () => { for (const variant of getBinaryNames(binName)) await makeBin(cwd, variant as Filename, {ignorePlatform: true}); - const PATH = process.env.PATH; - try { - process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${PATH}`; - await expect(runCli(cwd, [`disable`])).resolves.toMatchObject({ - exitCode: 0, - }); - } finally { - process.env.PATH = PATH; - } + process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${process.env.PATH}`; + await expect(runCli(cwd, [`disable`])).resolves.toMatchObject({ + exitCode: 0, + }); const sortedEntries = xfs.readdirPromise(cwd).then(entries => { return entries.sort(); @@ -84,15 +80,10 @@ describe(`DisableCommand`, () => { const dontRemoveBin = await makeBin(cwd, `dont-remove` as Filename); binNames.add(ppath.basename(dontRemoveBin)); - const PATH = process.env.PATH; - try { - process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${PATH}`; - await expect(runCli(cwd, [`disable`, `yarn`])).resolves.toMatchObject({ - exitCode: 0, - }); - } finally { - process.env.PATH = PATH; - } + process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${process.env.PATH}`; + await expect(runCli(cwd, [`disable`, `yarn`])).resolves.toMatchObject({ + exitCode: 0, + }); for (const variant of getBinaryNames(`yarn`)) binNames.delete(variant); diff --git a/tests/Enable.test.ts b/tests/Enable.test.ts index ce9a8a9e3..b0f4e168f 100644 --- a/tests/Enable.test.ts +++ b/tests/Enable.test.ts @@ -12,6 +12,7 @@ import {runCli} from './ const engine = new Engine(); beforeEach(async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_HOME = npath.fromPortablePath(await xfs.mktempPromise()); process.env.COREPACK_DEFAULT_TO_LATEST = `0`; }); @@ -21,17 +22,12 @@ describe(`EnableCommand`, () => { await xfs.mktempPromise(async cwd => { const corepackBin = await makeBin(cwd, `corepack` as Filename); - const PATH = process.env.PATH; - try { - process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${PATH}`; - await expect(runCli(cwd, [`enable`])).resolves.toMatchObject({ - stdout: ``, - stderr: ``, - exitCode: 0, - }); - } finally { - process.env.PATH = PATH; - } + process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${process.env.PATH}`; + await expect(runCli(cwd, [`enable`])).resolves.toMatchObject({ + stdout: ``, + stderr: ``, + exitCode: 0, + }); const sortedEntries = xfs.readdirPromise(cwd).then(entries => { return entries.sort(); @@ -73,17 +69,12 @@ describe(`EnableCommand`, () => { await xfs.mktempPromise(async cwd => { const corepackBin = await makeBin(cwd, `corepack` as Filename); - const PATH = process.env.PATH; - try { - process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${PATH}`; - await expect(runCli(cwd, [`enable`, `yarn`])).resolves.toMatchObject({ - stdout: ``, - stderr: ``, - exitCode: 0, - }); - } finally { - process.env.PATH = PATH; - } + process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${process.env.PATH}`; + await expect(runCli(cwd, [`enable`, `yarn`])).resolves.toMatchObject({ + stdout: ``, + stderr: ``, + exitCode: 0, + }); const sortedEntries = xfs.readdirPromise(cwd).then(entries => { return entries.sort(); diff --git a/tests/Up.test.ts b/tests/Up.test.ts index 1c78afdc5..c1c094f43 100644 --- a/tests/Up.test.ts +++ b/tests/Up.test.ts @@ -5,6 +5,7 @@ import process from 'node:process'; import {runCli} from './_runCli'; beforeEach(async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_HOME = npath.fromPortablePath(await xfs.mktempPromise()); process.env.COREPACK_DEFAULT_TO_LATEST = `0`; }); diff --git a/tests/Use.test.ts b/tests/Use.test.ts index 10deef19e..8c91fa217 100644 --- a/tests/Use.test.ts +++ b/tests/Use.test.ts @@ -5,6 +5,7 @@ import process from 'node:process'; import {runCli} from './_runCli'; beforeEach(async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_HOME = npath.fromPortablePath(await xfs.mktempPromise()); process.env.COREPACK_DEFAULT_TO_LATEST = `0`; }); diff --git a/tests/main.test.ts b/tests/main.test.ts index c54fb1f5d..ec05db235 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -9,6 +9,7 @@ import {runCli} from './_runCli'; beforeEach(async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_HOME = npath.fromPortablePath(await xfs.mktempPromise()); process.env.COREPACK_DEFAULT_TO_LATEST = `0`; }); @@ -344,15 +345,11 @@ it(`should allow to call "corepack install" without arguments within a configure // Disable the network to make sure we don't succeed by accident process.env.COREPACK_ENABLE_NETWORK = `0`; - try { - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - stdout: `1.0.0\n`, - stderr: ``, - exitCode: 0, - }); - } finally { - delete process.env.COREPACK_ENABLE_NETWORK; - } + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + stdout: `1.0.0\n`, + stderr: ``, + exitCode: 0, + }); }); }); @@ -372,21 +369,16 @@ it(`should refuse to run a different package manager within a configured project // Disable strict checking to workaround the UsageError. process.env.COREPACK_ENABLE_STRICT = `0`; - try { - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - stdout: `1.0.0\n`, - stderr: ``, - exitCode: 0, - }); - await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ - stdout: `${config.definitions.pnpm.default.split(`+`, 1)[0]}\n`, - stderr: ``, - exitCode: 0, - }); - } finally { - delete process.env.COREPACK_ENABLE_STRICT; - delete process.env.FORCE_COLOR; - } + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + stdout: `1.0.0\n`, + stderr: ``, + exitCode: 0, + }); + await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ + stdout: `${config.definitions.pnpm.default.split(`+`, 1)[0]}\n`, + stderr: ``, + exitCode: 0, + }); }); }); @@ -398,20 +390,16 @@ it(`should always use fallback version when project spec env is disabled`, async }); process.env.COREPACK_ENABLE_PROJECT_SPEC = `0`; - try { - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - stdout: `${config.definitions.yarn.default.split(`+`, 1)[0]}\n`, - stderr: ``, - exitCode: 0, - }); - await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ - stdout: `${config.definitions.pnpm.default.split(`+`, 1)[0]}\n`, - stderr: ``, - exitCode: 0, - }); - } finally { - delete process.env.COREPACK_ENABLE_PROJECT_SPEC; - } + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + stdout: `${config.definitions.yarn.default.split(`+`, 1)[0]}\n`, + stderr: ``, + exitCode: 0, + }); + await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ + stdout: `${config.definitions.pnpm.default.split(`+`, 1)[0]}\n`, + stderr: ``, + exitCode: 0, + }); }); }); @@ -428,48 +416,40 @@ it(`should allow to call "corepack install -g --all" to prepare all package mana process.env.COREPACK_ENABLE_NETWORK = `0`; - try { - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - stdout: `${config.definitions.yarn.default.split(`+`, 1)[0]}\n`, - stderr: ``, - exitCode: 0, - }); + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + stdout: `${config.definitions.yarn.default.split(`+`, 1)[0]}\n`, + stderr: ``, + exitCode: 0, + }); - await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ - stdout: `${config.definitions.pnpm.default.split(`+`, 1)[0]}\n`, - stderr: ``, - exitCode: 0, - }); + await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ + stdout: `${config.definitions.pnpm.default.split(`+`, 1)[0]}\n`, + stderr: ``, + exitCode: 0, + }); - await expect(runCli(cwd, [`npm`, `--version`])).resolves.toMatchObject({ - stdout: `${config.definitions.npm.default.split(`+`, 1)[0]}\n`, - stderr: ``, - exitCode: 0, - }); - } finally { - delete process.env.COREPACK_ENABLE_NETWORK; - } + await expect(runCli(cwd, [`npm`, `--version`])).resolves.toMatchObject({ + stdout: `${config.definitions.npm.default.split(`+`, 1)[0]}\n`, + stderr: ``, + exitCode: 0, + }); }); }); it(`should support disabling the network accesses from the environment`, async () => { process.env.COREPACK_ENABLE_NETWORK = `0`; - try { - await xfs.mktempPromise(async cwd => { - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `yarn@2.2.2`, - }); + await xfs.mktempPromise(async cwd => { + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `yarn@2.2.2`, + }); - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - stdout: expect.stringContaining(`Network access disabled by the environment`), - stderr: ``, - exitCode: 1, - }); + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + stdout: expect.stringContaining(`Network access disabled by the environment`), + stderr: ``, + exitCode: 1, }); - } finally { - delete process.env.COREPACK_ENABLE_NETWORK; - } + }); }); it(`should support hydrating package managers from cached archives`, async () => { @@ -485,24 +465,20 @@ it(`should support hydrating package managers from cached archives`, async () => // Disable the network to make sure we don't succeed by accident process.env.COREPACK_ENABLE_NETWORK = `0`; - try { - await expect(runCli(cwd, [`install`, `-g`, `corepack.tgz`])).resolves.toMatchObject({ - stderr: ``, - exitCode: 0, - }); + await expect(runCli(cwd, [`install`, `-g`, `corepack.tgz`])).resolves.toMatchObject({ + stderr: ``, + exitCode: 0, + }); - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `yarn@2.2.2`, - }); + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `yarn@2.2.2`, + }); - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - stdout: `2.2.2\n`, - stderr: ``, - exitCode: 0, - }); - } finally { - delete process.env.COREPACK_ENABLE_NETWORK; - } + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + stdout: `2.2.2\n`, + stderr: ``, + exitCode: 0, + }); }); }); @@ -522,24 +498,20 @@ it(`should support hydrating package managers if cache folder was removed`, asyn // Disable the network to make sure we don't succeed by accident process.env.COREPACK_ENABLE_NETWORK = `0`; - try { - await expect(runCli(cwd, [`install`, `-g`, `corepack.tgz`])).resolves.toMatchObject({ - stderr: ``, - exitCode: 0, - }); + await expect(runCli(cwd, [`install`, `-g`, `corepack.tgz`])).resolves.toMatchObject({ + stderr: ``, + exitCode: 0, + }); - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `yarn@2.2.2`, - }); + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `yarn@2.2.2`, + }); - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - stdout: `2.2.2\n`, - stderr: ``, - exitCode: 0, - }); - } finally { - delete process.env.COREPACK_ENABLE_NETWORK; - } + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + stdout: `2.2.2\n`, + stderr: ``, + exitCode: 0, + }); }); }); @@ -556,34 +528,30 @@ it(`should support hydrating multiple package managers from cached archives`, as // Disable the network to make sure we don't succeed by accident process.env.COREPACK_ENABLE_NETWORK = `0`; - try { - await expect(runCli(cwd, [`install`, `-g`, `corepack.tgz`])).resolves.toMatchObject({ - stderr: ``, - exitCode: 0, - }); + await expect(runCli(cwd, [`install`, `-g`, `corepack.tgz`])).resolves.toMatchObject({ + stderr: ``, + exitCode: 0, + }); - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `yarn@2.2.2`, - }); + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `yarn@2.2.2`, + }); - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - stdout: `2.2.2\n`, - stderr: ``, - exitCode: 0, - }); + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + stdout: `2.2.2\n`, + stderr: ``, + exitCode: 0, + }); - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `pnpm@5.8.0`, - }); + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `pnpm@5.8.0`, + }); - await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ - stdout: `5.8.0\n`, - stderr: ``, - exitCode: 0, - }); - } finally { - delete process.env.COREPACK_ENABLE_NETWORK; - } + await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ + stdout: `5.8.0\n`, + stderr: ``, + exitCode: 0, + }); }); }, 180_000); @@ -741,17 +709,13 @@ it(`should support package managers in ESM format`, async () => { it(`should show a warning on stderr before downloading when enable`, async() => { await xfs.mktempPromise(async cwd => { process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT = `1`; - try { - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `yarn@3.0.0`, - }); - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - exitCode: 0, - stdout: `3.0.0\n`, - stderr: `Corepack is about to download https://repo.yarnpkg.com/3.0.0/packages/yarnpkg-cli/bin/yarn.js.\n`, - }); - } finally { - delete process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT; - } + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `yarn@3.0.0`, + }); + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + exitCode: 0, + stdout: `3.0.0\n`, + stderr: `Corepack is about to download https://repo.yarnpkg.com/3.0.0/packages/yarnpkg-cli/bin/yarn.js.\n`, + }); }); }); diff --git a/tests/npmRegistryUtils.test.ts b/tests/npmRegistryUtils.test.ts index 1ee82a635..69dc0b582 100644 --- a/tests/npmRegistryUtils.test.ts +++ b/tests/npmRegistryUtils.test.ts @@ -1,4 +1,4 @@ -import {jest, describe, beforeEach, afterEach, it, expect} from '@jest/globals'; +import {jest, describe, beforeEach, it, expect} from '@jest/globals'; import {Buffer} from 'node:buffer'; import process from 'node:process'; @@ -8,18 +8,12 @@ import {DEFAULT_HEADERS, DEFAULT_NPM_REGISTRY_URL, fetchAsJson} from '../sources jest.mock(`../sources/httpUtils`); describe(`npm registry utils fetchAsJson`, () => { - const OLD_ENV = process.env; - beforeEach(() => { - process.env = {...OLD_ENV}; // Make a copy jest.resetAllMocks(); }); - afterEach(() => { - process.env = OLD_ENV; // Restore old environment - }); - it(`throw usage error if COREPACK_ENABLE_NETWORK env is set to 0`, async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_ENABLE_NETWORK = `0`; await expect(fetchAsJson(`package-name`)).rejects.toThrowError(); @@ -33,6 +27,7 @@ describe(`npm registry utils fetchAsJson`, () => { }); it(`loads from custom COREPACK_NPM_REGISTRY if set`, async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_NPM_REGISTRY = `https://registry.example.org`; await fetchAsJson(`package-name`); @@ -41,6 +36,7 @@ describe(`npm registry utils fetchAsJson`, () => { }); it(`adds authorization header with bearer token if COREPACK_NPM_TOKEN is set`, async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_NPM_TOKEN = `foo`; await fetchAsJson(`package-name`); @@ -53,6 +49,7 @@ describe(`npm registry utils fetchAsJson`, () => { }); it(`only adds authorization header with bearer token if COREPACK_NPM_TOKEN and COREPACK_NPM_USERNAME are set`, async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_NPM_TOKEN = `foo`; process.env.COREPACK_NPM_USERNAME = `bar`; process.env.COREPACK_NPM_PASSWORD = `foobar`; @@ -68,6 +65,7 @@ describe(`npm registry utils fetchAsJson`, () => { it(`adds authorization header with basic auth if COREPACK_NPM_USERNAME and COREPACK_NPM_PASSWORD are set`, async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_NPM_USERNAME = `foo`; process.env.COREPACK_NPM_PASSWORD = `bar`; @@ -83,6 +81,7 @@ describe(`npm registry utils fetchAsJson`, () => { }); it(`does not add authorization header if COREPACK_NPM_USERNAME is set and COREPACK_NPM_PASSWORD is not.`, async () => { + // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_NPM_USERNAME = `foo`; await fetchAsJson(`package-name`); diff --git a/tests/setupTests.js b/tests/setupTests.js index fdf59307c..cf8ca57f9 100644 --- a/tests/setupTests.js +++ b/tests/setupTests.js @@ -1,43 +1,53 @@ /* global jest, expect, beforeEach, afterAll */ const crypto = require(`crypto`); +const process = require(`process`); jest.retryTimes(2, {logErrorsBeforeRetry: true}); +const OLD_ENV = process.env; +const { + // To ensure we test the default behavior, we must remove these env vars + // in case the local machine already set these values. + COREPACK_DEFAULT_TO_LATEST, + COREPACK_ENABLE_NETWORK, + COREPACK_ENABLE_PROJECT_SPEC, + COREPACK_ENABLE_STRICT, + COREPACK_HOME, + COREPACK_NPM_REGISTRY, + COREPACK_NPM_TOKEN, + COREPACK_NPM_USERNAME, + FORCE_COLOR, + // We save the rest to put it into `process.env` for tests. + ...processEnv +} = process.env; + switch (process.env.NOCK_ENV || ``) { case `record`: case `replay`: beforeEach(() => { - // To ensure we test the default behavior, we must remove these env vars - // in case the local machine already set these values. - delete process.env.COREPACK_DEFAULT_TO_LATEST; - delete process.env.COREPACK_ENABLE_NETWORK; - delete process.env.COREPACK_ENABLE_PROJECT_SPEC; - delete process.env.COREPACK_ENABLE_STRICT; - delete process.env.COREPACK_HOME; - delete process.env.COREPACK_NPM_REGISTRY; - delete process.env.COREPACK_NPM_TOKEN; - delete process.env.COREPACK_NPM_USERNAME; - delete process.env.FORCE_COLOR; - - process.env.RUN_CLI_ID = 0; - process.env.NOCK_FILE_NAME = crypto - .createHash(`md5`) - .update(expect.getState().currentTestName) - .digest(`base64url`); - }); - - afterAll(() => { - delete process.env.RUN_CLI_ID; - delete process.env.NOCK_FILE_NAME; + process.env = { + ...processEnv, + RUN_CLI_ID: `0`, + NOCK_FILE_NAME: crypto + .createHash(`md5`) + .update(expect.getState().currentTestName) + .digest(`base64url`), + }; }); break; case ``: { - // Nothing + beforeEach(() => { + process.env = {...processEnv}; + }); } break; default: { throw new Error(`Invalid NOCK_ENV variable`); } } + +afterAll(() => { + process.env = OLD_ENV; +});