Files
NetMesh/domain/keywordHighlight.test.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

152 lines
4.6 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
DEFAULT_KEYWORD_HIGHLIGHT_RULES,
KeywordHighlightRule,
normalizeTerminalSettings,
} from "./models";
const IP_MAC_RULE = "ip-mac";
const ipMacDefault = () => {
const def = DEFAULT_KEYWORD_HIGHLIGHT_RULES.find((r) => r.id === IP_MAC_RULE);
if (!def) throw new Error("ip-mac default rule missing");
return def;
};
const getRule = (
rules: KeywordHighlightRule[],
id: string,
): KeywordHighlightRule => {
const rule = rules.find((r) => r.id === id);
if (!rule) throw new Error(`rule ${id} missing`);
return rule;
};
const matchesAny = (patterns: string[], input: string): boolean =>
patterns.some((p) => new RegExp(p, "gi").test(input));
test("ip-mac built-in rule includes IPv6 patterns by default", () => {
const def = ipMacDefault();
// Compressed mid-form (issue #958 example #1)
assert.ok(
matchesAny(def.patterns, "2001:11:22:33::5"),
"expected default ip-mac rule to match 2001:11:22:33::5",
);
// Link-local compressed (issue #958 example #2)
assert.ok(
matchesAny(def.patterns, "fe80::d2dd:bff:fe79:f2bb"),
"expected default ip-mac rule to match fe80::d2dd:bff:fe79:f2bb",
);
// Loopback
assert.ok(matchesAny(def.patterns, "::1"), "expected ::1 to match");
// Full form
assert.ok(
matchesAny(def.patterns, "2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
"expected full-form IPv6 to match",
);
});
test("ip-mac IPv6 regex still matches IPv4 and MAC", () => {
const def = ipMacDefault();
assert.ok(matchesAny(def.patterns, "10.0.0.1"), "expected IPv4 still matches");
assert.ok(
matchesAny(def.patterns, "aa:bb:cc:dd:ee:ff"),
"expected MAC still matches",
);
});
test("ip-mac IPv6 regex does not match obviously-not-IPv6 hex blobs", () => {
const def = ipMacDefault();
// A single hex word without colons must not match
assert.ok(!matchesAny(def.patterns, "deadbeef"), "single hex word matched");
// A typical sha-like string with colons separating fewer than two groups
assert.ok(!matchesAny(def.patterns, "abc"), "stray hex matched");
});
test("normalize adds newly-shipped default rules to legacy saved sets", () => {
// Simulate an older save that only has 'error' and an old-shape 'ip-mac'
// (i.e. without IPv6). Because the rule is NOT marked customized, normalize
// should re-sync it with the latest shipped patterns.
const legacyIpMacPatterns = ["legacy-pattern-from-old-default"];
const saved: KeywordHighlightRule[] = [
{
id: "error",
label: "Error",
patterns: ["\\berror\\b"],
color: "#F87171",
enabled: true,
},
{
id: IP_MAC_RULE,
label: "URL, IP & MAC",
patterns: legacyIpMacPatterns,
color: "#EC4899",
enabled: true,
},
];
const settings = normalizeTerminalSettings({
keywordHighlightRules: saved,
});
const rules = settings.keywordHighlightRules;
// Every shipped default exists (warning/ok/info/debug get added).
for (const def of DEFAULT_KEYWORD_HIGHLIGHT_RULES) {
assert.ok(
rules.some((r) => r.id === def.id),
`expected normalize to include shipped rule ${def.id}`,
);
}
// ip-mac was not customized → patterns re-sync to defaults, picking up IPv6.
const ipMac = getRule(rules, IP_MAC_RULE);
assert.deepEqual(ipMac.patterns, ipMacDefault().patterns);
assert.ok(matchesAny(ipMac.patterns, "2001:11:22:33::5"));
});
test("normalize preserves user-edited patterns when rule.customized is set", () => {
const customPatterns = ["\\bMY_CUSTOM\\b", "\\bANOTHER\\b"];
const customLabel = "My Errors";
const saved: KeywordHighlightRule[] = [
{
id: "error",
label: customLabel,
patterns: customPatterns,
color: "#FF0000",
enabled: false,
customized: true,
},
];
const settings = normalizeTerminalSettings({
keywordHighlightRules: saved,
});
const rule = getRule(settings.keywordHighlightRules, "error");
assert.equal(rule.label, customLabel);
assert.deepEqual(rule.patterns, customPatterns);
assert.equal(rule.color, "#FF0000");
assert.equal(rule.enabled, false);
assert.equal(rule.customized, true);
});
test("normalize keeps custom (non-built-in) rules verbatim", () => {
const customRule: KeywordHighlightRule = {
id: "user-uuid-1",
label: "Pager",
patterns: ["\\b[A-Z]{3}-\\d+\\b"],
color: "#00FF00",
enabled: true,
};
const settings = normalizeTerminalSettings({
keywordHighlightRules: [customRule],
});
const rule = getRule(settings.keywordHighlightRules, "user-uuid-1");
assert.deepEqual(rule.patterns, customRule.patterns);
assert.equal(rule.label, customRule.label);
});