mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2026-10-25 17:36:37 +08:00
MCP 建出来的命令 features.icon 是空的,命令卡片上就是个空位。现在 icon 留空时 按 program 填对应语言的默认图标(shell -> logo/shell.png、python -> logo/python.png,编排用内置图标),显式传了 icon 就用传入的。
123 lines
4.7 KiB
JavaScript
123 lines
4.7 KiB
JavaScript
/**
|
|
* commandStore 的自检脚本(不依赖 uTools,用假 db 跑一遍增删改查)
|
|
* 运行:node test/commandStore.test.js
|
|
*/
|
|
const assert = require("assert");
|
|
|
|
const db = new Map();
|
|
const features = new Map();
|
|
|
|
global.window = {
|
|
lodashM: { cloneDeep: (x) => JSON.parse(JSON.stringify(x)) },
|
|
dispatchEvent: () => true,
|
|
utools: {
|
|
db: {
|
|
get: (id) => (db.has(id) ? { _id: id, _rev: "1-x", data: db.get(id) } : undefined),
|
|
put: (doc) => (db.set(doc._id, doc.data), { ok: true }),
|
|
remove: (id) => (db.delete(id), { ok: true }),
|
|
allDocs: (prefix) =>
|
|
[...db.entries()]
|
|
.filter(([id]) => id.startsWith(prefix))
|
|
.map(([id, data]) => ({ _id: id, data })),
|
|
},
|
|
getFeatures: () => [...features.values()],
|
|
setFeature: (feature) => (features.set(feature.code, feature), true),
|
|
removeFeature: (code) => features.delete(code),
|
|
},
|
|
};
|
|
global.localStorage = { length: 0, key: () => null, removeItem: () => {} };
|
|
|
|
const store = require("../plugin/lib/commandStore.js");
|
|
|
|
const draft = {
|
|
program: "quickcommand",
|
|
cmd: "console.log(1)",
|
|
features: { explain: "测试命令", cmds: ["测试命令"] },
|
|
output: "text",
|
|
tags: ["测试"],
|
|
};
|
|
|
|
// 建
|
|
const created = store.create(draft);
|
|
assert.deepStrictEqual(created.errors, undefined);
|
|
const command = created.command;
|
|
const code = command.features.code;
|
|
assert.match(code, /^key_[0-9a-f]{8}$/);
|
|
assert.strictEqual(command.features.cmds[0], "测试命令");
|
|
assert.strictEqual(command.features.mainHide, false);
|
|
// 不带图标时用该执行方式的默认图标
|
|
assert.strictEqual(command.features.icon, "logo/quickcommand.png");
|
|
const pyCommand = store.create({
|
|
program: "python",
|
|
cmd: "print(1)",
|
|
features: { explain: "py", cmds: ["py"] },
|
|
}).command;
|
|
assert.strictEqual(pyCommand.features.icon, "logo/python.png");
|
|
const customCommand = store.create({
|
|
program: "custom",
|
|
cmd: "x",
|
|
features: { explain: "自定义", cmds: ["自定义"], icon: "data:image/png;base64,xxx" },
|
|
}).command;
|
|
assert.strictEqual(customCommand.features.icon, "data:image/png;base64,xxx");
|
|
store.remove(pyCommand.features.code);
|
|
store.remove(customCommand.features.code);
|
|
assert.ok(db.has("qc_" + code));
|
|
assert.ok(features.has(code));
|
|
|
|
// 参数不合法时不落库
|
|
const before = db.size;
|
|
assert.ok(store.create({ ...draft, program: "python3" }).errors.length);
|
|
assert.ok(store.create({ ...draft, features: { explain: "", cmds: [] } }).errors.length);
|
|
assert.strictEqual(db.size, before);
|
|
|
|
// 查
|
|
assert.strictEqual(store.list({}).total, 1);
|
|
assert.strictEqual(store.list({ tag: "测试" }).total, 1);
|
|
assert.strictEqual(store.list({ tag: "不存在" }).total, 0);
|
|
assert.strictEqual(store.list({ keyword: "测试" }).total, 1);
|
|
assert.strictEqual(store.list({ enabled: true }).total, 1);
|
|
assert.strictEqual(store.list({ enabled: false }).total, 0);
|
|
assert.deepStrictEqual(store.listTags(), [{ tag: "测试", count: 1 }]);
|
|
assert.strictEqual(store.get(code).cmd, "console.log(1)");
|
|
|
|
// 改
|
|
const updated = store.update(code, {
|
|
...command,
|
|
cmd: "console.log(2)",
|
|
features: { ...command.features, explain: "改名了" },
|
|
});
|
|
assert.strictEqual(updated.command.features.code, code);
|
|
assert.strictEqual(updated.command.features.explain, "改名了");
|
|
assert.strictEqual(db.get("qc_" + code).cmd, "console.log(2)");
|
|
// 字符串形式的触发方式是关键词,不派生 label;对象形式的匹配规则 label 跟随 explain
|
|
assert.strictEqual(db.get("qc_" + code).features.cmds[0], "测试命令");
|
|
const withRule = store.create({
|
|
...draft,
|
|
features: { explain: "正则命令", cmds: [{ type: "regex", match: "/^\\d+$/i" }] },
|
|
}).command;
|
|
assert.strictEqual(withRule.features.cmds[0].label, "正则命令");
|
|
assert.ok(store.update(code, { ...command, tags: "不是数组" }).errors.length);
|
|
assert.ok(store.update(code, { ...command, features: { ...command.features, icon: "x".repeat(40000) } }).errors.length);
|
|
|
|
// 启用/禁用
|
|
assert.deepStrictEqual(store.setEnabled([code], false), [{ code, enabled: false }]);
|
|
assert.ok(!features.has(code));
|
|
assert.strictEqual(store.list({ enabled: false }).total, 1);
|
|
store.setEnabled([code], true);
|
|
assert.ok(features.has(code));
|
|
|
|
// 内置命令一律只读
|
|
assert.throws(() => store.get("default_textReplacer"), /内置/);
|
|
assert.throws(() => store.remove("default_textReplacer"), /内置/);
|
|
assert.throws(() => store.update("default_textReplacer", draft), /内置/);
|
|
assert.notDeepStrictEqual(store.create({ ...draft, features: { ...draft.features, code: "default_x" } }).command.features.code, "default_x");
|
|
|
|
// 删
|
|
const removed = store.remove(code);
|
|
assert.strictEqual(removed.features.code, code);
|
|
assert.ok(!db.has("qc_" + code));
|
|
assert.ok(!features.has(code));
|
|
assert.throws(() => store.get(code), /没有找到/);
|
|
|
|
console.log("commandStore 自检通过");
|