Files
kandev/apps/web/scripts/generate-licenses.test.ts
T
João Salavisa 3d042e9d8f fix(deps): address Dependabot vulnerabilities (#3450)
Co-authored-by: Kandev Agent <agent@kandev.dev>
2026-09-07 22:58:18 +01:00

104 lines
3.3 KiB
TypeScript

import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, it, expect } from "vitest";
const OUTPUT_FILE = join(__dirname, "..", "generated", "licenses.json");
type LicenseEntry = {
name: string;
version: string;
license: string;
repository?: string;
license_text?: string;
stale?: boolean;
ecosystem: "npm" | "go" | "source";
};
const ECOSYSTEMS = new Set(["npm", "go", "source"]);
const REQUIRED_FIELDS = ["name", "version", "license", "ecosystem"] as const;
function loadEntries(): LicenseEntry[] | null {
if (!existsSync(OUTPUT_FILE)) return null;
const raw = readFileSync(OUTPUT_FILE, "utf-8");
return JSON.parse(raw) as LicenseEntry[];
}
function compareKeys(a: LicenseEntry, b: LicenseEntry): number {
if (a.ecosystem !== b.ecosystem) return a.ecosystem < b.ecosystem ? -1 : 1;
if (a.name !== b.name) return a.name < b.name ? -1 : 1;
if (a.version !== b.version) return a.version < b.version ? -1 : 1;
return 0;
}
describe("generated/licenses.json", () => {
const entries = loadEntries();
it("parses as a JSON array (or is absent in fresh checkouts)", () => {
if (!entries) {
// Generator hasn't run yet — skip the rest. CI runs `licenses:gen` first.
expect(existsSync(OUTPUT_FILE)).toBe(false);
return;
}
expect(Array.isArray(entries)).toBe(true);
});
if (!entries) return;
it("every entry has the required fields and a valid ecosystem", () => {
for (const entry of entries) {
for (const field of REQUIRED_FIELDS) {
expect(entry, `missing ${field} in ${JSON.stringify(entry)}`).toHaveProperty(field);
expect(typeof entry[field]).toBe("string");
expect(entry[field].length).toBeGreaterThan(0);
}
expect(ECOSYSTEMS.has(entry.ecosystem)).toBe(true);
if (entry.repository !== undefined) {
expect(typeof entry.repository).toBe("string");
}
if (entry.license_text !== undefined) {
expect(typeof entry.license_text).toBe("string");
}
if (entry.stale !== undefined) {
expect(typeof entry.stale).toBe("boolean");
}
}
});
it("is sorted by (ecosystem, name, version)", () => {
for (let i = 1; i < entries.length; i++) {
const prev = entries[i - 1];
const curr = entries[i];
expect(
compareKeys(prev, curr),
`out-of-order at index ${i}: ${prev.ecosystem}/${prev.name}@${prev.version} vs ${curr.ecosystem}/${curr.name}@${curr.version}`,
).toBeLessThan(0);
}
});
it("has no duplicate (ecosystem, name, version) tuples", () => {
const seen = new Set<string>();
for (const entry of entries) {
const key = `${entry.ecosystem}|${entry.name}|${entry.version}`;
expect(seen.has(key), `duplicate entry ${key}`).toBe(false);
seen.add(key);
}
});
it("contains entries from both ecosystems (sanity check)", () => {
const eco = new Set(entries.map((e) => e.ecosystem));
expect(eco.has("npm")).toBe(true);
expect(eco.has("go")).toBe(true);
});
it("contains the notice for the vendored shadcn/ui Tailwind CSS", () => {
expect(entries).toContainEqual(
expect.objectContaining({
name: "shadcn/ui Tailwind CSS",
version: "3.6.3",
license: "MIT",
ecosystem: "source",
}),
);
});
});