mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-08-02 01:08:41 +02:00
183 lines
4.9 KiB
JavaScript
183 lines
4.9 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import test from "node:test";
|
|
import { XRAY_SOURCE_URL } from "../src-tauri/download-xray.mjs";
|
|
import {
|
|
collectPnpmLicenses,
|
|
collectReachableRustLicenses,
|
|
normalizeLicenseExpression,
|
|
prepareLicenseInventory,
|
|
} from "./generate-licenses.mjs";
|
|
|
|
test("normalizes legacy dual-license metadata into SPDX expressions", () => {
|
|
assert.equal(
|
|
normalizeLicenseExpression("MIT/Apache-2.0"),
|
|
"Apache-2.0 OR MIT",
|
|
);
|
|
assert.equal(
|
|
normalizeLicenseExpression("Apache-2.0 OR MIT"),
|
|
"Apache-2.0 OR MIT",
|
|
);
|
|
assert.throws(() => normalizeLicenseExpression(""), /declare a license/);
|
|
assert.throws(
|
|
() => normalizeLicenseExpression("not/a/license"),
|
|
/Invalid SPDX expression/,
|
|
);
|
|
for (const invalid of [
|
|
"NOASSERTION",
|
|
"Definitely-Not-A-License",
|
|
"MPL-999.0",
|
|
]) {
|
|
assert.throws(
|
|
() => normalizeLicenseExpression(invalid),
|
|
/Invalid SPDX expression/,
|
|
);
|
|
}
|
|
});
|
|
|
|
test("collects only normal Rust dependencies reachable from the app", () => {
|
|
const metadata = {
|
|
packages: [
|
|
{ id: "app", name: "app", license: "AGPL-3.0" },
|
|
{ id: "runtime", name: "runtime", license: "MIT" },
|
|
{ id: "nested", name: "nested", license: "Apache-2.0" },
|
|
{ id: "build", name: "build", license: "MIT" },
|
|
{ id: "dev", name: "dev", license: "MIT" },
|
|
],
|
|
resolve: {
|
|
root: "app",
|
|
nodes: [
|
|
{
|
|
id: "app",
|
|
deps: [
|
|
{ pkg: "runtime", dep_kinds: [{ kind: null }] },
|
|
{ pkg: "build", dep_kinds: [{ kind: "build" }] },
|
|
{ pkg: "dev", dep_kinds: [{ kind: "dev" }] },
|
|
],
|
|
},
|
|
{
|
|
id: "runtime",
|
|
deps: [{ pkg: "nested", dep_kinds: [{ kind: null }] }],
|
|
},
|
|
{ id: "nested", deps: [] },
|
|
{ id: "build", deps: [] },
|
|
{ id: "dev", deps: [] },
|
|
],
|
|
},
|
|
};
|
|
|
|
assert.deepEqual(collectReachableRustLicenses(metadata), [
|
|
{ name: "runtime", license: "MIT" },
|
|
{ name: "nested", license: "Apache-2.0" },
|
|
]);
|
|
});
|
|
|
|
test("flattens pnpm groups and emits a stable name-and-license-only list", () => {
|
|
const pnpmEntries = collectPnpmLicenses({
|
|
MIT: [
|
|
{
|
|
name: "zeta",
|
|
license: "MIT",
|
|
versions: ["1.2.3"],
|
|
author: "Not included",
|
|
},
|
|
{ name: "@next/swc-darwin-arm64", license: "MIT" },
|
|
{ name: "@next/swc-linux-x64-gnu", license: "MIT" },
|
|
],
|
|
"Apache-2.0": [
|
|
{ name: "@img/sharp-darwin-arm64" },
|
|
{ name: "@img/sharp-linux-x64" },
|
|
],
|
|
"LGPL-3.0-or-later": [
|
|
{ name: "@img/sharp-libvips-darwin-arm64" },
|
|
{ name: "@img/sharp-libvips-linux-x64" },
|
|
],
|
|
"MIT OR Apache-2.0": [{ name: "alpha" }],
|
|
});
|
|
const inventory = prepareLicenseInventory([
|
|
...pnpmEntries,
|
|
{ name: "zeta", license: "MIT", copyright: "Not included" },
|
|
]);
|
|
|
|
assert.deepEqual(inventory, [
|
|
{ name: "alpha", license: "Apache-2.0 OR MIT" },
|
|
{ name: "zeta", license: "MIT" },
|
|
]);
|
|
assert.deepEqual(Object.keys(inventory[0]).sort(), ["license", "name"]);
|
|
});
|
|
|
|
test("pnpm inventory is stable across host-native build packages", () => {
|
|
const reportForHost = (swc, sharp, libvips) => ({
|
|
MIT: [
|
|
{ name: "shared-runtime" },
|
|
{ name: swc },
|
|
{ name: sharp, license: "Apache-2.0" },
|
|
{ name: libvips, license: "LGPL-3.0-or-later" },
|
|
],
|
|
});
|
|
|
|
const darwin = collectPnpmLicenses(
|
|
reportForHost(
|
|
"@next/swc-darwin-arm64",
|
|
"@img/sharp-darwin-arm64",
|
|
"@img/sharp-libvips-darwin-arm64",
|
|
),
|
|
);
|
|
const linux = collectPnpmLicenses(
|
|
reportForHost(
|
|
"@next/swc-linux-x64-gnu",
|
|
"@img/sharp-linux-x64",
|
|
"@img/sharp-libvips-linux-x64",
|
|
),
|
|
);
|
|
|
|
assert.deepEqual(darwin, linux);
|
|
assert.deepEqual(darwin, [{ name: "shared-runtime", license: "MIT" }]);
|
|
});
|
|
|
|
test("generated inventory includes the bundled sidecar and Tauri opener", async () => {
|
|
const inventory = JSON.parse(
|
|
await readFile(
|
|
new URL("../src/generated/licenses.json", import.meta.url),
|
|
"utf8",
|
|
),
|
|
);
|
|
|
|
assert.ok(
|
|
inventory.some(
|
|
(entry) =>
|
|
entry.name === "Donut Browser" && entry.license === "AGPL-3.0-only",
|
|
),
|
|
);
|
|
assert.ok(
|
|
inventory.some(
|
|
(entry) => entry.name === "Xray-core" && entry.license === "MPL-2.0",
|
|
),
|
|
);
|
|
assert.ok(
|
|
inventory.some(
|
|
(entry) =>
|
|
entry.name === "tauri-plugin-opener" &&
|
|
entry.license === "Apache-2.0 OR MIT",
|
|
),
|
|
);
|
|
assert.ok(
|
|
inventory.every(
|
|
(entry) =>
|
|
Object.keys(entry).length === 2 &&
|
|
typeof entry.name === "string" &&
|
|
typeof entry.license === "string",
|
|
),
|
|
);
|
|
});
|
|
|
|
test("generated Xray source link matches the packaged release", async () => {
|
|
const source = JSON.parse(
|
|
await readFile(
|
|
new URL("../src/generated/xray-source.json", import.meta.url),
|
|
"utf8",
|
|
),
|
|
);
|
|
assert.deepEqual(source, { sourceUrl: XRAY_SOURCE_URL });
|
|
});
|