test: migrate some tests to Node test runner (#3245)

This commit is contained in:
Tommy Nguyen 2024-07-27 10:03:40 +02:00 коммит произвёл GitHub
Родитель fc19779a48
Коммит b3fd0b32c0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
22 изменённых файлов: 501 добавлений и 462 удалений

Просмотреть файл

@ -0,0 +1,2 @@
---
---

Просмотреть файл

@ -30,20 +30,13 @@
},
"devDependencies": {
"@rnx-kit/eslint-config": "*",
"@rnx-kit/jest-preset": "*",
"@rnx-kit/scripts": "*",
"@rnx-kit/tsconfig": "*",
"@types/babel__core": "^7.0.0",
"@types/babel__helper-plugin-utils": "^7.0.0",
"@types/jest": "^29.2.1",
"@types/node": "^20.0.0",
"eslint": "^8.56.0",
"jest": "^29.2.1",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
},
"jest": {
"preset": "@rnx-kit/jest-preset/private",
"testRegex": "/test/.*\\.test\\.js$"
}
}

Просмотреть файл

@ -1,5 +1,5 @@
// @ts-check
"use strict";
import { equal, throws } from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
describe("@rnx-kit/babel-plugin-import-path-remapper", () => {
const babel = require("@babel/core");
@ -9,20 +9,18 @@ describe("@rnx-kit/babel-plugin-import-path-remapper", () => {
/**
* Returns whether requested source is in @rnx-kit scope.
* @param {string} source
* @returns {boolean}
*/
function isRNXKit(source) {
function isRNXKit(source: string): boolean {
return source.startsWith("@rnx-kit/");
}
/**
* Transforms the specified code.
* @param {string} code
* @param {unknown=} options
* @returns {string | null | undefined}
*/
function transform(code, options = { test: isRNXKit }) {
function transform(
code: string,
options: unknown | undefined = { test: isRNXKit }
): string | null | undefined {
const result = babel.transformSync(code, {
plugins: [[path.join(__dirname, "..", "src", "index.js"), options]],
});
@ -33,19 +31,18 @@ describe("@rnx-kit/babel-plugin-import-path-remapper", () => {
process.chdir(currentWorkingDir);
});
test("throws if no test function is specified", () => {
expect(() => transform("", {})).toThrow(
"Expected option `test` to be a function"
);
it("throws if no test function is specified", () => {
throws(() => transform("", {}), "Expected option `test` to be a function");
});
test("throws if remap is not a function", () => {
expect(() => transform("", { test: isRNXKit, remap: "error" })).toThrow(
it("throws if remap is not a function", () => {
throws(
() => transform("", { test: isRNXKit, remap: "error" }),
"Expected option `remap` to be undefined or a function"
);
});
test("leaves unmatched import/export statements", () => {
it("leaves unmatched import/export statements", () => {
[
"export const zero = () => 0;",
`export * from "@contoso/example/lib/index";`,
@ -56,99 +53,100 @@ describe("@rnx-kit/babel-plugin-import-path-remapper", () => {
`require("@contoso/example/lib/index");`,
`require("fs").readFileSync("@contoso/example/lib/index");`,
].forEach((code) => {
expect(transform(code)).toBe(code);
equal(transform(code), code);
});
});
test("remaps require() calls", () => {
expect(transform(`require("@rnx-kit/example/lib/index");`)).toBe(
it("remaps require() calls", () => {
equal(
transform(`require("@rnx-kit/example/lib/index");`),
`require("@rnx-kit/example/src/index");`
);
});
test("remaps import() calls", () => {
expect(transform(`import("@rnx-kit/example/lib/index");`)).toBe(
it("remaps import() calls", () => {
equal(
transform(`import("@rnx-kit/example/lib/index");`),
`import("@rnx-kit/example/src/index");`
);
});
test("remaps import declaration (all)", () => {
expect(
transform(`import * as Example from "@rnx-kit/example/lib/index";`)
).toBe(`import * as Example from "@rnx-kit/example/src/index";`);
it("remaps import declaration (all)", () => {
equal(
transform(`import * as Example from "@rnx-kit/example/lib/index";`),
`import * as Example from "@rnx-kit/example/src/index";`
);
});
test("remaps import declaration (named)", () => {
expect(
transform(`import { a, b } from "@rnx-kit/example/lib/index";`)
).toBe(`import { a, b } from "@rnx-kit/example/src/index";`);
it("remaps import declaration (named)", () => {
equal(
transform(`import { a, b } from "@rnx-kit/example/lib/index";`),
`import { a, b } from "@rnx-kit/example/src/index";`
);
});
test("remaps export declaration (all)", () => {
expect(transform(`export * from "@rnx-kit/example/lib/index";`)).toBe(
it("remaps export declaration (all)", () => {
equal(
transform(`export * from "@rnx-kit/example/lib/index";`),
`export * from "@rnx-kit/example/src/index";`
);
});
test("remaps export declaration (named)", () => {
expect(
transform(`export { a, b } from "@rnx-kit/example/lib/index";`)
).toBe(`export { a, b } from "@rnx-kit/example/src/index";`);
it("remaps export declaration (named)", () => {
equal(
transform(`export { a, b } from "@rnx-kit/example/lib/index";`),
`export { a, b } from "@rnx-kit/example/src/index";`
);
});
test("remaps `lib` only", () => {
expect(transform(`import A from "@rnx-kit/example/lib";`)).toBe(
it("remaps `lib` only", () => {
equal(
transform(`import A from "@rnx-kit/example/lib";`),
`import A from "@rnx-kit/example/src";`
);
});
test("ignores subsequent `lib` folders", () => {
expect(
transform(`import A from "@rnx-kit/example/lib/index/lib/index";`)
).toBe(`import A from "@rnx-kit/example/src/index/lib/index";`);
it("ignores subsequent `lib` folders", () => {
equal(
transform(`import A from "@rnx-kit/example/lib/index/lib/index";`),
`import A from "@rnx-kit/example/src/index/lib/index";`
);
});
test("preserves magic comments", () => {
expect(
it("preserves magic comments", () => {
equal(
transform(
`import(/* webpackChunkName: "example" */ "@rnx-kit/example/lib/index");`
)
).toBe(
),
`import( /* webpackChunkName: "example" */"@rnx-kit/example/src/index");`
);
});
test("uses custom remap function when importing a module without path", () => {
it("uses custom remap function when importing a module without path", () => {
process.chdir("test/__fixtures__/with-main");
expect(
equal(
transform(
`import(/* webpackChunkName: "example" */ "@rnx-kit/example");`,
{
test: isRNXKit,
remap: (
/** @type {string} */ moduleName,
/** @type {string} */ path
) => `${moduleName}/__mocks__/${path}`,
remap: (moduleName: string, path: string) =>
`${moduleName}/__mocks__/${path}`,
}
)
).toBe(
),
`import( /* webpackChunkName: "example" */"@rnx-kit/example/__mocks__/index.js");`
);
});
test("uses custom remap function when importing a module with path", () => {
expect(
it("uses custom remap function when importing a module with path", () => {
equal(
transform(
`import(/* webpackChunkName: "example" */ "@rnx-kit/example/lib/index");`,
{
test: isRNXKit,
remap: (
/** @type {string} */ moduleName,
/** @type {string} */ path
) => `${moduleName}/__mocks__/${path}`,
remap: (moduleName: string, path: string) =>
`${moduleName}/__mocks__/${path}`,
}
)
).toBe(
),
`import( /* webpackChunkName: "example" */"@rnx-kit/example/__mocks__/lib/index");`
);
});

Просмотреть файл

@ -36,17 +36,11 @@
},
"devDependencies": {
"@rnx-kit/eslint-config": "*",
"@rnx-kit/jest-preset": "*",
"@rnx-kit/scripts": "*",
"@rnx-kit/tsconfig": "*",
"@types/jest": "^29.2.1",
"@types/node": "^20.0.0",
"eslint": "^8.56.0",
"jest": "^29.2.1",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
},
"jest": {
"preset": "@rnx-kit/jest-preset/private"
}
}

Просмотреть файл

@ -14,7 +14,11 @@ export const error: Log = (...args) => console.error(errorTag, ...args);
export const info: Log = (...args) => console.log(infoTag, ...args);
export const warn: Log = (...args) => console.warn(warnTag, ...args);
if (WriteStream.prototype.hasColors() && process.env["NODE_ENV"] !== "test") {
if (
WriteStream.prototype.hasColors() &&
!process.env["NODE_TEST_CONTEXT"] &&
process.env["NODE_ENV"] !== "test"
) {
errorTag = "\u001B[31m\u001B[1merror\u001B[22m\u001B[39m";
infoTag = "\u001B[36m\u001B[1minfo\u001B[22m\u001B[39m";
warnTag = "\u001B[33m\u001B[1mwarn\u001B[22m\u001B[39m";

Просмотреть файл

@ -1,34 +1,34 @@
import { deepEqual, equal } from "node:assert/strict";
import { describe, it } from "node:test";
import { error, info, warn } from "../src/index";
describe("console", () => {
const consoleErrorSpy = jest.spyOn(global.console, "error");
const consoleLogSpy = jest.spyOn(global.console, "log");
const consoleWarnSpy = jest.spyOn(global.console, "warn");
const args = ["string", 0, true];
beforeEach(() => {
consoleErrorSpy.mockReset();
consoleLogSpy.mockReset();
consoleWarnSpy.mockReset();
});
it("prints error messages", (t) => {
const errorMock = t.mock.method(console, "error", () => null);
afterAll(() => {
jest.clearAllMocks();
});
test("prints error messages", () => {
error(...args);
expect(consoleErrorSpy).toHaveBeenCalledWith("error", ...args);
equal(errorMock.mock.calls.length, 1);
deepEqual(errorMock.mock.calls[0].arguments, ["error", ...args]);
});
test("prints info messages", () => {
it("prints info messages", (t) => {
const infoMock = t.mock.method(console, "log", () => null);
info(...args);
expect(consoleLogSpy).toHaveBeenCalledWith("info", ...args);
equal(infoMock.mock.calls.length, 1);
deepEqual(infoMock.mock.calls[0].arguments, ["info", ...args]);
});
test("prints warning messages", () => {
it("prints warning messages", (t) => {
const warnMock = t.mock.method(console, "warn", () => null);
warn(...args);
expect(consoleWarnSpy).toHaveBeenCalledWith("warn", ...args);
equal(warnMock.mock.calls.length, 1);
deepEqual(warnMock.mock.calls[0].arguments, ["warn", ...args]);
});
});

Просмотреть файл

@ -43,14 +43,11 @@
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@rnx-kit/eslint-config": "*",
"@rnx-kit/jest-preset": "*",
"@rnx-kit/scripts": "*",
"@rnx-kit/tsconfig": "*",
"@types/babel__core": "^7.0.0",
"@types/connect": "^3.4.36",
"@types/jest": "^29.2.1",
"eslint": "^8.56.0",
"jest": "^29.2.1",
"metro": "^0.80.0",
"metro-config": "^0.80.0",
"metro-resolver": "^0.80.0",
@ -67,8 +64,5 @@
"metro-resolver",
"type-fest"
]
},
"jest": {
"preset": "@rnx-kit/jest-preset/private"
}
}

Просмотреть файл

@ -2,6 +2,8 @@ import type { IncomingMessage, ServerResponse } from "http";
import type { AssetData } from "metro";
import type { Middleware } from "metro-config";
import type Server from "metro/src/Server";
import { equal } from "node:assert/strict";
import { describe, it } from "node:test";
describe("@rnx-kit/metro-config/assetPluginForMonorepos", () => {
const assetPlugin = require("../src/assetPluginForMonorepos");
@ -15,21 +17,17 @@ describe("@rnx-kit/metro-config/assetPluginForMonorepos", () => {
"/assets/node_modules/@@/@@/react-native",
};
test("escapes `..` in URLs", () => {
it("escapes `..` in URLs", () => {
Object.entries(cases).forEach(([input, output]) => {
const assetData = { httpServerLocation: input } as AssetData;
expect(assetPlugin(assetData)).toEqual(
expect.objectContaining({
httpServerLocation: output,
})
);
equal(assetPlugin(assetData).httpServerLocation, output);
});
});
test("unescapes `..` in URLs", () => {
it("unescapes `..` in URLs", () => {
Object.entries(cases).forEach(([output, input]) => {
const middleware: Middleware = (req: Middleware) => {
expect(req).toEqual(expect.objectContaining({ url: output }));
equal(req.url, output);
return middleware;
};
const server = {

Просмотреть файл

@ -1,5 +1,7 @@
import { deepEqual, equal, match, ok, throws } from "node:assert/strict";
import * as fs from "node:fs";
import * as path from "node:path";
import { afterEach, describe, it } from "node:test";
import { enhanceMiddleware } from "../src/assetPluginForMonorepos";
import {
defaultWatchFolders,
@ -27,38 +29,32 @@ describe("@rnx-kit/metro-config", () => {
afterEach(() => process.chdir(currentWorkingDir));
test("defaultWatchFolders() returns an empty list outside a monorepo", () => {
it("defaultWatchFolders() returns an empty list outside a monorepo", () => {
setFixture("app-repo");
expect(defaultWatchFolders().length).toBe(0);
equal(defaultWatchFolders().length, 0);
});
test("defaultWatchFolders() returns packages in a monorepo", () => {
it("defaultWatchFolders() returns packages in a monorepo", () => {
setFixture("awesome-repo/packages/t-800");
const expected = [
/__fixtures__[/\\]awesome-repo[/\\]node_modules$/,
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]conan$/,
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]dutch$/,
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]john$/,
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]quaid$/,
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]t-800$/,
];
const folders = defaultWatchFolders()
.map((path) => path.replace(/\\/g, "/"))
.sort();
expect(folders).toEqual([
expect.stringMatching(/__fixtures__[/\\]awesome-repo[/\\]node_modules$/),
expect.stringMatching(
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]conan$/
),
expect.stringMatching(
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]dutch$/
),
expect.stringMatching(
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]john$/
),
expect.stringMatching(
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]quaid$/
),
expect.stringMatching(
/__fixtures__[/\\]awesome-repo[/\\]packages[/\\]t-800$/
),
]);
for (let i = 0; i < folders.length; ++i) {
match(folders[i], expected[i]);
}
});
test("resolveUniqueModule() ignores symlinks", () => {
it("resolveUniqueModule() ignores symlinks", () => {
const repo = fixturePath("awesome-repo");
const packageCopy = path.join(
repo,
@ -77,17 +73,15 @@ describe("@rnx-kit/metro-config", () => {
setFixture("awesome-repo/packages/t-800");
expect(
fs.lstatSync("node_modules/react-native").isSymbolicLink()
).toBeTruthy();
ok(fs.lstatSync("node_modules/react-native").isSymbolicLink());
const [reactNativePath, exclude] = resolveUniqueModule("react-native");
expect(reactNativePath).toBe(path.dirname(projectCopy));
expect(exclude.test(packageCopy)).toBeTruthy();
expect(exclude.test(projectCopy)).toBeFalsy();
equal(reactNativePath, path.dirname(projectCopy));
ok(exclude.test(packageCopy));
ok(!exclude.test(projectCopy));
});
test("resolveUniqueModule() handles nested dependencies", () => {
it("resolveUniqueModule() handles nested dependencies", () => {
const repo = fixturePath("awesome-repo");
const packageRnCopy = path.join(
repo,
@ -125,35 +119,37 @@ describe("@rnx-kit/metro-config", () => {
const [reactNativePath, excludeReactNative] =
resolveUniqueModule("react-native");
expect(reactNativePath).toBe(path.dirname(packageRnCopy));
expect(excludeReactNative.test(packageRnCopy)).toBeFalsy();
expect(excludeReactNative.test(projectRnCopy)).toBeTruthy();
equal(reactNativePath, path.dirname(packageRnCopy));
ok(!excludeReactNative.test(packageRnCopy));
ok(excludeReactNative.test(projectRnCopy));
const [matrixPath, excludeMatrix] = resolveUniqueModule("@commando/matrix");
expect(matrixPath).toBe(path.dirname(packageMatrixCopy));
expect(excludeMatrix.test(packageMatrixCopy)).toBeFalsy();
expect(excludeMatrix.test(projectMatrixCopy)).toBeTruthy();
equal(matrixPath, path.dirname(packageMatrixCopy));
ok(!excludeMatrix.test(packageMatrixCopy));
ok(excludeMatrix.test(projectMatrixCopy));
});
test("resolveUniqueModule() throws if a package is not found", () => {
expect(resolveUniqueModule("jest", process.cwd())).toBeDefined();
it("resolveUniqueModule() throws if a package is not found", () => {
ok(resolveUniqueModule("eslint", process.cwd()));
const packageName = "this-package-does-not-exist";
expect(() => resolveUniqueModule(packageName, process.cwd())).toThrow(
`Cannot find module '${packageName}'`
throws(
() => resolveUniqueModule(packageName, process.cwd()),
new Error(`Cannot find module '${packageName}'`)
);
});
test("resolveUniqueModule() escapes characters clashing with regex tokens", () => {
it("resolveUniqueModule() escapes characters clashing with regex tokens", () => {
const repo = fixturePath("pnpm-repo");
const [rnPath, rnExclude] = resolveUniqueModule("react-native", repo);
expect(rnPath).toMatch(
match(
rnPath,
/__fixtures__[/\\]pnpm-repo[/\\]node_modules[/\\]\.pnpm[/\\]github\.com\+facebook\+react-native@72e1eda0736d34d027e4d4b1c3cace529ab5dcf3_react@17\.0\.2[/\\]node_modules[/\\]react-native$/
);
expect(rnExclude.test(path.join(rnPath, "package.json"))).toBeFalsy();
ok(!rnExclude.test(path.join(rnPath, "package.json")));
});
test("exclusionList() ignores extra copies of react and react-native", () => {
it("exclusionList() ignores extra copies of react and react-native", () => {
const repo = fixturePath("awesome-repo");
const reactCopy = path.join(repo, "node_modules", "react", "package.json");
const packageCopy = path.join(
@ -175,31 +171,31 @@ describe("@rnx-kit/metro-config", () => {
// exclude all but the repo's copy.
setFixture("awesome-repo/packages/conan");
const conanExclude = exclusionList();
expect(conanExclude.test(reactCopy)).toBeFalsy();
expect(conanExclude.test(packageCopy)).toBeTruthy();
expect(conanExclude.test(projectCopy)).toBeFalsy();
expect(
ok(!conanExclude.test(reactCopy));
ok(conanExclude.test(packageCopy));
ok(!conanExclude.test(projectCopy));
ok(
conanExclude.test(
path.join("conan", "windows", ".vs", "conan", "v16", "Browse.VC.db")
)
).toBeTruthy();
expect(conanExclude.test("Test.ProjectImports.zip")).toBeTruthy();
);
ok(conanExclude.test("Test.ProjectImports.zip"));
// John has a local copy of react-native and should ignore all other copies.
setFixture("awesome-repo/packages/john");
const johnExclude = exclusionList();
expect(johnExclude.test(reactCopy)).toBeFalsy();
expect(johnExclude.test(packageCopy)).toBeFalsy();
expect(johnExclude.test(projectCopy)).toBeTruthy();
expect(
ok(!johnExclude.test(reactCopy));
ok(!johnExclude.test(packageCopy));
ok(johnExclude.test(projectCopy));
ok(
johnExclude.test(
path.join("john", "windows", ".vs", "conan", "v16", "Browse.VC.db")
)
).toBeTruthy();
expect(johnExclude.test("Test.ProjectImports.zip")).toBeTruthy();
);
ok(johnExclude.test("Test.ProjectImports.zip"));
});
test("exclusionList() returns additional exclusions", () => {
it("exclusionList() returns additional exclusions", () => {
const repo = fixturePath("awesome-repo");
const reactCopy = path.join(repo, "node_modules", "react", "package.json");
const packageCopy = path.join(
@ -219,30 +215,25 @@ describe("@rnx-kit/metro-config", () => {
setFixture("awesome-repo/packages/conan");
const conanExclude = exclusionList([/.*[/\\]__fixtures__[/\\].*/]);
expect(conanExclude.test(reactCopy)).toBeTruthy();
expect(conanExclude.test(packageCopy)).toBeTruthy();
expect(conanExclude.test(projectCopy)).toBeTruthy();
expect(
ok(conanExclude.test(reactCopy));
ok(conanExclude.test(packageCopy));
ok(conanExclude.test(projectCopy));
ok(
conanExclude.test(
path.join("conan", "windows", ".vs", "conan", "v16", "Browse.VC.db")
)
).toBeTruthy();
expect(conanExclude.test("Test.ProjectImports.zip")).toBeTruthy();
);
ok(conanExclude.test("Test.ProjectImports.zip"));
});
});
describe("makeMetroConfig", () => {
const projectRoot = path.resolve("../test-app");
const consoleWarnSpy = jest.spyOn(require("@rnx-kit/console"), "warn");
afterEach(() => {
consoleWarnSpy.mockReset();
});
test("returns a default Metro config", async () => {
it("returns a default Metro config", async () => {
const config = makeMetroConfig({ projectRoot });
expect(Object.keys(config).sort()).toEqual([
deepEqual(Object.keys(config).sort(), [
"cacheStores",
"cacheVersion",
"maxWorkers",
@ -279,7 +270,7 @@ describe("makeMetroConfig", () => {
fail("Expected `config.watchFolders` to be an array");
}
expect(Object.keys(config.resolver.extraNodeModules)).toEqual([
deepEqual(Object.keys(config.resolver.extraNodeModules), [
"react",
"react-native",
"react-native-macos",
@ -288,11 +279,11 @@ describe("makeMetroConfig", () => {
]);
const blockList = exclusionList([], projectRoot).source;
expect(config.resolver.blacklistRE.source).toBe(blockList);
expect(config.resolver.blockList.source).toBe(blockList);
equal(config.resolver.blacklistRE.source, blockList);
equal(config.resolver.blockList.source, blockList);
expect(config.server.enhanceMiddleware).toBe(enhanceMiddleware);
expect(config.transformer.assetPlugins).toEqual([]);
equal(config.server.enhanceMiddleware, enhanceMiddleware);
deepEqual(config.transformer.assetPlugins, []);
const opts = { dev: false, hot: false };
const transformerOptions = await config.transformer.getTransformOptions(
@ -300,21 +291,21 @@ describe("makeMetroConfig", () => {
opts,
() => Promise.resolve([])
);
expect(transformerOptions?.transform).toEqual({
deepEqual(transformerOptions?.transform, {
experimentalImportSupport: false,
inlineRequires: false,
});
expect(config.watchFolders.length).toBeGreaterThan(0);
ok(config.watchFolders.length > 0);
});
test("merges Metro configs", async () => {
it("merges Metro configs", async () => {
const config = makeMetroConfig({
projectRoot,
resetCache: true,
});
expect(Object.keys(config).sort()).toEqual([
deepEqual(Object.keys(config).sort(), [
"cacheStores",
"cacheVersion",
"maxWorkers",
@ -333,8 +324,8 @@ describe("makeMetroConfig", () => {
"watcher",
]);
expect(config.projectRoot).toBe(projectRoot);
expect(config.resetCache).toBeTruthy();
equal(config.projectRoot, projectRoot);
ok(config.resetCache);
if (!config.resolver) {
fail("Expected `config.resolver` to be defined");
@ -354,7 +345,7 @@ describe("makeMetroConfig", () => {
fail("Expected `config.watchFolders` to be an array");
}
expect(Object.keys(config.resolver.extraNodeModules)).toEqual([
deepEqual(Object.keys(config.resolver.extraNodeModules), [
"react",
"react-native",
"react-native-macos",
@ -363,11 +354,11 @@ describe("makeMetroConfig", () => {
]);
const blockList = exclusionList([], projectRoot).source;
expect(config.resolver.blacklistRE.source).toBe(blockList);
expect(config.resolver.blockList.source).toBe(blockList);
equal(config.resolver.blacklistRE.source, blockList);
equal(config.resolver.blockList.source, blockList);
expect(config.server.enhanceMiddleware).toBe(enhanceMiddleware);
expect(config.transformer.assetPlugins).toEqual([]);
equal(config.server.enhanceMiddleware, enhanceMiddleware);
deepEqual(config.transformer.assetPlugins, []);
const opts = { dev: false, hot: false };
const transformerOptions = await config.transformer.getTransformOptions(
@ -375,15 +366,15 @@ describe("makeMetroConfig", () => {
opts,
() => Promise.resolve([])
);
expect(transformerOptions?.transform).toEqual({
deepEqual(transformerOptions?.transform, {
experimentalImportSupport: false,
inlineRequires: false,
});
expect(config.watchFolders.length).toBeGreaterThan(0);
ok(config.watchFolders.length > 0);
});
test("merges `extraNodeModules`", () => {
it("merges `extraNodeModules`", () => {
const config = makeMetroConfig({
projectRoot,
resolver: {
@ -399,7 +390,7 @@ describe("makeMetroConfig", () => {
fail("Expected config.resolver.extraNodeModules to be set");
}
expect(Object.keys(extraNodeModules).sort()).toEqual([
deepEqual(Object.keys(extraNodeModules).sort(), [
"@babel/runtime",
"my-awesome-package",
"react",
@ -408,11 +399,11 @@ describe("makeMetroConfig", () => {
"react-native-windows",
]);
expect(extraNodeModules["my-awesome-package"]).toBe("/skynet");
expect(extraNodeModules["react-native"]).toBe("/skynet");
equal(extraNodeModules["my-awesome-package"], "/skynet");
equal(extraNodeModules["react-native"], "/skynet");
});
test("sets both `blacklistRE` and `blockList`", () => {
it("sets both `blacklistRE` and `blockList`", () => {
const configWithBlacklist = makeMetroConfig({
resolver: {
blacklistRE: /.*/,
@ -420,8 +411,8 @@ describe("makeMetroConfig", () => {
});
const blacklistRE = configWithBlacklist.resolver?.blacklistRE;
expect(blacklistRE).not.toBeUndefined();
expect(blacklistRE).toBe(configWithBlacklist.resolver?.blockList);
ok(blacklistRE);
equal(blacklistRE, configWithBlacklist.resolver?.blockList);
const configWithBlockList = makeMetroConfig({
resolver: {
@ -430,7 +421,7 @@ describe("makeMetroConfig", () => {
});
const blockList = configWithBlockList.resolver?.blockList;
expect(blockList).not.toBeUndefined();
expect(blockList).toBe(configWithBlockList.resolver?.blacklistRE);
ok(blockList);
equal(blockList, configWithBlockList.resolver?.blacklistRE);
});
});

Просмотреть файл

@ -54,12 +54,10 @@
},
"devDependencies": {
"@rnx-kit/eslint-config": "*",
"@rnx-kit/jest-preset": "*",
"@rnx-kit/scripts": "*",
"@rnx-kit/tsconfig": "*",
"@types/node": "^20.0.0",
"eslint": "^8.56.0",
"jest": "^29.2.1",
"metro": "^0.80.0",
"metro-config": "^0.80.0",
"metro-core": "^0.80.0",
@ -67,8 +65,5 @@
"metro-source-map": "^0.80.0",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
},
"jest": {
"preset": "@rnx-kit/jest-preset/private"
}
}

Просмотреть файл

@ -1,9 +1,8 @@
import * as os from "node:os";
import { ok, throws } from "node:assert/strict";
import * as path from "node:path";
import { describe, it } from "node:test";
import { requireModuleFromMetro } from "../src/metro";
const nixOnlyTest = os.platform() === "win32" ? test.skip : test;
describe("requireModuleFromMetro", () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const context: any = {};
@ -12,11 +11,11 @@ describe("requireModuleFromMetro", () => {
return requireModuleFromMetro("metro-resolver", fromDir).resolve;
}
test("returns `metro-resolver` installed by `react-native`", () => {
it("returns `metro-resolver` installed by `react-native`", () => {
const p = path.join(__dirname, "__fixtures__", "metro-resolver-duplicates");
expect(getMetroResolver(p)(context, "", null)).toEqual(
expect.stringContaining(
ok(
getMetroResolver(p)(context, "", null).includes(
path.join(
"metro-resolver-duplicates",
"node_modules",
@ -30,20 +29,26 @@ describe("requireModuleFromMetro", () => {
});
// The symlinks under `pnpm` don't work on Windows
nixOnlyTest("returns `metro-resolver` from a central storage", () => {
const p = path.join(__dirname, "__fixtures__", "pnpm");
it(
"returns `metro-resolver` from a central storage",
{ skip: process.platform === "win32" },
() => {
const p = path.join(__dirname, "__fixtures__", "pnpm");
expect(getMetroResolver(p)(context, "", null)).toEqual(
expect.stringContaining(
path.join("pnpm", "node_modules", ".pnpm", "metro-resolver")
)
);
});
ok(
getMetroResolver(p)(context, "", null).includes(
path.join("pnpm", "node_modules", ".pnpm", "metro-resolver")
)
);
}
);
test("throws if `metro-resolver` cannot be found", () => {
it("throws if `metro-resolver` cannot be found", () => {
const cwd = process.cwd();
const root = cwd.substring(0, cwd.indexOf(path.sep) + 1);
expect(() => getMetroResolver(root)(context, "", null)).toThrow(
throws(
() => getMetroResolver(root)(context, "", null),
"Cannot find module"
);
});

Просмотреть файл

@ -1,4 +1,6 @@
import * as path from "path";
import { deepEqual, equal, throws } from "node:assert/strict";
import * as path from "node:path";
import { describe, it } from "node:test";
import {
expandPlatformExtensions,
getAvailablePlatformsUncached,
@ -7,8 +9,8 @@ import {
} from "../src/platform";
describe("React Native > Platform", () => {
test("expandPlatformExtensions() expands returns all platform extensions", () => {
expect(expandPlatformExtensions("ios", [".ts", ".tsx"])).toEqual([
it("expandPlatformExtensions() expands returns all platform extensions", () => {
deepEqual(expandPlatformExtensions("ios", [".ts", ".tsx"]), [
".ios.ts",
".ios.tsx",
".native.ts",
@ -16,7 +18,7 @@ describe("React Native > Platform", () => {
".ts",
".tsx",
]);
expect(expandPlatformExtensions("windows", [".ts", ".tsx"])).toEqual([
deepEqual(expandPlatformExtensions("windows", [".ts", ".tsx"]), [
".windows.ts",
".windows.tsx",
".win.ts",
@ -28,9 +30,9 @@ describe("React Native > Platform", () => {
]);
});
test("getAvailablePlatformsUncached() returns available platforms", () => {
it("getAvailablePlatformsUncached() returns available platforms", () => {
const fixture = path.join(__dirname, "__fixtures__", "available-platforms");
expect(getAvailablePlatformsUncached(fixture)).toEqual({
deepEqual(getAvailablePlatformsUncached(fixture), {
android: "",
ios: "",
macos: "react-native-macos",
@ -39,7 +41,7 @@ describe("React Native > Platform", () => {
});
});
test("getAvailablePlatformsUncached() finds package root", () => {
it("getAvailablePlatformsUncached() finds package root", () => {
const fixture = path.join(
__dirname,
"__fixtures__",
@ -47,7 +49,7 @@ describe("React Native > Platform", () => {
"node_modules",
"react-native"
);
expect(getAvailablePlatformsUncached(fixture)).toEqual({
deepEqual(getAvailablePlatformsUncached(fixture), {
android: "",
ios: "",
macos: "react-native-macos",
@ -56,30 +58,30 @@ describe("React Native > Platform", () => {
});
});
test("getAvailablePlatformsUncached() handles 'missing' package root", () => {
expect(getAvailablePlatformsUncached()).toEqual({
it("getAvailablePlatformsUncached() handles 'missing' package root", () => {
deepEqual(getAvailablePlatformsUncached(), {
android: "",
ios: "",
});
});
test("parsePlatform() succeeds for all known platforms", () => {
expect(parsePlatform("ios")).toEqual("ios");
expect(parsePlatform("android")).toEqual("android");
expect(parsePlatform("windows")).toEqual("windows");
expect(parsePlatform("win32")).toEqual("win32");
expect(parsePlatform("macos")).toEqual("macos");
it("parsePlatform() succeeds for all known platforms", () => {
equal(parsePlatform("ios"), "ios");
equal(parsePlatform("android"), "android");
equal(parsePlatform("windows"), "windows");
equal(parsePlatform("win32"), "win32");
equal(parsePlatform("macos"), "macos");
});
test("parsePlatform() throws on failure", () => {
expect(() => parsePlatform("invalid")).toThrow();
it("parsePlatform() throws on failure", () => {
throws(() => parsePlatform("invalid"));
});
test("platformExtensions() returns extensions", () => {
expect(platformExtensions("android")).toEqual(["android", "native"]);
expect(platformExtensions("ios")).toEqual(["ios", "native"]);
expect(platformExtensions("macos")).toEqual(["macos", "native"]);
expect(platformExtensions("win32")).toEqual(["win32", "win", "native"]);
expect(platformExtensions("windows")).toEqual(["windows", "win", "native"]);
it("platformExtensions() returns extensions", () => {
deepEqual(platformExtensions("android"), ["android", "native"]);
deepEqual(platformExtensions("ios"), ["ios", "native"]);
deepEqual(platformExtensions("macos"), ["macos", "native"]);
deepEqual(platformExtensions("win32"), ["win32", "win", "native"]);
deepEqual(platformExtensions("windows"), ["windows", "win", "native"]);
});
});

Просмотреть файл

@ -43,19 +43,14 @@
},
"devDependencies": {
"@rnx-kit/eslint-config": "*",
"@rnx-kit/jest-preset": "*",
"@rnx-kit/scripts": "*",
"@rnx-kit/tsconfig": "*",
"@types/node": "^20.0.0",
"eslint": "^8.56.0",
"jest": "^29.2.1",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
},
"engines": {
"node": ">=14.15"
},
"jest": {
"preset": "@rnx-kit/jest-preset/private"
}
}

Просмотреть файл

@ -27,12 +27,13 @@ export const WORKSPACE_ROOT_SENTINELS = [
BUN_LOCKB,
];
const isTesting = Boolean(process.env.NODE_TEST_CONTEXT);
function dirnameAll(paths: string[]): string[] {
return paths.map((p) => path.dirname(p));
}
function makeFindSentinel<R>(finder: (name: string[]) => R) {
const isTesting = Boolean(process.env.JEST_WORKER_ID);
let result: R | undefined;
return () => {
if (isTesting || !result) {

Просмотреть файл

@ -1,3 +1,6 @@
import { equal, match } from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import { findSentinel, findSentinelSync } from "../src/common";
import {
findWorkspacePackages,
findWorkspacePackagesSync,
@ -6,27 +9,51 @@ import {
} from "../src/index";
import { setFixture, unsetFixture } from "./helper";
describe("findSentinel", () => {
afterEach(() => {
unsetFixture();
});
it("returns sentinel for Bun", async () => {
setFixture("bun");
match((await findSentinel()) ?? "", /[/\\]bun.lockb$/);
});
it("returns sentinel for Bun (sync)", () => {
setFixture("bun");
match(findSentinelSync() ?? "", /[/\\]bun.lockb$/);
});
});
describe("findWorkspacePackages", () => {
const packages = [
expect.stringMatching(/__fixtures__[/\\]bun[/\\]packages[/\\]conan$/),
expect.stringMatching(/__fixtures__[/\\]bun[/\\]packages[/\\]dutch$/),
expect.stringMatching(/__fixtures__[/\\]bun[/\\]packages[/\\]john$/),
expect.stringMatching(/__fixtures__[/\\]bun[/\\]packages[/\\]quaid$/),
expect.stringMatching(/__fixtures__[/\\]bun[/\\]packages[/\\]t-800$/),
/__fixtures__[/\\]bun[/\\]packages[/\\]conan$/,
/__fixtures__[/\\]bun[/\\]packages[/\\]dutch$/,
/__fixtures__[/\\]bun[/\\]packages[/\\]john$/,
/__fixtures__[/\\]bun[/\\]packages[/\\]quaid$/,
/__fixtures__[/\\]bun[/\\]packages[/\\]t-800$/,
];
afterEach(() => {
unsetFixture();
});
test("returns packages for Bun workspaces", async () => {
it("returns packages for Bun workspaces", async () => {
setFixture("bun");
expect((await findWorkspacePackages()).sort()).toEqual(packages);
const result = (await findWorkspacePackages()).sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
test("returns packages for Bun workspaces (sync)", () => {
it("returns packages for Bun workspaces (sync)", () => {
setFixture("bun");
expect(findWorkspacePackagesSync().sort()).toEqual(packages);
const result = findWorkspacePackagesSync().sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
});
@ -35,13 +62,13 @@ describe("findWorkspaceRoot", () => {
unsetFixture();
});
test("returns workspace root for Bun workspaces", async () => {
it("returns workspace root for Bun workspaces", async () => {
const root = setFixture("bun");
expect(await findWorkspaceRoot()).toBe(root);
equal(await findWorkspaceRoot(), root);
});
test("returns workspace root for Bun workspaces (sync)", () => {
it("returns workspace root for Bun workspaces (sync)", () => {
const root = setFixture("bun");
expect(findWorkspaceRootSync()).toBe(root);
equal(findWorkspaceRootSync(), root);
});
});

Просмотреть файл

@ -1,89 +1,13 @@
import {
findPackages,
findPackagesSync,
findSentinel,
findSentinelSync,
} from "../src/common";
import { setFixture, unsetFixture } from "./helper";
import { deepEqual } from "node:assert/strict";
import { describe, it } from "node:test";
import { findPackages, findPackagesSync } from "../src/common";
describe("findPackages", () => {
test("returns an empty array when passed no patterns", () => {
expect(findPackages(undefined, "/")).resolves.toEqual([]);
it("returns an empty array when passed no patterns", async () => {
deepEqual(await findPackages(undefined, "/"), []);
});
test("returns an empty array when passed no patterns (sync)", () => {
expect(findPackagesSync(undefined, "/")).toEqual([]);
});
});
describe("findSentinel", () => {
afterEach(() => {
unsetFixture();
});
test("returns sentinel for Bun", async () => {
setFixture("bun");
expect(await findSentinel()).toMatch(/[/\\]bun.lockb$/);
});
test("returns sentinel for Bun (sync)", () => {
setFixture("bun");
expect(findSentinelSync()).toMatch(/[/\\]bun.lockb$/);
});
test("returns sentinel for Lerna", async () => {
setFixture("lerna-packages");
expect(await findSentinel()).toMatch(/[/\\]lerna.json$/);
setFixture("lerna-workspaces");
expect(await findSentinel()).toMatch(/[/\\]lerna.json$/);
});
test("returns sentinel for Lerna (sync)", () => {
setFixture("lerna-packages");
expect(findSentinelSync()).toMatch(/[/\\]lerna.json$/);
setFixture("lerna-workspaces");
expect(findSentinelSync()).toMatch(/[/\\]lerna.json$/);
});
test("returns sentinel for npm", async () => {
setFixture("npm");
expect(await findSentinel()).toMatch(/[/\\]package-lock.json$/);
});
test("returns sentinel for npm (sync)", () => {
setFixture("npm");
expect(findSentinelSync()).toMatch(/[/\\]package-lock.json$/);
});
test("returns sentinel for pnpm", async () => {
setFixture("pnpm");
expect(await findSentinel()).toMatch(/[/\\]pnpm-workspace.yaml$/);
});
test("returns sentinel for pnpm (sync)", () => {
setFixture("pnpm");
expect(findSentinelSync()).toMatch(/[/\\]pnpm-workspace.yaml$/);
});
test("returns sentinel for Rush", async () => {
setFixture("rush");
expect(await findSentinel()).toMatch(/[/\\]rush.json$/);
});
test("returns sentinel for Rush (sync)", () => {
setFixture("rush");
expect(findSentinelSync()).toMatch(/[/\\]rush.json$/);
});
test("returns sentinel for Yarn", async () => {
setFixture("yarn");
expect(await findSentinel()).toMatch(/[/\\]yarn.lock$/);
});
test("returns sentinel for Yarn (sync)", () => {
setFixture("yarn");
expect(findSentinelSync()).toMatch(/[/\\]yarn.lock$/);
it("returns an empty array when passed no patterns (sync)", () => {
deepEqual(findPackagesSync(undefined, "/"), []);
});
});

Просмотреть файл

@ -1,3 +1,6 @@
import { equal, match } from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import { findSentinel, findSentinelSync } from "../src/common";
import {
findWorkspacePackages,
findWorkspacePackagesSync,
@ -6,65 +9,83 @@ import {
} from "../src/index";
import { setFixture, unsetFixture } from "./helper";
describe("findSentinel", () => {
afterEach(() => {
unsetFixture();
});
it("returns sentinel for Lerna", async () => {
setFixture("lerna-packages");
match((await findSentinel()) ?? "", /[/\\]lerna.json$/);
setFixture("lerna-workspaces");
match((await findSentinel()) ?? "", /[/\\]lerna.json$/);
});
it("returns sentinel for Lerna (sync)", () => {
setFixture("lerna-packages");
match(findSentinelSync() ?? "", /[/\\]lerna.json$/);
setFixture("lerna-workspaces");
match(findSentinelSync() ?? "", /[/\\]lerna.json$/);
});
});
describe("findWorkspacePackages", () => {
const packagesPackages = [
expect.stringMatching(
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]conan$/
),
expect.stringMatching(
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]dutch$/
),
expect.stringMatching(
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]john$/
),
expect.stringMatching(
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]quaid$/
),
expect.stringMatching(
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]t-800$/
),
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]conan$/,
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]dutch$/,
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]john$/,
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]quaid$/,
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]t-800$/,
];
const workspacesPackages = [
expect.stringMatching(
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]conan$/
),
expect.stringMatching(
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]dutch$/
),
expect.stringMatching(
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]john$/
),
expect.stringMatching(
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]quaid$/
),
expect.stringMatching(
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]t-800$/
),
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]conan$/,
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]dutch$/,
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]john$/,
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]quaid$/,
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]t-800$/,
];
afterEach(() => {
unsetFixture();
});
test("returns packages for Lerna workspaces", async () => {
it("returns packages for Lerna workspaces", async () => {
setFixture("lerna-packages");
expect((await findWorkspacePackages()).sort()).toEqual(packagesPackages);
const result = (await findWorkspacePackages()).sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packagesPackages[i]);
}
});
test("returns packages for Lerna workspaces (sync)", () => {
it("returns packages for Lerna workspaces (sync)", () => {
setFixture("lerna-packages");
expect(findWorkspacePackagesSync().sort()).toEqual(packagesPackages);
const result = findWorkspacePackagesSync().sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packagesPackages[i]);
}
});
test("returns packages for delegated workspaces", async () => {
it("returns packages for delegated workspaces", async () => {
setFixture("lerna-workspaces");
expect((await findWorkspacePackages()).sort()).toEqual(workspacesPackages);
const result = (await findWorkspacePackages()).sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], workspacesPackages[i]);
}
});
test("returns packages for delegated workspaces (sync)", () => {
it("returns packages for delegated workspaces (sync)", () => {
setFixture("lerna-workspaces");
expect(findWorkspacePackagesSync().sort()).toEqual(workspacesPackages);
const result = findWorkspacePackagesSync().sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], workspacesPackages[i]);
}
});
});
@ -73,23 +94,23 @@ describe("findWorkspaceRoot", () => {
unsetFixture();
});
test("returns workspace root for Lerna workspaces", async () => {
it("returns workspace root for Lerna workspaces", async () => {
const root = setFixture("lerna-packages");
expect(await findWorkspaceRoot()).toBe(root);
equal(await findWorkspaceRoot(), root);
});
test("returns workspace root for Lerna workspaces (sync)", () => {
it("returns workspace root for Lerna workspaces (sync)", () => {
const root = setFixture("lerna-packages");
expect(findWorkspaceRootSync()).toBe(root);
equal(findWorkspaceRootSync(), root);
});
test("returns workspace root for delegated workspaces", async () => {
it("returns workspace root for delegated workspaces", async () => {
const root = setFixture("lerna-workspaces");
expect(await findWorkspaceRoot()).toBe(root);
equal(await findWorkspaceRoot(), root);
});
test("returns workspace root for delegated workspaces (sync)", () => {
it("returns workspace root for delegated workspaces (sync)", () => {
const root = setFixture("lerna-workspaces");
expect(findWorkspaceRootSync()).toBe(root);
equal(findWorkspaceRootSync(), root);
});
});

Просмотреть файл

@ -1,3 +1,6 @@
import { equal, match } from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import { findSentinel, findSentinelSync } from "../src/common";
import {
findWorkspacePackages,
findWorkspacePackagesSync,
@ -6,27 +9,51 @@ import {
} from "../src/index";
import { setFixture, unsetFixture } from "./helper";
describe("findSentinel", () => {
afterEach(() => {
unsetFixture();
});
it("returns sentinel for npm", async () => {
setFixture("npm");
match((await findSentinel()) ?? "", /[/\\]package-lock.json$/);
});
it("returns sentinel for npm (sync)", () => {
setFixture("npm");
match(findSentinelSync() ?? "", /[/\\]package-lock.json$/);
});
});
describe("findWorkspacePackages", () => {
const packages = [
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]conan$/),
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]dutch$/),
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]john$/),
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]quaid$/),
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]t-800$/),
/__fixtures__[/\\]npm[/\\]packages[/\\]conan$/,
/__fixtures__[/\\]npm[/\\]packages[/\\]dutch$/,
/__fixtures__[/\\]npm[/\\]packages[/\\]john$/,
/__fixtures__[/\\]npm[/\\]packages[/\\]quaid$/,
/__fixtures__[/\\]npm[/\\]packages[/\\]t-800$/,
];
afterEach(() => {
unsetFixture();
});
test("returns packages for npm workspaces", async () => {
it("returns packages for npm workspaces", async () => {
setFixture("npm");
expect((await findWorkspacePackages()).sort()).toEqual(packages);
const result = (await findWorkspacePackages()).sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
test("returns packages for npm workspaces (sync)", () => {
it("returns packages for npm workspaces (sync)", () => {
setFixture("npm");
expect(findWorkspacePackagesSync().sort()).toEqual(packages);
const result = findWorkspacePackagesSync().sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
});
@ -35,13 +62,13 @@ describe("findWorkspaceRoot", () => {
unsetFixture();
});
test("returns workspace root for npm workspaces", async () => {
it("returns workspace root for npm workspaces", async () => {
const root = setFixture("npm");
expect(await findWorkspaceRoot()).toBe(root);
equal(await findWorkspaceRoot(), root);
});
test("returns workspace root for npm workspaces (sync)", () => {
it("returns workspace root for npm workspaces (sync)", () => {
const root = setFixture("npm");
expect(findWorkspaceRootSync()).toBe(root);
equal(findWorkspaceRootSync(), root);
});
});

Просмотреть файл

@ -1,3 +1,6 @@
import { equal, match } from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import { findSentinel, findSentinelSync } from "../src/common";
import {
findWorkspacePackages,
findWorkspacePackagesSync,
@ -6,27 +9,51 @@ import {
} from "../src/index";
import { setFixture, unsetFixture } from "./helper";
describe("findSentinel", () => {
afterEach(() => {
unsetFixture();
});
it("returns sentinel for pnpm", async () => {
setFixture("pnpm");
match((await findSentinel()) ?? "", /[/\\]pnpm-workspace.yaml$/);
});
it("returns sentinel for pnpm (sync)", () => {
setFixture("pnpm");
match(findSentinelSync() ?? "", /[/\\]pnpm-workspace.yaml$/);
});
});
describe("findWorkspacePackages", () => {
const packages = [
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]conan$/),
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]dutch$/),
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]john$/),
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]quaid$/),
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]t-800$/),
/__fixtures__[/\\]pnpm[/\\]packages[/\\]conan$/,
/__fixtures__[/\\]pnpm[/\\]packages[/\\]dutch$/,
/__fixtures__[/\\]pnpm[/\\]packages[/\\]john$/,
/__fixtures__[/\\]pnpm[/\\]packages[/\\]quaid$/,
/__fixtures__[/\\]pnpm[/\\]packages[/\\]t-800$/,
];
afterEach(() => {
unsetFixture();
});
test("returns packages for pnpm workspaces", async () => {
it("returns packages for pnpm workspaces", async () => {
setFixture("pnpm");
expect((await findWorkspacePackages()).sort()).toEqual(packages);
const result = (await findWorkspacePackages()).sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
test("returns packages for pnpm workspaces (sync)", () => {
it("returns packages for pnpm workspaces (sync)", () => {
setFixture("pnpm");
expect(findWorkspacePackagesSync().sort()).toEqual(packages);
const result = findWorkspacePackagesSync().sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
});
@ -35,13 +62,13 @@ describe("findWorkspaceRoot", () => {
unsetFixture();
});
test("returns workspace root for pnpm workspaces", async () => {
it("returns workspace root for pnpm workspaces", async () => {
const root = setFixture("pnpm");
expect(await findWorkspaceRoot()).toBe(root);
equal(await findWorkspaceRoot(), root);
});
test("returns workspace root for pnpm workspaces (sync)", async () => {
it("returns workspace root for pnpm workspaces (sync)", async () => {
const root = setFixture("pnpm");
expect(findWorkspaceRootSync()).toBe(root);
equal(findWorkspaceRootSync(), root);
});
});

Просмотреть файл

@ -1,3 +1,6 @@
import { equal, match } from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import { findSentinel, findSentinelSync } from "../src/common";
import {
findWorkspacePackages,
findWorkspacePackagesSync,
@ -6,27 +9,51 @@ import {
} from "../src/index";
import { setFixture, unsetFixture } from "./helper";
describe("findSentinel", () => {
afterEach(() => {
unsetFixture();
});
it("returns sentinel for Rush", async () => {
setFixture("rush");
match((await findSentinel()) ?? "", /[/\\]rush.json$/);
});
it("returns sentinel for Rush (sync)", () => {
setFixture("rush");
match(findSentinelSync() ?? "", /[/\\]rush.json$/);
});
});
describe("findWorkspacePackages", () => {
const packages = [
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]conan$/),
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]dutch$/),
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]john$/),
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]quaid$/),
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]t-800$/),
/__fixtures__[/\\]rush[/\\]packages[/\\]conan$/,
/__fixtures__[/\\]rush[/\\]packages[/\\]dutch$/,
/__fixtures__[/\\]rush[/\\]packages[/\\]john$/,
/__fixtures__[/\\]rush[/\\]packages[/\\]quaid$/,
/__fixtures__[/\\]rush[/\\]packages[/\\]t-800$/,
];
afterEach(() => {
unsetFixture();
});
test("returns packages for Rush workspaces", async () => {
it("returns packages for Rush workspaces", async () => {
setFixture("rush");
expect((await findWorkspacePackages()).sort()).toEqual(packages);
const result = (await findWorkspacePackages()).sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
test("returns packages for Rush workspaces (sync)", () => {
it("returns packages for Rush workspaces (sync)", () => {
setFixture("rush");
expect(findWorkspacePackagesSync().sort()).toEqual(packages);
const result = findWorkspacePackagesSync().sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
});
@ -35,13 +62,13 @@ describe("findWorkspaceRoot", () => {
unsetFixture();
});
test("returns workspace root for Rush workspaces", async () => {
it("returns workspace root for Rush workspaces", async () => {
const root = setFixture("rush");
expect(await findWorkspaceRoot()).toBe(root);
equal(await findWorkspaceRoot(), root);
});
test("returns workspace root for Rush workspaces (sync)", () => {
it("returns workspace root for Rush workspaces (sync)", () => {
const root = setFixture("rush");
expect(findWorkspaceRootSync()).toBe(root);
equal(findWorkspaceRootSync(), root);
});
});

Просмотреть файл

@ -1,3 +1,6 @@
import { equal, match } from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import { findSentinel, findSentinelSync } from "../src/common";
import {
findWorkspacePackages,
findWorkspacePackagesSync,
@ -6,27 +9,51 @@ import {
} from "../src/index";
import { setFixture, unsetFixture } from "./helper";
describe("findSentinel", () => {
afterEach(() => {
unsetFixture();
});
it("returns sentinel for Yarn", async () => {
setFixture("yarn");
match((await findSentinel()) ?? "", /[/\\]yarn.lock$/);
});
it("returns sentinel for Yarn (sync)", () => {
setFixture("yarn");
match(findSentinelSync() ?? "", /[/\\]yarn.lock$/);
});
});
describe("findWorkspacePackages", () => {
const packages = [
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]conan$/),
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]dutch$/),
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]john$/),
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]quaid$/),
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]t-800$/),
/__fixtures__[/\\]yarn[/\\]packages[/\\]conan$/,
/__fixtures__[/\\]yarn[/\\]packages[/\\]dutch$/,
/__fixtures__[/\\]yarn[/\\]packages[/\\]john$/,
/__fixtures__[/\\]yarn[/\\]packages[/\\]quaid$/,
/__fixtures__[/\\]yarn[/\\]packages[/\\]t-800$/,
];
afterEach(() => {
unsetFixture();
});
test("returns packages for Yarn workspaces", async () => {
it("returns packages for Yarn workspaces", async () => {
setFixture("yarn");
expect((await findWorkspacePackages()).sort()).toEqual(packages);
const result = (await findWorkspacePackages()).sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
test("returns packages for Yarn workspaces (sync)", () => {
it("returns packages for Yarn workspaces (sync)", () => {
setFixture("yarn");
expect(findWorkspacePackagesSync().sort()).toEqual(packages);
const result = findWorkspacePackagesSync().sort();
for (let i = 0; i < result.length; ++i) {
match(result[i], packages[i]);
}
});
});
@ -35,13 +62,13 @@ describe("findWorkspaceRoot", () => {
unsetFixture();
});
test("returns workspace root for Yarn workspaces", async () => {
it("returns workspace root for Yarn workspaces", async () => {
const root = setFixture("yarn");
expect(await findWorkspaceRoot()).toBe(root);
equal(await findWorkspaceRoot(), root);
});
test("returns workspace root for Yarn workspaces (sync)", () => {
it("returns workspace root for Yarn workspaces (sync)", () => {
const root = setFixture("yarn");
expect(findWorkspaceRootSync()).toBe(root);
equal(findWorkspaceRootSync(), root);
});
});

Просмотреть файл

@ -3654,16 +3654,13 @@ __metadata:
"@babel/core": "npm:^7.0.0"
"@babel/helper-plugin-utils": "npm:^7.0.0"
"@rnx-kit/eslint-config": "npm:*"
"@rnx-kit/jest-preset": "npm:*"
"@rnx-kit/scripts": "npm:*"
"@rnx-kit/tools-node": "npm:^2.0.1"
"@rnx-kit/tsconfig": "npm:*"
"@types/babel__core": "npm:^7.0.0"
"@types/babel__helper-plugin-utils": "npm:^7.0.0"
"@types/jest": "npm:^29.2.1"
"@types/node": "npm:^20.0.0"
eslint: "npm:^8.56.0"
jest: "npm:^29.2.1"
prettier: "npm:^3.0.0"
typescript: "npm:^5.0.0"
languageName: unknown
@ -3885,13 +3882,10 @@ __metadata:
resolution: "@rnx-kit/console@workspace:packages/console"
dependencies:
"@rnx-kit/eslint-config": "npm:*"
"@rnx-kit/jest-preset": "npm:*"
"@rnx-kit/scripts": "npm:*"
"@rnx-kit/tsconfig": "npm:*"
"@types/jest": "npm:^29.2.1"
"@types/node": "npm:^20.0.0"
eslint: "npm:^8.56.0"
jest: "npm:^29.2.1"
prettier: "npm:^3.0.0"
typescript: "npm:^5.0.0"
languageName: unknown
@ -4030,7 +4024,6 @@ __metadata:
"@babel/preset-env": "npm:^7.20.0"
"@rnx-kit/console": "npm:^1.0.0"
"@rnx-kit/eslint-config": "npm:*"
"@rnx-kit/jest-preset": "npm:*"
"@rnx-kit/scripts": "npm:*"
"@rnx-kit/tools-node": "npm:^2.0.0"
"@rnx-kit/tools-react-native": "npm:^1.3.4"
@ -4038,9 +4031,7 @@ __metadata:
"@rnx-kit/tsconfig": "npm:*"
"@types/babel__core": "npm:^7.0.0"
"@types/connect": "npm:^3.4.36"
"@types/jest": "npm:^29.2.1"
eslint: "npm:^8.56.0"
jest: "npm:^29.2.1"
metro: "npm:^0.80.0"
metro-config: "npm:^0.80.0"
metro-resolver: "npm:^0.80.0"
@ -4595,13 +4586,11 @@ __metadata:
resolution: "@rnx-kit/tools-react-native@workspace:packages/tools-react-native"
dependencies:
"@rnx-kit/eslint-config": "npm:*"
"@rnx-kit/jest-preset": "npm:*"
"@rnx-kit/scripts": "npm:*"
"@rnx-kit/tools-node": "npm:^2.0.1"
"@rnx-kit/tsconfig": "npm:*"
"@types/node": "npm:^20.0.0"
eslint: "npm:^8.56.0"
jest: "npm:^29.2.1"
metro: "npm:^0.80.0"
metro-config: "npm:^0.80.0"
metro-core: "npm:^0.80.0"
@ -4647,14 +4636,12 @@ __metadata:
resolution: "@rnx-kit/tools-workspaces@workspace:packages/tools-workspaces"
dependencies:
"@rnx-kit/eslint-config": "npm:*"
"@rnx-kit/jest-preset": "npm:*"
"@rnx-kit/scripts": "npm:*"
"@rnx-kit/tsconfig": "npm:*"
"@types/node": "npm:^20.0.0"
eslint: "npm:^8.56.0"
fast-glob: "npm:^3.2.7"
find-up: "npm:^5.0.0"
jest: "npm:^29.2.1"
prettier: "npm:^3.0.0"
read-yaml-file: "npm:^2.1.0"
strip-json-comments: "npm:^3.1.1"