From 1e32b2ba73a560a518e753f708e42fe7e0a787de Mon Sep 17 00:00:00 2001 From: Param Harrison Date: Wed, 23 Sep 2026 17:46:28 +0300 Subject: [PATCH 1/3] factory: claim #15 by runner-15214-1790174788973 From ea0526c567fc2593de30b965877d9895c2db00a4 Mon Sep 17 00:00:00 2001 From: Param Harrison Date: Wed, 23 Sep 2026 19:25:05 +0300 Subject: [PATCH 2/3] factory: build #15 --- README.md | 19 +++++++++++++++++ tests/readme.test.ts | 49 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 tests/readme.test.ts diff --git a/README.md b/README.md index 666ab78..d0a5e5f 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,25 @@ transfers. - A CLI (`groups`, `balances `, `export `) alongside the web page and API. +## Run it + +```sh +bun install +bun run dev # serves http://localhost:3200 +``` + +The first run creates `splitbill.sqlite` and seeds two demo groups +(`goa-trip`, `flat-4b`). + +The CLI reads the same database: + +```sh +bun run src/cli.ts groups +``` + +`bun run src/cli.ts balances ` and `bun run src/cli.ts export ` +are also available, e.g. `bun run src/cli.ts balances goa-trip`. + ## Stack Bun, TypeScript, Hono, `bun:sqlite`. No build step for the web page diff --git a/tests/readme.test.ts b/tests/readme.test.ts new file mode 100644 index 0000000..58aad57 --- /dev/null +++ b/tests/readme.test.ts @@ -0,0 +1,49 @@ +import { describe, expect, test } from "bun:test"; + +const root = new URL("..", import.meta.url).pathname; + +async function readme(): Promise { + return Bun.file(new URL("../README.md", import.meta.url)).text(); +} + +function runItSection(text: string): string { + const start = text.indexOf("## Run it"); + expect(start).toBeGreaterThanOrEqual(0); + const next = text.indexOf("\n## ", start + 1); + return next === -1 ? text.slice(start) : text.slice(start, next); +} + +describe("README Run it section", () => { + test("README has a Run it section with install, dev and CLI commands", async () => { + const section = runItSection(await readme()); + expect(section).toContain("bun install"); + expect(section).toContain("bun run dev"); + expect(section).toContain("http://localhost:3200"); + expect(section).toContain("bun run src/cli.ts groups"); + }); + + test("README dev URL port matches the server default", async () => { + const section = runItSection(await readme()); + const port = section.match(/http:\/\/localhost:(\d+)/)?.[1]; + expect(port).toBeDefined(); + const server = await Bun.file(new URL("../src/server.ts", import.meta.url)).text(); + expect(server).toContain(`process.env.PORT ?? ${port}`); + }); + + test("documented CLI example lists the demo groups", async () => { + const proc = Bun.spawn([process.execPath, "run", "src/cli.ts", "groups"], { + cwd: root, + env: { ...process.env, SPLITBILL_DB: ":memory:" }, + stdout: "pipe", + stderr: "pipe", + }); + const [output, errors, code] = await Promise.all([ + new Response(proc.stdout).text(), + new Response(proc.stderr).text(), + proc.exited, + ]); + expect({ code, errors }).toEqual({ code: 0, errors: "" }); + expect(output).toContain("goa-trip"); + expect(output).toContain("flat-4b"); + }); +}); From f225da75cc7cb1d77e0ab434bc65d9bcdab3c068 Mon Sep 17 00:00:00 2001 From: Param Harrison Date: Wed, 23 Sep 2026 19:31:28 +0300 Subject: [PATCH 3/3] factory: build #15 --- tests/readme.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/readme.test.ts b/tests/readme.test.ts index 58aad57..09f695b 100644 --- a/tests/readme.test.ts +++ b/tests/readme.test.ts @@ -27,7 +27,7 @@ describe("README Run it section", () => { const port = section.match(/http:\/\/localhost:(\d+)/)?.[1]; expect(port).toBeDefined(); const server = await Bun.file(new URL("../src/server.ts", import.meta.url)).text(); - expect(server).toContain(`process.env.PORT ?? ${port}`); + expect(server).toMatch(new RegExp(`process\\.env\\.PORT\\s*\\?\\?\\s*${port}\\b`)); }); test("documented CLI example lists the demo groups", async () => { @@ -36,6 +36,7 @@ describe("README Run it section", () => { env: { ...process.env, SPLITBILL_DB: ":memory:" }, stdout: "pipe", stderr: "pipe", + timeout: 10_000, }); const [output, errors, code] = await Promise.all([ new Response(proc.stdout).text(),