test: keep the shortcuts page from naming an action that was renamed

Checked the page against the keymap in both directions and found no rot,
which is worth writing down as much as a fix would be:

- All 47 action names it prints exist, including the compound families
  (`ForkAgentSession` + `Right`/`Left`/`Up`/`Down`).
- Every default chord is on the page. Eight looked missing and none were:
  `ActivateTab2`..`8` live under the page's "Go to Tab 1-9 / ⌘1…⌘9", and
  `IncreaseFontSize` reads `secondary-=` in the table while the page says
  ⌘+, which is right because line 41 binds `secondary-+` as well.

Only the names are pinned. The page lists bindings by label and chord --
"New Tab | ⌘ T" -- and a test that parsed those would be asserting against
a notation a person chose, failing on a range or a middle dot rather than
on anything being wrong. The names are identifiers, so they can be
compared to `default_bindings()` without interpreting anything.

Bare direction words are skipped rather than expanded for the same reason:
guessing that `ResizePaneLeft/Right` means `ResizePaneRight` is guessing at
prose, and the stem is checked either way.

Verified by renaming a page entry to `RenameTabNow`, which fails it.
This commit is contained in:
l0ng-ai
2026-08-16 12:32:48 +08:00
parent f828e9ce22
commit 8a07d8f9c5
+41
View File
@@ -1055,6 +1055,47 @@ fn make_binding(action: &str, keystroke: &str) -> Option<KeyBinding> {
mod tests {
use super::*;
use gpui::Action as _;
/// Every action the shortcuts page names still exists.
///
/// The page is written by hand and lists most bindings by label and chord,
/// which no test should try to parse — but it also prints action names for
/// rebinding, and those are identifiers. A rename that misses the page
/// leaves a reader typing a name the Keybindings screen will not accept.
///
/// Compound entries — `ResizePaneLeft/Right/Up/Down`, `ForkAgentSession`
/// (+ `Right`), the numbered families — are why the bare direction words
/// are skipped rather than expanded: expanding them is guesswork about a
/// notation a person chose, and the stems are checked either way.
#[test]
fn the_shortcuts_page_names_no_action_that_has_been_renamed() {
const PAGE: &str = include_str!("../../docs/reference/keyboard-shortcuts.mdx");
let known: Vec<&str> = default_bindings().into_iter().map(|(a, _)| a).collect();
let mut checked = 0usize;
let mut unknown: Vec<String> = Vec::new();
for token in PAGE.split('`').skip(1).step_by(2) {
for name in token.split('/') {
let name = name.trim();
// Two CamelCase words or more: `Right` on its own is part of a
// compound, and `Settings` is prose.
let words = name.chars().filter(|c| c.is_uppercase()).count();
if words < 2 || !name.chars().all(|c| c.is_ascii_alphanumeric()) {
continue;
}
checked += 1;
if !known.contains(&name) {
unknown.push(name.to_string());
}
}
}
assert!(checked > 30, "only {checked} action names were read");
assert!(
unknown.is_empty(),
"the page names actions the keymap does not have: {unknown:?}"
);
}
/// The actions a keymap built from `action_bindings` dispatches for `keys`
/// typed in `context`, in precedence order — the same lookup gpui performs