Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: migrate to node:test #356

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
"eslint-plugin-arca": "^0.16.0",
"jest": "^29.0.0",
"nock": "^13.0.4",
"pirates": "^4.0.6",
"proxy-agent": "^6.2.2",
"semver": "^7.5.2",
"sucrase": "^3.35.0",
"supports-color": "^9.0.0",
"tar": "^6.0.1",
"ts-node": "^10.0.0",
Expand All @@ -58,7 +60,7 @@
"prepack": "yarn build",
"postpack": "rm -rf dist shims",
"typecheck": "tsc --noEmit",
"test": "jest"
"test": "yarn node tests"
},
"files": [
"dist",
Expand Down
28 changes: 12 additions & 16 deletions tests/Disable.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {describe, beforeEach, it, expect} from '@jest/globals';
import {Filename, ppath, xfs, npath} from '@yarnpkg/fslib';
import assert from 'node:assert';
import {delimiter} from 'node:path';
import process from 'node:process';
import {describe, beforeEach, it} from 'node:test';

import {Engine} from '../sources/Engine';
import {SupportedPackageManagerSetWithoutNpm} from '../sources/types';
Expand Down Expand Up @@ -29,9 +30,7 @@ describe(`DisableCommand`, () => {
const PATH = process.env.PATH;
try {
process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${PATH}`;
await expect(runCli(cwd, [`disable`])).resolves.toMatchObject({
exitCode: 0,
});
assert.strictEqual((await runCli(cwd, [`disable`])).exitCode, 0);
} finally {
process.env.PATH = PATH;
}
Expand All @@ -40,7 +39,7 @@ describe(`DisableCommand`, () => {
return entries.sort();
});

await expect(sortedEntries).resolves.toEqual([
assert.deepStrictEqual(await sortedEntries, [
ppath.basename(corepackBin),
ppath.basename(dontRemoveBin),
]);
Expand All @@ -56,11 +55,10 @@ describe(`DisableCommand`, () => {
for (const variant of getBinaryNames(binName))
await makeBin(cwd, variant as Filename, {ignorePlatform: true});

await expect(runCli(cwd, [`disable`, `--install-directory`, npath.fromPortablePath(cwd)])).resolves.toMatchObject({
exitCode: 0,
});

await expect(xfs.readdirPromise(cwd)).resolves.toEqual([
const runResult = await runCli(cwd, [`disable`, `--install-directory`, npath.fromPortablePath(cwd)]);
assert.strictEqual(runResult.exitCode, 0);
const readdirResult = await xfs.readdirPromise(cwd);
assert.deepStrictEqual(readdirResult, [
ppath.basename(dontRemoveBin),
]);
});
Expand All @@ -87,9 +85,8 @@ describe(`DisableCommand`, () => {
const PATH = process.env.PATH;
try {
process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${PATH}`;
await expect(runCli(cwd, [`disable`, `yarn`])).resolves.toMatchObject({
exitCode: 0,
});
const runResult = await runCli(cwd, [`disable`, `yarn`]);
assert.strictEqual(runResult.exitCode, 0);
} finally {
process.env.PATH = PATH;
}
Expand All @@ -99,11 +96,10 @@ describe(`DisableCommand`, () => {
for (const variant of getBinaryNames(`yarnpkg`))
binNames.delete(variant);

const sortedEntries = xfs.readdirPromise(cwd).then(entries => {
const sortedEntries = await xfs.readdirPromise(cwd).then(entries => {
return entries.sort();
});

await expect(sortedEntries).resolves.toEqual([...binNames].sort());
assert.deepStrictEqual(sortedEntries, [...binNames].sort());
});
});
});
18 changes: 11 additions & 7 deletions tests/Enable.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {describe, beforeEach, it, expect} from '@jest/globals';
import {Filename, ppath, xfs, npath} from '@yarnpkg/fslib';
import assert from 'node:assert';
import {delimiter} from 'node:path';
import process from 'node:process';
import {describe, beforeEach, it} from 'node:test';

import {Engine} from '../sources/Engine';
import {SupportedPackageManagers, SupportedPackageManagerSetWithoutNpm} from '../sources/types';
Expand All @@ -24,7 +25,8 @@ describe(`EnableCommand`, () => {
const PATH = process.env.PATH;
try {
process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${PATH}`;
await expect(runCli(cwd, [`enable`])).resolves.toMatchObject({
const {stdout, stderr, exitCode} = await runCli(cwd, [`enable`]);
assert.deepStrictEqual({stdout, stderr, exitCode}, {
stdout: ``,
stderr: ``,
exitCode: 0,
Expand All @@ -42,15 +44,16 @@ describe(`EnableCommand`, () => {
for (const binName of engine.getBinariesFor(packageManager))
expectedEntries.push(...getBinaryNames(binName));

await expect(sortedEntries).resolves.toEqual(expectedEntries.sort());
assert.deepStrictEqual(await sortedEntries, expectedEntries.sort());
});
});

it(`should add the binaries to the specified folder when using --install-directory`, async () => {
await xfs.mktempPromise(async cwd => {
const corepackBin = await makeBin(cwd, `corepack` as Filename);

await expect(runCli(cwd, [`enable`, `--install-directory`, npath.fromPortablePath(cwd)])).resolves.toMatchObject({
const {stdout, stderr, exitCode} = await runCli(cwd, [`enable`, `--install-directory`, npath.fromPortablePath(cwd)]);
assert.deepStrictEqual({stdout, stderr, exitCode}, {
stdout: ``,
stderr: ``,
exitCode: 0,
Expand All @@ -65,7 +68,7 @@ describe(`EnableCommand`, () => {
for (const binName of engine.getBinariesFor(packageManager))
expectedEntries.push(...getBinaryNames(binName));

await expect(sortedEntries).resolves.toEqual(expectedEntries.sort());
assert.deepStrictEqual(await sortedEntries, expectedEntries.sort());
});
});

Expand All @@ -76,7 +79,8 @@ describe(`EnableCommand`, () => {
const PATH = process.env.PATH;
try {
process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${PATH}`;
await expect(runCli(cwd, [`enable`, `yarn`])).resolves.toMatchObject({
const {stdout, stderr, exitCode} = await runCli(cwd, [`enable`, `yarn`]);
assert.deepStrictEqual({stdout, stderr, exitCode}, {
stdout: ``,
stderr: ``,
exitCode: 0,
Expand All @@ -93,7 +97,7 @@ describe(`EnableCommand`, () => {
for (const binName of engine.getBinariesFor(SupportedPackageManagers.Yarn))
expectedEntries.push(...getBinaryNames(binName));

await expect(sortedEntries).resolves.toEqual(expectedEntries.sort());
assert.deepStrictEqual(await sortedEntries, expectedEntries.sort());
});
});
});
22 changes: 18 additions & 4 deletions tests/Up.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import {describe, beforeEach, it, expect} from '@jest/globals';
import {ppath, xfs, npath} from '@yarnpkg/fslib';
import process from 'node:process';
import {ppath, xfs, npath} from '@yarnpkg/fslib';
import assert from 'node:assert';
import process from 'node:process';
import {describe, beforeEach, it} from 'node:test';

import {runCli} from './_runCli';

function expect(promise: Promise<Record<string, unknown>>) {
return {
resolves: {
async toMatchObject(expected: Record<string, unknown>) {
const result = await promise;

assert.deepStrictEqual(Object.fromEntries(Object.entries(result).filter(e => e[0] in expected)), expected);
},
},
};
}

import {runCli} from './_runCli';

beforeEach(async () => {
process.env.COREPACK_HOME = npath.fromPortablePath(await xfs.mktempPromise());
Expand Down
22 changes: 18 additions & 4 deletions tests/Use.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import {describe, beforeEach, it, expect} from '@jest/globals';
import {ppath, xfs, npath} from '@yarnpkg/fslib';
import process from 'node:process';
import {ppath, xfs, npath} from '@yarnpkg/fslib';
import assert from 'node:assert';
import process from 'node:process';
import {describe, beforeEach, it} from 'node:test';

import {runCli} from './_runCli';

function expect(promise: Promise<Record<string, unknown>>) {
return {
resolves: {
async toMatchObject(expected: Record<string, unknown>) {
const result = await promise;

assert.deepStrictEqual(Object.fromEntries(Object.entries(result).filter(e => e[0] in expected)), expected);
},
},
};
}

import {runCli} from './_runCli';

beforeEach(async () => {
process.env.COREPACK_HOME = npath.fromPortablePath(await xfs.mktempPromise());
Expand Down
75 changes: 38 additions & 37 deletions tests/httpUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
import {jest, describe, beforeEach, beforeAll, it, expect} from '@jest/globals';

import {fetchUrlStream} from '../sources/httpUtils';
import assert from 'node:assert';
import {describe, before as beforeAll, it} from 'node:test';

import {fetchUrlStream} from '../sources/httpUtils';

function doMock (pkg: string, replacer: (...args: Array<unknown>) => unknown) {
const actualPath = require.resolve(pkg);
if (arguments.length === 1) {
require.cache[actualPath] = require(`../__mocks__/${pkg}`);
} else {
const actual = require(pkg);
const Module = require(`node:module`); // eslint-disable-line global-require
require.cache[actualPath] = new Module(actualPath, module);
Object.defineProperties(require.cache[actualPath], {
exports: {
// @ts-expect-error TS is wrong
__proto__: null,
value: replacer(actual),
},
// @ts-expect-error TS is wrong
resetFn: {__proto__: null, value: replacer.bind(null, actual)},
});
}
}


describe(`http utils fetchUrlStream`, () => {
const getUrl = (statusCode: number | string, redirectCode?: number | string) =>
`https://registry.example.org/answered/${statusCode}${redirectCode ? `?redirectCode=${redirectCode}` : ``}`;

const httpsGetFn = jest.fn((url: string, _, callback: (response: any) => void) => {
const httpsGetFn = ((url: string, _: never, callback: (response: any) => void) => {
const parsedURL = new URL(url);
const statusCode = parsedURL.pathname.slice(parsedURL.pathname.lastIndexOf(`/`) + 1);
const response = {url, statusCode: +statusCode};
Expand Down Expand Up @@ -37,59 +58,39 @@ describe(`http utils fetchUrlStream`, () => {
});

beforeAll(() => {
jest.doMock(`https`, () => ({
doMock(`https`, () => ({
get: httpsGetFn,
Agent: class Agent {},
}));
});

beforeEach(() => {
httpsGetFn.mockClear();
});

it(`correct response answered statusCode should be >= 200 and < 300`, async () => {
await expect(fetchUrlStream(getUrl(200))).resolves.toMatchObject({
statusCode: 200,
});

await expect(fetchUrlStream(getUrl(299))).resolves.toMatchObject({
statusCode: 299,
});

expect(httpsGetFn).toHaveBeenCalledTimes(2);
assert.strictEqual((await fetchUrlStream(getUrl(200))).statusCode, 200);
assert.strictEqual((await fetchUrlStream(getUrl(299))).statusCode, 299);
});

it(`bad response`, async () => {
await expect(fetchUrlStream(getUrl(300))).rejects.toThrowError();
await expect(fetchUrlStream(getUrl(199))).rejects.toThrowError();
await assert.rejects(fetchUrlStream(getUrl(300)));
await assert.rejects(fetchUrlStream(getUrl(199)));
});

it(`redirection with correct response`, async () => {
await expect(fetchUrlStream(getUrl(301, 200))).resolves.toMatchObject({
statusCode: 200,
});

expect(httpsGetFn).toHaveBeenCalledTimes(2);

await expect(fetchUrlStream(getUrl(308, 299))).resolves.toMatchObject({
statusCode: 299,
});

expect(httpsGetFn).toHaveBeenCalledTimes(4);
assert.strictEqual((await fetchUrlStream(getUrl(301, 200))).statusCode, 200);
assert.strictEqual((await fetchUrlStream(getUrl(308, 299))).statusCode, 299);
});

it(`redirection with bad response`, async () => {
await expect(fetchUrlStream(getUrl(301, 300))).rejects.toThrowError();
await expect(fetchUrlStream(getUrl(308, 199))).rejects.toThrowError();
await expect(fetchUrlStream(getUrl(301, 302))).rejects.toThrowError();
await expect(fetchUrlStream(getUrl(307))).rejects.toThrowError();
await assert.rejects(fetchUrlStream(getUrl(301, 300)));
await assert.rejects(fetchUrlStream(getUrl(308, 199)));
await assert.rejects(fetchUrlStream(getUrl(301, 302)));
await assert.rejects(fetchUrlStream(getUrl(307)));
});

it(`rejects with error`, async () => {
await expect(fetchUrlStream(getUrl(`error`))).rejects.toThrowError();
await assert.rejects(fetchUrlStream(getUrl(`error`)));
});

it(`rejects when redirection with error`, async () => {
await expect(fetchUrlStream(getUrl(307, `error`))).rejects.toThrowError();
await assert.rejects(fetchUrlStream(getUrl(307, `error`)));
});
});
69 changes: 69 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict';

const fs = require("fs/promises");
const path = require("path");

const pirates = require('pirates');
const { transform } = require('sucrase');

/**
* @param {string} extension File extension. All files with said file extension
* that go through the CJS loader will be transpiled.
* @param {import('sucrase').Options} [options] Options to pass to the Sucrase transform function.
* @returns {import('pirates').RevertFunction}
*/
function addHook(extension, options) {
return pirates.addHook(
(code, filePath) => {
if (!options?.transforms) {
// If there are no Sucrase transform necessary, we can return the code as is.
return code;
}
const { code: transformedCode, sourceMap } = transform(
// Replace dynamic imports of `.ts` files with `require`.
// Hooking into the Node.js ESM resolver would take more effort.
code,
{
...options,
sourceMapOptions: { compiledFilename: filePath },
filePath,
},
);
// Split the source map comment across two strings so that tools like
// source-map-support don't accidentally interpret it as a source map
// comment for this file.
const sourceMappingURL = 'sourceMappingURL';
const suffix = `//# ${sourceMappingURL}=data:application/json,${encodeURIComponent(
JSON.stringify(sourceMap),
)}`;
return `${filePath.endsWith(`types.ts`) ? transformedCode.replace(/\] ?= ?"(Npm|Pnpm|Yarn)";/g, s => s.toLowerCase()) :transformedCode}\n${suffix}`;
},
{ exts: [extension] },
);
}

addHook('.ts', {
transforms: ['imports', 'typescript'],
disableESTransforms: true,
// We ask Sucrase to preserve dynamic imports because we replace them
// ourselves.
preserveDynamicImport: true,
});



async function* findTestFiles(dirpath) {
for await (const dirent of await fs.opendir(dirpath)) {
if (dirent.name === "node_modules") continue;

if (dirent.isDirectory())
yield* findTestFiles(path.join(dirpath, dirent.name));
else if (dirent.name.endsWith(".test.ts")) yield path.join(dirpath, dirent.name);
}
}

(async () => {
for await (const file of findTestFiles(__dirname)) {
require(file);
}
})()
Loading
Loading