gpui: Stub out prompt_for_paths in TestPlatform
Conrad Irwin
created 13 hours ago
Add stubbing support for prompt_for_paths in TestPlatform, following the
same pattern as prompt_for_new_path. This allows tests to simulate user
interactions with the file open dialog.
- Add paths field to TestPrompts to store pending prompts
- Add did_prompt_for_paths() to check for pending prompts
- Add simulate_paths_selection() to simulate user path selection
- Update prompt_for_paths() to queue prompts instead of panicking
- Expose these methods on TestAppContext and TestApp
Change summary
crates/gpui/src/app/test_app.rs | 15 ++++++++++++
crates/gpui/src/app/test_context.rs | 15 ++++++++++++
crates/gpui/src/platform/test/platform.rs | 27 +++++++++++++++++++++++-
3 files changed, 53 insertions(+), 4 deletions(-)
Detailed changes
@@ -286,7 +286,12 @@ impl TestApp {
self.platform.did_prompt_for_new_path()
}
- /// Simulate answering a path selection dialog.
+ /// Check if a path selection prompt is pending.
+ pub fn did_prompt_for_paths(&self) -> bool {
+ self.platform.did_prompt_for_paths()
+ }
+
+ /// Simulate answering a "Save" path selection dialog.
pub fn simulate_new_path_selection(
&self,
select: impl FnOnce(&std::path::Path) -> Option<std::path::PathBuf>,
@@ -294,6 +299,14 @@ impl TestApp {
self.platform.simulate_new_path_selection(select);
}
+ /// Simulate answering an "Open" path selection dialog.
+ pub fn simulate_paths_selection(
+ &self,
+ select_paths: impl FnOnce(&crate::PathPromptOptions) -> Option<Vec<std::path::PathBuf>>,
+ ) {
+ self.platform.simulate_paths_selection(select_paths);
+ }
+
/// Check if a prompt dialog is pending.
pub fn has_pending_prompt(&self) -> bool {
self.platform.has_pending_prompt()
@@ -159,6 +159,11 @@ impl TestAppContext {
self.test_platform.did_prompt_for_new_path()
}
+ /// Checks whether there have been any path prompts received by the platform.
+ pub fn did_prompt_for_paths(&self) -> bool {
+ self.test_platform.did_prompt_for_paths()
+ }
+
/// returns a new `TestAppContext` re-using the same executors to interleave tasks.
pub fn new_app(&self) -> TestAppContext {
Self::build(self.dispatcher.clone(), self.fn_name)
@@ -325,7 +330,7 @@ impl TestAppContext {
self.test_platform.read_from_clipboard()
}
- /// Simulates choosing a File in the platform's "Open" dialog.
+ /// Simulates choosing a File in the platform's "Save" dialog.
pub fn simulate_new_path_selection(
&self,
select_path: impl FnOnce(&std::path::Path) -> Option<std::path::PathBuf>,
@@ -333,6 +338,14 @@ impl TestAppContext {
self.test_platform.simulate_new_path_selection(select_path);
}
+ /// Simulates choosing paths in the platform's "Open" dialog.
+ pub fn simulate_paths_selection(
+ &self,
+ select_paths: impl FnOnce(&crate::PathPromptOptions) -> Option<Vec<std::path::PathBuf>>,
+ ) {
+ self.test_platform.simulate_paths_selection(select_paths);
+ }
+
/// Simulates clicking a button in an platform-level alert dialog.
#[track_caller]
pub fn simulate_prompt_answer(&self, button: &str) {
@@ -85,6 +85,10 @@ struct TestPrompt {
pub(crate) struct TestPrompts {
multiple_choice: VecDeque<TestPrompt>,
new_path: VecDeque<(PathBuf, oneshot::Sender<Result<Option<PathBuf>>>)>,
+ paths: VecDeque<(
+ crate::PathPromptOptions,
+ oneshot::Sender<Result<Option<Vec<PathBuf>>>>,
+ )>,
}
impl TestPlatform {
@@ -226,6 +230,23 @@ impl TestPlatform {
pub(crate) fn did_prompt_for_new_path(&self) -> bool {
!self.prompts.borrow().new_path.is_empty()
}
+
+ pub(crate) fn did_prompt_for_paths(&self) -> bool {
+ !self.prompts.borrow().paths.is_empty()
+ }
+
+ pub(crate) fn simulate_paths_selection(
+ &self,
+ select_paths: impl FnOnce(&crate::PathPromptOptions) -> Option<Vec<PathBuf>>,
+ ) {
+ let (options, tx) = self
+ .prompts
+ .borrow_mut()
+ .paths
+ .pop_front()
+ .expect("no pending paths prompt");
+ tx.send(Ok(select_paths(&options))).ok();
+ }
}
impl Platform for TestPlatform {
@@ -348,9 +369,11 @@ impl Platform for TestPlatform {
fn prompt_for_paths(
&self,
- _options: crate::PathPromptOptions,
+ options: crate::PathPromptOptions,
) -> oneshot::Receiver<Result<Option<Vec<std::path::PathBuf>>>> {
- unimplemented!()
+ let (tx, rx) = oneshot::channel();
+ self.prompts.borrow_mut().paths.push_back((options, tx));
+ rx
}
fn prompt_for_new_path(