Files
wehub-resource-sync b3a7f98e5a
CI / E2E Cloudflare (4/8) (push) Failing after 0s
CI / E2E Cloudflare (8/8) (push) Failing after 1s
CI / Lint (push) Failing after 1s
Auto Extract / Extract (push) Failing after 4s
CI / Version Check (push) Failing after 9s
CI / Integration Tests (push) Failing after 1s
CI / E2E tests (1/8) (push) Failing after 1s
CI / E2E tests (2/8) (push) Failing after 2s
CI / E2E tests (3/8) (push) Failing after 2s
CI / Browser Tests (push) Failing after 1s
CI / E2E tests (5/8) (push) Failing after 1s
CI / E2E Cloudflare (2/8) (push) Failing after 2s
CI / Typecheck (push) Failing after 1s
CI / Changeset Validation (push) Failing after 2s
CI / E2E Cloudflare (5/8) (push) Failing after 1s
CI / E2E Cloudflare (6/8) (push) Failing after 1s
CI / E2E Cloudflare (7/8) (push) Failing after 1s
CodeQL / Analyze (javascript-typescript) (push) Failing after 1s
Format / Format (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 4s
CI / E2E tests (4/8) (push) Failing after 1s
CI / E2E tests (6/8) (push) Failing after 1s
CI / E2E tests (7/8) (push) Failing after 2s
CI / E2E tests (8/8) (push) Failing after 1s
CI / E2E Cloudflare (1/8) (push) Failing after 1s
CI / E2E Cloudflare (3/8) (push) Failing after 2s
Preview Releases / Publish Preview (push) Failing after 0s
zizmor / Run zizmor (push) Failing after 1s
Release / Release (push) Failing after 2s
CI / Smoke Tests (push) Failing after 5m36s
CI / Tests (push) Failing after 6m36s
Release / Sync Templates (push) Has been skipped
CI / E2E Tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:23:53 +08:00

228 lines
7.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
checkEnvCompatibility,
findSkippedEnvConstraints,
hostEnvFromVersions,
isValidVersionRange,
parseRequires,
satisfiesRange,
} from "../src/env/index.js";
describe("isValidVersionRange", () => {
it("accepts comparator ranges", () => {
expect(isValidVersionRange(">=4.16")).toBe(true);
expect(isValidVersionRange(">=4.16.0")).toBe(true);
expect(isValidVersionRange(">4.0.0")).toBe(true);
expect(isValidVersionRange("<=2.0.0")).toBe(true);
expect(isValidVersionRange("<2.0.0")).toBe(true);
expect(isValidVersionRange("=1.2.3")).toBe(true);
expect(isValidVersionRange("1.2.3")).toBe(true);
});
it("accepts caret and tilde ranges", () => {
expect(isValidVersionRange("^4.0.0")).toBe(true);
expect(isValidVersionRange("^4.16")).toBe(true);
expect(isValidVersionRange("~4.16.0")).toBe(true);
expect(isValidVersionRange("~4")).toBe(true);
});
it("accepts wildcard and any", () => {
expect(isValidVersionRange("*")).toBe(true);
expect(isValidVersionRange("4.x")).toBe(true);
expect(isValidVersionRange("4.16.x")).toBe(true);
});
it("accepts AND-joined comparator sets", () => {
expect(isValidVersionRange(">=4.16.0 <5.0.0")).toBe(true);
});
it("accepts || union ranges", () => {
expect(isValidVersionRange("^4.0.0 || ^5.0.0")).toBe(true);
});
it("accepts prerelease versions in comparators", () => {
expect(isValidVersionRange(">=6.0.0-beta.0")).toBe(true);
});
it("rejects empty and garbage", () => {
expect(isValidVersionRange("")).toBe(false);
expect(isValidVersionRange(" ")).toBe(false);
expect(isValidVersionRange("not-a-range")).toBe(false);
expect(isValidVersionRange(">=")).toBe(false);
expect(isValidVersionRange("4.16.0.0")).toBe(false);
expect(isValidVersionRange(">>4.0.0")).toBe(false);
});
});
describe("satisfiesRange", () => {
it("evaluates comparator ranges", () => {
expect(satisfiesRange("4.16.0", ">=4.16")).toBe(true);
expect(satisfiesRange("4.16.1", ">=4.16.0")).toBe(true);
expect(satisfiesRange("4.12.0", ">=4.16")).toBe(false);
expect(satisfiesRange("4.16.0", ">4.16.0")).toBe(false);
expect(satisfiesRange("4.16.1", ">4.16.0")).toBe(true);
});
it("evaluates caret ranges", () => {
expect(satisfiesRange("4.16.0", "^4.0.0")).toBe(true);
expect(satisfiesRange("4.99.0", "^4.0.0")).toBe(true);
expect(satisfiesRange("5.0.0", "^4.0.0")).toBe(false);
expect(satisfiesRange("3.9.0", "^4.0.0")).toBe(false);
});
it("evaluates tilde ranges", () => {
expect(satisfiesRange("4.16.5", "~4.16.0")).toBe(true);
expect(satisfiesRange("4.17.0", "~4.16.0")).toBe(false);
});
it("evaluates AND-joined comparator sets", () => {
expect(satisfiesRange("4.16.0", ">=4.16.0 <5.0.0")).toBe(true);
expect(satisfiesRange("5.0.0", ">=4.16.0 <5.0.0")).toBe(false);
});
it("matches the wildcard against any version", () => {
expect(satisfiesRange("4.16.0", "*")).toBe(true);
expect(satisfiesRange("1.0.0-rc.1", "*")).toBe(true);
});
it("evaluates || union ranges", () => {
expect(satisfiesRange("5.1.0", "^4.0.0 || ^5.0.0")).toBe(true);
expect(satisfiesRange("3.0.0", "^4.0.0 || ^5.0.0")).toBe(false);
});
it("evaluates a prerelease host by precedence, not excluded from release ranges", () => {
expect(satisfiesRange("1.0.0-rc.1", ">=0.13.0")).toBe(true);
expect(satisfiesRange("4.1.0-beta.2", "^4.0.0")).toBe(true);
});
it("treats an unparseable host version as satisfied (cannot prove incompatible)", () => {
expect(satisfiesRange("dev", ">=4.16")).toBe(true);
expect(satisfiesRange("", ">=4.16")).toBe(true);
});
it("treats an unparseable range as satisfied (cannot enforce garbage)", () => {
expect(satisfiesRange("4.16.0", "not-a-range")).toBe(true);
});
});
describe("parseRequires", () => {
it("returns env:* and DID keys with string values", () => {
const parsed = parseRequires({
"env:emdash": ">=1.0.0",
"env:astro": ">=4.16",
"did:plc:abc123": "^1.0.0",
});
expect(parsed).toEqual({
"env:emdash": ">=1.0.0",
"env:astro": ">=4.16",
"did:plc:abc123": "^1.0.0",
});
});
it("drops non-string values", () => {
expect(parseRequires({ "env:astro": 4 })).toEqual({});
expect(parseRequires({ "env:astro": { foo: "bar" } })).toEqual({});
});
it("drops keys that are not env:* or DID-shaped", () => {
expect(parseRequires({ astro: ">=4.16", "env:": ">=1", foo: ">=1" })).toEqual({});
});
it("returns an empty object for non-object input", () => {
expect(parseRequires(undefined)).toEqual({});
expect(parseRequires(null)).toEqual({});
expect(parseRequires("garbage")).toEqual({});
expect(parseRequires(42)).toEqual({});
expect(parseRequires([])).toEqual({});
});
});
describe("checkEnvCompatibility", () => {
it("returns no mismatches when every constraint is satisfied", () => {
const result = checkEnvCompatibility(
{ "env:emdash": ">=1.0.0", "env:astro": ">=4.16" },
{ "env:emdash": "1.2.0", "env:astro": "4.16.0" },
);
expect(result).toEqual([]);
});
it("reports the env keys whose host version does not satisfy the range", () => {
const result = checkEnvCompatibility(
{ "env:emdash": ">=1.0.0", "env:astro": ">=4.16" },
{ "env:emdash": "1.2.0", "env:astro": "4.12.0" },
);
expect(result).toEqual([{ key: "env:astro", required: ">=4.16", host: "4.12.0" }]);
});
it("skips env keys the host does not advertise (no known version)", () => {
const result = checkEnvCompatibility(
{ "did:plc:abc": "^1.0.0" },
{ "env:emdash": "1.2.0", "env:astro": "4.16.0" },
);
expect(result).toEqual([]);
});
it("guards unknown requires shapes without crashing", () => {
expect(checkEnvCompatibility(undefined, { "env:emdash": "1.2.0" })).toEqual([]);
expect(checkEnvCompatibility("garbage", { "env:emdash": "1.2.0" })).toEqual([]);
expect(checkEnvCompatibility({ "env:astro": 999 }, { "env:astro": "4.16.0" })).toEqual([]);
});
it("skips host envs whose version is unknown/unparseable", () => {
const result = checkEnvCompatibility({ "env:emdash": ">=1.0.0" }, { "env:emdash": "dev" });
expect(result).toEqual([]);
});
});
describe("findSkippedEnvConstraints", () => {
it("returns nothing when every env constraint is evaluable", () => {
expect(
findSkippedEnvConstraints(
{ "env:emdash": ">=1.0.0", "env:astro": ">=4.0.0" },
{ "env:emdash": "1.2.0", "env:astro": "4.16.0" },
),
).toEqual([]);
});
it("flags an env the host does not advertise as unknown", () => {
expect(findSkippedEnvConstraints({ "env:astro": ">=4.16" }, { "env:emdash": "1.2.0" })).toEqual(
[{ key: "env:astro", required: ">=4.16", reason: "unknown" }],
);
});
it("flags an env whose host version is not parseable semver", () => {
expect(findSkippedEnvConstraints({ "env:emdash": ">=1.0.0" }, { "env:emdash": "dev" })).toEqual(
[{ key: "env:emdash", required: ">=1.0.0", reason: "unparseable" }],
);
});
it("ignores DID-keyed constraints (package deps, not host envs)", () => {
expect(findSkippedEnvConstraints({ "did:plc:abc": "^1.0.0" }, {})).toEqual([]);
});
it("does not crash on a garbage requires shape", () => {
expect(findSkippedEnvConstraints("garbage", {})).toEqual([]);
expect(findSkippedEnvConstraints(null, {})).toEqual([]);
});
});
describe("hostEnvFromVersions", () => {
it("maps emdash + astro versions to env:* keys", () => {
expect(hostEnvFromVersions("1.2.0", "4.16.0")).toEqual({
"env:emdash": "1.2.0",
"env:astro": "4.16.0",
});
});
it("omits a dev emdash build so the gate skips it", () => {
expect(hostEnvFromVersions("dev", "4.16.0")).toEqual({ "env:astro": "4.16.0" });
});
it("omits each env whose version is unknown", () => {
expect(hostEnvFromVersions("1.2.0", undefined)).toEqual({ "env:emdash": "1.2.0" });
expect(hostEnvFromVersions(undefined, "4.16.0")).toEqual({ "env:astro": "4.16.0" });
expect(hostEnvFromVersions(undefined, undefined)).toEqual({});
});
});