befly 3.9.40 → 3.10.1
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 +47 -19
- package/befly.config.ts +19 -2
- package/checks/checkApi.ts +79 -77
- package/checks/checkHook.ts +48 -0
- package/checks/checkMenu.ts +168 -0
- package/checks/checkPlugin.ts +48 -0
- package/checks/checkTable.ts +137 -183
- package/docs/README.md +17 -11
- package/docs/api/api.md +16 -2
- package/docs/guide/quickstart.md +31 -10
- package/docs/hooks/hook.md +2 -2
- package/docs/hooks/rateLimit.md +1 -1
- package/docs/infra/redis.md +26 -14
- package/docs/plugins/plugin.md +23 -21
- package/docs/quickstart.md +5 -328
- package/docs/reference/addon.md +0 -4
- package/docs/reference/config.md +14 -31
- package/docs/reference/logger.md +3 -3
- package/docs/reference/sync.md +132 -237
- package/docs/reference/table.md +28 -30
- package/hooks/auth.ts +3 -4
- package/hooks/cors.ts +4 -6
- package/hooks/parser.ts +3 -4
- package/hooks/permission.ts +3 -4
- package/hooks/validator.ts +3 -4
- package/lib/cacheHelper.ts +89 -153
- package/lib/cacheKeys.ts +1 -1
- package/lib/connect.ts +9 -13
- package/lib/dbDialect.ts +285 -0
- package/lib/dbHelper.ts +179 -507
- package/lib/dbUtils.ts +450 -0
- package/lib/logger.ts +41 -5
- package/lib/redisHelper.ts +1 -0
- package/lib/sqlBuilder.ts +358 -58
- package/lib/sqlCheck.ts +136 -0
- package/lib/validator.ts +1 -1
- package/loader/loadApis.ts +23 -126
- package/loader/loadHooks.ts +31 -46
- package/loader/loadPlugins.ts +37 -52
- package/main.ts +58 -19
- package/package.json +24 -25
- package/paths.ts +14 -14
- package/plugins/cache.ts +12 -6
- package/plugins/cipher.ts +2 -2
- package/plugins/config.ts +6 -8
- package/plugins/db.ts +14 -19
- package/plugins/jwt.ts +6 -7
- package/plugins/logger.ts +7 -9
- package/plugins/redis.ts +8 -10
- package/plugins/tool.ts +3 -4
- package/router/api.ts +3 -2
- package/router/static.ts +7 -5
- package/sync/syncApi.ts +80 -235
- package/sync/syncCache.ts +16 -0
- package/sync/syncDev.ts +167 -202
- package/sync/syncMenu.ts +230 -444
- package/sync/syncTable.ts +1247 -0
- package/tests/_mocks/mockSqliteDb.ts +204 -0
- package/tests/addonHelper-cache.test.ts +32 -0
- package/tests/apiHandler-routePath-only.test.ts +32 -0
- package/tests/cacheHelper.test.ts +16 -51
- package/tests/checkApi-routePath-strict.test.ts +166 -0
- package/tests/checkMenu.test.ts +346 -0
- package/tests/checkTable-smoke.test.ts +157 -0
- package/tests/dbDialect-cache.test.ts +23 -0
- package/tests/dbDialect.test.ts +46 -0
- package/tests/dbHelper-advanced.test.ts +1 -1
- package/tests/dbHelper-all-array-types.test.ts +15 -15
- package/tests/dbHelper-batch-write.test.ts +90 -0
- package/tests/dbHelper-columns.test.ts +36 -54
- package/tests/dbHelper-execute.test.ts +26 -26
- package/tests/dbHelper-joins.test.ts +85 -176
- package/tests/fixtures/scanFilesAddon/node_modules/@befly-addon/demo/apis/sub/b.ts +3 -0
- package/tests/fixtures/scanFilesApis/a.ts +3 -0
- package/tests/fixtures/scanFilesApis/sub/b.ts +3 -0
- package/tests/loadPlugins-order-smoke.test.ts +75 -0
- package/tests/logger.test.ts +6 -6
- package/tests/redisHelper.test.ts +6 -1
- package/tests/scanFiles-routePath.test.ts +46 -0
- package/tests/smoke-sql.test.ts +24 -0
- package/tests/sqlBuilder-advanced.test.ts +18 -5
- package/tests/sqlBuilder.test.ts +24 -0
- package/tests/sync-init-guard.test.ts +105 -0
- package/tests/syncApi-insBatch-fields-consistent.test.ts +61 -0
- package/tests/syncApi-obsolete-records.test.ts +69 -0
- package/tests/syncApi-type-compat.test.ts +72 -0
- package/tests/syncDev-permissions.test.ts +81 -0
- package/tests/syncMenu-disableMenus-hard-delete.test.ts +88 -0
- package/tests/syncMenu-duplicate-path.test.ts +122 -0
- package/tests/syncMenu-obsolete-records.test.ts +161 -0
- package/tests/syncMenu-parentPath-from-tree.test.ts +75 -0
- package/tests/syncMenu-paths.test.ts +0 -9
- package/tests/{syncDb-apply.test.ts → syncTable-apply.test.ts} +14 -24
- package/tests/{syncDb-array-number.test.ts → syncTable-array-number.test.ts} +31 -31
- package/tests/syncTable-constants.test.ts +101 -0
- package/tests/syncTable-db-integration.test.ts +237 -0
- package/tests/{syncDb-ddl.test.ts → syncTable-ddl.test.ts} +67 -53
- package/tests/{syncDb-helpers.test.ts → syncTable-helpers.test.ts} +12 -26
- package/tests/syncTable-schema.test.ts +99 -0
- package/tests/syncTable-testkit.test.ts +25 -0
- package/tests/syncTable-types.test.ts +122 -0
- package/tests/tableRef-and-deserialize.test.ts +67 -0
- package/tsconfig.json +1 -1
- package/types/api.d.ts +1 -1
- package/types/befly.d.ts +13 -12
- package/types/cache.d.ts +2 -2
- package/types/context.d.ts +1 -1
- package/types/database.d.ts +0 -5
- package/types/hook.d.ts +1 -10
- package/types/plugin.d.ts +2 -96
- package/types/sync.d.ts +19 -25
- package/utils/convertBigIntFields.ts +38 -0
- package/utils/disableMenusGlob.ts +85 -0
- package/utils/importDefault.ts +21 -0
- package/utils/isDirentDirectory.ts +23 -0
- package/utils/loadMenuConfigs.ts +145 -0
- package/utils/processFields.ts +25 -0
- package/utils/scanAddons.ts +72 -0
- package/utils/scanFiles.ts +129 -21
- package/utils/scanSources.ts +64 -0
- package/utils/sortModules.ts +137 -0
- package/checks/checkApp.ts +0 -55
- package/docs/cipher.md +0 -582
- package/docs/database.md +0 -1176
- package/hooks/rateLimit.ts +0 -276
- package/sync/syncAll.ts +0 -35
- package/sync/syncDb/apply.ts +0 -192
- package/sync/syncDb/constants.ts +0 -119
- package/sync/syncDb/ddl.ts +0 -251
- package/sync/syncDb/helpers.ts +0 -84
- package/sync/syncDb/schema.ts +0 -202
- package/sync/syncDb/sqlite.ts +0 -48
- package/sync/syncDb/table.ts +0 -207
- package/sync/syncDb/tableCreate.ts +0 -163
- package/sync/syncDb/types.ts +0 -132
- package/sync/syncDb/version.ts +0 -69
- package/sync/syncDb.ts +0 -168
- package/tests/rateLimit-hook.test.ts +0 -477
- package/tests/syncDb-constants.test.ts +0 -130
- package/tests/syncDb-schema.test.ts +0 -179
- package/tests/syncDb-types.test.ts +0 -139
- package/utils/addonHelper.ts +0 -90
- package/utils/modules.ts +0 -98
- package/utils/route.ts +0 -23
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, expect, it, mock } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { MySqlDialect } from "../lib/dbDialect.js";
|
|
4
|
+
import { DbHelper } from "../lib/dbHelper.js";
|
|
5
|
+
|
|
6
|
+
function createRedisMock() {
|
|
7
|
+
return {
|
|
8
|
+
getObject: async () => null,
|
|
9
|
+
setObject: async () => "OK",
|
|
10
|
+
genTimeID: async () => 1
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
describe("DbHelper - batch write helpers", () => {
|
|
15
|
+
it("delForceBatch: 空数组直接返回 0 且不执行 SQL", async () => {
|
|
16
|
+
const sqlMock = {
|
|
17
|
+
unsafe: mock(() => Promise.resolve({ changes: 0 }))
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
21
|
+
|
|
22
|
+
const changes = await (dbHelper as any).delForceBatch("addon_admin_api", []);
|
|
23
|
+
|
|
24
|
+
expect(changes).toBe(0);
|
|
25
|
+
expect(sqlMock.unsafe).toHaveBeenCalledTimes(0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("delForceBatch: 生成单条 DELETE ... IN 并执行一次", async () => {
|
|
29
|
+
const sqlMock = {
|
|
30
|
+
unsafe: mock(() => Promise.resolve({ changes: 2 }))
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
34
|
+
|
|
35
|
+
const changes = await (dbHelper as any).delForceBatch("addon_admin_api", [1, 2]);
|
|
36
|
+
|
|
37
|
+
expect(changes).toBe(2);
|
|
38
|
+
expect(sqlMock.unsafe).toHaveBeenCalledTimes(1);
|
|
39
|
+
|
|
40
|
+
const call = (sqlMock.unsafe as any).mock.calls[0];
|
|
41
|
+
expect(call[0]).toBe("DELETE FROM `addon_admin_api` WHERE `id` IN (?,?)");
|
|
42
|
+
expect(call[1]).toEqual([1, 2]);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("updBatch: 空数组直接返回 0 且不执行 SQL", async () => {
|
|
46
|
+
const sqlMock = {
|
|
47
|
+
unsafe: mock(() => Promise.resolve({ changes: 0 }))
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
51
|
+
|
|
52
|
+
const changes = await (dbHelper as any).updBatch("addon_admin_api", []);
|
|
53
|
+
|
|
54
|
+
expect(changes).toBe(0);
|
|
55
|
+
expect(sqlMock.unsafe).toHaveBeenCalledTimes(0);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("updBatch: 生成单条 UPDATE + CASE 并执行一次", async () => {
|
|
59
|
+
const sqlMock = {
|
|
60
|
+
unsafe: mock(() => Promise.resolve({ changes: 2 }))
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
64
|
+
|
|
65
|
+
const changes = await (dbHelper as any).updBatch("addon_admin_api", [
|
|
66
|
+
{ id: 1, data: { name: "A", routePath: "/api/a", addonName: "x" } },
|
|
67
|
+
{ id: 2, data: { name: "B", routePath: "/api/b", addonName: "y" } }
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
expect(changes).toBe(2);
|
|
71
|
+
expect(sqlMock.unsafe).toHaveBeenCalledTimes(1);
|
|
72
|
+
|
|
73
|
+
const call = (sqlMock.unsafe as any).mock.calls[0];
|
|
74
|
+
const sql = String(call[0]);
|
|
75
|
+
const params = call[1] as any[];
|
|
76
|
+
|
|
77
|
+
expect(sql.startsWith("UPDATE `addon_admin_api` SET")).toBe(true);
|
|
78
|
+
expect(sql.includes("`name` = CASE `id`")).toBe(true);
|
|
79
|
+
expect(sql.includes("`route_path` = CASE `id`")).toBe(true);
|
|
80
|
+
expect(sql.includes("`addon_name` = CASE `id`")).toBe(true);
|
|
81
|
+
expect(sql.includes("`updated_at` = ?")).toBe(true);
|
|
82
|
+
expect(sql.endsWith("WHERE `id` IN (?,?) AND `state` > 0")).toBe(true);
|
|
83
|
+
|
|
84
|
+
// 参数数量应包含:每个字段 2 行 * (id,value) *3字段 => 12,+ updated_at 1,+ where ids 2 => 15
|
|
85
|
+
expect(params.length).toBe(15);
|
|
86
|
+
// 末尾两个参数是 where ids
|
|
87
|
+
expect(params[params.length - 2]).toBe(1);
|
|
88
|
+
expect(params[params.length - 1]).toBe(2);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -6,17 +6,20 @@
|
|
|
6
6
|
import { test, expect, mock } from "bun:test";
|
|
7
7
|
|
|
8
8
|
import { CacheKeys } from "../lib/cacheKeys.js";
|
|
9
|
+
import { MySqlDialect } from "../lib/dbDialect.js";
|
|
9
10
|
import { DbHelper } from "../lib/dbHelper.js";
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
function createRedisMock(options?: { getObject?: any; setObject?: any; del?: any; genTimeID?: any }) {
|
|
13
|
+
const getObject = options?.getObject ? options.getObject : mock(async () => null);
|
|
14
|
+
const setObject = options?.setObject ? options.setObject : mock(async () => true);
|
|
15
|
+
const del = options?.del ? options.del : mock(async () => 1);
|
|
16
|
+
const genTimeID = options?.genTimeID ? options.genTimeID : mock(async () => 1);
|
|
17
|
+
|
|
13
18
|
return {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
db: null
|
|
19
|
+
getObject: getObject,
|
|
20
|
+
setObject: setObject,
|
|
21
|
+
del: del,
|
|
22
|
+
genTimeID: genTimeID
|
|
20
23
|
};
|
|
21
24
|
}
|
|
22
25
|
|
|
@@ -31,14 +34,11 @@ test("getTableColumns - 正常查询表字段", async () => {
|
|
|
31
34
|
})
|
|
32
35
|
};
|
|
33
36
|
|
|
34
|
-
const redisMock = {
|
|
35
|
-
getObject: mock(async () => null)
|
|
36
|
-
|
|
37
|
-
del: mock(async () => 1)
|
|
38
|
-
};
|
|
37
|
+
const redisMock = createRedisMock({
|
|
38
|
+
getObject: mock(async () => null) // 缓存未命中
|
|
39
|
+
});
|
|
39
40
|
|
|
40
|
-
const
|
|
41
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
41
|
+
const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
42
42
|
|
|
43
43
|
const columns = await (dbHelper as any).getTableColumns("users");
|
|
44
44
|
|
|
@@ -50,11 +50,9 @@ test("getTableColumns - 正常查询表字段", async () => {
|
|
|
50
50
|
|
|
51
51
|
test("getTableColumns - Redis 缓存命中", async () => {
|
|
52
52
|
const cachedColumns = ["id", "name", "email"];
|
|
53
|
-
const redisMock = {
|
|
54
|
-
getObject: mock(async () => cachedColumns)
|
|
55
|
-
|
|
56
|
-
del: mock(async () => 1)
|
|
57
|
-
};
|
|
53
|
+
const redisMock = createRedisMock({
|
|
54
|
+
getObject: mock(async () => cachedColumns)
|
|
55
|
+
});
|
|
58
56
|
|
|
59
57
|
const sqlMock = {
|
|
60
58
|
unsafe: mock(async () => {
|
|
@@ -62,8 +60,7 @@ test("getTableColumns - Redis 缓存命中", async () => {
|
|
|
62
60
|
})
|
|
63
61
|
};
|
|
64
62
|
|
|
65
|
-
const
|
|
66
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
63
|
+
const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
67
64
|
|
|
68
65
|
const columns = await (dbHelper as any).getTableColumns("users");
|
|
69
66
|
|
|
@@ -78,14 +75,9 @@ test("getTableColumns - 表不存在错误", async () => {
|
|
|
78
75
|
unsafe: mock(async () => []) // 返回空结果
|
|
79
76
|
};
|
|
80
77
|
|
|
81
|
-
const redisMock =
|
|
82
|
-
getObject: mock(async () => null),
|
|
83
|
-
setObject: mock(async () => true),
|
|
84
|
-
del: mock(async () => 1)
|
|
85
|
-
};
|
|
78
|
+
const redisMock = createRedisMock();
|
|
86
79
|
|
|
87
|
-
const
|
|
88
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
80
|
+
const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
89
81
|
|
|
90
82
|
try {
|
|
91
83
|
await (dbHelper as any).getTableColumns("non_existent_table");
|
|
@@ -106,8 +98,7 @@ test("getTableColumns - SQL 语法使用反引号", async () => {
|
|
|
106
98
|
})
|
|
107
99
|
};
|
|
108
100
|
|
|
109
|
-
const
|
|
110
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
101
|
+
const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
111
102
|
|
|
112
103
|
await (dbHelper as any).getTableColumns("addon_admin_user");
|
|
113
104
|
|
|
@@ -123,8 +114,7 @@ test("getTableColumns - 表名特殊字符处理", async () => {
|
|
|
123
114
|
unsafe: mock(async () => mockColumns)
|
|
124
115
|
};
|
|
125
116
|
|
|
126
|
-
const
|
|
127
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
117
|
+
const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
128
118
|
|
|
129
119
|
// 测试下划线表名
|
|
130
120
|
await (dbHelper as any).getTableColumns("addon_admin_user");
|
|
@@ -141,7 +131,7 @@ test("getTableColumns - 缓存键格式正确", async () => {
|
|
|
141
131
|
unsafe: mock(async () => mockColumns)
|
|
142
132
|
};
|
|
143
133
|
|
|
144
|
-
const redisMock = {
|
|
134
|
+
const redisMock = createRedisMock({
|
|
145
135
|
getObject: mock(async () => null),
|
|
146
136
|
setObject: mock(async (key: string, value: any, seconds: number) => {
|
|
147
137
|
// 验证缓存键格式
|
|
@@ -151,12 +141,10 @@ test("getTableColumns - 缓存键格式正确", async () => {
|
|
|
151
141
|
// 验证过期时间
|
|
152
142
|
expect(seconds).toBe(3600); // 1 小时
|
|
153
143
|
return true;
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
};
|
|
144
|
+
})
|
|
145
|
+
});
|
|
157
146
|
|
|
158
|
-
const
|
|
159
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
147
|
+
const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
160
148
|
|
|
161
149
|
await (dbHelper as any).getTableColumns("test_table");
|
|
162
150
|
|
|
@@ -175,17 +163,15 @@ test("getTableColumns - 多次调用相同表(缓存效果)", async () => {
|
|
|
175
163
|
};
|
|
176
164
|
|
|
177
165
|
const cache: Record<string, any> = {};
|
|
178
|
-
const redisMock = {
|
|
166
|
+
const redisMock = createRedisMock({
|
|
179
167
|
getObject: mock(async (key: string) => cache[key] || null),
|
|
180
168
|
setObject: mock(async (key: string, value: any) => {
|
|
181
169
|
cache[key] = value;
|
|
182
170
|
return true;
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
};
|
|
171
|
+
})
|
|
172
|
+
});
|
|
186
173
|
|
|
187
|
-
const
|
|
188
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
174
|
+
const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
189
175
|
|
|
190
176
|
// 第一次调用 - 应该查询数据库
|
|
191
177
|
const columns1 = await (dbHelper as any).getTableColumns("users");
|
|
@@ -209,16 +195,13 @@ test("getTableColumns - Redis 错误处理", async () => {
|
|
|
209
195
|
unsafe: mock(async () => mockColumns)
|
|
210
196
|
};
|
|
211
197
|
|
|
212
|
-
const redisMock = {
|
|
198
|
+
const redisMock = createRedisMock({
|
|
213
199
|
getObject: mock(async () => {
|
|
214
200
|
throw new Error("Redis 连接失败");
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
del: mock(async () => 1)
|
|
218
|
-
};
|
|
201
|
+
})
|
|
202
|
+
});
|
|
219
203
|
|
|
220
|
-
const
|
|
221
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
204
|
+
const dbHelper = new DbHelper({ redis: redisMock as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
222
205
|
|
|
223
206
|
try {
|
|
224
207
|
await (dbHelper as any).getTableColumns("users");
|
|
@@ -240,8 +223,7 @@ test("getTableColumns - 字段映射正确性", async () => {
|
|
|
240
223
|
unsafe: mock(async () => mockColumns)
|
|
241
224
|
};
|
|
242
225
|
|
|
243
|
-
const
|
|
244
|
-
const dbHelper = new DbHelper(befly as any, sqlMock);
|
|
226
|
+
const dbHelper = new DbHelper({ redis: createRedisMock() as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
245
227
|
|
|
246
228
|
const columns = await (dbHelper as any).getTableColumns("users");
|
|
247
229
|
|
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
|
|
6
6
|
import { test, expect, mock } from "bun:test";
|
|
7
7
|
|
|
8
|
+
import { MySqlDialect } from "../lib/dbDialect.js";
|
|
8
9
|
import { DbHelper } from "../lib/dbHelper.js";
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
function createMockBefly() {
|
|
11
|
+
function createMockRedis() {
|
|
12
12
|
return {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
get: mock(async () => null),
|
|
14
|
+
set: mock(async () => true),
|
|
15
|
+
del: mock(async () => 1),
|
|
16
|
+
getObject: mock(async () => null),
|
|
17
|
+
setObject: mock(async () => true),
|
|
18
|
+
genTimeID: mock(async () => 1)
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -25,8 +25,8 @@ test("executeWithConn - 正常执行(无参数)", async () => {
|
|
|
25
25
|
unsafe: mock(async () => mockResult)
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const
|
|
29
|
-
const dbHelper = new DbHelper(
|
|
28
|
+
const redis = createMockRedis();
|
|
29
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
30
30
|
|
|
31
31
|
// 使用反射访问私有方法
|
|
32
32
|
const result = await (dbHelper as any).executeWithConn("SELECT * FROM users");
|
|
@@ -41,8 +41,8 @@ test("executeWithConn - 正常执行(带参数)", async () => {
|
|
|
41
41
|
unsafe: mock(async () => mockResult)
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
const
|
|
45
|
-
const dbHelper = new DbHelper(
|
|
44
|
+
const redis = createMockRedis();
|
|
45
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
46
46
|
|
|
47
47
|
const result = await (dbHelper as any).executeWithConn("SELECT * FROM users WHERE id = ?", [1]);
|
|
48
48
|
|
|
@@ -58,8 +58,8 @@ test("executeWithConn - SQL 错误捕获", async () => {
|
|
|
58
58
|
})
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
const
|
|
62
|
-
const dbHelper = new DbHelper(
|
|
61
|
+
const redis = createMockRedis();
|
|
62
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
63
63
|
|
|
64
64
|
try {
|
|
65
65
|
await (dbHelper as any).executeWithConn("SELECT * FROM invalid_table");
|
|
@@ -81,8 +81,8 @@ test("executeWithConn - 错误信息包含完整信息", async () => {
|
|
|
81
81
|
})
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
const
|
|
85
|
-
const dbHelper = new DbHelper(
|
|
84
|
+
const redis = createMockRedis();
|
|
85
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
86
86
|
|
|
87
87
|
const testSql = "SHOW COLUMNS FROM ??";
|
|
88
88
|
const testParams = ["users"];
|
|
@@ -106,8 +106,8 @@ test("executeWithConn - 超长 SQL 保留在错误对象中", async () => {
|
|
|
106
106
|
})
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
-
const
|
|
110
|
-
const dbHelper = new DbHelper(
|
|
109
|
+
const redis = createMockRedis();
|
|
110
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
111
111
|
|
|
112
112
|
try {
|
|
113
113
|
await (dbHelper as any).executeWithConn(longSql);
|
|
@@ -128,8 +128,8 @@ test("executeWithConn - 慢查询检测(>1000ms)", async () => {
|
|
|
128
128
|
})
|
|
129
129
|
};
|
|
130
130
|
|
|
131
|
-
const
|
|
132
|
-
const dbHelper = new DbHelper(
|
|
131
|
+
const redis = createMockRedis();
|
|
132
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
133
133
|
|
|
134
134
|
const result = await (dbHelper as any).executeWithConn("SELECT SLEEP(1)");
|
|
135
135
|
|
|
@@ -138,8 +138,8 @@ test("executeWithConn - 慢查询检测(>1000ms)", async () => {
|
|
|
138
138
|
});
|
|
139
139
|
|
|
140
140
|
test("executeWithConn - 数据库未连接错误", async () => {
|
|
141
|
-
const
|
|
142
|
-
const dbHelper = new DbHelper(
|
|
141
|
+
const redis = createMockRedis();
|
|
142
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: null, dialect: new MySqlDialect() }); // 没有 sql 实例
|
|
143
143
|
|
|
144
144
|
try {
|
|
145
145
|
await (dbHelper as any).executeWithConn("SELECT * FROM users");
|
|
@@ -155,8 +155,8 @@ test("executeWithConn - 空参数数组", async () => {
|
|
|
155
155
|
unsafe: mock(async () => mockResult)
|
|
156
156
|
};
|
|
157
157
|
|
|
158
|
-
const
|
|
159
|
-
const dbHelper = new DbHelper(
|
|
158
|
+
const redis = createMockRedis();
|
|
159
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
160
160
|
|
|
161
161
|
const result = await (dbHelper as any).executeWithConn("SELECT COUNT(*) as count FROM users", []);
|
|
162
162
|
|
|
@@ -172,8 +172,8 @@ test("executeWithConn - 复杂参数处理", async () => {
|
|
|
172
172
|
})
|
|
173
173
|
};
|
|
174
174
|
|
|
175
|
-
const
|
|
176
|
-
const dbHelper = new DbHelper(
|
|
175
|
+
const redis = createMockRedis();
|
|
176
|
+
const dbHelper = new DbHelper({ redis: redis as any, sql: sqlMock, dialect: new MySqlDialect() });
|
|
177
177
|
|
|
178
178
|
const complexParams = [1, "test", { nested: "object" }, [1, 2, 3], null, undefined];
|
|
179
179
|
|