mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-20 09:31:15 +00:00
test: Remove duplicate and theatrical tests (#2020)
Remove 162 lines of duplicate/theatrical test code across 5 files: - manifest-integrity.test.ts: Drop 5 crude toBeTruthy() field checks superseded by manifest-type-contracts.test.ts with precise type assertions - manifest-type-contracts.test.ts: Remove dead deps block (0 agents have deps) and Dotenv configuration describe block (0 agents have dotenv) — both generated zero tests at runtime - commands-error-paths.test.ts: Remove 5-test "swapped arguments detection" block duplicated by the more thorough commands-swap-resolve.test.ts - run-path-credential-display.test.ts: Remove 5-test "implementation checks" block that retested getImplementedClouds/Agents already covered by commands-exported-utils.test.ts; also remove now-unused imports - manifest.test.ts: Remove redundant toBeDefined() assertion after an already-present toHaveProperty() check on the same field Co-authored-by: spawn-qa-bot <qa@openrouter.ai> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ae3f4001cc
commit
ba06e49d97
5 changed files with 4 additions and 162 deletions
|
|
@ -330,51 +330,6 @@ describe("Commands Error Paths", () => {
|
|||
});
|
||||
});
|
||||
|
||||
// ── cmdRun: swapped arguments detection ──────────────────────────────
|
||||
|
||||
describe("cmdRun - swapped arguments detection", () => {
|
||||
it("should detect when cloud and agent arguments are swapped", async () => {
|
||||
// "spawn sprite claude" should detect that sprite is a cloud and claude is an agent
|
||||
await expect(cmdRun("sprite", "claude")).rejects.toThrow("process.exit");
|
||||
expect(processExitSpy).toHaveBeenCalledWith(1);
|
||||
|
||||
const infoCalls = mockLogInfo.mock.calls.map((c: any[]) => c.join(" "));
|
||||
expect(infoCalls.some((msg: string) => msg.includes("swapped"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should suggest the correct argument order when swapped", async () => {
|
||||
await expect(cmdRun("sprite", "claude")).rejects.toThrow("process.exit");
|
||||
|
||||
const infoCalls = mockLogInfo.mock.calls.map((c: any[]) => c.join(" "));
|
||||
expect(infoCalls.some((msg: string) => msg.includes("spawn claude sprite"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should suggest correct order for hetzner/codex swap", async () => {
|
||||
await expect(cmdRun("hetzner", "codex")).rejects.toThrow("process.exit");
|
||||
|
||||
const infoCalls2 = mockLogInfo.mock.calls.map((c: any[]) => c.join(" "));
|
||||
expect(infoCalls2.some((msg: string) => msg.includes("swapped"))).toBe(true);
|
||||
|
||||
const infoCalls = mockLogInfo.mock.calls.map((c: any[]) => c.join(" "));
|
||||
expect(infoCalls.some((msg: string) => msg.includes("spawn codex hetzner"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should NOT trigger swap detection when both args are unknown", async () => {
|
||||
await expect(cmdRun("unknown1", "unknown2")).rejects.toThrow("process.exit");
|
||||
|
||||
const warnCalls = mockLogWarn.mock.calls.map((c: any[]) => c.join(" "));
|
||||
expect(warnCalls.some((msg: string) => msg.includes("swapped"))).toBe(false);
|
||||
});
|
||||
|
||||
it("should NOT trigger swap detection when agent is valid", async () => {
|
||||
// "spawn claude nonexistent" - agent is valid, cloud is not
|
||||
await expect(cmdRun("claude", "nonexistent")).rejects.toThrow("process.exit");
|
||||
|
||||
const warnCalls = mockLogWarn.mock.calls.map((c: any[]) => c.join(" "));
|
||||
expect(warnCalls.some((msg: string) => msg.includes("swapped"))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// ── cmdRun: batch validation (both errors at once) ──────────────────
|
||||
|
||||
describe("cmdRun - batch validation shows all errors at once", () => {
|
||||
|
|
|
|||
|
|
@ -53,38 +53,16 @@ describe("Manifest Integrity", () => {
|
|||
});
|
||||
|
||||
// ── Agent definitions ───────────────────────────────────────────────
|
||||
// Field type precision is covered by manifest-type-contracts.test.ts.
|
||||
// Only naming conventions and uniqueness constraints live here.
|
||||
|
||||
describe("agent definitions", () => {
|
||||
it("should have required fields for every agent", () => {
|
||||
for (const [key, agent] of Object.entries(manifest.agents)) {
|
||||
expect(agent.name).toBeTruthy();
|
||||
expect(agent.description).toBeTruthy();
|
||||
expect(agent.url).toBeTruthy();
|
||||
expect(agent.install).toBeTruthy();
|
||||
expect(agent.launch).toBeTruthy();
|
||||
expect(agent.env).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
it("should use lowercase-hyphen-underscore keys for agents", () => {
|
||||
for (const key of agents) {
|
||||
expect(key).toMatch(/^[a-z0-9_-]+$/);
|
||||
}
|
||||
});
|
||||
|
||||
it("should have valid URL format for agent urls", () => {
|
||||
for (const [key, agent] of Object.entries(manifest.agents)) {
|
||||
expect(agent.url).toMatch(/^https?:\/\//);
|
||||
}
|
||||
});
|
||||
|
||||
it("should have env as an object for every agent", () => {
|
||||
for (const [key, agent] of Object.entries(manifest.agents)) {
|
||||
expect(typeof agent.env).toBe("object");
|
||||
expect(agent.env).not.toBeNull();
|
||||
}
|
||||
});
|
||||
|
||||
it("should have unique agent display names", () => {
|
||||
const names = Object.values(manifest.agents).map((a) => a.name);
|
||||
const uniqueNames = new Set(names);
|
||||
|
|
@ -93,33 +71,16 @@ describe("Manifest Integrity", () => {
|
|||
});
|
||||
|
||||
// ── Cloud definitions ───────────────────────────────────────────────
|
||||
// Field type precision is covered by manifest-type-contracts.test.ts.
|
||||
// Only naming conventions and uniqueness constraints live here.
|
||||
|
||||
describe("cloud definitions", () => {
|
||||
it("should have required fields for every cloud", () => {
|
||||
for (const [key, cloud] of Object.entries(manifest.clouds)) {
|
||||
expect(cloud.name).toBeTruthy();
|
||||
expect(cloud.description).toBeTruthy();
|
||||
expect(cloud.url).toBeTruthy();
|
||||
expect(cloud.type).toBeTruthy();
|
||||
expect(cloud.auth).toBeTruthy();
|
||||
expect(cloud.provision_method).toBeTruthy();
|
||||
expect(cloud.exec_method).toBeTruthy();
|
||||
expect(cloud.interactive_method).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
it("should use lowercase-hyphen-underscore keys for clouds", () => {
|
||||
for (const key of clouds) {
|
||||
expect(key).toMatch(/^[a-z0-9_-]+$/);
|
||||
}
|
||||
});
|
||||
|
||||
it("should have valid URL format for cloud urls", () => {
|
||||
for (const [key, cloud] of Object.entries(manifest.clouds)) {
|
||||
expect(cloud.url).toMatch(/^https?:\/\//);
|
||||
}
|
||||
});
|
||||
|
||||
it("should have unique cloud display names", () => {
|
||||
const names = Object.values(manifest.clouds).map((c) => c.name);
|
||||
const uniqueNames = new Set(names);
|
||||
|
|
|
|||
|
|
@ -109,16 +109,6 @@ describe("Agent optional field types (when present)", () => {
|
|||
});
|
||||
}
|
||||
|
||||
if (agent.deps !== undefined) {
|
||||
it(`agent "${key}" deps should be an array of strings`, () => {
|
||||
expect(Array.isArray(agent.deps)).toBe(true);
|
||||
for (const dep of agent.deps!) {
|
||||
expect(typeof dep).toBe("string");
|
||||
expect(dep.length).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (agent.config_files !== undefined) {
|
||||
it(`agent "${key}" config_files should be an object with string keys`, () => {
|
||||
expect(typeof agent.config_files).toBe("object");
|
||||
|
|
@ -290,24 +280,6 @@ describe("Agent launch command consistency", () => {
|
|||
});
|
||||
});
|
||||
|
||||
// ── Dotenv path validation ────────────────────────────────────────────────
|
||||
|
||||
describe("Dotenv configuration", () => {
|
||||
for (const [key, agent] of allAgents.filter(([, a]) => a.dotenv !== undefined)) {
|
||||
it(`agent "${key}" dotenv path should look like a file path`, () => {
|
||||
const path = agent.dotenv!.path;
|
||||
// Should contain a / or ~ indicating a path
|
||||
expect(path).toMatch(/[/~]/);
|
||||
});
|
||||
|
||||
it(`agent "${key}" dotenv values should all be strings`, () => {
|
||||
for (const [k, v] of Object.entries(agent.dotenv!.values)) {
|
||||
expect(typeof v).toBe("string");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ── Interactive prompts structure ─────────────────────────────────────────
|
||||
|
||||
describe("Interactive prompts structure", () => {
|
||||
|
|
|
|||
|
|
@ -123,9 +123,6 @@ describe("manifest", () => {
|
|||
signal: expect.any(AbortSignal),
|
||||
}),
|
||||
);
|
||||
|
||||
// The manifest was fetched and returned successfully
|
||||
expect(manifest.agents).toBeDefined();
|
||||
});
|
||||
|
||||
it("should use disk cache when fresh", async () => {
|
||||
|
|
|
|||
|
|
@ -151,8 +151,6 @@ mock.module("@clack/prompts", () => ({
|
|||
// Import after mocks are set up
|
||||
const {
|
||||
prioritizeCloudsByCredentials,
|
||||
getImplementedClouds,
|
||||
getImplementedAgents,
|
||||
checkEntity,
|
||||
resolveAgentKey,
|
||||
resolveCloudKey,
|
||||
|
|
@ -463,47 +461,6 @@ describe("key resolution for run path", () => {
|
|||
});
|
||||
});
|
||||
|
||||
// ── getImplementedClouds / getImplementedAgents for run path ─────────────
|
||||
|
||||
describe("implementation checks for run path", () => {
|
||||
const manifest = makeManifest();
|
||||
|
||||
it("should return implemented clouds for claude", () => {
|
||||
const clouds = getImplementedClouds(manifest, "claude");
|
||||
expect(clouds).toContain("hetzner");
|
||||
expect(clouds).toContain("sprite");
|
||||
expect(clouds).toContain("digitalocean");
|
||||
expect(clouds).toContain("upcloud");
|
||||
expect(clouds).toContain("localcloud");
|
||||
});
|
||||
|
||||
it("should return implemented clouds for codex (fewer)", () => {
|
||||
const clouds = getImplementedClouds(manifest, "codex");
|
||||
expect(clouds).toContain("hetzner");
|
||||
expect(clouds).toContain("digitalocean");
|
||||
expect(clouds).toContain("localcloud");
|
||||
// sprite/codex and upcloud/codex are "missing"
|
||||
expect(clouds).not.toContain("sprite");
|
||||
expect(clouds).not.toContain("upcloud");
|
||||
});
|
||||
|
||||
it("should return implemented agents for hetzner", () => {
|
||||
const agents = getImplementedAgents(manifest, "hetzner");
|
||||
expect(agents).toContain("claude");
|
||||
expect(agents).toContain("codex");
|
||||
});
|
||||
|
||||
it("should return empty for nonexistent agent", () => {
|
||||
const clouds = getImplementedClouds(manifest, "nonexistent");
|
||||
expect(clouds).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return empty for nonexistent cloud", () => {
|
||||
const agents = getImplementedAgents(manifest, "nonexistent");
|
||||
expect(agents).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Integration: full run-path validation sequence ──────────────────────
|
||||
|
||||
describe("run-path validation sequence integration", () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue