use std::collections::BTreeSet;
use escriba_command::CommandRegistry;
use escriba_core::Action;
const INERT: &[&str] = &[
"ai.chat",
"ai.inline",
"cmp.abort",
"cmp.complete",
"conflict.choose-both",
"conflict.choose-ours",
"conflict.choose-theirs",
"conflict.next",
"conflict.prev",
"dap.continue",
"dap.repl",
"dap.step-into",
"dap.step-out",
"dap.step-over",
"dap.toggle-breakpoint",
"dap.toggle-ui",
"files.open",
"files.open-parent",
"fold.close-all",
"fold.open-all",
"fold.toggle",
"git.blame",
"git.commit",
"git.diff",
"git.next-hunk",
"git.prev-hunk",
"git.preview-hunk",
"git.reset-hunk",
"git.stage-hunk",
"git.status",
"illuminate.next",
"illuminate.prev",
"leap.backward",
"leap.forward",
"lsp.code-action",
"lsp.definition",
"lsp.diagnostic-next",
"lsp.diagnostic-prev",
"lsp.format",
"lsp.hover",
"lsp.implementation",
"lsp.incoming-calls",
"lsp.outgoing-calls",
"lsp.outline",
"lsp.peek-definition",
"lsp.references",
"lsp.rename",
"lsp.signature",
"lsp.type-definition",
"pane.down",
"pane.left",
"pane.right",
"pane.up",
"picker.symbols",
"picker.lsp-references",
"snacks.gitbrowse",
"snacks.terminal",
"snacks.zen",
"snippet.jump-next",
"snippet.jump-prev",
"surround.add",
"surround.change",
"surround.delete",
"test.run-file",
"test.run-nearest",
"test.run-suite",
"test.toggle-output",
"test.toggle-summary",
"tree.toggle",
"trouble.document",
"trouble.toggle",
"trouble.workspace",
"whichkey.show",
];
fn shipped() -> (escriba_lisp::ApplyPlan, CommandRegistry) {
let plan = escriba::default_plan(false).expect("shipped defaults parse");
let mut registry = CommandRegistry::default_set();
escriba_lisp::apply_plan_to_commands(&plan, &mut registry);
(plan, registry)
}
fn resolves(action: &str, registry: &CommandRegistry) -> bool {
match escriba_lisp::resolve_action(action) {
(_, false) => true,
(Action::Command { name, .. }, true) => registry.contains(&name),
(_, true) => unreachable!("the deferred arm always yields Action::Command"),
}
}
#[test]
fn the_inert_action_inventory_is_exactly_what_we_claim_it_is() {
let (plan, registry) = shipped();
let found: BTreeSet<String> = plan
.keybinds
.iter()
.map(|kb| kb.action.clone())
.filter(|a| !resolves(a, ®istry))
.collect();
let claimed: BTreeSet<String> = INERT.iter().map(|s| (*s).to_string()).collect();
let unexpected: Vec<&String> = found.difference(&claimed).collect();
assert!(
unexpected.is_empty(),
"NEW unresolvable action(s) — a typo, or a subsystem bound to a name \
nothing registers. Fix the name, register the command, or add it to \
INERT with the subsystem that will retire it:\n{unexpected:#?}",
);
let retired: Vec<&String> = claimed.difference(&found).collect();
assert!(
retired.is_empty(),
"these are listed as inert but now RESOLVE — the subsystem landed. \
Delete them from INERT so the inventory stops overstating what is \
missing:\n{retired:#?}",
);
}
#[test]
fn every_start_screen_entry_actually_does_something() {
let (plan, registry) = shipped();
let splash = escriba_lisp::apply_plan_to_splash(&plan)
.expect("the shipped rc declares an enabled start screen");
assert!(!splash.entries.is_empty(), "a menu with no entries");
for entry in &splash.entries {
let executable = match &entry.action {
Action::Command { name, .. } => registry.contains(name),
_ => true,
};
assert!(
executable,
"start screen offers `{}` ({}) but nothing would happen",
entry.key, entry.label,
);
}
}
#[test]
fn start_screen_keys_are_unique() {
let (plan, _) = shipped();
let splash = escriba_lisp::apply_plan_to_splash(&plan).expect("a start screen");
let mut seen = BTreeSet::new();
for e in &splash.entries {
assert!(
seen.insert(e.key),
"duplicate start-screen key `{}` — the later entry is unreachable",
e.key,
);
}
}
#[test]
fn a_typo_in_an_action_is_caught_by_the_same_check_the_gate_uses() {
let (_, registry) = shipped();
assert!(
!resolves("serch-forwrd", ®istry),
"a misspelled action must not read as resolvable",
);
assert!(
resolves("search-forward", ®istry),
"the real one must — this is the exact string that was missing",
);
}