use crossterm::event::{KeyCode, KeyModifiers};
use dotstate::config::Config;
use dotstate::keymap::{Action, KeyBinding, KeymapPreset};
use tempfile::TempDir;
#[test]
fn test_keymap_override_in_config() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("config.toml");
let repo_path = temp_dir.path().join("repo");
let mut config = Config {
repo_path: repo_path.clone(),
..Default::default()
};
config.keymap.preset = KeymapPreset::Vim;
config
.keymap
.overrides
.push(KeyBinding::new("x", Action::Quit));
config
.keymap
.overrides
.push(KeyBinding::new("w", Action::MoveUp));
config.save(&config_path).unwrap();
let loaded = Config::load_or_create(&config_path).unwrap();
assert_eq!(loaded.keymap.preset, KeymapPreset::Vim);
assert_eq!(loaded.keymap.overrides.len(), 2);
assert!(loaded
.keymap
.overrides
.iter()
.any(|b| b.key == "x" && b.action == Action::Quit));
assert!(loaded
.keymap
.overrides
.iter()
.any(|b| b.key == "w" && b.action == Action::MoveUp));
let action = loaded
.keymap
.get_action(KeyCode::Char('x'), KeyModifiers::NONE);
assert_eq!(action, Some(Action::Quit));
let action = loaded
.keymap
.get_action(KeyCode::Char('w'), KeyModifiers::NONE);
assert_eq!(action, Some(Action::MoveUp));
let action = loaded
.keymap
.get_action(KeyCode::Char('q'), KeyModifiers::NONE);
assert_eq!(action, None);
let action = loaded
.keymap
.get_action(KeyCode::Char('k'), KeyModifiers::NONE);
assert_eq!(action, None);
let action = loaded
.keymap
.get_action(KeyCode::Char('j'), KeyModifiers::NONE);
assert_eq!(action, Some(Action::MoveDown));
}
#[test]
fn test_keymap_override_shadows_preset() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("config.toml");
let repo_path = temp_dir.path().join("repo");
let mut config = Config {
repo_path: repo_path.clone(),
..Default::default()
};
config.keymap.preset = KeymapPreset::Vim;
config
.keymap
.overrides
.push(KeyBinding::new("j", Action::MoveUp));
config.save(&config_path).unwrap();
let loaded = Config::load_or_create(&config_path).unwrap();
let action = loaded
.keymap
.get_action(KeyCode::Char('j'), KeyModifiers::NONE);
assert_eq!(action, Some(Action::MoveUp));
let action = loaded
.keymap
.get_action(KeyCode::Char('k'), KeyModifiers::NONE);
assert_eq!(action, None);
let action = loaded
.keymap
.get_action(KeyCode::Char('h'), KeyModifiers::NONE);
assert_eq!(action, Some(Action::MoveLeft));
}
#[test]
fn test_keymap_override_with_modifiers() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("config.toml");
let repo_path = temp_dir.path().join("repo");
let mut config = Config {
repo_path: repo_path.clone(),
..Default::default()
};
config.keymap.preset = KeymapPreset::Standard;
config
.keymap
.overrides
.push(KeyBinding::new("ctrl+n", Action::Quit));
config.save(&config_path).unwrap();
let loaded = Config::load_or_create(&config_path).unwrap();
let action = loaded
.keymap
.get_action(KeyCode::Char('n'), KeyModifiers::CONTROL);
assert_eq!(action, Some(Action::Quit));
let action = loaded
.keymap
.get_action(KeyCode::Char('n'), KeyModifiers::NONE);
assert_ne!(action, Some(Action::Quit));
}
#[test]
fn test_keymap_override_serialization_format() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("config.toml");
let repo_path = temp_dir.path().join("repo");
let mut config = Config {
repo_path: repo_path.clone(),
..Default::default()
};
config.keymap.preset = KeymapPreset::Emacs;
config
.keymap
.overrides
.push(KeyBinding::new("f1", Action::Help));
config
.keymap
.overrides
.push(KeyBinding::new("ctrl+h", Action::Quit));
config.save(&config_path).unwrap();
let content = std::fs::read_to_string(&config_path).unwrap();
assert!(content.contains("[keymap]"));
assert!(content.contains("preset = \"emacs\""));
assert!(content.contains("overrides"));
let loaded = Config::load_or_create(&config_path).unwrap();
assert_eq!(loaded.keymap.preset, KeymapPreset::Emacs);
assert_eq!(loaded.keymap.overrides.len(), 2);
let action = loaded.keymap.get_action(KeyCode::F(1), KeyModifiers::NONE);
assert_eq!(action, Some(Action::Help));
let action = loaded
.keymap
.get_action(KeyCode::Char('h'), KeyModifiers::CONTROL);
assert_eq!(action, Some(Action::Quit));
}