@prairielearn/postgres 4.4.3 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/test-utils.d.ts +2 -2
- package/dist/test-utils.d.ts.map +1 -1
- package/dist/test-utils.js +10 -9
- package/dist/test-utils.js.map +1 -1
- package/package.json +4 -4
- package/src/test-utils.ts +19 -14
package/CHANGELOG.md
CHANGED
package/dist/test-utils.d.ts
CHANGED
|
@@ -20,10 +20,10 @@ interface DropDatabaseOptions {
|
|
|
20
20
|
closePool?: boolean;
|
|
21
21
|
}
|
|
22
22
|
export interface PostgresTestUtils {
|
|
23
|
-
createDatabase: (options?: CreateDatabaseOptions) => Promise<
|
|
23
|
+
createDatabase: (options?: CreateDatabaseOptions) => Promise<pg.PoolConfig>;
|
|
24
24
|
resetDatabase: () => Promise<void>;
|
|
25
25
|
dropDatabase: (options?: DropDatabaseOptions) => Promise<void>;
|
|
26
|
-
|
|
26
|
+
getDatabaseNameForCurrentTestWorker: () => string;
|
|
27
27
|
getPoolConfig: () => pg.PoolConfig;
|
|
28
28
|
}
|
|
29
29
|
export declare function makePostgresTestUtils(options: PostgresTestUtilsOptions): PostgresTestUtils;
|
package/dist/test-utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAQpB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,GAAG,mBAAmB,CAAC,CAAC;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;
|
|
1
|
+
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAQpB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,GAAG,mBAAmB,CAAC,CAAC;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAID,UAAU,qBAAqB;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAmHD,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAC5E,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,mCAAmC,EAAE,MAAM,MAAM,CAAC;IAClD,aAAa,EAAE,MAAM,EAAE,CAAC,UAAU,CAAC;CACpC;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAU1F"}
|
package/dist/test-utils.js
CHANGED
|
@@ -9,7 +9,7 @@ async function createDatabase(options, { dropExistingDatabase = true, configureP
|
|
|
9
9
|
database: options.defaultDatabase ?? POSTGRES_DATABASE,
|
|
10
10
|
});
|
|
11
11
|
await client.connect();
|
|
12
|
-
const escapedDatabase = client.escapeIdentifier(database ??
|
|
12
|
+
const escapedDatabase = client.escapeIdentifier(database ?? getDatabaseNameForCurrentTestWorker(options.database));
|
|
13
13
|
if (dropExistingDatabase ?? true) {
|
|
14
14
|
await client.query(`DROP DATABASE IF EXISTS ${escapedDatabase}`);
|
|
15
15
|
}
|
|
@@ -22,11 +22,10 @@ async function createDatabase(options, { dropExistingDatabase = true, configureP
|
|
|
22
22
|
}
|
|
23
23
|
await client.end();
|
|
24
24
|
await prepare?.(client);
|
|
25
|
+
const poolConfig = getPoolConfig(options);
|
|
25
26
|
if (configurePool) {
|
|
26
27
|
await defaultPool.initAsync({
|
|
27
|
-
|
|
28
|
-
host: options.host ?? POSTGRES_HOST,
|
|
29
|
-
database: getDatabaseNameForCurrentMochaWorker(options.database),
|
|
28
|
+
...poolConfig,
|
|
30
29
|
// Offer sensible default, but these can be overridden by `options.poolConfig`.
|
|
31
30
|
max: 10,
|
|
32
31
|
idleTimeoutMillis: 30000,
|
|
@@ -36,6 +35,7 @@ async function createDatabase(options, { dropExistingDatabase = true, configureP
|
|
|
36
35
|
throw err;
|
|
37
36
|
});
|
|
38
37
|
}
|
|
38
|
+
return poolConfig;
|
|
39
39
|
}
|
|
40
40
|
async function resetDatabase(options) {
|
|
41
41
|
const client = new pg.Client(getPoolConfig(options));
|
|
@@ -60,7 +60,7 @@ async function dropDatabase(options, { closePool = true, force = false, database
|
|
|
60
60
|
if (closePool) {
|
|
61
61
|
await defaultPool.closeAsync();
|
|
62
62
|
}
|
|
63
|
-
const databaseName = database ??
|
|
63
|
+
const databaseName = database ?? getDatabaseNameForCurrentTestWorker(options.database);
|
|
64
64
|
if ('PL_KEEP_TEST_DB' in process.env && !force) {
|
|
65
65
|
// eslint-disable-next-line no-console
|
|
66
66
|
console.log(`PL_KEEP_TEST_DB environment variable set, not dropping database ${databaseName}`);
|
|
@@ -74,15 +74,16 @@ async function dropDatabase(options, { closePool = true, force = false, database
|
|
|
74
74
|
await client.query(`DROP DATABASE IF EXISTS ${client.escapeIdentifier(databaseName)}`);
|
|
75
75
|
await client.end();
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
|
|
77
|
+
function getDatabaseNameForCurrentTestWorker(namespace) {
|
|
78
|
+
// https://playwright.dev/docs/test-parallel#isolate-test-data-between-parallel-workers
|
|
79
|
+
const workerId = process.env.TEST_WORKER_INDEX ?? process.env.VITEST_POOL_ID ?? '1';
|
|
79
80
|
return `${namespace}_${workerId}`;
|
|
80
81
|
}
|
|
81
82
|
function getPoolConfig(options) {
|
|
82
83
|
return {
|
|
83
84
|
user: options.user ?? POSTGRES_USER,
|
|
84
85
|
host: options.host ?? POSTGRES_HOST,
|
|
85
|
-
database:
|
|
86
|
+
database: getDatabaseNameForCurrentTestWorker(options.database),
|
|
86
87
|
};
|
|
87
88
|
}
|
|
88
89
|
export function makePostgresTestUtils(options) {
|
|
@@ -90,7 +91,7 @@ export function makePostgresTestUtils(options) {
|
|
|
90
91
|
createDatabase: (createOptions) => createDatabase(options, createOptions),
|
|
91
92
|
resetDatabase: () => resetDatabase(options),
|
|
92
93
|
dropDatabase: (dropOptions) => dropDatabase(options, dropOptions),
|
|
93
|
-
|
|
94
|
+
getDatabaseNameForCurrentTestWorker: () => getDatabaseNameForCurrentTestWorker(options.database),
|
|
94
95
|
getPoolConfig: () => getPoolConfig(options),
|
|
95
96
|
};
|
|
96
97
|
}
|
package/dist/test-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AAEjD,MAAM,aAAa,GAAG,UAAU,CAAC;AACjC,MAAM,aAAa,GAAG,WAAW,CAAC;AAClC,MAAM,iBAAiB,GAAG,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import pg from 'pg';\n\nimport * as defaultPool from './default-pool.js';\n\nconst POSTGRES_USER = 'postgres';\nconst POSTGRES_HOST = 'localhost';\nconst POSTGRES_DATABASE = 'postgres';\n\nexport interface PostgresTestUtilsOptions {\n database: string;\n user?: string;\n host?: string;\n poolConfig?: Pick<pg.PoolConfig, 'max' | 'idleTimeoutMillis'>;\n defaultDatabase?: string;\n prepareAfterReset?: (client: pg.Client) => Promise<void>;\n}\n\ntype PostgresTestPoolConfig = Required<Pick<pg.PoolConfig, 'user' | 'host' | 'database'>>;\n\ninterface CreateDatabaseOptions {\n dropExistingDatabase?: boolean;\n database?: string;\n templateDatabase?: string;\n configurePool?: boolean;\n prepare?: (client: pg.Client) => Promise<void>;\n}\n\ninterface DropDatabaseOptions {\n database?: string;\n force?: boolean;\n closePool?: boolean;\n}\n\nasync function createDatabase(\n options: PostgresTestUtilsOptions,\n {\n dropExistingDatabase = true,\n configurePool = true,\n database,\n templateDatabase,\n prepare,\n }: CreateDatabaseOptions = {},\n): Promise<PostgresTestPoolConfig> {\n const client = new pg.Client({\n ...getPoolConfig(options),\n database: options.defaultDatabase ?? POSTGRES_DATABASE,\n });\n await client.connect();\n\n const escapedDatabase = client.escapeIdentifier(\n database ?? getDatabaseNameForCurrentTestWorker(options.database),\n );\n if (dropExistingDatabase ?? true) {\n await client.query(`DROP DATABASE IF EXISTS ${escapedDatabase}`);\n }\n\n if (templateDatabase) {\n const escapedTemplateDatabase = client.escapeIdentifier(templateDatabase);\n await client.query(`CREATE DATABASE ${escapedDatabase} TEMPLATE ${escapedTemplateDatabase}`);\n } else {\n await client.query(`CREATE DATABASE ${escapedDatabase}`);\n }\n\n await client.end();\n\n await prepare?.(client);\n\n const poolConfig = getPoolConfig(options);\n\n if (configurePool) {\n await defaultPool.initAsync(\n {\n ...poolConfig,\n // Offer sensible default, but these can be overridden by `options.poolConfig`.\n max: 10,\n idleTimeoutMillis: 30000,\n errorOnUnusedParameters: true,\n ...options.poolConfig,\n },\n (err) => {\n throw err;\n },\n );\n }\n\n return poolConfig;\n}\n\nasync function resetDatabase(options: PostgresTestUtilsOptions): Promise<void> {\n const client = new pg.Client(getPoolConfig(options));\n await client.connect();\n await client.query(`\n DO\n $func$\n BEGIN\n EXECUTE (\n SELECT 'TRUNCATE TABLE ' || string_agg(oid::regclass::text, ', ') || ' RESTART IDENTITY CASCADE'\n FROM pg_class\n WHERE relkind = 'r'\n AND relnamespace = 'public'::regnamespace\n );\n END\n $func$;\n `);\n await options.prepareAfterReset?.(client);\n await client.end();\n}\n\nasync function dropDatabase(\n options: PostgresTestUtilsOptions,\n { closePool = true, force = false, database }: DropDatabaseOptions = {},\n): Promise<void> {\n if (closePool) {\n await defaultPool.closeAsync();\n }\n\n const databaseName = database ?? getDatabaseNameForCurrentTestWorker(options.database);\n if ('PL_KEEP_TEST_DB' in process.env && !force) {\n // eslint-disable-next-line no-console\n console.log(`PL_KEEP_TEST_DB environment variable set, not dropping database ${databaseName}`);\n return;\n }\n\n const client = new pg.Client({\n ...getPoolConfig(options),\n database: options.defaultDatabase ?? POSTGRES_DATABASE,\n });\n await client.connect();\n await client.query(`DROP DATABASE IF EXISTS ${client.escapeIdentifier(databaseName)}`);\n await client.end();\n}\n\nfunction getDatabaseNameForCurrentTestWorker(namespace: string): string {\n // https://playwright.dev/docs/test-parallel#isolate-test-data-between-parallel-workers\n const workerId = process.env.TEST_WORKER_INDEX ?? process.env.VITEST_POOL_ID ?? '1';\n return `${namespace}_${workerId}`;\n}\n\nfunction getPoolConfig(options: PostgresTestUtilsOptions): PostgresTestPoolConfig {\n return {\n user: options.user ?? POSTGRES_USER,\n host: options.host ?? POSTGRES_HOST,\n database: getDatabaseNameForCurrentTestWorker(options.database),\n };\n}\n\nexport interface PostgresTestUtils {\n createDatabase: (options?: CreateDatabaseOptions) => Promise<pg.PoolConfig>;\n resetDatabase: () => Promise<void>;\n dropDatabase: (options?: DropDatabaseOptions) => Promise<void>;\n getDatabaseNameForCurrentTestWorker: () => string;\n getPoolConfig: () => pg.PoolConfig;\n}\n\nexport function makePostgresTestUtils(options: PostgresTestUtilsOptions): PostgresTestUtils {\n return {\n createDatabase: (createOptions?: CreateDatabaseOptions) =>\n createDatabase(options, createOptions),\n resetDatabase: () => resetDatabase(options),\n dropDatabase: (dropOptions?: DropDatabaseOptions) => dropDatabase(options, dropOptions),\n getDatabaseNameForCurrentTestWorker: () =>\n getDatabaseNameForCurrentTestWorker(options.database),\n getPoolConfig: () => getPoolConfig(options),\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prairielearn/postgres",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@prairielearn/tsconfig": "^0.0.0",
|
|
29
29
|
"@types/multipipe": "^3.0.5",
|
|
30
|
-
"@types/node": "^22.
|
|
31
|
-
"@vitest/coverage-v8": "^4.0.
|
|
30
|
+
"@types/node": "^22.19.0",
|
|
31
|
+
"@vitest/coverage-v8": "^4.0.7",
|
|
32
32
|
"tsx": "^4.20.6",
|
|
33
33
|
"typescript": "^5.9.3",
|
|
34
|
-
"vitest": "^4.0.
|
|
34
|
+
"vitest": "^4.0.7"
|
|
35
35
|
}
|
|
36
36
|
}
|
package/src/test-utils.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface PostgresTestUtilsOptions {
|
|
|
15
15
|
prepareAfterReset?: (client: pg.Client) => Promise<void>;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
type PostgresTestPoolConfig = Required<Pick<pg.PoolConfig, 'user' | 'host' | 'database'>>;
|
|
19
|
+
|
|
18
20
|
interface CreateDatabaseOptions {
|
|
19
21
|
dropExistingDatabase?: boolean;
|
|
20
22
|
database?: string;
|
|
@@ -38,7 +40,7 @@ async function createDatabase(
|
|
|
38
40
|
templateDatabase,
|
|
39
41
|
prepare,
|
|
40
42
|
}: CreateDatabaseOptions = {},
|
|
41
|
-
): Promise<
|
|
43
|
+
): Promise<PostgresTestPoolConfig> {
|
|
42
44
|
const client = new pg.Client({
|
|
43
45
|
...getPoolConfig(options),
|
|
44
46
|
database: options.defaultDatabase ?? POSTGRES_DATABASE,
|
|
@@ -46,7 +48,7 @@ async function createDatabase(
|
|
|
46
48
|
await client.connect();
|
|
47
49
|
|
|
48
50
|
const escapedDatabase = client.escapeIdentifier(
|
|
49
|
-
database ??
|
|
51
|
+
database ?? getDatabaseNameForCurrentTestWorker(options.database),
|
|
50
52
|
);
|
|
51
53
|
if (dropExistingDatabase ?? true) {
|
|
52
54
|
await client.query(`DROP DATABASE IF EXISTS ${escapedDatabase}`);
|
|
@@ -63,12 +65,12 @@ async function createDatabase(
|
|
|
63
65
|
|
|
64
66
|
await prepare?.(client);
|
|
65
67
|
|
|
68
|
+
const poolConfig = getPoolConfig(options);
|
|
69
|
+
|
|
66
70
|
if (configurePool) {
|
|
67
71
|
await defaultPool.initAsync(
|
|
68
72
|
{
|
|
69
|
-
|
|
70
|
-
host: options.host ?? POSTGRES_HOST,
|
|
71
|
-
database: getDatabaseNameForCurrentMochaWorker(options.database),
|
|
73
|
+
...poolConfig,
|
|
72
74
|
// Offer sensible default, but these can be overridden by `options.poolConfig`.
|
|
73
75
|
max: 10,
|
|
74
76
|
idleTimeoutMillis: 30000,
|
|
@@ -80,6 +82,8 @@ async function createDatabase(
|
|
|
80
82
|
},
|
|
81
83
|
);
|
|
82
84
|
}
|
|
85
|
+
|
|
86
|
+
return poolConfig;
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
async function resetDatabase(options: PostgresTestUtilsOptions): Promise<void> {
|
|
@@ -110,7 +114,7 @@ async function dropDatabase(
|
|
|
110
114
|
await defaultPool.closeAsync();
|
|
111
115
|
}
|
|
112
116
|
|
|
113
|
-
const databaseName = database ??
|
|
117
|
+
const databaseName = database ?? getDatabaseNameForCurrentTestWorker(options.database);
|
|
114
118
|
if ('PL_KEEP_TEST_DB' in process.env && !force) {
|
|
115
119
|
// eslint-disable-next-line no-console
|
|
116
120
|
console.log(`PL_KEEP_TEST_DB environment variable set, not dropping database ${databaseName}`);
|
|
@@ -126,24 +130,25 @@ async function dropDatabase(
|
|
|
126
130
|
await client.end();
|
|
127
131
|
}
|
|
128
132
|
|
|
129
|
-
function
|
|
130
|
-
|
|
133
|
+
function getDatabaseNameForCurrentTestWorker(namespace: string): string {
|
|
134
|
+
// https://playwright.dev/docs/test-parallel#isolate-test-data-between-parallel-workers
|
|
135
|
+
const workerId = process.env.TEST_WORKER_INDEX ?? process.env.VITEST_POOL_ID ?? '1';
|
|
131
136
|
return `${namespace}_${workerId}`;
|
|
132
137
|
}
|
|
133
138
|
|
|
134
|
-
function getPoolConfig(options: PostgresTestUtilsOptions):
|
|
139
|
+
function getPoolConfig(options: PostgresTestUtilsOptions): PostgresTestPoolConfig {
|
|
135
140
|
return {
|
|
136
141
|
user: options.user ?? POSTGRES_USER,
|
|
137
142
|
host: options.host ?? POSTGRES_HOST,
|
|
138
|
-
database:
|
|
143
|
+
database: getDatabaseNameForCurrentTestWorker(options.database),
|
|
139
144
|
};
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
export interface PostgresTestUtils {
|
|
143
|
-
createDatabase: (options?: CreateDatabaseOptions) => Promise<
|
|
148
|
+
createDatabase: (options?: CreateDatabaseOptions) => Promise<pg.PoolConfig>;
|
|
144
149
|
resetDatabase: () => Promise<void>;
|
|
145
150
|
dropDatabase: (options?: DropDatabaseOptions) => Promise<void>;
|
|
146
|
-
|
|
151
|
+
getDatabaseNameForCurrentTestWorker: () => string;
|
|
147
152
|
getPoolConfig: () => pg.PoolConfig;
|
|
148
153
|
}
|
|
149
154
|
|
|
@@ -153,8 +158,8 @@ export function makePostgresTestUtils(options: PostgresTestUtilsOptions): Postgr
|
|
|
153
158
|
createDatabase(options, createOptions),
|
|
154
159
|
resetDatabase: () => resetDatabase(options),
|
|
155
160
|
dropDatabase: (dropOptions?: DropDatabaseOptions) => dropDatabase(options, dropOptions),
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
getDatabaseNameForCurrentTestWorker: () =>
|
|
162
|
+
getDatabaseNameForCurrentTestWorker(options.database),
|
|
158
163
|
getPoolConfig: () => getPoolConfig(options),
|
|
159
164
|
};
|
|
160
165
|
}
|