From 3624d739abd3dfd7dc097030cb0588022ea9ce67 Mon Sep 17 00:00:00 2001 From: Param Harrison Date: Fri, 9 Oct 2026 00:27:25 +0300 Subject: [PATCH 1/2] factory: claim #60 by runner-95312-1791494845559 From 07cf598cee5d0e1a3be4a2a273f7f013df48ca4b Mon Sep 17 00:00:00 2001 From: Param Harrison Date: Fri, 9 Oct 2026 00:29:58 +0300 Subject: [PATCH 2/2] factory: build #60 --- README.md | 20 +++++++++++++++++ tests/readme.test.ts | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 tests/readme.test.ts diff --git a/README.md b/README.md index 3c8e3ec..4faa5cb 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,26 @@ transfers. - A CLI (`groups`, `balances `, `export `) alongside the web page and API. +## Run it + +Needs [Bun](https://bun.sh). + +```sh +bun install +bun run dev # serves http://localhost:3200 +``` + +The first run creates `splitbill.sqlite` and seeds demo groups. Set `PORT` to use another port +and `SPLITBILL_DB` to use another database file. + +The CLI reads the same database: + +```sh +bun run src/cli.ts groups # list all groups +bun run src/cli.ts balances # e.g. bun run src/cli.ts balances goa-trip +bun run src/cli.ts export # the group's expenses as CSV +``` + ## 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..32b1d9b --- /dev/null +++ b/tests/readme.test.ts @@ -0,0 +1,51 @@ +import { describe, expect, test } from "bun:test"; +import { Database } from "bun:sqlite"; +import { initSchema } from "../src/db.ts"; +import { seedDemoData } from "../src/seed.ts"; +import { run } from "../src/cli.ts"; + +const root = new URL("..", import.meta.url); + +async function readText(path: string): Promise { + return Bun.file(new URL(path, root)).text(); +} + +async function runItSection(): Promise { + const readme = await readText("README.md"); + const start = readme.indexOf("\n## Run it\n"); + if (start === -1) return ""; + const next = readme.indexOf("\n## ", start + 1); + return next === -1 ? readme.slice(start) : readme.slice(start, next); +} + +describe("README Run it section", () => { + test("README has a Run it section with bun install", async () => { + const section = await runItSection(); + expect(section).not.toBe(""); + expect(section).toContain("bun install"); + }); + + test("README dev command and URL match package.json and server default port", async () => { + const section = await runItSection(); + expect(section).toContain("bun run dev"); + expect(section).toContain("http://localhost:3200"); + + const pkg = JSON.parse(await readText("package.json")); + expect(pkg.scripts.dev).toBeDefined(); + + const server = await readText("src/server.ts"); + expect(server).toContain("process.env.PORT ?? 3200"); + }); + + test("README CLI example points at a real CLI command", async () => { + const section = await runItSection(); + expect(section).toContain("bun run src/cli.ts groups"); + expect(section).toContain("balances "); + expect(section).toContain("export "); + + const db = new Database(":memory:"); + initSchema(db); + seedDemoData(db); + expect(run(["groups"], db)).toContain("goa-trip"); + }); +});