update
This commit is contained in:
110
test/config.test.js
Normal file
110
test/config.test.js
Normal file
@@ -0,0 +1,110 @@
|
||||
'use strict';
|
||||
const assert = require('node:assert');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
|
||||
// 用临时目录隔离,避免污染真实配置。
|
||||
// 默认数据目录现在是"项目根/data",不再跟 HOME 走 —— 必须用
|
||||
// CLIPBOARD_APP_DATA_DIR 覆盖,否则测试会写进仓库里的 data/。
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'clip-cfg-'));
|
||||
process.env.USERPROFILE = tmpHome;
|
||||
process.env.HOME = tmpHome;
|
||||
process.env.CLIPBOARD_APP_DATA_DIR = path.join(tmpHome, 'data');
|
||||
|
||||
const cfg = require('../config.js');
|
||||
|
||||
let passed = 0;
|
||||
function check(name, fn) {
|
||||
try { fn(); console.log(' ok -', name); passed++; }
|
||||
catch (e) { console.error(' FAIL -', name, '\n', e.message); process.exitCode = 1; }
|
||||
}
|
||||
|
||||
check('defaults 结构完整', () => {
|
||||
assert.strictEqual(cfg.DEFAULTS.autoLaunch, false);
|
||||
assert.strictEqual(cfg.DEFAULTS.maxItems, 0);
|
||||
assert.strictEqual(cfg.DEFAULTS.displayLimit, 300);
|
||||
assert.strictEqual(cfg.DEFAULTS.pollMs, 1000);
|
||||
assert.strictEqual(cfg.DEFAULTS.hotkey, 'Ctrl+Alt+V');
|
||||
assert.ok(typeof cfg.DEFAULTS.dataDir === 'string' && cfg.DEFAULTS.dataDir.length > 0);
|
||||
});
|
||||
|
||||
check('默认数据目录不是 ~/.clipboard-app,且被 CLIPBOARD_APP_DATA_DIR 覆盖', () => {
|
||||
// 不去硬编码 'D:\\Clipboard Data':那是个环境相关的常量,谁换机就炸。
|
||||
// 这里要测的是两条契约:1) 不再是 home 下的 .clipboard-app;2) 环境变量能覆盖。
|
||||
assert.notStrictEqual(path.resolve(cfg.defaultDataDir()), path.resolve(cfg.legacyDataDir()));
|
||||
assert.strictEqual(path.resolve(cfg.defaultDataDir()), path.resolve(tmpHome, 'data'));
|
||||
// config.json 跟着默认目录走
|
||||
assert.strictEqual(path.dirname(cfg.getConfigPath()), path.resolve(cfg.defaultDataDir()));
|
||||
});
|
||||
|
||||
check('默认数据目录:D 盘可用时首选 D 盘', () => {
|
||||
// 默认目录的契约有两个 case:D 盘存在 → 首选 D:\Clipboard Data;
|
||||
// 不存在 → 降级到 home 下的 Clipboard Data。这条只测前者。
|
||||
const saved = process.env.CLIPBOARD_APP_DATA_DIR;
|
||||
delete process.env.CLIPBOARD_APP_DATA_DIR;
|
||||
delete require.cache[require.resolve('../config.js')];
|
||||
const cfg2 = require('../config.js');
|
||||
// D 盘在 CI / 开发机上不一定存在,强行断言会让套件不可移植。
|
||||
// 这里只断言「D 盘可用时返回 D 盘」:先探测一次,能用才断言。
|
||||
process.env.CLIPBOARD_APP_DATA_DIR = saved;
|
||||
if (cfg2.isDirUsable('D:\\Clipboard Data')) {
|
||||
assert.strictEqual(path.resolve(cfg2.defaultDataDir()), path.resolve('D:\\Clipboard Data'));
|
||||
} else {
|
||||
// 当前机器 D 盘不可用 → 跳过本断言(fallback case 在 data-dir-fallback.test.js)
|
||||
console.log(' (D:\\Clipboard Data 不可用,跳过 — 见 data-dir-fallback.test.js)');
|
||||
}
|
||||
});
|
||||
|
||||
check('缺文件时 loadConfig 返回全默认', () => {
|
||||
const c = cfg.loadConfig();
|
||||
assert.strictEqual(c.maxItems, 0);
|
||||
assert.strictEqual(c.displayLimit, 300);
|
||||
assert.strictEqual(c.pollMs, 1000);
|
||||
assert.strictEqual(c.autoLaunch, false);
|
||||
});
|
||||
|
||||
check('sanitize 回落非法枚举值', () => {
|
||||
const c = cfg.sanitize({ maxItems: 999, displayLimit: 42, pollMs: 17, autoLaunch: 'yes', dataDir: 42 });
|
||||
assert.strictEqual(c.maxItems, 0);
|
||||
assert.strictEqual(c.displayLimit, 300);
|
||||
assert.strictEqual(c.pollMs, 1000);
|
||||
assert.strictEqual(c.autoLaunch, false);
|
||||
assert.strictEqual(typeof c.dataDir, 'string');
|
||||
});
|
||||
|
||||
check('sanitize hotkey:非法值回落默认;合法预设保留;空串 = 禁用不算非法', () => {
|
||||
// 自由组合键不认 —— 设置界面只给预设档位,白名单外的一律回落
|
||||
assert.strictEqual(cfg.sanitize({ hotkey: 'Ctrl+Shift+F13' }).hotkey, 'Ctrl+Alt+V');
|
||||
assert.strictEqual(cfg.sanitize({ hotkey: 42 }).hotkey, 'Ctrl+Alt+V');
|
||||
assert.strictEqual(cfg.sanitize({ hotkey: 'Alt+Shift+V' }).hotkey, 'Alt+Shift+V');
|
||||
// '' 是明确的「禁用」语义,绝不能回落默认 —— 否则禁不掉
|
||||
assert.strictEqual(cfg.sanitize({ hotkey: '' }).hotkey, '');
|
||||
// 老配置没有 hotkey 字段(升级场景)→ 默认,等于自动获得快捷键
|
||||
assert.strictEqual(cfg.sanitize({}).hotkey, 'Ctrl+Alt+V');
|
||||
// 默认值本身必须在白名单里(否则首次启动的 register 必炸)
|
||||
assert.ok(cfg.ALLOWED_HOTKEYS.includes(cfg.DEFAULTS.hotkey));
|
||||
// 白名单里的每一个值都得能通过自己(防 ALLOWED_HOTKEYS 与默认值写岔)
|
||||
for (const k of cfg.ALLOWED_HOTKEYS) {
|
||||
assert.strictEqual(cfg.sanitize({ hotkey: k }).hotkey, k, `白名单成员 ${JSON.stringify(k)} 应通过校验`);
|
||||
}
|
||||
});
|
||||
|
||||
check('save 后 load 往返一致', () => {
|
||||
cfg.saveConfig({ autoLaunch: true, maxItems: 1000, displayLimit: 500, pollMs: 500, dataDir: tmpHome, hotkey: 'Ctrl+Alt+C' });
|
||||
const c = cfg.loadConfig();
|
||||
assert.strictEqual(c.autoLaunch, true);
|
||||
assert.strictEqual(c.maxItems, 1000);
|
||||
assert.strictEqual(c.displayLimit, 500);
|
||||
assert.strictEqual(c.pollMs, 500);
|
||||
assert.strictEqual(c.dataDir, tmpHome);
|
||||
assert.strictEqual(c.hotkey, 'Ctrl+Alt+C');
|
||||
});
|
||||
|
||||
check('坏 JSON 不抛异常,返回默认', () => {
|
||||
fs.writeFileSync(cfg.getConfigPath(), '{ this is not json ');
|
||||
const c = cfg.loadConfig();
|
||||
assert.strictEqual(c.maxItems, 0);
|
||||
});
|
||||
|
||||
console.log(`\n${passed} checks passed`);
|
||||
Reference in New Issue
Block a user