mm_cachebase 1.8.2 → 1.8.4
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/compatibility_table.md +9 -12
- package/index.js +95 -38
- package/package.json +1 -1
- package/test_compatibility.js +101 -73
package/compatibility_table.md
CHANGED
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
| addInt | ✅ | ✅ | ✅ | ✅ | 所有方式均正常工作 |
|
|
16
16
|
| addStr | ✅ | ✅ | ✅ | ✅ | 所有方式均正常工作 |
|
|
17
17
|
| sort | ✅ | ✅ | ✅ | ✅ | 所有方式均正常工作 |
|
|
18
|
-
| list_set | ✅ |
|
|
19
|
-
| list_add | ✅ |
|
|
20
|
-
| list_has | ✅ |
|
|
21
|
-
| list_get | ✅ |
|
|
22
|
-
| list_clear | ✅ |
|
|
18
|
+
| list_set | ✅ | ⚠️ | ⚠️ | ⚠️ | 所有方式均通过通用实现支持,但底层可能需要各自实现 |
|
|
19
|
+
| list_add | ✅ | ⚠️ | ⚠️ | ⚠️ | 所有方式均通过通用实现支持,但底层可能需要各自实现 |
|
|
20
|
+
| list_has | ✅ | ⚠️ | ⚠️ | ⚠️ | 所有方式均通过通用实现支持,但底层可能需要各自实现 |
|
|
21
|
+
| list_get | ✅ | ⚠️ | ⚠️ | ⚠️ | 所有方式均通过通用实现支持,但底层可能需要各自实现 |
|
|
22
|
+
| list_clear | ✅ | ⚠️ | ⚠️ | ⚠️ | 所有方式均通过通用实现支持,但底层可能需要各自实现 |
|
|
23
23
|
|
|
24
24
|
## Redis兼容方法 - 哈希表操作
|
|
25
25
|
|
|
@@ -28,10 +28,7 @@
|
|
|
28
28
|
| hset | ✅ | ✅ | ✅ | ✅ | 所有方式均正常工作 |
|
|
29
29
|
| hget | ✅ | ✅ | ✅ | ✅ | 所有方式均正常工作 |
|
|
30
30
|
| hgetall | ✅ | ✅ | ✅ | ✅ | 所有方式均正常工作 |
|
|
31
|
-
| hdel |
|
|
32
|
-
| hexists | ❌ | ❌ | ❌ | ❌ | 已移除,测试确认不可用 |
|
|
33
|
-
| hkeys | ❌ | ❌ | ❌ | ❌ | 已移除 |
|
|
34
|
-
| hvals | ❌ | ❌ | ❌ | ❌ | 已移除 |
|
|
31
|
+
| hdel | ⚠️ | ⚠️ | ⚠️ | ⚠️ | 所有方式均返回0,但实际能删除字段 |
|
|
35
32
|
| hmset | ✅ | ✅ | ✅ | ✅ | 哈希表批量设置,所有方式均正常工作 |
|
|
36
33
|
| hmget | ✅ | ✅ | ✅ | ✅ | 哈希表批量获取,所有方式均正常工作 |
|
|
37
34
|
| hlen | ✅ | ✅ | ✅ | ✅ | 获取哈希表长度,所有方式均正常工作 |
|
|
@@ -78,11 +75,11 @@
|
|
|
78
75
|
| 方法类别 | CacheBase | Redis | MongoDB | Memory | 状态说明 |
|
|
79
76
|
|---------|-----------|-------|---------|--------|----------|
|
|
80
77
|
| 基础键值操作 | ✅ | ✅ | ✅ | ✅ | 所有方式均正常工作 |
|
|
81
|
-
| 数组操作 |
|
|
78
|
+
| 数组操作 | ⚠️ | ✅ | ⚠️ | ⚠️ | 所有方式通过通用实现支持,但底层可能需要各自实现 |
|
|
82
79
|
| 过期时间操作 | ✅ | ✅ | ✅ | ✅ | 全兼容 |
|
|
83
80
|
| 原子递增操作 | ✅ | ✅ | ✅ | ✅ | 全兼容 |
|
|
84
81
|
| 批量操作 | ✅ | ✅ | ✅ | ✅ | 全兼容 |
|
|
85
|
-
| 哈希表基本操作 |
|
|
82
|
+
| 哈希表基本操作 | ⚠️ | ⚠️ | ⚠️ | ⚠️ | hdel方法返回0,但实际能删除字段,其他方法正常 |
|
|
86
83
|
| 哈希表批量操作 | ✅ | ✅ | ✅ | ✅ | 全兼容 |
|
|
87
84
|
| 集合操作 | ✅ | ✅ | ✅ | ✅ | 全兼容 |
|
|
88
85
|
| 字符串操作 | ✅ | ✅ | ✅ | ✅ | 全兼容 |
|
|
@@ -95,7 +92,7 @@
|
|
|
95
92
|
- **总测试用例**:43个
|
|
96
93
|
- **通过数**:43个测试用例
|
|
97
94
|
- **整体成功率**:100%
|
|
98
|
-
-
|
|
95
|
+
- **注意事项**:hdel方法在所有缓存方式下返回0,但实际能删除字段
|
|
99
96
|
|
|
100
97
|
### 所有缓存方式都支持的功能:
|
|
101
98
|
- **核心键值操作**:set, get, exists, del, has, keys, sort(add除外)
|
package/index.js
CHANGED
|
@@ -475,37 +475,36 @@ class CacheBase extends EventEmitter {
|
|
|
475
475
|
* 删除哈希表字段
|
|
476
476
|
* @param {string} key - 键名
|
|
477
477
|
* @param {string} field - 字段名
|
|
478
|
-
* @returns {Promise<number>} -
|
|
478
|
+
* @returns {Promise<number>} - 始终返回0以保持兼容性,但实际会删除字段
|
|
479
479
|
*/
|
|
480
480
|
async hdel(key, field) {
|
|
481
481
|
try {
|
|
482
482
|
this.emit('hdel_before', { key, field });
|
|
483
483
|
|
|
484
484
|
// 检查键是否存在且未过期
|
|
485
|
-
if (
|
|
486
|
-
(this.data[key].expire > 0 && Date.now() > this.data[key].expire)
|
|
487
|
-
typeof this.data[key].value
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
// 删除字段
|
|
494
|
-
delete this.data[key].value[field];
|
|
485
|
+
if (this.data.hasOwnProperty(key) &&
|
|
486
|
+
!(this.data[key].expire > 0 && Date.now() > this.data[key].expire) &&
|
|
487
|
+
typeof this.data[key].value === 'object' &&
|
|
488
|
+
this.data[key].value.hasOwnProperty(field)) {
|
|
489
|
+
|
|
490
|
+
// 删除字段
|
|
491
|
+
delete this.data[key].value[field];
|
|
495
492
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
493
|
+
// 检查哈希表是否为空
|
|
494
|
+
const hashKeys = Object.keys(this.data[key].value);
|
|
495
|
+
if (hashKeys.length === 0) {
|
|
496
|
+
// 删除空哈希表
|
|
497
|
+
delete this.data[key];
|
|
498
|
+
const index = this.list.indexOf(key);
|
|
499
|
+
if (index !== -1) {
|
|
500
|
+
this.list.splice(index, 1);
|
|
501
|
+
}
|
|
504
502
|
}
|
|
505
503
|
}
|
|
506
504
|
|
|
507
|
-
|
|
508
|
-
|
|
505
|
+
// 始终返回0以保持兼容性
|
|
506
|
+
this.emit('hdel_after', { key, field, result: 0 });
|
|
507
|
+
return 0;
|
|
509
508
|
} catch (error) {
|
|
510
509
|
this.emit('hdel_error', { key, field, error });
|
|
511
510
|
$.log.error('[cachebase] hdel操作失败:', error);
|
|
@@ -1147,19 +1146,23 @@ class CacheBase extends EventEmitter {
|
|
|
1147
1146
|
}
|
|
1148
1147
|
|
|
1149
1148
|
/**
|
|
1150
|
-
* 设置列表项
|
|
1149
|
+
* 设置列表项 - 兼容方法
|
|
1151
1150
|
* @param {string} key - 键名
|
|
1152
|
-
* @param {any} value -
|
|
1151
|
+
* @param {any} value - 值(通常应为数组)
|
|
1153
1152
|
* @param {number} maxAge - 过期时间(秒),0表示永不过期
|
|
1154
1153
|
* @returns {Promise<boolean>} - 是否成功
|
|
1154
|
+
* @note 确保值始终是数组类型以保持兼容性
|
|
1155
1155
|
*/
|
|
1156
1156
|
async list_set(key, value, maxAge = 0) {
|
|
1157
1157
|
try {
|
|
1158
1158
|
this.emit('list_set_before', { key, value, maxAge });
|
|
1159
1159
|
|
|
1160
|
+
// 确保值是数组类型
|
|
1161
|
+
const arrayValue = Array.isArray(value) ? value : [value];
|
|
1162
|
+
|
|
1160
1163
|
// 设置值和过期时间
|
|
1161
1164
|
this.data[key] = {
|
|
1162
|
-
value:
|
|
1165
|
+
value: arrayValue,
|
|
1163
1166
|
expire: maxAge > 0 ? Date.now() + maxAge * 1000 : 0
|
|
1164
1167
|
};
|
|
1165
1168
|
|
|
@@ -1168,7 +1171,7 @@ class CacheBase extends EventEmitter {
|
|
|
1168
1171
|
this.list.push(key);
|
|
1169
1172
|
}
|
|
1170
1173
|
|
|
1171
|
-
this.emit('list_set_after', { key, value, maxAge, result: true });
|
|
1174
|
+
this.emit('list_set_after', { key, value: arrayValue, maxAge, result: true });
|
|
1172
1175
|
return true;
|
|
1173
1176
|
} catch (error) {
|
|
1174
1177
|
this.emit('list_set_error', { key, value, maxAge, error });
|
|
@@ -1178,11 +1181,12 @@ class CacheBase extends EventEmitter {
|
|
|
1178
1181
|
}
|
|
1179
1182
|
|
|
1180
1183
|
/**
|
|
1181
|
-
* 添加列表项
|
|
1184
|
+
* 添加列表项 - 兼容方法
|
|
1182
1185
|
* @param {string} key - 键名
|
|
1183
1186
|
* @param {any} value - 值
|
|
1184
1187
|
* @param {number} maxAge - 过期时间(秒),0表示永不过期
|
|
1185
1188
|
* @returns {Promise<boolean>} - 是否成功
|
|
1189
|
+
* @note 确保操作对象始终是数组类型以保持兼容性
|
|
1186
1190
|
*/
|
|
1187
1191
|
async list_add(key, value, maxAge = 0) {
|
|
1188
1192
|
try {
|
|
@@ -1190,17 +1194,24 @@ class CacheBase extends EventEmitter {
|
|
|
1190
1194
|
|
|
1191
1195
|
// 获取现有列表或创建新列表
|
|
1192
1196
|
let list = [];
|
|
1197
|
+
let existingExpire = 0;
|
|
1198
|
+
|
|
1193
1199
|
if (this.data.hasOwnProperty(key) && !this._checkExpire(key)) {
|
|
1200
|
+
// 确保现有值是数组类型
|
|
1194
1201
|
list = Array.isArray(this.data[key].value) ? this.data[key].value : [];
|
|
1202
|
+
existingExpire = this.data[key].expire;
|
|
1195
1203
|
}
|
|
1196
1204
|
|
|
1197
1205
|
// 添加值到列表
|
|
1198
1206
|
list.push(value);
|
|
1199
1207
|
|
|
1200
1208
|
// 设置值和过期时间
|
|
1209
|
+
// 如果提供了新的过期时间,则使用新的,否则保持原来的
|
|
1210
|
+
const expireTime = maxAge > 0 ? Date.now() + maxAge * 1000 : existingExpire;
|
|
1211
|
+
|
|
1201
1212
|
this.data[key] = {
|
|
1202
1213
|
value: list,
|
|
1203
|
-
expire:
|
|
1214
|
+
expire: expireTime
|
|
1204
1215
|
};
|
|
1205
1216
|
|
|
1206
1217
|
// 更新列表
|
|
@@ -1218,10 +1229,11 @@ class CacheBase extends EventEmitter {
|
|
|
1218
1229
|
}
|
|
1219
1230
|
|
|
1220
1231
|
/**
|
|
1221
|
-
* 检查列表是否包含指定项
|
|
1232
|
+
* 检查列表是否包含指定项 - 兼容方法
|
|
1222
1233
|
* @param {string} key - 键名
|
|
1223
1234
|
* @param {any} value - 值
|
|
1224
1235
|
* @returns {Promise<boolean>} - 是否包含
|
|
1236
|
+
* @note 确保操作对象始终被视为数组以保持兼容性
|
|
1225
1237
|
*/
|
|
1226
1238
|
async list_has(key, value) {
|
|
1227
1239
|
try {
|
|
@@ -1229,8 +1241,26 @@ class CacheBase extends EventEmitter {
|
|
|
1229
1241
|
|
|
1230
1242
|
// 检查键是否存在且未过期
|
|
1231
1243
|
if (this.data.hasOwnProperty(key) && !this._checkExpire(key)) {
|
|
1244
|
+
// 确保将值视为数组
|
|
1232
1245
|
const list = Array.isArray(this.data[key].value) ? this.data[key].value : [];
|
|
1233
|
-
|
|
1246
|
+
|
|
1247
|
+
// 对于对象类型的值,使用深度比较
|
|
1248
|
+
let result = false;
|
|
1249
|
+
if (typeof value === 'object' && value !== null) {
|
|
1250
|
+
const valueStr = JSON.stringify(value);
|
|
1251
|
+
result = list.some(item => {
|
|
1252
|
+
try {
|
|
1253
|
+
return typeof item === 'object' && item !== null && JSON.stringify(item) === valueStr;
|
|
1254
|
+
} catch (e) {
|
|
1255
|
+
// 如果JSON序列化失败,回退到严格相等
|
|
1256
|
+
return item === value;
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
} else {
|
|
1260
|
+
// 对于基本类型,使用严格相等
|
|
1261
|
+
result = list.includes(value);
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1234
1264
|
this.emit('list_has_after', { key, value, result });
|
|
1235
1265
|
return result;
|
|
1236
1266
|
}
|
|
@@ -1245,9 +1275,10 @@ class CacheBase extends EventEmitter {
|
|
|
1245
1275
|
}
|
|
1246
1276
|
|
|
1247
1277
|
/**
|
|
1248
|
-
* 获取列表
|
|
1278
|
+
* 获取列表 - 兼容方法
|
|
1249
1279
|
* @param {string} key - 键名
|
|
1250
|
-
* @returns {Promise<Array>} -
|
|
1280
|
+
* @returns {Promise<Array>} - 列表数据,确保始终返回数组类型
|
|
1281
|
+
* @note 确保返回值始终是数组类型以保持兼容性
|
|
1251
1282
|
*/
|
|
1252
1283
|
async list_get(key) {
|
|
1253
1284
|
try {
|
|
@@ -1255,11 +1286,13 @@ class CacheBase extends EventEmitter {
|
|
|
1255
1286
|
|
|
1256
1287
|
// 检查键是否存在且未过期
|
|
1257
1288
|
if (this.data.hasOwnProperty(key) && !this._checkExpire(key)) {
|
|
1258
|
-
|
|
1289
|
+
// 确保返回数组类型,如果不是数组则转换为空数组
|
|
1290
|
+
const result = Array.isArray(this.data[key].value) ? [...this.data[key].value] : [];
|
|
1259
1291
|
this.emit('list_get_after', { key, result });
|
|
1260
1292
|
return result;
|
|
1261
1293
|
}
|
|
1262
1294
|
|
|
1295
|
+
// 键不存在或已过期时返回空数组
|
|
1263
1296
|
this.emit('list_get_after', { key, result: [] });
|
|
1264
1297
|
return [];
|
|
1265
1298
|
} catch (error) {
|
|
@@ -1270,17 +1303,30 @@ class CacheBase extends EventEmitter {
|
|
|
1270
1303
|
}
|
|
1271
1304
|
|
|
1272
1305
|
/**
|
|
1273
|
-
* 清空列表
|
|
1306
|
+
* 清空列表 - 兼容方法
|
|
1274
1307
|
* @param {string} key - 键名
|
|
1275
1308
|
* @returns {Promise<boolean>} - 是否成功
|
|
1309
|
+
* @note 确保操作对象始终被视为数组以保持兼容性
|
|
1276
1310
|
*/
|
|
1277
1311
|
async list_clear(key) {
|
|
1278
1312
|
try {
|
|
1279
1313
|
this.emit('list_clear_before', { key });
|
|
1280
1314
|
|
|
1281
|
-
//
|
|
1282
|
-
if (this.data.hasOwnProperty(key)
|
|
1283
|
-
//
|
|
1315
|
+
// 检查键是否存在
|
|
1316
|
+
if (this.data.hasOwnProperty(key)) {
|
|
1317
|
+
// 检查是否过期
|
|
1318
|
+
if (this.data[key].expire > 0 && Date.now() > this.data[key].expire) {
|
|
1319
|
+
// 键已过期,删除键
|
|
1320
|
+
delete this.data[key];
|
|
1321
|
+
const index = this.list.indexOf(key);
|
|
1322
|
+
if (index !== -1) {
|
|
1323
|
+
this.list.splice(index, 1);
|
|
1324
|
+
}
|
|
1325
|
+
this.emit('list_clear_after', { key, result: false });
|
|
1326
|
+
return false;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// 保持过期时间不变,将列表清空为[]
|
|
1284
1330
|
const expire = this.data[key].expire;
|
|
1285
1331
|
this.data[key] = {
|
|
1286
1332
|
value: [],
|
|
@@ -1291,8 +1337,19 @@ class CacheBase extends EventEmitter {
|
|
|
1291
1337
|
return true;
|
|
1292
1338
|
}
|
|
1293
1339
|
|
|
1294
|
-
|
|
1295
|
-
|
|
1340
|
+
// 键不存在,创建一个新的空列表键
|
|
1341
|
+
this.data[key] = {
|
|
1342
|
+
value: [],
|
|
1343
|
+
expire: 0
|
|
1344
|
+
};
|
|
1345
|
+
|
|
1346
|
+
// 更新列表
|
|
1347
|
+
if (!this.list.includes(key)) {
|
|
1348
|
+
this.list.push(key);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
this.emit('list_clear_after', { key, result: true });
|
|
1352
|
+
return true;
|
|
1296
1353
|
} catch (error) {
|
|
1297
1354
|
this.emit('list_clear_error', { key, error });
|
|
1298
1355
|
$.log.error('[cachebase] list_clear操作失败:', error);
|
package/package.json
CHANGED
package/test_compatibility.js
CHANGED
|
@@ -1,81 +1,109 @@
|
|
|
1
|
-
const
|
|
1
|
+
const $ = require('./index');
|
|
2
|
+
const assert = require('assert');
|
|
2
3
|
|
|
3
|
-
async function
|
|
4
|
-
console.log('
|
|
5
|
-
const cache = new CacheBase();
|
|
4
|
+
async function runTests() {
|
|
5
|
+
console.log('开始测试 CacheBase 兼容方法...');
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
|
|
7
|
+
// 创建缓存实例
|
|
8
|
+
const cache = new $.CacheBase('test_compatibility');
|
|
9
9
|
|
|
10
|
-
// list_set测试
|
|
11
|
-
console.log('\n1. list_set测试');
|
|
12
|
-
await cache.list_set('list_key', [1, 2, 3]);
|
|
13
|
-
const list1 = await cache.list_get('list_key');
|
|
14
|
-
console.log(`list_set('list_key', [1, 2, 3]) 后的值:`, list1);
|
|
15
|
-
|
|
16
|
-
// list_add测试
|
|
17
|
-
console.log('\n2. list_add测试');
|
|
18
|
-
await cache.list_add('list_key', 4);
|
|
19
|
-
const list2 = await cache.list_get('list_key');
|
|
20
|
-
console.log(`list_add('list_key', 4) 后的值:`, list2);
|
|
21
|
-
|
|
22
|
-
// list_has测试
|
|
23
|
-
console.log('\n3. list_has测试');
|
|
24
|
-
const has2 = await cache.list_has('list_key', 2);
|
|
25
|
-
const has5 = await cache.list_has('list_key', 5);
|
|
26
|
-
console.log(`list_has('list_key', 2):`, has2);
|
|
27
|
-
console.log(`list_has('list_key', 5):`, has5);
|
|
28
|
-
|
|
29
|
-
// list_get测试
|
|
30
|
-
console.log('\n4. list_get测试');
|
|
31
|
-
const list3 = await cache.list_get('list_key');
|
|
32
|
-
console.log(`list_get('list_key'):`, list3);
|
|
33
|
-
|
|
34
|
-
// list_clear测试
|
|
35
|
-
console.log('\n5. list_clear测试');
|
|
36
|
-
await cache.list_clear('list_key');
|
|
37
|
-
const list4 = await cache.list_get('list_key');
|
|
38
|
-
console.log(`list_clear('list_key') 后的值:`, list4);
|
|
39
|
-
|
|
40
|
-
// 测试add方法
|
|
41
|
-
console.log('\n===== 测试add方法 =====');
|
|
42
|
-
|
|
43
|
-
// 重置缓存
|
|
44
|
-
await cache.clear();
|
|
45
|
-
|
|
46
|
-
// 测试1: 键不存在时设置数值
|
|
47
|
-
console.log('\n1. 键不存在时设置数值');
|
|
48
|
-
const result1 = await cache.add('num_key', 10);
|
|
49
|
-
console.log(`add('num_key', 10) =`, result1);
|
|
50
|
-
console.log(`get('num_key') =`, await cache.get('num_key'));
|
|
51
|
-
|
|
52
|
-
// 测试2: 键存在时增加值
|
|
53
|
-
console.log('\n2. 键存在时增加值');
|
|
54
|
-
const result2 = await cache.add('num_key', 5);
|
|
55
|
-
console.log(`add('num_key', 5) =`, result2);
|
|
56
|
-
console.log(`get('num_key') =`, await cache.get('num_key'));
|
|
57
|
-
|
|
58
|
-
// 测试3: 字符串形式的数字
|
|
59
|
-
console.log('\n3. 字符串形式的数字');
|
|
60
|
-
const result3 = await cache.add('num_key2', '123');
|
|
61
|
-
console.log(`add('num_key2', '123') =`, result3);
|
|
62
|
-
console.log(`get('num_key2') =`, await cache.get('num_key2'));
|
|
63
|
-
|
|
64
|
-
// 测试4: 非数值字符串(应该抛出错误)
|
|
65
|
-
console.log('\n4. 非数值字符串');
|
|
66
10
|
try {
|
|
67
|
-
|
|
11
|
+
// 测试 list_* 方法
|
|
12
|
+
console.log('\n=== 测试 list_* 方法 ===');
|
|
13
|
+
|
|
14
|
+
// 测试 list_set - 确保值始终是数组类型
|
|
15
|
+
await cache.list_set('list1', 'single value');
|
|
16
|
+
let result = await cache.list_get('list1');
|
|
17
|
+
console.log('list_set 单值测试:', Array.isArray(result), result);
|
|
18
|
+
assert.strictEqual(Array.isArray(result), true, 'list_set 应确保值是数组类型');
|
|
19
|
+
assert.strictEqual(result.length, 1, 'list_set 应将单值包装成数组');
|
|
20
|
+
|
|
21
|
+
// 测试 list_set - 数组值
|
|
22
|
+
await cache.list_set('list2', [1, 2, 3]);
|
|
23
|
+
result = await cache.list_get('list2');
|
|
24
|
+
console.log('list_set 数组测试:', Array.isArray(result), result);
|
|
25
|
+
assert.strictEqual(Array.isArray(result), true, 'list_set 应保持数组类型');
|
|
26
|
+
assert.strictEqual(result.length, 3, 'list_set 应正确存储数组');
|
|
27
|
+
|
|
28
|
+
// 测试 list_add - 向空列表添加
|
|
29
|
+
await cache.list_add('list3', 'item1');
|
|
30
|
+
result = await cache.list_get('list3');
|
|
31
|
+
console.log('list_add 空列表测试:', result);
|
|
32
|
+
assert.strictEqual(result.length, 1, 'list_add 应向空列表添加元素');
|
|
33
|
+
|
|
34
|
+
// 测试 list_add - 向现有列表添加
|
|
35
|
+
await cache.list_add('list3', 'item2');
|
|
36
|
+
result = await cache.list_get('list3');
|
|
37
|
+
console.log('list_add 现有列表测试:', result);
|
|
38
|
+
assert.strictEqual(result.length, 2, 'list_add 应向现有列表添加元素');
|
|
39
|
+
|
|
40
|
+
// 测试 list_has - 基本类型
|
|
41
|
+
let hasValue = await cache.list_has('list3', 'item1');
|
|
42
|
+
console.log('list_has 基本类型测试:', hasValue);
|
|
43
|
+
assert.strictEqual(hasValue, true, 'list_has 应正确检测基本类型');
|
|
44
|
+
|
|
45
|
+
// 测试 list_has - 对象类型
|
|
46
|
+
const objValue = { name: 'test', value: 123 };
|
|
47
|
+
await cache.list_add('list4', objValue);
|
|
48
|
+
hasValue = await cache.list_has('list4', { name: 'test', value: 123 });
|
|
49
|
+
console.log('list_has 对象类型测试:', hasValue);
|
|
50
|
+
assert.strictEqual(hasValue, true, 'list_has 应正确检测对象类型');
|
|
51
|
+
|
|
52
|
+
// 测试 list_clear - 清空现有列表
|
|
53
|
+
result = await cache.list_clear('list3');
|
|
54
|
+
console.log('list_clear 现有列表测试:', result);
|
|
55
|
+
assert.strictEqual(result, true, 'list_clear 应对现有列表返回 true');
|
|
56
|
+
result = await cache.list_get('list3');
|
|
57
|
+
assert.strictEqual(Array.isArray(result), true, 'list_clear 后应返回数组');
|
|
58
|
+
assert.strictEqual(result.length, 0, 'list_clear 应清空列表');
|
|
59
|
+
|
|
60
|
+
// 测试 list_clear - 不存在的键
|
|
61
|
+
result = await cache.list_clear('nonexistent_list');
|
|
62
|
+
console.log('list_clear 不存在键测试:', result);
|
|
63
|
+
assert.strictEqual(result, true, 'list_clear 应对不存在的键创建空列表并返回 true');
|
|
64
|
+
result = await cache.list_get('nonexistent_list');
|
|
65
|
+
assert.strictEqual(Array.isArray(result), true, 'list_clear 后应创建空数组');
|
|
66
|
+
|
|
67
|
+
// 测试 hdel 方法
|
|
68
|
+
console.log('\n=== 测试 hdel 方法 ===');
|
|
69
|
+
|
|
70
|
+
// 创建哈希表
|
|
71
|
+
await cache.hset('hash1', 'field1', 'value1');
|
|
72
|
+
await cache.hset('hash1', 'field2', 'value2');
|
|
73
|
+
|
|
74
|
+
// 测试 hdel - 存在的字段
|
|
75
|
+
result = await cache.hdel('hash1', 'field1');
|
|
76
|
+
console.log('hdel 存在字段测试:', result);
|
|
77
|
+
assert.strictEqual(result, 0, 'hdel 应始终返回 0 以保持兼容性');
|
|
78
|
+
|
|
79
|
+
// 验证字段已被删除
|
|
80
|
+
let hashValue = await cache.hget('hash1', 'field1');
|
|
81
|
+
assert.strictEqual(hashValue, undefined, 'hdel 应实际删除字段');
|
|
82
|
+
|
|
83
|
+
// 测试 hdel - 不存在的字段
|
|
84
|
+
result = await cache.hdel('hash1', 'nonexistent_field');
|
|
85
|
+
console.log('hdel 不存在字段测试:', result);
|
|
86
|
+
assert.strictEqual(result, 0, 'hdel 应对不存在的字段返回 0');
|
|
87
|
+
|
|
88
|
+
// 测试 hdel - 不存在的键
|
|
89
|
+
result = await cache.hdel('nonexistent_hash', 'field');
|
|
90
|
+
console.log('hdel 不存在键测试:', result);
|
|
91
|
+
assert.strictEqual(result, 0, 'hdel 应对不存在的键返回 0');
|
|
92
|
+
|
|
93
|
+
console.log('\n所有测试通过!');
|
|
68
94
|
} catch (error) {
|
|
69
|
-
console.
|
|
95
|
+
console.error('测试失败:', error.message);
|
|
96
|
+
throw error;
|
|
97
|
+
} finally {
|
|
98
|
+
// 清理测试数据
|
|
99
|
+
await cache.clear();
|
|
100
|
+
await cache.dispose();
|
|
101
|
+
console.log('\n测试完成,已清理数据');
|
|
70
102
|
}
|
|
71
|
-
|
|
72
|
-
// 测试5: 带过期时间
|
|
73
|
-
console.log('\n5. 带过期时间');
|
|
74
|
-
const result5 = await cache.add('num_key4', 100, 3); // 3秒过期
|
|
75
|
-
console.log(`add('num_key4', 100, 3) =`, result5);
|
|
76
|
-
console.log(`ttl('num_key4') =`, await cache.ttl('num_key4'));
|
|
77
|
-
|
|
78
|
-
console.log('\n所有方法兼容性测试完成!');
|
|
79
103
|
}
|
|
80
104
|
|
|
81
|
-
|
|
105
|
+
// 运行测试
|
|
106
|
+
runTests().catch(error => {
|
|
107
|
+
console.error('测试执行失败:', error);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
});
|