Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ transfers.
- A CLI (`groups`, `balances <group>`, `export <group>`) 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 <group-id> # e.g. bun run src/cli.ts balances goa-trip
bun run src/cli.ts export <group-id> # the group's expenses as CSV
```

## Stack

Bun, TypeScript, Hono, `bun:sqlite`. No build step for the web page
Expand Down
51 changes: 51 additions & 0 deletions tests/readme.test.ts
Original file line number Diff line number Diff line change
@@ -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<string> {
return Bun.file(new URL(path, root)).text();
}

async function runItSection(): Promise<string> {
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 <group-id>");
expect(section).toContain("export <group-id>");

const db = new Database(":memory:");
initSchema(db);
seedDemoData(db);
expect(run(["groups"], db)).toContain("goa-trip");
});
});
Loading