aboutsummaryrefslogtreecommitdiff
path: root/test/profile
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmail.com>2026-07-27 00:13:06 +0530
committerAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-08-02 19:12:46 +0530
commit3607b5523f9d23ec6b9facf8474c7bdf047537e1 (patch)
tree87c433788599b1f414cb248759f2eed6500071e2 /test/profile
parent84ebb018f59ab5efe8bc97e8e4b87435d6665b0b (diff)
chore(build): split tsconfig, typecheck tests, add node:test runner
test/ was never type-checked and had no runner. Adds tsconfig.base.json shared by a src project and a test project, an npm test script scoped to non-manual suites, and a CI step. Ports the profile store suite as proof. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'test/profile')
-rw-r--r--test/profile/store-test.ts145
1 files changed, 71 insertions, 74 deletions
diff --git a/test/profile/store-test.ts b/test/profile/store-test.ts
index c881372..7d38d34 100644
--- a/test/profile/store-test.ts
+++ b/test/profile/store-test.ts
@@ -4,24 +4,14 @@
* Redirects pi's agent dir via $PI_CODING_AGENT_DIR so the real
* ~/.pi/agent/browser-harness.json is never touched.
*
- * Run: npx tsx test/profile/store-test.ts
+ * Run: npm test
*/
+import { test, before, after, describe } from "node:test";
+import assert from "node:assert/strict";
import { mkdtempSync, mkdirSync, readdirSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
-let passed = 0;
-let failed = 0;
-const check = (cond: boolean, label: string): void => {
- if (cond) {
- passed++;
- console.log(` ✓ ${label}`);
- } else {
- failed++;
- console.error(` ✗ ${label}`);
- }
-};
-
const pin = {
userDataDir: "/home/u/.config/google-chrome",
profileDir: "Profile 1",
@@ -29,70 +19,87 @@ const pin = {
savedAt: new Date(0).toISOString(),
};
-async function main(): Promise<void> {
- const sandbox = mkdtempSync(join(tmpdir(), "pi-pin-test-"));
- process.env["PI_CODING_AGENT_DIR"] = sandbox;
+describe("profile pin store", () => {
+ let sandbox: string;
+
+ before(() => {
+ sandbox = mkdtempSync(join(tmpdir(), "pi-pin-test-"));
+ process.env["PI_CODING_AGENT_DIR"] = sandbox;
+ });
- // Imported after the env override so paths.ts resolves into the sandbox.
- const { pinFilePath } = await import("../../src/profile/paths");
- const { readPin, writePin, clearPin } = await import("../../src/profile/store");
+ after(() => {
+ rmSync(sandbox, { recursive: true, force: true });
+ });
- // P1: agent dir honours the env override
- check(pinFilePath() === join(sandbox, "browser-harness.json"), "P1: pin path follows $PI_CODING_AGENT_DIR");
+ test("P1: pin path follows $PI_CODING_AGENT_DIR", async () => {
+ const { pinFilePath } = await import("../../src/profile/paths");
+ assert.equal(pinFilePath(), join(sandbox, "browser-harness.json"));
+ });
- // P2: nothing written yet
- check((await readPin()) === null, "P2: absent file reads as no pin");
+ test("P2: absent file reads as no pin", async () => {
+ const { readPin } = await import("../../src/profile/store");
+ assert.equal(await readPin(), null);
+ });
- // P3: round trip
- {
+ test("P3: write succeeds and round-trips", async () => {
+ const { readPin, writePin } = await import("../../src/profile/store");
const written = await writePin(pin);
- check(written.success, "P3: write succeeds");
+ assert.equal(written.success, true);
const read = await readPin();
- check(read?.profileDir === "Profile 1", "P3: profileDir round-trips");
- check(read?.userDataDir === pin.userDataDir, "P3: userDataDir round-trips");
- check(read?.label === pin.label, "P3: label round-trips");
- }
+ assert.equal(read?.profileDir, "Profile 1");
+ assert.equal(read?.userDataDir, pin.userDataDir);
+ assert.equal(read?.label, pin.label);
+ });
- // P4: no temp files survive an atomic write
- check(readdirSync(sandbox).filter((f) => f.endsWith(".tmp")).length === 0, "P4: write leaves no .tmp files");
+ test("P4: write leaves no .tmp files", () => {
+ assert.equal(readdirSync(sandbox).filter((f) => f.endsWith(".tmp")).length, 0);
+ });
- // P5: overwrite replaces rather than appends
- {
+ test("P5: second write replaces the first", async () => {
+ const { readPin, writePin } = await import("../../src/profile/store");
await writePin({ ...pin, profileDir: "Default", label: "Work (work@example.com)" });
const read = await readPin();
- check(read?.profileDir === "Default", "P5: second write replaces the first");
- check(readdirSync(sandbox).filter((f) => f === "browser-harness.json").length === 1, "P5: one pin file on disk");
- }
+ assert.equal(read?.profileDir, "Default");
+ assert.equal(readdirSync(sandbox).filter((f) => f === "browser-harness.json").length, 1);
+ });
- // P6: clear
- {
+ test("P6: clear succeeds and cleared pin reads as none", async () => {
+ const { readPin, clearPin } = await import("../../src/profile/store");
const cleared = await clearPin();
- check(cleared.success, "P6: clear succeeds");
- check((await readPin()) === null, "P6: cleared pin reads as none");
- }
-
- // P7: corrupt file degrades to no pin
- writeFileSync(pinFilePath(), "{ not json at all", "utf8");
- check((await readPin()) === null, "P7: malformed JSON reads as no pin");
-
- // P8: unknown schema version is not guessed at
- writeFileSync(pinFilePath(), JSON.stringify({ version: 99, profile: pin }), "utf8");
- check((await readPin()) === null, "P8: future version reads as no pin");
-
- // P9: structurally invalid pin is rejected
- writeFileSync(pinFilePath(), JSON.stringify({ version: 1, profile: { profileDir: 42 } }), "utf8");
- check((await readPin()) === null, "P9: wrong field types read as no pin");
-
- // P10: a missing agent dir is created on write
- {
+ assert.equal(cleared.success, true);
+ assert.equal(await readPin(), null);
+ });
+
+ test("P7: malformed JSON reads as no pin", async () => {
+ const { readPin } = await import("../../src/profile/store");
+ const { pinFilePath } = await import("../../src/profile/paths");
+ writeFileSync(pinFilePath(), "{ not json at all", "utf8");
+ assert.equal(await readPin(), null);
+ });
+
+ test("P8: future version reads as no pin", async () => {
+ const { readPin } = await import("../../src/profile/store");
+ const { pinFilePath } = await import("../../src/profile/paths");
+ writeFileSync(pinFilePath(), JSON.stringify({ version: 99, profile: pin }), "utf8");
+ assert.equal(await readPin(), null);
+ });
+
+ test("P9: wrong field types read as no pin", async () => {
+ const { readPin } = await import("../../src/profile/store");
+ const { pinFilePath } = await import("../../src/profile/paths");
+ writeFileSync(pinFilePath(), JSON.stringify({ version: 1, profile: { profileDir: 42 } }), "utf8");
+ assert.equal(await readPin(), null);
+ });
+
+ test("P10: write recreates a missing agent dir", async () => {
+ const { readPin, writePin } = await import("../../src/profile/store");
rmSync(sandbox, { recursive: true, force: true });
const written = await writePin(pin);
- check(written.success, "P10: write recreates a missing agent dir");
- check((await readPin())?.profileDir === "Profile 1", "P10: pin readable after dir recreation");
- }
+ assert.equal(written.success, true);
+ assert.equal((await readPin())?.profileDir, "Profile 1");
+ });
- // P11: an unwritable location surfaces as an error result, not a throw
- {
+ test("P11: write into an invalid dir returns an error result", async () => {
const blocked = join(sandbox, "blocked");
mkdirSync(blocked, { recursive: true });
writeFileSync(join(blocked, "browser-harness.json"), "{}", "utf8");
@@ -100,17 +107,7 @@ async function main(): Promise<void> {
process.env["PI_CODING_AGENT_DIR"] = join(blocked, "browser-harness.json");
const { writePin: writeAgain } = await import(`../../src/profile/store?nocache=${Date.now()}`);
const written = await writeAgain(pin);
- check(!written.success, "P11: write into an invalid dir returns an error result");
+ assert.equal(written.success, false);
process.env["PI_CODING_AGENT_DIR"] = sandbox;
- }
-
- rmSync(sandbox, { recursive: true, force: true });
-
- console.log(`\n${passed} passed, ${failed} failed`);
- process.exit(failed === 0 ? 0 : 1);
-}
-
-main().catch((e) => {
- console.error("profile store test failed:", e);
- process.exit(1);
+ });
});