@yss123/cage-testkit 0.1.0 → 0.3.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/README.md +77 -9
- package/dist/derived-diagnostics.d.ts +98 -0
- package/dist/derived-diagnostics.js +73 -0
- package/dist/derived-diagnostics.js.map +1 -0
- package/dist/derived.d.ts +19 -5
- package/dist/derived.js +177 -48
- package/dist/derived.js.map +1 -1
- package/dist/embedded-exit.d.ts +14 -0
- package/dist/embedded-exit.js +30 -0
- package/dist/embedded-exit.js.map +1 -0
- package/dist/env.d.ts +20 -1
- package/dist/env.js +62 -2
- package/dist/env.js.map +1 -1
- package/dist/fakes.d.ts +31 -2
- package/dist/fakes.js +50 -4
- package/dist/fakes.js.map +1 -1
- package/dist/global-setup.d.ts +4 -0
- package/dist/global-setup.js +9 -0
- package/dist/global-setup.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/pg.d.ts +18 -0
- package/dist/pg.js +87 -13
- package/dist/pg.js.map +1 -1
- package/dist/session.d.ts +9 -0
- package/dist/session.js +7 -0
- package/dist/session.js.map +1 -1
- package/package.json +8 -7
package/dist/env.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 为真实 PostgreSQL 回归准备独立临时数据库、组织根节点、内核与手动驱动 worker。
|
|
3
|
+
* 默认按当前声明建表,也可传入迁移文件;测试用户与角色通过领域命令创建,insert 是仅供夹具的直接写入捷径。
|
|
4
|
+
* 该环境需要独立测试集群权限,会创建角色和数据库,close 会关闭连接并尝试删除本次临时库,不能连接生产集群。
|
|
5
|
+
*/
|
|
1
6
|
// 集成测试环境:每个测试文件一个临时库,执行初始化脚本、建表、重建安全层,返回内核和一组测试工具。
|
|
2
7
|
import { randomBytes, randomUUID } from 'node:crypto';
|
|
3
8
|
import { DEFAULT_TENANT, createKernel, isCageError, silentLogger, systemCtx, toCageError, } from '@yss123/cage-kernel';
|
|
@@ -9,6 +14,10 @@ import { sampleRecord } from './fakes.js';
|
|
|
9
14
|
import { startEmbeddedPostgres, withDb } from './pg.js';
|
|
10
15
|
import { setSessionVarsSql } from './session.js';
|
|
11
16
|
let ownPg = null;
|
|
17
|
+
/**
|
|
18
|
+
* 优先复用 globalSetup 提供的测试管理员连接,再读取显式测试连接,否则启动内嵌 PostgreSQL。
|
|
19
|
+
* 返回的管理员连接仅用于建测试库和准备角色;缓存实例避免同进程反复启动。
|
|
20
|
+
*/
|
|
12
21
|
async function superUrl() {
|
|
13
22
|
if (process.env.CAGE_TEST_SUPER_URL)
|
|
14
23
|
return process.env.CAGE_TEST_SUPER_URL;
|
|
@@ -18,6 +27,12 @@ async function superUrl() {
|
|
|
18
27
|
process.env.CAGE_TEST_SUPER_URL = ownPg.superUrl;
|
|
19
28
|
return ownPg.superUrl;
|
|
20
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* 创建随机命名的测试库并返回可执行测试的环境,调用方必须在 teardown 中 close。
|
|
32
|
+
* 先在共同管理库取得角色初始化锁,避免不同测试库并发修改同一集群角色;随后按迁移或声明建结构。
|
|
33
|
+
* domain 必须包含组织模型,否则无法准备用户与部门并报错;logger 默认静默,可注入用于诊断回归。
|
|
34
|
+
* 默认新库测试不等于带旧数据的升级验收,未传 migrations 时也不验证应用迁移文件。
|
|
35
|
+
*/
|
|
21
36
|
export async function createTestEnv(opts) {
|
|
22
37
|
const su = await superUrl();
|
|
23
38
|
const dbName = `cage_t_${randomBytes(5).toString('hex')}`;
|
|
@@ -80,10 +95,19 @@ export async function createTestEnv(opts) {
|
|
|
80
95
|
urls,
|
|
81
96
|
system: sys,
|
|
82
97
|
callAs,
|
|
98
|
+
/**
|
|
99
|
+
* 通过 Dept.create 建立测试部门,省略父级时挂到本环境根部门。
|
|
100
|
+
* 返回真实持久化 ID;命令失败直接传播,不伪造可用部门。
|
|
101
|
+
*/
|
|
83
102
|
async dept(name, parentId) {
|
|
84
103
|
const d = await kernel.execute('Dept.create', { name, parentId: parentId ?? root.id }, sys());
|
|
85
104
|
return d.id;
|
|
86
105
|
},
|
|
106
|
+
/**
|
|
107
|
+
* 先创建独立角色,再逐个授能力与范围,最后创建用户并分配该角色。
|
|
108
|
+
* caps=all 取当前内核目录;params 给特定能力提供额度等参数,scopes 保留组合子语义。
|
|
109
|
+
* 返回的 ctx 会重新解析身份,账号没有自动设置登录密码,HTTP 测试需单独设置。
|
|
110
|
+
*/
|
|
87
111
|
async user(o) {
|
|
88
112
|
const s = sys();
|
|
89
113
|
const role = await kernel.execute('Role.create', { code: `r_${randomBytes(4).toString('hex')}`, name: 'test role' }, s);
|
|
@@ -104,10 +128,17 @@ export async function createTestEnv(opts) {
|
|
|
104
128
|
ctx: async () => (await kernel.contextFor(u.id, tenantId, { requestId: randomUUID() })),
|
|
105
129
|
};
|
|
106
130
|
},
|
|
131
|
+
/**
|
|
132
|
+
* 创建拥有其他全部能力且范围为 all 的身份,用于把拒绝原因定位到缺少目标能力。
|
|
133
|
+
*/
|
|
107
134
|
async actorWithout(capability) {
|
|
108
135
|
const u = await env.user({ caps: kernel.catalogCaps().filter((c) => c !== capability), scopes: { '*': 'all' } });
|
|
109
136
|
return u.ctx();
|
|
110
137
|
},
|
|
138
|
+
/**
|
|
139
|
+
* 直接构造测试记录并补必要引用,主表与集合关联在同一事务写入。
|
|
140
|
+
* values 覆盖样例字段,可指定状态/归属;这条捷径跳过 handler、业务硬约束和命令审计,不能当业务写入范例。
|
|
141
|
+
*/
|
|
111
142
|
async insert(aggRef, values = {}) {
|
|
112
143
|
const agg = typeof aggRef === 'string' ? kernel.registry.aggregate(aggRef) : aggRef;
|
|
113
144
|
const { status, ownerId, id: givenId, ...fields } = values;
|
|
@@ -118,7 +149,7 @@ export async function createTestEnv(opts) {
|
|
|
118
149
|
rec[agg.scope.deptField] = root.id;
|
|
119
150
|
// 引用字段:指向真实存在的记录(外键)
|
|
120
151
|
for (const [k, f] of Object.entries(agg.fields)) {
|
|
121
|
-
if (
|
|
152
|
+
if (f.kind !== 'ref' || fields[k] !== undefined || k === agg.scope.ownerField || (k === agg.scope.deptField && rec[k]))
|
|
122
153
|
continue;
|
|
123
154
|
if (f.isOptional) {
|
|
124
155
|
rec[k] = null;
|
|
@@ -129,9 +160,22 @@ export async function createTestEnv(opts) {
|
|
|
129
160
|
const row = {
|
|
130
161
|
id: givenId ?? randomUUID(), tenant_id: tenantId, ...fieldsToColumns(agg, rec), status: status ?? agg.states.initial, version: 1,
|
|
131
162
|
};
|
|
132
|
-
|
|
163
|
+
// 种子绕过命令,但仍按真实物理结构在同一事务插入主记录和关联,外键约束照常生效。
|
|
164
|
+
await kernel.app.transaction().execute(async (tx) => {
|
|
165
|
+
await tx.insertInto(`${agg.table.schema}.${agg.table.name}`).values(row).execute();
|
|
166
|
+
for (const table of model.tables.filter((t) => t.aggregate === agg.name && t.relation)) {
|
|
167
|
+
const ids = [...new Set(rec[table.relation.field])];
|
|
168
|
+
if (ids.length)
|
|
169
|
+
await tx.insertInto(`${table.schema}.${table.name}`)
|
|
170
|
+
.values(ids.map((id) => ({ tenant_id: tenantId, source_id: row.id, target_id: id }))).execute();
|
|
171
|
+
}
|
|
172
|
+
});
|
|
133
173
|
return { ...rec, id: row.id, status: row.status, version: 1 };
|
|
134
174
|
},
|
|
175
|
+
/**
|
|
176
|
+
* 按已有记录命令的第一个合法起始状态建立夹具,调用者可覆盖字段。
|
|
177
|
+
* 新建命令不需要种子,传入会报错;只保证选用声明状态,不保证满足任意业务不变量。
|
|
178
|
+
*/
|
|
135
179
|
async seedFor(capability, values = {}) {
|
|
136
180
|
const rc = kernel.registry.command(capability);
|
|
137
181
|
if (!rc)
|
|
@@ -140,6 +184,10 @@ export async function createTestEnv(opts) {
|
|
|
140
184
|
throw new Error(`${capability} 是新建命令,不需要种子数据`);
|
|
141
185
|
return env.insert(rc.cmd.agg, { status: rc.cmd.from[0], ...values });
|
|
142
186
|
},
|
|
187
|
+
/**
|
|
188
|
+
* 创建单连接的只读池,设置会话级范围与掩码变量后返回 Kysely 连接。
|
|
189
|
+
* 用于验证直接读取安全视图也受限制;调用者应 release,环境 close 另作最终清理。
|
|
190
|
+
*/
|
|
143
191
|
async readConnectionAs(ctx) {
|
|
144
192
|
const pool = new pg.Pool({ connectionString: urls.read, max: 1, idleTimeoutMillis: 0 });
|
|
145
193
|
readers.push(pool);
|
|
@@ -153,6 +201,10 @@ export async function createTestEnv(opts) {
|
|
|
153
201
|
return db;
|
|
154
202
|
},
|
|
155
203
|
drain: () => worker.drain(),
|
|
204
|
+
/**
|
|
205
|
+
* 以测试管理员查询审计记录,可按对象 ID、命令与类别过滤,按 ID 返回。
|
|
206
|
+
* 这是断言审计行为的测试通道,不代表业务角色能绕过安全视图读取审计。
|
|
207
|
+
*/
|
|
156
208
|
async audit(where = {}) {
|
|
157
209
|
const cond = [];
|
|
158
210
|
const params = [];
|
|
@@ -165,9 +217,17 @@ export async function createTestEnv(opts) {
|
|
|
165
217
|
const r = await superPool.query(`select * from sys.audit_log ${cond.length ? 'where ' + cond.join(' and ') : ''} order by id`, params);
|
|
166
218
|
return r.rows;
|
|
167
219
|
},
|
|
220
|
+
/**
|
|
221
|
+
* 使用本测试库管理员执行参数化 SQL 并返回行,用于夹具检查与故障注入。
|
|
222
|
+
* 只能在测试中使用,调用者负责 SQL 意图与参数,不经过领域命令和业务范围。
|
|
223
|
+
*/
|
|
168
224
|
async query(text, params = []) {
|
|
169
225
|
return (await superPool.query(text, params)).rows;
|
|
170
226
|
},
|
|
227
|
+
/**
|
|
228
|
+
* 关闭内核、读池与管理员池,再尝试强制删除本次随机命名的临时数据库。
|
|
229
|
+
* 不停止调用方提供的集群;个别清理失败按当前实现被忽略,连接异常仍可能传播。
|
|
230
|
+
*/
|
|
171
231
|
async close() {
|
|
172
232
|
await kernel.close();
|
|
173
233
|
for (const p of readers)
|
package/dist/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
|
package/dist/fakes.d.ts
CHANGED
|
@@ -1,20 +1,49 @@
|
|
|
1
1
|
import fc from 'fast-check';
|
|
2
2
|
import type { AnyAggregate, AnyCommand, AnyField, Draft, ReadRepo } from '@yss123/cage-kernel';
|
|
3
|
-
/**
|
|
3
|
+
/** 字段形状的基础示例,用于构造草稿和种子候选,不推导任意业务约束。 */
|
|
4
|
+
/**
|
|
5
|
+
* 为一个字段生成基础样例;可选字段默认 null,force=true 才强制构造非空候选。
|
|
6
|
+
* name 影响普通文本,敏感类型用固定测试示例,金额用十进制字符串;引用 ID 不保证已有目标记录。
|
|
7
|
+
*/
|
|
4
8
|
export declare function sampleValue(f: AnyField, name?: string, force?: boolean): unknown;
|
|
5
9
|
/** 字段的 fast-check 生成器:用于不变量的性质测试 */
|
|
10
|
+
/**
|
|
11
|
+
* 根据字段种类构造有界 fast-check 候选生成器,集合限制数量以控制测试规模。
|
|
12
|
+
* 金额通过整数分映射为两位小数字符串,可选字段混入 null;输入仍需业务校验,不是成功路径夹具保证。
|
|
13
|
+
*/
|
|
6
14
|
export declare function arbitraryOf(f: AnyField): fc.Arbitrary<unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* 组合聚合持久字段的候选对象,跳过只读 hasMany 反查。
|
|
17
|
+
* 不附加系统列,也不替调用方建立外键目标或满足跨字段不变量。
|
|
18
|
+
*/
|
|
7
19
|
export declare function arbitrarySnapshot(agg: AnyAggregate): fc.Arbitrary<Record<string, unknown>>;
|
|
8
|
-
/**
|
|
20
|
+
/** 按字段形状构造候选记录;合法业务前置条件由具体测试补齐。 */
|
|
21
|
+
/**
|
|
22
|
+
* 按聚合字段构造候选记录,再用 overrides 覆盖指定值,跳过非持久 hasMany。
|
|
23
|
+
* 可选值可能为 null;函数不执行聚合不变量、命令规则或数据库校验。
|
|
24
|
+
*/
|
|
9
25
|
export declare function sampleRecord(agg: AnyAggregate, overrides?: Record<string, unknown>): Record<string, any>;
|
|
10
26
|
/**
|
|
11
27
|
* 构造命令 handler 的草稿:状态取命令的第一个起始状态(新建命令取目标状态)
|
|
12
28
|
* const order = draftOf(approve, { items: [{ sku: 'A-01', qty: 10 }] })
|
|
13
29
|
*/
|
|
30
|
+
/**
|
|
31
|
+
* 构造直接传给 handler 的测试草稿,补 ID、版本和当前时间等系统字段。
|
|
32
|
+
* 新建命令取目标状态,已有记录命令取首个起始状态;overrides 最后覆盖以支持边界场景。
|
|
33
|
+
* 此草稿未持久化,也未经过内核权限和不变量检查。
|
|
34
|
+
*/
|
|
14
35
|
export declare function draftOf<C extends AnyCommand>(cmd: C, overrides?: Partial<Draft<C['agg']>>): Draft<C['agg']>;
|
|
15
36
|
/** 内存只读仓储:等值条件查询,与内核的 ReadRepo 接口一致 */
|
|
37
|
+
/**
|
|
38
|
+
* 用给定 rows 模拟 ReadRepo 的基本 get/find/findOne/count 等值读取,返回深拷贝避免测试污染夹具。
|
|
39
|
+
* find 支持 limit,但不模拟数据库排序、范围、锁、事务或安全视图;适合纯 handler 分支测试。
|
|
40
|
+
*/
|
|
16
41
|
export declare function fakeRepo<A extends AnyAggregate = AnyAggregate>(rows: Record<string, any>[]): ReadRepo<A>;
|
|
17
42
|
/** 直接调用 handler 时的第四个参数 */
|
|
43
|
+
/**
|
|
44
|
+
* 生成 handler 使用的冻结上下文,包含当前时间与可空操作者 ID。
|
|
45
|
+
* 省略操作者时给随机测试 ID;不包含能力信息,也不完成身份认证。
|
|
46
|
+
*/
|
|
18
47
|
export declare function handlerCtx(actorUserId?: string | null): Readonly<{
|
|
19
48
|
now: Date;
|
|
20
49
|
actorUserId: string | null;
|
package/dist/fakes.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 纯 handler 单测的样例数据与内存只读依赖工具。
|
|
3
|
+
* 样例按字段形状生成,不能推导任意业务规则;直接调用 handler 跳过权限、状态、事务和审计,应另用集成测试覆盖。
|
|
4
|
+
* fast-check 生成器用于探索字段空间,不承诺所生成的每个记录都满足聚合不变量或外键存在性。
|
|
5
|
+
*/
|
|
1
6
|
// handler 单测工具:handler 不碰数据库,把读依赖换成内存假对象,直接调用函数。毫秒级。
|
|
2
7
|
import { randomUUID } from 'node:crypto';
|
|
3
8
|
import fc from 'fast-check';
|
|
4
|
-
/**
|
|
9
|
+
/** 字段形状的基础示例,用于构造草稿和种子候选,不推导任意业务约束。 */
|
|
10
|
+
/**
|
|
11
|
+
* 为一个字段生成基础样例;可选字段默认 null,force=true 才强制构造非空候选。
|
|
12
|
+
* name 影响普通文本,敏感类型用固定测试示例,金额用十进制字符串;引用 ID 不保证已有目标记录。
|
|
13
|
+
*/
|
|
5
14
|
export function sampleValue(f, name = '', force = false) {
|
|
6
15
|
if (f.isOptional && !force)
|
|
7
16
|
return null;
|
|
@@ -26,6 +35,7 @@ export function sampleValue(f, name = '', force = false) {
|
|
|
26
35
|
return '100.00';
|
|
27
36
|
case 'id':
|
|
28
37
|
case 'ref':
|
|
38
|
+
case 'file':
|
|
29
39
|
return randomUUID();
|
|
30
40
|
case 'date':
|
|
31
41
|
return '2026-01-01';
|
|
@@ -41,11 +51,18 @@ export function sampleValue(f, name = '', force = false) {
|
|
|
41
51
|
if ('item' in f.shape && Object.keys(f.shape).length === 1)
|
|
42
52
|
return [sampleValue(f.shape.item, 'item')];
|
|
43
53
|
return [Object.fromEntries(Object.entries(f.shape).map(([k, sf]) => [k, sampleValue(sf, k)]))];
|
|
54
|
+
case 'manyToMany':
|
|
55
|
+
case 'files':
|
|
56
|
+
return [];
|
|
44
57
|
default:
|
|
45
58
|
return null;
|
|
46
59
|
}
|
|
47
60
|
}
|
|
48
61
|
/** 字段的 fast-check 生成器:用于不变量的性质测试 */
|
|
62
|
+
/**
|
|
63
|
+
* 根据字段种类构造有界 fast-check 候选生成器,集合限制数量以控制测试规模。
|
|
64
|
+
* 金额通过整数分映射为两位小数字符串,可选字段混入 null;输入仍需业务校验,不是成功路径夹具保证。
|
|
65
|
+
*/
|
|
49
66
|
export function arbitraryOf(f) {
|
|
50
67
|
let a;
|
|
51
68
|
switch (f.kind) {
|
|
@@ -63,8 +80,15 @@ export function arbitraryOf(f) {
|
|
|
63
80
|
break;
|
|
64
81
|
case 'id':
|
|
65
82
|
case 'ref':
|
|
83
|
+
case 'file':
|
|
66
84
|
a = fc.uuid();
|
|
67
85
|
break;
|
|
86
|
+
case 'manyToMany':
|
|
87
|
+
a = fc.uniqueArray(fc.uuid(), { maxLength: 5 }).map((ids) => ids.sort());
|
|
88
|
+
break;
|
|
89
|
+
case 'files':
|
|
90
|
+
a = fc.constant([]);
|
|
91
|
+
break;
|
|
68
92
|
case 'bool':
|
|
69
93
|
a = fc.boolean();
|
|
70
94
|
break;
|
|
@@ -84,20 +108,34 @@ export function arbitraryOf(f) {
|
|
|
84
108
|
}
|
|
85
109
|
return f.isOptional ? fc.option(a, { nil: null }) : a;
|
|
86
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* 组合聚合持久字段的候选对象,跳过只读 hasMany 反查。
|
|
113
|
+
* 不附加系统列,也不替调用方建立外键目标或满足跨字段不变量。
|
|
114
|
+
*/
|
|
87
115
|
export function arbitrarySnapshot(agg) {
|
|
88
|
-
return fc.record(Object.fromEntries(Object.entries(agg.fields).map(([k, f]) => [k, arbitraryOf(f)])));
|
|
116
|
+
return fc.record(Object.fromEntries(Object.entries(agg.fields).filter(([, f]) => f.kind !== 'hasMany').map(([k, f]) => [k, arbitraryOf(f)])));
|
|
89
117
|
}
|
|
90
|
-
/**
|
|
118
|
+
/** 按字段形状构造候选记录;合法业务前置条件由具体测试补齐。 */
|
|
119
|
+
/**
|
|
120
|
+
* 按聚合字段构造候选记录,再用 overrides 覆盖指定值,跳过非持久 hasMany。
|
|
121
|
+
* 可选值可能为 null;函数不执行聚合不变量、命令规则或数据库校验。
|
|
122
|
+
*/
|
|
91
123
|
export function sampleRecord(agg, overrides = {}) {
|
|
92
124
|
const out = {};
|
|
93
125
|
for (const [k, f] of Object.entries(agg.fields))
|
|
94
|
-
|
|
126
|
+
if (f.kind !== 'hasMany')
|
|
127
|
+
out[k] = sampleValue(f, k);
|
|
95
128
|
return { ...out, ...overrides };
|
|
96
129
|
}
|
|
97
130
|
/**
|
|
98
131
|
* 构造命令 handler 的草稿:状态取命令的第一个起始状态(新建命令取目标状态)
|
|
99
132
|
* const order = draftOf(approve, { items: [{ sku: 'A-01', qty: 10 }] })
|
|
100
133
|
*/
|
|
134
|
+
/**
|
|
135
|
+
* 构造直接传给 handler 的测试草稿,补 ID、版本和当前时间等系统字段。
|
|
136
|
+
* 新建命令取目标状态,已有记录命令取首个起始状态;overrides 最后覆盖以支持边界场景。
|
|
137
|
+
* 此草稿未持久化,也未经过内核权限和不变量检查。
|
|
138
|
+
*/
|
|
101
139
|
export function draftOf(cmd, overrides = {}) {
|
|
102
140
|
const now = new Date().toISOString();
|
|
103
141
|
const status = cmd.from === 'new' ? cmd.to : cmd.from[0];
|
|
@@ -112,6 +150,10 @@ export function draftOf(cmd, overrides = {}) {
|
|
|
112
150
|
};
|
|
113
151
|
}
|
|
114
152
|
/** 内存只读仓储:等值条件查询,与内核的 ReadRepo 接口一致 */
|
|
153
|
+
/**
|
|
154
|
+
* 用给定 rows 模拟 ReadRepo 的基本 get/find/findOne/count 等值读取,返回深拷贝避免测试污染夹具。
|
|
155
|
+
* find 支持 limit,但不模拟数据库排序、范围、锁、事务或安全视图;适合纯 handler 分支测试。
|
|
156
|
+
*/
|
|
115
157
|
export function fakeRepo(rows) {
|
|
116
158
|
const match = (r, where) => Object.entries(where ?? {}).every(([k, v]) => v === undefined || JSON.stringify(r[k] ?? null) === JSON.stringify(v));
|
|
117
159
|
const clone = (r) => structuredClone(r);
|
|
@@ -123,6 +165,10 @@ export function fakeRepo(rows) {
|
|
|
123
165
|
};
|
|
124
166
|
}
|
|
125
167
|
/** 直接调用 handler 时的第四个参数 */
|
|
168
|
+
/**
|
|
169
|
+
* 生成 handler 使用的冻结上下文,包含当前时间与可空操作者 ID。
|
|
170
|
+
* 省略操作者时给随机测试 ID;不包含能力信息,也不完成身份认证。
|
|
171
|
+
*/
|
|
126
172
|
export function handlerCtx(actorUserId = randomUUID()) {
|
|
127
173
|
return Object.freeze({ now: new Date(), actorUserId });
|
|
128
174
|
}
|
package/dist/fakes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fakes.js","sourceRoot":"","sources":["../src/fakes.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,
|
|
1
|
+
{"version":3,"file":"fakes.js","sourceRoot":"","sources":["../src/fakes.ts"],"names":[],"mappings":"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"}
|
package/dist/global-setup.d.ts
CHANGED
package/dist/global-setup.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest 测试运行共享的 PostgreSQL 启停入口。
|
|
3
|
+
* 已有 CAGE_TEST_DATABASE_URL 时仅转交测试管理员地址;否则启动本次内嵌集群并在全局结束时关闭。
|
|
4
|
+
* 每个测试环境仍创建独立数据库,共享集群不等于共享业务记录。
|
|
5
|
+
*/
|
|
1
6
|
// Vitest globalSetup:整个测试运行只启动一个 PostgreSQL,每个测试文件各建一个临时库。
|
|
2
7
|
// // vitest.config.ts
|
|
3
8
|
// export default { test: { globalSetup: ['@yss123/cage-testkit/global-setup'] } }
|
|
4
9
|
import { startEmbeddedPostgres } from './pg.js';
|
|
5
10
|
let instance = null;
|
|
11
|
+
/**
|
|
12
|
+
* 准备测试进程可见的 CAGE_TEST_SUPER_URL 并返回 teardown 回调。
|
|
13
|
+
* 外部集群分支不负责停止外部服务;内嵌分支等待 stop 完成后清空实例引用,清理异常向测试框架传播。
|
|
14
|
+
*/
|
|
6
15
|
export default async function setup() {
|
|
7
16
|
if (process.env.CAGE_TEST_DATABASE_URL) {
|
|
8
17
|
process.env.CAGE_TEST_SUPER_URL = process.env.CAGE_TEST_DATABASE_URL;
|
package/dist/global-setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-setup.js","sourceRoot":"","sources":["../src/global-setup.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,wBAAwB;AACxB,oFAAoF;AACpF,OAAO,EAAE,qBAAqB,EAAmB,MAAM,SAAS,CAAC;AAEjE,IAAI,QAAQ,GAAsB,IAAI,CAAC;AAEvC,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,KAAK;IACjC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;QACrE,OAAO,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;IACxB,CAAC;IACD,QAAQ,GAAG,MAAM,qBAAqB,EAAE,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACpD,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,QAAQ,EAAE,IAAI,EAAE,CAAC;QACvB,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"global-setup.js","sourceRoot":"","sources":["../src/global-setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,2DAA2D;AAC3D,wBAAwB;AACxB,oFAAoF;AACpF,OAAO,EAAE,qBAAqB,EAAmB,MAAM,SAAS,CAAC;AAEjE,IAAI,QAAQ,GAAsB,IAAI,CAAC;AAEvC;;;GAGG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,KAAK;IACjC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;QACrE,OAAO,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;IACxB,CAAC;IACD,QAAQ,GAAG,MAAM,qBAAqB,EAAE,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACpD,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,QAAQ,EAAE,IAAI,EAAE,CAAC;QACvB,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 测试工具包的公共入口:纯 handler 假依赖、真实 PostgreSQL 集成环境及声明派生测试。
|
|
3
|
+
* 业务测试按需要选择层次;fake 工具不证明数据库权限,集成工具使用独立可丢弃数据库。
|
|
4
|
+
* 本入口只重导出,不启动 PostgreSQL;生命周期由 createTestEnv 或 Vitest globalSetup 的调用方管理。
|
|
5
|
+
*/
|
|
1
6
|
export { fakeRepo, draftOf, sampleValue, sampleRecord, arbitraryOf, arbitrarySnapshot, handlerCtx } from './fakes.js';
|
|
2
7
|
export { createTestEnv, type TestEnv, type TestUser, type CallResult } from './env.js';
|
|
3
8
|
export { startEmbeddedPostgres, withDb, freePort, type PgInstance } from './pg.js';
|
|
4
9
|
export { setSessionVarsSql } from './session.js';
|
|
5
|
-
export { derived, SKIP, type Derived, type Skip } from './derived.js';
|
|
10
|
+
export { derived, SKIP, DerivedTestError, type Derived, type Skip, type DerivedOptions, type DerivedFixtureContext, type DerivedCommandTrace, type DerivedRunTrace, type DerivedInvariantResult } from './derived.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 测试工具包的公共入口:纯 handler 假依赖、真实 PostgreSQL 集成环境及声明派生测试。
|
|
3
|
+
* 业务测试按需要选择层次;fake 工具不证明数据库权限,集成工具使用独立可丢弃数据库。
|
|
4
|
+
* 本入口只重导出,不启动 PostgreSQL;生命周期由 createTestEnv 或 Vitest globalSetup 的调用方管理。
|
|
5
|
+
*/
|
|
1
6
|
// @yss123/cage-testkit:handler 单测工具、集成测试环境、派生测试运行时。
|
|
2
7
|
export { fakeRepo, draftOf, sampleValue, sampleRecord, arbitraryOf, arbitrarySnapshot, handlerCtx } from './fakes.js';
|
|
3
8
|
export { createTestEnv } from './env.js';
|
|
4
9
|
export { startEmbeddedPostgres, withDb, freePort } from './pg.js';
|
|
5
10
|
export { setSessionVarsSql } from './session.js';
|
|
6
|
-
export { derived, SKIP } from './derived.js';
|
|
11
|
+
export { derived, SKIP, DerivedTestError } from './derived.js';
|
|
7
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtH,OAAO,EAAE,aAAa,EAAgD,MAAM,UAAU,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAQ,EAAmB,MAAM,SAAS,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,oDAAoD;AACpD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtH,OAAO,EAAE,aAAa,EAAgD,MAAM,UAAU,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAQ,EAAmB,MAAM,SAAS,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAyJ,MAAM,cAAc,CAAC"}
|
package/dist/pg.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 内嵌实例句柄:host/port 定位本地监听,superUrl 是测试管理员连接。
|
|
3
|
+
* stop 幂等关闭本次实例并按 persistent 决定目录清理,不按进程名停止其他 PostgreSQL。
|
|
4
|
+
*/
|
|
1
5
|
export interface PgInstance {
|
|
2
6
|
/** 超级用户连接串(指向 postgres 库) */
|
|
3
7
|
superUrl: string;
|
|
@@ -5,7 +9,17 @@ export interface PgInstance {
|
|
|
5
9
|
port: number;
|
|
6
10
|
stop(): Promise<void>;
|
|
7
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 让系统在回环地址分配临时端口,关闭探测 socket 后返回端口号。
|
|
14
|
+
* 该结果是当时空闲端口,不在函数返回后持续占用;后续启动仍可能遇到竞争并失败。
|
|
15
|
+
*/
|
|
8
16
|
export declare function freePort(): Promise<number>;
|
|
17
|
+
/**
|
|
18
|
+
* 启动测试 PostgreSQL;dir/port 可显式指定,persistent 默认 false,log 决定是否转发进程日志。
|
|
19
|
+
* 拒绝根目录和把已有数据库目录作为可自动删除临时目录;启动后记录真实路径及唯一归属令牌。
|
|
20
|
+
* stop 在关闭前后核对目录归属,Windows 还核对服务报告的数据目录和端口;归属不符时拒绝清理。
|
|
21
|
+
* 临时目录删除有界重试以等待文件句柄释放,失败抛出;持久目录只移除本次归属标记。
|
|
22
|
+
*/
|
|
9
23
|
export declare function startEmbeddedPostgres(opts?: {
|
|
10
24
|
dir?: string;
|
|
11
25
|
port?: number;
|
|
@@ -13,6 +27,10 @@ export declare function startEmbeddedPostgres(opts?: {
|
|
|
13
27
|
log?: boolean;
|
|
14
28
|
}): Promise<PgInstance>;
|
|
15
29
|
/** 把超级用户连接串换成另一个库、另一个账号 */
|
|
30
|
+
/**
|
|
31
|
+
* 复制并改写连接 URL 的数据库路径,可选替换账号与密码,保留主机及其他 URL 参数。
|
|
32
|
+
* 仅返回字符串,不建立连接、创建数据库或验证账号;调用方不得把含凭据结果写入日志。
|
|
33
|
+
*/
|
|
16
34
|
export declare function withDb(url: string, db: string, user?: {
|
|
17
35
|
name: string;
|
|
18
36
|
password: string;
|
package/dist/pg.js
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 内嵌真实 PostgreSQL 的测试进程与目录生命周期管理。
|
|
3
|
+
* 启动临时或显式持久实例,使用路径和归属标记约束停止/删除目标;Windows 通过 pg_ctl 关闭本次实例。
|
|
4
|
+
* 业务 dev 不使用这里自动建库,测试连接选择由上层 env/globalSetup 负责;目录和管理员连接只供受控测试。
|
|
5
|
+
* 加载上游依赖后安装退出码兼容层,避免其异步清理钩子把已有测试失败改为成功退出。
|
|
6
|
+
*/
|
|
1
7
|
// 测试与本地开发用的 PostgreSQL:优先使用 CAGE_TEST_DATABASE_URL(超级用户连接串,例如 CI 里的服务容器),
|
|
2
8
|
// 否则启动 embedded-postgres(npm 包自带真实的 PostgreSQL 二进制,不需要 Docker)。
|
|
3
|
-
import { mkdtempSync,
|
|
9
|
+
import { mkdtempSync, existsSync, mkdirSync } from 'node:fs';
|
|
10
|
+
import { readFile, realpath, rm, unlink, writeFile } from 'node:fs/promises';
|
|
11
|
+
import { randomUUID } from 'node:crypto';
|
|
12
|
+
import { execFile } from 'node:child_process';
|
|
13
|
+
import { createRequire } from 'node:module';
|
|
14
|
+
import { promisify } from 'node:util';
|
|
15
|
+
import { pathToFileURL } from 'node:url';
|
|
4
16
|
import { createServer } from 'node:net';
|
|
5
17
|
import { tmpdir } from 'node:os';
|
|
6
|
-
import { join } from 'node:path';
|
|
18
|
+
import { join, parse, resolve } from 'node:path';
|
|
19
|
+
import pg from 'pg';
|
|
20
|
+
import { preserveEmbeddedPostgresExitCode } from './embedded-exit.js';
|
|
21
|
+
/**
|
|
22
|
+
* 让系统在回环地址分配临时端口,关闭探测 socket 后返回端口号。
|
|
23
|
+
* 该结果是当时空闲端口,不在函数返回后持续占用;后续启动仍可能遇到竞争并失败。
|
|
24
|
+
*/
|
|
7
25
|
export async function freePort() {
|
|
8
26
|
return new Promise((resolve, reject) => {
|
|
9
27
|
const s = createServer();
|
|
@@ -15,38 +33,94 @@ export async function freePort() {
|
|
|
15
33
|
});
|
|
16
34
|
});
|
|
17
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* 启动测试 PostgreSQL;dir/port 可显式指定,persistent 默认 false,log 决定是否转发进程日志。
|
|
38
|
+
* 拒绝根目录和把已有数据库目录作为可自动删除临时目录;启动后记录真实路径及唯一归属令牌。
|
|
39
|
+
* stop 在关闭前后核对目录归属,Windows 还核对服务报告的数据目录和端口;归属不符时拒绝清理。
|
|
40
|
+
* 临时目录删除有界重试以等待文件句柄释放,失败抛出;持久目录只移除本次归属标记。
|
|
41
|
+
*/
|
|
18
42
|
export async function startEmbeddedPostgres(opts = {}) {
|
|
19
43
|
const { default: EmbeddedPostgres } = await import('embedded-postgres');
|
|
44
|
+
// 依赖仅被导入就注册固定退出码的钩子;在创建实例前保留失败状态,初始化失败同样不能变成成功。
|
|
45
|
+
preserveEmbeddedPostgresExitCode();
|
|
20
46
|
const port = opts.port ?? (await freePort());
|
|
21
47
|
const persistent = opts.persistent ?? false;
|
|
22
|
-
const dir = opts.dir ?? mkdtempSync(join(tmpdir(), 'cage-pg-'));
|
|
48
|
+
const dir = resolve(opts.dir ?? mkdtempSync(join(tmpdir(), 'cage-pg-')));
|
|
49
|
+
if (dir === parse(dir).root)
|
|
50
|
+
throw new Error('[CAGE-TEST-003] 内嵌 PostgreSQL 目录不能是文件系统根目录');
|
|
23
51
|
const fresh = !existsSync(join(dir, 'PG_VERSION'));
|
|
52
|
+
if (!persistent && !fresh)
|
|
53
|
+
throw new Error('[CAGE-TEST-003] 不允许将已有 PostgreSQL 目录作为自动删除的临时实例;使用 persistent: true');
|
|
24
54
|
if (persistent)
|
|
25
55
|
mkdirSync(dir, { recursive: true });
|
|
26
|
-
const
|
|
56
|
+
const instance = new EmbeddedPostgres({
|
|
27
57
|
databaseDir: dir,
|
|
28
58
|
user: 'postgres',
|
|
29
59
|
password: 'postgres',
|
|
30
60
|
port,
|
|
31
|
-
|
|
61
|
+
// 目录清理由本包装层负责。上游在 Windows 杀进程后立即删目录,没有处理
|
|
62
|
+
// 文件句柄释放的短暂延迟;保留目录再由 stop() 做有界重试,失败仍明确抛出。
|
|
63
|
+
persistent: true,
|
|
32
64
|
onLog: opts.log ? (m) => process.stdout.write(m) : () => { },
|
|
33
65
|
onError: opts.log ? (m) => process.stderr.write(String(m)) : () => { },
|
|
34
66
|
});
|
|
35
67
|
if (fresh)
|
|
36
|
-
await
|
|
37
|
-
await
|
|
68
|
+
await instance.initialise();
|
|
69
|
+
await instance.start();
|
|
70
|
+
const ownedDir = await realpath(dir);
|
|
71
|
+
const marker = join(ownedDir, '.cage-testkit-owner');
|
|
72
|
+
const token = randomUUID();
|
|
73
|
+
await writeFile(marker, token, 'utf8');
|
|
74
|
+
const superUrl = `postgres://postgres:postgres@127.0.0.1:${port}/postgres`;
|
|
75
|
+
let stopping = null;
|
|
76
|
+
const upstreamStop = instance.stop.bind(instance);
|
|
77
|
+
const samePath = (a, b) => process.platform === 'win32' ? resolve(a).toLowerCase() === resolve(b).toLowerCase() : resolve(a) === resolve(b);
|
|
78
|
+
const stopOwned = async () => {
|
|
79
|
+
// 只关闭本包装器刚启动的实例,不能按进程名终止机器上其他 PostgreSQL。
|
|
80
|
+
if (!samePath(await realpath(dir), ownedDir) || (await readFile(marker, 'utf8')) !== token)
|
|
81
|
+
throw new Error('[CAGE-TEST-003] 临时 PostgreSQL 目录归属变化,拒绝停止或删除');
|
|
82
|
+
if (process.platform === 'win32') {
|
|
83
|
+
const client = new pg.Client({ connectionString: superUrl, connectionTimeoutMillis: 2_000, statement_timeout: 2_000 });
|
|
84
|
+
try {
|
|
85
|
+
await client.connect();
|
|
86
|
+
const { rows } = await client.query("select current_setting('data_directory') as directory, current_setting('port')::int as port");
|
|
87
|
+
if (!samePath(await realpath(rows[0].directory), ownedDir) || rows[0].port !== port)
|
|
88
|
+
throw new Error('[CAGE-TEST-003] PostgreSQL 实际目录或端口与本次实例不符');
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
await client.end();
|
|
92
|
+
}
|
|
93
|
+
// 平台包公开导出 pg_ctl;不用上游的私有 process,也不用会被沙箱阻断的 taskkill。
|
|
94
|
+
// Vite 的 globalSetup 不实现 import.meta.resolve;使用 Node 的公开模块解析接口。
|
|
95
|
+
const requireEmbedded = createRequire(createRequire(import.meta.url).resolve('embedded-postgres'));
|
|
96
|
+
const binaries = await import(pathToFileURL(requireEmbedded.resolve(`@embedded-postgres/windows-${process.arch}`)).href);
|
|
97
|
+
await promisify(execFile)(binaries.pg_ctl, ['-D', ownedDir, '-m', 'fast', '-w', '-t', '10', 'stop'], { windowsHide: true, timeout: 12_000, maxBuffer: 64 * 1024 });
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
await upstreamStop();
|
|
101
|
+
}
|
|
102
|
+
// 删除前再次核对绝对路径与归属标记,保留调用者要求的持久目录。
|
|
103
|
+
if (!samePath(await realpath(dir), ownedDir) || (await readFile(marker, 'utf8')) !== token)
|
|
104
|
+
throw new Error('[CAGE-TEST-003] 停止后目录归属变化,拒绝删除');
|
|
105
|
+
if (persistent)
|
|
106
|
+
await unlink(marker);
|
|
107
|
+
else
|
|
108
|
+
await rm(ownedDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
109
|
+
};
|
|
110
|
+
// 上游退出钩子仍会调用这个公开 stop;幂等包装避免重复等待已经退出的子进程。
|
|
111
|
+
instance.stop = () => stopping ??= stopOwned();
|
|
38
112
|
return {
|
|
39
|
-
superUrl
|
|
113
|
+
superUrl,
|
|
40
114
|
host: '127.0.0.1',
|
|
41
115
|
port,
|
|
42
|
-
|
|
43
|
-
await pg.stop();
|
|
44
|
-
if (!persistent)
|
|
45
|
-
rmSync(dir, { recursive: true, force: true });
|
|
46
|
-
},
|
|
116
|
+
stop: () => instance.stop(),
|
|
47
117
|
};
|
|
48
118
|
}
|
|
49
119
|
/** 把超级用户连接串换成另一个库、另一个账号 */
|
|
120
|
+
/**
|
|
121
|
+
* 复制并改写连接 URL 的数据库路径,可选替换账号与密码,保留主机及其他 URL 参数。
|
|
122
|
+
* 仅返回字符串,不建立连接、创建数据库或验证账号;调用方不得把含凭据结果写入日志。
|
|
123
|
+
*/
|
|
50
124
|
export function withDb(url, db, user) {
|
|
51
125
|
const u = new URL(url);
|
|
52
126
|
u.pathname = `/${db}`;
|