Files
nextcraft/apps/cli/tests/path-invocation.test.ts
T
CIAgent 02d324b896 test(P01): harness wiring — coverage, timeouts, markers, turbo pipeline, leak fixes (REQ-7-001)
- pytest-cov + [tool.coverage] config (95% branch, term-missing every run); c8
  wired around tsx --test in web (95.9%) + cli (76.9%) — no runner swap (D-052)
- markers fast/real_server/userns under --strict-markers (D-053); real_server ×5
  uvicorn suites + userns ×2 files + 1 test (test_manager real-unshare catch);
  test_sandbox_agent unmarked per G-105 (plain stdlib process), outlier timeout(120)
- pytest-timeout signal method: 60s global, 180s via conftest collection hook for
  marked tiers; BOTH tiers probe-proven (60.07s / 180.07s)
- FAST=1 fast subset: 621 passed, 49 deselected, 55.4s bare (MH-M2 <60s holds);
  FAST implies NO_COV per verifier GAP-1 fix
- CLI fresh-clone E2E env-gated (CLI_E2E=1, D-055): visible skip, opt-in green
  (902s aggregate step budget); path-invocation silent return → visible skip
- web#test turbo task + root test/web:test/web:test:cov/cli:test:cov/cli:test:e2e/
  ai:test:fast scripts; pnpm test runs 3/3 workspaces (3m)
- leak fixes: AI_PROVIDER via monkeypatch (probe-proven restore),
  seed_verified_identity check-first + IntegrityError-only, test_engine.py:428
  Path.read_text (P3 item done early)
- PLAN.md count discipline: baseline 670/53/64 (671→670 collection fact; 61→64
  v0.5.7 hotfix tests); Task 1-1-04 no-split decision recorded (6.8s combined)

---ci---
phase: 1
milestone: v0.7
status: execute
---/ci---
2026-09-26 17:40:05 +00:00

37 lines
2.1 KiB
TypeScript

import { test } from "node:test";
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { cpSync, existsSync, mkdirSync, mkdtempSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const cliDir = join(dirname(fileURLToPath(import.meta.url)), "..");
const repoRoot = join(cliDir, "..", "..");
const binary = join(repoRoot, "apps", "cli", "dist", "nextcraft-linux-x64");
test("PATH bare-word invocation: installed binary speaks (SEA regression, v0.3.4 bug)", { skip: existsSync(binary) ? false : `built binary missing: ${binary} (run cli:build:binary)` }, () => {
const binDir = mkdtempSync(join(tmpdir(), "nc-pathword-"));
cpSync(binary, join(binDir, "nextcraft"));
const env = {
PATH: [binDir, process.env.PATH].filter(Boolean).join(":"),
HOME: process.env.HOME,
};
const { NODE_TEST_CONTEXT, ...rest } = process.env as Record<string, string | undefined>;
const envClean = { ...rest, ...env } as Record<string, string | undefined>;
const ver = spawnSync("sh", ["-c", "nextcraft --version"], { encoding: "utf8", timeout: 30000, env: envClean });
assert.equal(ver.status, 0, `--version rc: ${ver.status} stderr: ${ver.stderr}`);
assert.ok(ver.stdout.trim().length > 0, "--version must print the version (v0.3.4 was silent)");
const doc = spawnSync("sh", ["-c", "nextcraft doctor"], { encoding: "utf8", timeout: 120000, env: envClean });
assert.equal(doc.status, 0, `doctor rc: ${doc.status} stderr: ${doc.stderr}`);
assert.ok(doc.stdout.includes("environment prerequisites"), "doctor must print its report");
const noArgs = spawnSync("sh", ["-c", "nextcraft"], { encoding: "utf8", timeout: 30000, env: envClean });
assert.equal(noArgs.status, 2, "no args must exit 2");
assert.ok((noArgs.stderr + noArgs.stdout).includes("Usage:"), "no args must print usage");
const bad = spawnSync("sh", ["-c", "nextcraft nosuchcmd"], { encoding: "utf8", timeout: 30000, env: envClean });
assert.equal(bad.status, 2, "unknown command must exit 2");
});