Files
trade-message-center/scripts/package-version.test.mjs
T

114 lines
4.7 KiB
JavaScript

// 验证 workspace 根版本与子包镜像
import assert from "node:assert/strict";
import { mkdtempSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, relative } from "node:path";
import test from "node:test";
import {
bumpPackageVersion,
readRootPackageVersion,
validatePackageVersion,
listWorkspacePackagePaths,
writeRootPackageVersion,
} from "./package-version.mjs";
import { checkPackageVersions } from "./check-package-versions.mjs";
import { syncPackageVersions } from "./sync-package-versions.mjs";
const createWorkspace = (rootVersion, packageVersions) => {
const rootDir = mkdtempSync(join(tmpdir(), "tmc-package-version-"));
mkdirSync(join(rootDir, "apps"));
mkdirSync(join(rootDir, "packages"));
writeFileSync(
join(rootDir, "package.json"),
`${JSON.stringify({ name: "fixture", version: rootVersion }, null, 4)}\n`,
);
for (const [relativePackagePath, version] of Object.entries(packageVersions)) {
const packageDir = join(rootDir, relativePackagePath);
mkdirSync(packageDir);
writeFileSync(
join(packageDir, "package.json"),
`${JSON.stringify({ name: relativePackagePath, version }, null, 4)}\n`,
);
}
return rootDir;
};
test("accepts the npm and Chrome version intersection", () => {
for (const version of ["0.1.0", "1.2.3", "65535.65535.65535"]) {
assert.equal(validatePackageVersion(version), version);
}
});
test("rejects missing, malformed, and Chrome-incompatible versions", () => {
const invalidVersions = [
[undefined, /fixture version must be a non-empty string/u],
[null, /fixture version must be a non-empty string/u],
["", /fixture version must be a non-empty string/u],
["1", /fixture version must be a three-component numeric SemVer/u],
["1.2", /fixture version must be a three-component numeric SemVer/u],
["1.2.3.4", /fixture version must be a three-component numeric SemVer/u],
["01.2.3", /fixture version must be a three-component numeric SemVer/u],
["1.2.3-beta.1", /fixture version must be a three-component numeric SemVer/u],
["1.2.3+build.1", /fixture version must be a three-component numeric SemVer/u],
["0.0.0", /fixture version must not be 0\.0\.0/u],
["65536.0.0", /fixture version components must be between 0 and 65535/u],
];
for (const [version, errorPattern] of invalidVersions) {
assert.throws(() => validatePackageVersion(version, "fixture"), errorPattern);
}
});
test("bumps and writes the root version without creating another version source", () => {
const rootDir = createWorkspace("0.8.16", { extension: "0.8.16" });
assert.equal(bumpPackageVersion("0.8.16"), "0.8.17");
assert.equal(bumpPackageVersion("0.8.16", "minor"), "0.9.0");
assert.equal(bumpPackageVersion("0.8.16", "major"), "1.0.0");
assert.throws(() => bumpPackageVersion("1.2.3", "preview"), /Release type/u);
assert.throws(() => bumpPackageVersion("65535.0.0", "major"), /Next package/u);
writeRootPackageVersion("0.8.17", rootDir);
assert.equal(readRootPackageVersion(rootDir), "0.8.17");
});
test("syncs and checks app and shared workspace package mirrors against the root version", () => {
const rootDir = createWorkspace("1.2.3", {
"apps/extension": "0.1.0",
"apps/server": "0.1.0",
"packages/contract": "0.1.0",
});
assert.throws(() => checkPackageVersions(rootDir), /must equal root version 1.2.3/u);
syncPackageVersions(rootDir);
assert.equal(readRootPackageVersion(rootDir), "1.2.3");
checkPackageVersions(rootDir);
assert.deepEqual(
listWorkspacePackagePaths(rootDir).map((packagePath) => relative(rootDir, packagePath)),
[
"apps/extension/package.json",
"apps/server/package.json",
"packages/contract/package.json",
],
);
});
test("syncs version mirrors before root quality commands check them", () => {
const packageJson = JSON.parse(
readFileSync(new URL("../package.json", import.meta.url), "utf8"),
);
const { scripts } = packageJson;
assert.equal(scripts["version:ensure"], "pnpm run version:sync && pnpm run version:check");
for (const scriptName of ["dev:extension", "format:check"]) {
assert.match(scripts[scriptName], /^pnpm run version:ensure && /u);
}
for (const scriptName of ["dev", "build", "typecheck", "test"]) {
assert.match(scripts[scriptName], /^pnpm run clean:dist && pnpm run version:ensure && /u);
}
assert.match(scripts.test, /scripts\/release\.test\.mjs/u);
assert.equal(scripts["clean:dist"], "node scripts/clean-generated-dist.mjs");
});