use super::*;
#[test]
fn an_unregistered_token_is_reported_as_unknown() {
let msg = fallthrough_message("zzznotacommand");
assert!(msg.contains("unknown command: /zzznotacommand"), "{msg}");
assert!(msg.contains("/help"), "{msg}");
}
#[test]
fn a_registered_token_is_not_called_unknown() {
for token in ["remember", "tab", "crew"] {
let msg = fallthrough_message(token);
assert!(
!msg.contains("unknown command"),
"`/{token}` is registered; calling it unknown is the defect: {msg}"
);
assert!(msg.contains("routing bug"), "{msg}");
}
}
#[test]
fn the_lifecycle_verbs_that_differ_are_separate_rows() {
for token in ["new", "end", "restart", "start"] {
let row = lookup(token).unwrap_or_else(|| panic!("/{token} is registered"));
assert_eq!(
row.name, token,
"`/{token}` resolves to `/{}` — it was made an alias of a \
command it does not behave like",
row.name
);
}
assert_eq!(
lookup("clear").map(|c| c.name),
Some("new"),
"`/clear` and `/new` share a dispatch arm; two rows would claim a \
difference the code does not have"
);
}
#[test]
fn the_registered_ghosts_are_typed_mutators_that_owe_a_receipt() {
for token in ["new", "clear", "end", "restart", "start", "cd"] {
let row = lookup(token).unwrap_or_else(|| panic!("/{token} is registered"));
assert_eq!(row.surface, Surface::Slash, "/{token} is typed today");
assert_eq!(
row.receipt,
Receipt::Missing,
"/{token} mutates durable state and records no receipt; \
saying otherwise hides it from the #1965 debt"
);
}
}
#[test]
fn a_section_action_names_the_door_it_is_behind() {
let msg = fallthrough_message("probe reset");
assert!(msg.contains("/settings"), "names where it lives: {msg}");
assert!(!msg.contains("routing bug"), "it is not a bug: {msg}");
assert!(!msg.contains("unknown command"), "{msg}");
}
#[test]
fn lookup_resolves_aliases_and_is_case_insensitive() {
assert_eq!(lookup("quit").map(|c| c.name), Some("exit"));
assert_eq!(lookup("vi").map(|c| c.name), Some("edit-mode"));
assert_eq!(lookup("NUDGE").map(|c| c.name), Some("nudge"));
assert!(lookup("zzznotacommand").is_none());
}
#[test]
fn psyche_performs_and_cognition_points_at_it() {
let psyche = lookup("psyche").expect("/psyche is registered");
assert_eq!(
psyche.name, "psyche",
"resolves to itself, not to cognition"
);
assert_eq!(psyche.surface, Surface::Slash, "it is still typed");
assert_eq!(psyche.disposition, Disposition::Keep, "and it performs");
let cognition = lookup("cognition").expect("/cognition is registered");
assert_eq!(
cognition.surface,
Surface::Retired("/settings cognition"),
"`commands::settings` answers /cognition with a redirect that \
mutates nothing — the registry has to say so"
);
}
#[test]
fn every_registry_command_is_advertised_or_ratcheted() {
const KNOWN_UNADVERTISED: &[&str] = &[
"callees",
"callers",
"cognition",
"detail",
"edit-mode",
"hierarchy",
"implementations",
"markdown",
"rename",
"tab",
"tenacity",
"undo-lock",
];
let is_advertised = |name: &str| -> bool {
let needle = format!("/{name}");
crate::help_lines().iter().any(|line| {
line.trim_start().strip_prefix(&needle).is_some_and(|rest| {
rest.is_empty() || rest.starts_with(char::is_whitespace)
})
})
};
let advertised_count = COMMANDS.iter().filter(|c| is_advertised(c.name)).count();
assert!(
advertised_count >= 20,
"help_lines() parse collapsed: only {advertised_count} commands \
matched a help row"
);
let missing: Vec<&str> = slash_commands()
.chain(
COMMANDS
.iter()
.filter(|c| c.surface == Surface::SectionAction),
)
.map(|c| c.name)
.filter(|n| !is_advertised(n) && !KNOWN_UNADVERTISED.contains(n))
.collect();
assert!(
missing.is_empty(),
"registry commands with no help_lines() row (add the row, or argue \
a KNOWN_UNADVERTISED entry in review): {missing:?}"
);
let taught: Vec<&str> = COMMANDS
.iter()
.filter(|c| matches!(c.surface, Surface::Retired(_)))
.map(|c| c.name)
.filter(|n| is_advertised(n))
.collect();
assert!(
taught.is_empty(),
"these rows are retired but the help still teaches them as \
top-level commands, which teaches the fold away: {taught:?}"
);
let stale: Vec<&str> = KNOWN_UNADVERTISED
.iter()
.copied()
.filter(|n| is_advertised(n))
.collect();
assert!(
stale.is_empty(),
"now advertised — remove from the list: {stale:?}"
);
}
#[test]
fn no_token_resolves_to_two_commands() {
let mut seen: std::collections::BTreeMap<&str, &str> = Default::default();
for c in COMMANDS {
for t in c.tokens() {
if let Some(prev) = seen.insert(t, c.name) {
panic!("token `/{t}` claimed by both `{prev}` and `{}`", c.name);
}
}
}
}