MiniSearch / scripts /license-check.test.js
system's picture
system HF Staff
Sync from felladrin/MiniSearch@8503bf4
7acc713 verified
Raw History Blame Contribute Delete
6.47 kB
import { execFileSync } from "node:child_process";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const SCRIPT_PATH = path.resolve(__dirname, "license-check.cjs");
const REPO_ROOT = path.resolve(__dirname, "..");
function runCheck(cwd, args = []) {
try {
const output = execFileSync(process.execPath, [SCRIPT_PATH, ...args], {
cwd,
encoding: "utf8",
stdio: "pipe",
});
return { exitCode: 0, stdout: output, stderr: "" };
} catch (error) {
if (error.signal) throw new Error(`Killed by ${error.signal}`);
return {
exitCode: error.status ?? 1,
stdout: error.stdout ?? "",
stderr: error.stderr ?? "",
};
}
}
function writeLockfile(dir, packages) {
const lockPath = path.join(dir, "package-lock.json");
fs.writeFileSync(
lockPath,
JSON.stringify({
name: "fixture",
lockfileVersion: 3,
requires: true,
packages: {
"": { name: "fixture", version: "0.0.0", dependencies: {} },
...packages,
},
}),
"utf8",
);
return lockPath;
}
describe("license-check", () => {
let tmpDir;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "license-check-test-"));
});
afterEach(() => {
fs.rmSync(tmpDir, { recursive: true, force: true });
});
it("exits 0 when every production package has an allowed license", () => {
writeLockfile(tmpDir, {
"node_modules/one": { version: "1.0.0", license: "MIT" },
"node_modules/two": { version: "2.0.0", license: "Apache-2.0" },
});
const { exitCode, stdout } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
]);
expect(exitCode).toBe(0);
expect(stdout).toContain("compatible with Apache-2.0");
});
it("exits 1 naming the package and license when a production package is GPL-3.0", () => {
writeLockfile(tmpDir, {
"node_modules/gpl-pkg": { version: "1.0.0", license: "GPL-3.0" },
});
const { exitCode, stdout } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
]);
expect(exitCode).toBe(1);
expect(stdout).toContain("gpl-pkg");
expect(stdout).toContain("GPL-3.0");
});
it("allows an OR expression where one side is allowed", () => {
writeLockfile(tmpDir, {
"node_modules/or-pkg": {
version: "1.0.0",
license: "MIT OR GPL-3.0",
},
});
const { exitCode } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
]);
expect(exitCode).toBe(0);
});
it("fails an AND expression where one side is not allowed", () => {
writeLockfile(tmpDir, {
"node_modules/and-pkg": {
version: "1.0.0",
license: "MIT AND GPL-3.0",
},
});
const { exitCode, stdout } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
]);
expect(exitCode).toBe(1);
expect(stdout).toContain("and-pkg");
});
it("ignores dev dependencies", () => {
writeLockfile(tmpDir, {
"node_modules/dev-gpl": {
version: "1.0.0",
license: "GPL-3.0",
dev: true,
},
});
const { exitCode } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
]);
expect(exitCode).toBe(0);
});
it("allows an opaque license field for a package that is in OVERRIDE", () => {
writeLockfile(tmpDir, {
"node_modules/flatbuffers": {
version: "1.0.0",
license: "SEE LICENSE IN LICENSE.txt",
},
});
const { exitCode } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
]);
expect(exitCode).toBe(0);
});
it("fails an opaque license field for a package that is not in OVERRIDE", () => {
writeLockfile(tmpDir, {
"node_modules/mystery-pkg": {
version: "1.0.0",
license: "SEE LICENSE IN LICENSE.txt",
},
});
const { exitCode, stdout } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
]);
expect(exitCode).toBe(1);
expect(stdout).toContain("mystery-pkg");
});
it("fails a production package with no license field and no OVERRIDE entry", () => {
writeLockfile(tmpDir, {
"node_modules/no-license": { version: "1.0.0" },
});
const { exitCode, stdout } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
]);
expect(exitCode).toBe(1);
expect(stdout).toContain("no-license");
});
it("passes the real repository lockfile", () => {
const { exitCode } = runCheck(REPO_ROOT, []);
expect(exitCode).toBe(0);
});
it("writes a LICENSES.md report with every production package when --report is given", () => {
writeLockfile(tmpDir, {
"node_modules/alpha": { version: "1.0.0", license: "MIT" },
"node_modules/beta": { version: "2.0.0", license: "ISC" },
"node_modules/dev-only": {
version: "3.0.0",
license: "GPL-3.0",
dev: true,
},
});
const reportPath = path.join(tmpDir, "LICENSES.md");
const { exitCode } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
"--report",
reportPath,
]);
expect(exitCode).toBe(0);
const report = fs.readFileSync(reportPath, "utf8");
expect(report).toContain("| Package | License |");
expect(report).toContain("| alpha | MIT |");
expect(report).toContain("| beta | ISC |");
expect(report).not.toContain("dev-only");
});
it("does not change the exit code when a failing check writes a report", () => {
writeLockfile(tmpDir, {
"node_modules/gpl-pkg": { version: "1.0.0", license: "GPL-3.0" },
});
const reportPath = path.join(tmpDir, "LICENSES.md");
const { exitCode } = runCheck(tmpDir, [
path.join(tmpDir, "package-lock.json"),
"--report",
reportPath,
]);
expect(exitCode).toBe(1);
expect(fs.existsSync(reportPath)).toBe(true);
});
it("does not write any file when --report is absent", () => {
writeLockfile(tmpDir, {
"node_modules/one": { version: "1.0.0", license: "MIT" },
});
const lockPath = path.join(tmpDir, "package-lock.json");
const reportPath = path.join(tmpDir, "LICENSES.md");
expect(runCheck(tmpDir, [lockPath]).exitCode).toBe(0);
expect(fs.existsSync(reportPath)).toBe(false);
});
});