Skip to content

Commit 5926c3e

Browse files
committed
docs: add README files for poutine, testine, mongodb driver with detailed usage and features
1 parent fce3d38 commit 5926c3e

3 files changed

Lines changed: 211 additions & 1 deletion

File tree

README.md

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,110 @@
1-
# poutine
1+
# poutine
2+
3+
[![Go Version](https://img.shields.io/badge/go-%3E%3D1.25-blue.svg)](https://golang.org/)
4+
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
5+
[![Go Report Card](https://goreportcard.com/badge/github.com/calumari/poutine)](https://goreportcard.com/report/github.com/calumari/poutine)
6+
7+
A Go library for database integration testing using JSON fixtures and snapshot assertions.
8+
9+
## Packages
10+
11+
* **`poutine`** – Core library providing a database-agnostic testing interface.
12+
* **`database/mongodb`** – MongoDB driver implementation.
13+
* **`testine`** – Utilities for loading fixtures, capturing snapshots, and cleaning up.
14+
15+
## Overview
16+
17+
Database integration tests can be tricky - like trying to eat poutine with a spoon. This library helps you **put in** your test data cleanly:
18+
19+
* Version-controlled JSON fixtures for consistent test data
20+
* Snapshot assertions to compare current database state with expected data
21+
* Handling of generated values like ObjectIDs and timestamps
22+
* Clean teardown so you don't leave a mess behind
23+
* Automatic cleanup of test data
24+
* Support for multiple backends through a driver interface
25+
26+
The goal is to reduce boilerplate and make test code easier to read and maintain, without adding extra complexity.
27+
28+
## Install
29+
30+
```bash
31+
go get github.com/calumari/poutine
32+
# Optional MongoDB driver
33+
go get github.com/calumari/poutine/database/mongodb
34+
```
35+
36+
## Quick Start (MongoDB)
37+
38+
```go
39+
package mytest
40+
41+
import (
42+
"testing"
43+
44+
"github.com/calumari/poutine"
45+
"github.com/calumari/poutine/database/mongodb"
46+
"github.com/calumari/poutine/testine"
47+
)
48+
49+
func Test_UserFlow(t *testing.T) {
50+
// Acquire a *mongo.Database instance
51+
pt := poutine.New(mongodb.NewDriver(db))
52+
ti, err := testine.New(pt)
53+
if err != nil {
54+
t.Fatalf("failed to create test helper: %v", err)
55+
}
56+
ti.Cleanup(t) // register teardown
57+
58+
// Seed DB from a JSON fixture
59+
snap := ti.Seed(t, ti.LoadJSON(t, "testdata/seed.json"))
60+
61+
// ... run code that modifies the database ...
62+
snap.Assert(t) // check expected state
63+
64+
// Or compare against a specific expected state
65+
ti.Assert(t, ti.LoadJSON(t, "testdata/after.json"))
66+
}
67+
```
68+
69+
## JSON Fixture Format
70+
71+
JSON fixtures are objects with collection (or table) names as keys and arrays of documents as values:
72+
73+
```jsonc
74+
{
75+
"users": [
76+
{"_id": {"$oid": true}, "email": "[email protected]"},
77+
{"_id": {"$oid": "507f1f77bcf86cd799439011"}, "email": "[email protected]"}
78+
],
79+
"pets": [
80+
{"name": "Fido", "ownerEmail": "[email protected]"}
81+
]
82+
}
83+
```
84+
85+
* `{"$oid": true}` – matches any ObjectID (wildcard)
86+
* `{"$oid": "hex_string"}` – matches a specific ObjectID
87+
88+
## Using `testine`
89+
90+
`testine.T` wraps a `Poutine` instance and provides helper methods:
91+
92+
* `Seed(t, doc) *Snapshot` – seed DB and capture snapshot
93+
* `Assert(t, expectedDoc)` – compare current DB state to expected
94+
* `Snapshot.Assert(t)` – compare current state to previously captured snapshot
95+
* `Cleanup(t)` – register teardown
96+
* `LoadJSON(t, path|glob|dir)` – load JSON from file, directory, or glob; supports caching with `testine.WithDocumentCache()`
97+
98+
## Custom Drivers
99+
100+
Implement the `database.Driver` interface to support new databases:
101+
102+
```go
103+
type Driver interface {
104+
Seed(ctx context.Context, root jwalk.Document) (jwalk.Document, error)
105+
Snapshot(ctx context.Context) (jwalk.Document, error)
106+
Teardown(ctx context.Context) error
107+
}
108+
```
109+
110+
See [`database/mongodb/driver.go`](database/mongodb/driver.go) for a reference implementation.

database/mongodb/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# poutine MongoDB Driver
2+
3+
MongoDB driver for the poutine testing library.
4+
5+
## Features
6+
7+
* Bulk insert operations for test data seeding
8+
* Database snapshot capture as JSON documents
9+
* ObjectID handling with `$oid` directives (wildcard or exact match)
10+
* Built on the official [MongoDB v2 Go driver](https://github.com/mongodb/mongo-go-driver)
11+
12+
## Install
13+
14+
```bash
15+
go get github.com/calumari/poutine/database/mongodb
16+
```
17+
18+
## Usage
19+
20+
Get started with familiar MongoDB patterns:
21+
22+
```go
23+
import (
24+
"testing"
25+
26+
"github.com/calumari/poutine"
27+
"github.com/calumari/poutine/database/mongodb"
28+
"github.com/calumari/poutine/testine"
29+
)
30+
31+
func Test_Something(t *testing.T) {
32+
// db is your *mongo.Database instance
33+
pt := poutine.New(mongodb.NewDriver(db))
34+
ti, err := testine.New(pt)
35+
if err != nil { t.Fatalf("failed to create test helper: %v", err) }
36+
ti.Cleanup(t)
37+
// ... mutate DB ...
38+
ti.Assert(t, ti.LoadJSON(t, "testdata/expected.json"))
39+
}
40+
```
41+
42+
## ObjectID Handling
43+
44+
Use `$oid` in JSON documents to represent MongoDB ObjectIDs:
45+
46+
```json
47+
{
48+
"users": [
49+
{"_id": {"$oid": true}, "email": "[email protected]"}, // wildcard: any ObjectID
50+
{"_id": {"$oid": "507f1f77bcf86cd799439011"}, "email": "[email protected]"} // exact match
51+
]
52+
}
53+
```
54+
55+
* `{"$oid": true}` – matches any valid ObjectID
56+
* `{"$oid": "hex_string"}` – matches a specific ObjectID

testine/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# testine
2+
3+
Testine provides helper APIs for seeding databases, capturing snapshots, and making assertions, helping reduce repetitive test setup.
4+
5+
## Features
6+
7+
* Load JSON fixture files from paths, glob patterns, or directories
8+
* Optional document caching to avoid re-parsing fixtures in subtests
9+
* Convenience methods for seeding, snapshotting, and assertions
10+
* Integration with [`testequals`](https://github.com/calumari/testequals/) for rich diffs
11+
12+
## Usage
13+
14+
```go
15+
func Test_Something(t *testing.T) {
16+
pt := poutine.New(mongodb.NewDriver(db))
17+
ti, err := testine.New(pt)
18+
if err != nil { t.Fatalf("failed to create test helper: %v", err) }
19+
ti.Cleanup(t) // cleanup after test
20+
21+
// seed database from a fixture
22+
snap := ti.Seed(t, ti.LoadJSON(t, "testdata/seed.json"))
23+
24+
// ... run code that modifies database ...
25+
snap.Assert(t) // assert no unintended mutations
26+
// or assert against a specific expected state
27+
ti.Assert(t, ti.LoadJSON(t, "testdata/after.json"))
28+
}
29+
```
30+
31+
## Document Caching
32+
33+
When the same fixtures are loaded in multiple subtests, caching avoids re-parsing:
34+
35+
```go
36+
ti, _ := testine.New(pt, testine.WithDocumentCache())
37+
```
38+
39+
## API
40+
41+
* **`Seed(t, doc) *Snapshot`** – Seed the database and capture the initial state for later comparison
42+
* **`Assert(t, expectedDoc)`** – Capture a snapshot and compare against expected state
43+
* **`Snapshot.Assert(t)`** – Compare the current database state against a previously captured snapshot
44+
* **`Cleanup(t)`** – Register a test cleanup function
45+
* **`LoadJSON(t, path)`** – Load JSON from a file, glob pattern, or directory, optionally using caching

0 commit comments

Comments
 (0)