Files
emdash-cms--emdash/packages/plugin-cli/tests/init-environment.test.ts
T
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

158 lines
5.1 KiB
TypeScript

/**
* Coverage for the init scaffolder's environment probe.
*
* The probe reads three external sources: git config, git remote, and
* package.json. Tests focus on the parts we control directly — repo
* URL normalisation and package.json field extraction. The git-config
* and git-remote subprocess calls are tested indirectly via `init`
* integration tests; mocking child_process gets brittle fast and the
* subprocess wrapper is a thin layer that doesn't have much to fail.
*/
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { probeEnvironment } from "../src/init/environment.js";
describe("probeEnvironment — package.json extraction", () => {
let dir: string;
beforeEach(async () => {
dir = await mkdtemp(join(tmpdir(), "emdash-env-test-"));
});
afterEach(async () => {
await rm(dir, { recursive: true, force: true });
});
it("returns all-undefined for a directory with no package.json", async () => {
const env = await probeEnvironment(dir);
expect(env.license).toBeUndefined();
expect(env.description).toBeUndefined();
// Note: authorName / authorEmail may be set from the user's
// global git config; we don't assert on them here. The package
// extraction is the focus.
});
it("reads license, description, and repository from package.json", async () => {
await writeFile(
join(dir, "package.json"),
JSON.stringify({
name: "test",
license: "Apache-2.0",
description: "A test plugin",
repository: "https://github.com/example/test",
}),
"utf8",
);
const env = await probeEnvironment(dir);
expect(env.license).toBe("Apache-2.0");
expect(env.description).toBe("A test plugin");
expect(env.repo).toBe("https://github.com/example/test");
});
it("normalizes git@github.com SSH URLs to https", async () => {
await writeFile(
join(dir, "package.json"),
JSON.stringify({
name: "test",
repository: { type: "git", url: "git+ssh://git@github.com:example/test.git" },
}),
"utf8",
);
// SSH URL with the `ssh://` scheme prefix isn't the shape our
// normaliser handles — the user-facing common case is
// `git@host:path`, not `ssh://git@host/path`. The probe
// returns undefined; the prompt's fallback chain handles it.
const env = await probeEnvironment(dir);
expect(env.repo).toBeUndefined();
});
it("strips the .git suffix and the git+ prefix from package.json#repository.url", async () => {
await writeFile(
join(dir, "package.json"),
JSON.stringify({
name: "test",
repository: { type: "git", url: "git+https://github.com/example/test.git" },
}),
"utf8",
);
const env = await probeEnvironment(dir);
expect(env.repo).toBe("https://github.com/example/test");
});
it("treats a malformed package.json as missing", async () => {
await writeFile(join(dir, "package.json"), "{ not valid json", "utf8");
const env = await probeEnvironment(dir);
expect(env.license).toBeUndefined();
expect(env.description).toBeUndefined();
expect(env.repo).toBeUndefined();
});
it("treats a non-object package.json as missing", async () => {
// Valid JSON but not an object — pathological but possible.
await writeFile(join(dir, "package.json"), "[]", "utf8");
const env = await probeEnvironment(dir);
expect(env.license).toBeUndefined();
expect(env.description).toBeUndefined();
});
it("ignores oversized package.json (defence against weird files)", async () => {
// Build a 100 KiB file. The cap is 64 KiB; the probe should
// skip rather than buffer the whole thing.
const fluff = " ".repeat(100 * 1024);
await writeFile(
join(dir, "package.json"),
`{ "license": "MIT", "_fluff": "${fluff}" }`,
"utf8",
);
const env = await probeEnvironment(dir);
expect(env.license).toBeUndefined();
});
it("treats empty-string license / description as undefined", async () => {
await writeFile(
join(dir, "package.json"),
JSON.stringify({ name: "test", license: "", description: " " }),
"utf8",
);
const env = await probeEnvironment(dir);
expect(env.license).toBeUndefined();
expect(env.description).toBeUndefined();
});
it("trims whitespace from license / description values", async () => {
await writeFile(
join(dir, "package.json"),
JSON.stringify({ name: "test", license: " MIT ", description: " hello " }),
"utf8",
);
const env = await probeEnvironment(dir);
expect(env.license).toBe("MIT");
expect(env.description).toBe("hello");
});
it("accepts repository as a bare string", async () => {
await writeFile(
join(dir, "package.json"),
JSON.stringify({ name: "test", repository: "https://github.com/example/test.git" }),
"utf8",
);
const env = await probeEnvironment(dir);
expect(env.repo).toBe("https://github.com/example/test");
});
it("returns undefined for unrecognised repository shapes", async () => {
await writeFile(
join(dir, "package.json"),
JSON.stringify({ name: "test", repository: { type: "git" /* no url */ } }),
"utf8",
);
const env = await probeEnvironment(dir);
expect(env.repo).toBeUndefined();
});
});