diff --git a/crates/ely_browser_core/src/state.rs b/crates/ely_browser_core/src/state.rs index 21ccb14..a744695 100644 --- a/crates/ely_browser_core/src/state.rs +++ b/crates/ely_browser_core/src/state.rs @@ -181,6 +181,10 @@ impl BrowserCore { self.open_tab(url); self.command_query.clear(); } + CommandIntent::Command(command) if self.submit_named_command(command)? => { + self.command_query.clear(); + } + CommandIntent::Command(_) => {} CommandIntent::ScopedSearch { scope: CommandScope::Tabs, query } => { if let Some(tab_id) = self.find_tab_match(query) { self.select_tab(&tab_id)?; @@ -231,6 +235,24 @@ impl BrowserCore { Ok(next_tab_id) } + fn submit_named_command(&mut self, command: &str) -> Result { + match command.trim().to_ascii_lowercase().as_str() { + "new-tab" => { + self.open_tab(self.new_tab_url.clone()); + Ok(true) + } + "close-tab" => { + self.close_active_tab()?; + Ok(true) + } + "favorite" | "toggle-favorite" => { + self.toggle_active_tab_favorite()?; + Ok(true) + } + _ => Ok(false), + } + } + fn active_tab_index(&self) -> Result { self.tabs .iter() diff --git a/crates/ely_browser_core/tests/commands.rs b/crates/ely_browser_core/tests/commands.rs new file mode 100644 index 0000000..68e03e7 --- /dev/null +++ b/crates/ely_browser_core/tests/commands.rs @@ -0,0 +1,69 @@ +use std::error::Error; + +use ely_browser_core::{BrowserCore, InitialBrowserConfig}; +use ely_domain::{CommandIntent, UrlText}; + +#[test] +fn favorite_command_toggles_active_tab() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + + core.set_command_query(">favorite"); + let intent = core.submit_command()?; + let snapshot = core.snapshot()?; + + assert_eq!(intent, Some(CommandIntent::Command("favorite".to_string()))); + assert_eq!(snapshot.favorites.len(), 1); + assert_eq!(snapshot.favorites[0].id(), &snapshot.active_tab_id); + assert_eq!(snapshot.command_query, ""); + Ok(()) +} + +#[test] +fn new_tab_command_opens_new_tab() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + + core.set_command_query(">new-tab"); + let intent = core.submit_command()?; + let snapshot = core.snapshot()?; + let active_tab = core.active_tab()?; + + assert_eq!(intent, Some(CommandIntent::Command("new-tab".to_string()))); + assert_eq!(snapshot.tabs.len(), 2); + assert_eq!(active_tab.url().as_str(), "ely://new-tab"); + assert_eq!(snapshot.command_query, ""); + Ok(()) +} + +#[test] +fn close_tab_command_closes_active_tab() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let first_tab_id = core.active_tab()?.id().clone(); + let second_tab_id = core.open_tab(UrlText::parse("https://example.com")?); + + core.set_command_query(">close-tab"); + let intent = core.submit_command()?; + let snapshot = core.snapshot()?; + + assert_eq!(intent, Some(CommandIntent::Command("close-tab".to_string()))); + assert_eq!(snapshot.tabs.len(), 1); + assert_eq!(snapshot.active_tab_id, first_tab_id); + assert!(snapshot.tabs.iter().all(|tab| tab.id() != &second_tab_id)); + assert_eq!(snapshot.command_query, ""); + Ok(()) +} + +#[test] +fn unknown_command_preserves_query() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let active_tab_id = core.active_tab()?.id().clone(); + + core.set_command_query(">missing"); + let intent = core.submit_command()?; + let snapshot = core.snapshot()?; + + assert_eq!(intent, Some(CommandIntent::Command("missing".to_string()))); + assert_eq!(snapshot.tabs.len(), 1); + assert_eq!(snapshot.active_tab_id, active_tab_id); + assert_eq!(snapshot.command_query, ">missing"); + Ok(()) +}