Skip to content

Commit c9a0af5

Browse files
committed
Update docs
1 parent 12fbf7c commit c9a0af5

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed

README.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,92 @@ test("foo bar", async (t) => {
9797

9898
## Advanced Usage
9999

100+
### Postgres container de-duping
101+
102+
In rare cases, you may want to spawn more than one Postgres container.
103+
104+
Internally, this library uses an AVA "shared worker". A shared worker is a singleton shared with the entire running test suite, and so one `ava-postgres` shared worker maps to exactly one Postgres container.
105+
106+
To spawn separate shared workers and thus additional Postgres containers, you have two options:
107+
108+
**Specify different version strings for the `postgresVersion` option in the factory function**:
109+
110+
```ts
111+
const getTestPostgresDatabase = getTestPostgresDatabaseFactory({
112+
postgresVersion: "14",
113+
})
114+
```
115+
116+
Each unique version will map to a unique shared worker.
117+
118+
**Set the `workerDedupeKey` option in the factory function**:
119+
120+
```ts
121+
const getTestPostgresDatabase = getTestPostgresDatabaseFactory({
122+
workerDedupeKey: "foo",
123+
})
124+
```
125+
126+
Each unique key will map to a unique shared worker.
127+
128+
### Database de-duping
129+
130+
By default, `ava-postgres` will create a new database for each test. If you want to share a database between tests, you can use the `databaseDedupeKey` option:
131+
132+
```ts
133+
import test from "ava"
134+
const getTestPostgresDatabase = getTestPostgresDatabaseFactory({})
135+
136+
test("foo", async (t) => {
137+
const connection1 = await getTestPostgresDatabase(t, null, {
138+
databaseDedupeKey: "foo",
139+
})
140+
const connection2 = await getTestPostgresDatabase(t, null, {
141+
databaseDedupeKey: "foo",
142+
})
143+
t.is(connection1.database, connection2.database)
144+
})
145+
```
146+
147+
This works across the entire test suite.
148+
149+
Note that if unique parameters are passed to the `beforeTemplateIsBaked` (`null` in the above example), separate databases will still be created.
150+
151+
### "Nested" `beforeTemplateIsBaked` calls
152+
153+
In some cases, if you do extensive setup in your `beforeTemplateIsBaked` hook, you might want to obtain a separate, additional database within it if your application uses several databases for different purposes. This is possible by using the passed `beforeTemplateIsBaked` to your hook callback:
154+
155+
```ts
156+
type DatabaseParams = {
157+
type: "foo" | "bar"
158+
}
159+
160+
const getTestServer = getTestPostgresDatabaseFactory<DatabaseParams>({
161+
beforeTemplateIsBaked: async ({
162+
params,
163+
connection: { pool },
164+
beforeTemplateIsBaked,
165+
}) => {
166+
if (params.type === "foo") {
167+
await pool.query(`CREATE TABLE "foo" ("id" SERIAL PRIMARY KEY)`)
168+
// Important: return early to avoid infinite loop
169+
return
170+
}
171+
172+
await pool.query(`CREATE TABLE "bar" ("id" SERIAL PRIMARY KEY)`)
173+
// This created database will be torn down at the end of the top-level `beforeTemplateIsBaked` call
174+
const fooDatabase = await beforeTemplateIsBaked({
175+
params: { type: "foo" },
176+
})
177+
178+
// This works now
179+
await fooDatabase.pool.query(`INSERT INTO "foo" DEFAULT VALUES`)
180+
},
181+
})
182+
```
183+
184+
Be very careful when using this to avoid infinite loops.
185+
100186
### Bind mounts & `exec`ing in the container
101187

102188
`ava-postgres` uses [testcontainers](https://www.npmjs.com/package/testcontainers) under the hood to manage the Postgres container.

src/public-types.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,50 @@ export interface GetTestPostgresDatabaseFactoryOptions<
4848
}
4949

5050
/**
51-
* Test workers will be de-duped by this key. You probably don't need to set this.
51+
* In rare cases, you may want to spawn more than one Postgres container.
52+
* Internally, this library uses an AVA "shared worker". A shared worker is a singleton shared with the entire running test suite, and so one `ava-postgres` shared worker maps to exactly one Postgres container.
53+
* To spawn separate shared workers and thus additional Postgres containers, you can specify a custom key here.
54+
* Each unique key will map to a unique shared worker/unique Postgres container.
5255
*/
5356
workerDedupeKey?: string
5457
beforeTemplateIsBaked?: (options: {
5558
connection: ConnectionDetails
5659
params: Params
5760
containerExec: (command: string[]) => Promise<ExecResult>
61+
/**
62+
*
63+
* In some cases, if you do extensive setup in your `beforeTemplateIsBaked` hook, you might want to obtain a separate, additional database within it if your application uses several databases for different purposes. This is possible by using the passed `beforeTemplateIsBaked` to your hook callback.
64+
* Be very careful when using this to avoid infinite loops.
65+
* @example
66+
* ```ts
67+
* type DatabaseParams = {
68+
* type: "foo" | "bar"
69+
* }
70+
71+
* const getTestServer = getTestPostgresDatabaseFactory<DatabaseParams>({
72+
* beforeTemplateIsBaked: async ({
73+
* params,
74+
* connection: { pool },
75+
* beforeTemplateIsBaked,
76+
* }) => {
77+
* if (params.type === "foo") {
78+
* await pool.query(`CREATE TABLE "foo" ("id" SERIAL PRIMARY KEY)`)
79+
* // Important: return early to avoid infinite loop
80+
* return
81+
* }
82+
83+
* await pool.query(`CREATE TABLE "bar" ("id" SERIAL PRIMARY KEY)`)
84+
* // This created database will be torn down at the end of the top-level `beforeTemplateIsBaked` call
85+
* const fooDatabase = await beforeTemplateIsBaked({
86+
* params: { type: "foo" },
87+
* })
88+
89+
* // This works now
90+
* await fooDatabase.pool.query(`INSERT INTO "foo" DEFAULT VALUES`)
91+
* },
92+
* })
93+
* ```
94+
*/
5895
beforeTemplateIsBaked: (
5996
options: {
6097
params: Params
@@ -71,6 +108,28 @@ export type GetTestPostgresDatabaseOptions = {
71108
/**
72109
* If `getTestPostgresDatabase()` is called multiple times with the same `key` and `params`, the same database is guaranteed to be returned.
73110
*/
111+
/**
112+
* By default, `ava-postgres` will create a new database for each test. If you want to share a database between tests, you can use the `databaseDedupeKey` option.
113+
* This works across the entire test suite.
114+
*
115+
* Note that if unique parameters are passed to the `beforeTemplateIsBaked` (`null` in the above example), separate databases will still be created.
116+
* @example
117+
* ```ts
118+
* import test from "ava"
119+
*
120+
* const getTestPostgresDatabase = getTestPostgresDatabaseFactory({})
121+
*
122+
* test("foo", async (t) => {
123+
* const connection1 = await getTestPostgresDatabase(t, null, {
124+
* databaseDedupeKey: "foo",
125+
* })
126+
* const connection2 = await getTestPostgresDatabase(t, null, {
127+
* databaseDedupeKey: "foo",
128+
* })
129+
* t.is(connection1.database, connection2.database)
130+
* })
131+
* ```
132+
*/
74133
databaseDedupeKey?: string
75134
}
76135

0 commit comments

Comments
 (0)