From 9c518085aeed7b388035c494bc8c1b27421fa253 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 7 Jul 2022 11:01:26 -0700 Subject: [PATCH 1/2] Fixed working directory issues, added tests. Working on regression --- Cargo.lock | 2 + crates/terminal/Cargo.toml | 4 ++ crates/terminal/src/terminal.rs | 99 ++++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5dbc470f597c8e3f17c9bfc3052115d51886227..634797507be3b71e9942be0cdee5e43f98924dc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4878,6 +4878,8 @@ name = "terminal" version = "0.1.0" dependencies = [ "alacritty_terminal", + "client", + "dirs 4.0.0", "editor", "futures", "gpui", diff --git a/crates/terminal/Cargo.toml b/crates/terminal/Cargo.toml index 0bbc0569227198a45538016b63a24f35d079abd0..b44b93e745ccabe06da58d540ded3eec17f3a145 100644 --- a/crates/terminal/Cargo.toml +++ b/crates/terminal/Cargo.toml @@ -21,7 +21,11 @@ mio-extras = "2.0.6" futures = "0.3" ordered-float = "2.1.1" itertools = "0.10" +dirs = "4.0.0" [dev-dependencies] gpui = { path = "../gpui", features = ["test-support"] } +client = { path = "../client", features = ["test-support"]} +project = { path = "../project", features = ["test-support"]} + diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index eb7f2a0a90b0d6d4b1204bdc13396634145c4371..846ed2680665264c0dfa4d4d0c0d6af74000fc52 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -9,6 +9,7 @@ use alacritty_terminal::{ Term, }; +use dirs::home_dir; use futures::{ channel::mpsc::{unbounded, UnboundedSender}, StreamExt, @@ -17,7 +18,7 @@ use gpui::{ actions, color::Color, elements::*, impl_internal_actions, platform::CursorStyle, ClipboardItem, Entity, MutableAppContext, View, ViewContext, }; -use project::{Project, ProjectPath}; +use project::{LocalWorktree, Project, ProjectPath}; use settings::Settings; use smallvec::SmallVec; use std::{collections::HashMap, path::PathBuf, sync::Arc}; @@ -268,11 +269,12 @@ impl Terminal { ///Create a new Terminal in the current working directory or the user's home directory fn deploy(workspace: &mut Workspace, _: &Deploy, cx: &mut ViewContext) { let project = workspace.project().read(cx); + let abs_path = project .active_entry() .and_then(|entry_id| project.worktree_for_entry(entry_id, cx)) .and_then(|worktree_handle| worktree_handle.read(cx).as_local()) - .map(|wt| wt.abs_path().to_path_buf()); + .and_then(get_working_directory); workspace.add_item(Box::new(cx.add_view(|cx| Terminal::new(cx, abs_path))), cx); } @@ -477,19 +479,28 @@ fn to_alac_rgb(color: Color) -> AlacRgb { } } +fn get_working_directory(wt: &LocalWorktree) -> Option { + Some(wt.abs_path().to_path_buf()) + .filter(|path| path.is_dir()) + .or_else(|| home_dir()) +} + #[cfg(test)] mod tests { + + use std::{path::Path, sync::atomic::AtomicUsize}; + use super::*; use alacritty_terminal::{grid::GridIterator, term::cell::Cell}; use gpui::TestAppContext; use itertools::Itertools; + use project::{FakeFs, Fs, RealFs, RemoveOptions, Worktree}; ///Basic integration test, can we get the terminal to show up, execute a command, //and produce noticable output? #[gpui::test] async fn test_terminal(cx: &mut TestAppContext) { let terminal = cx.add_view(Default::default(), |cx| Terminal::new(cx, None)); - terminal.update(cx, |terminal, cx| { terminal.write_to_pty(&Input(("expr 3 + 4".to_string()).to_string()), cx); terminal.carriage_return(&Return, cx); @@ -499,6 +510,7 @@ mod tests { .condition(cx, |terminal, _cx| { let term = terminal.term.clone(); let content = grid_as_str(term.lock().renderable_content().display_iter); + dbg!(&content); content.contains("7") }) .await; @@ -512,4 +524,85 @@ mod tests { .collect::>() .join("\n") } + + #[gpui::test] + async fn single_file_worktree(cx: &mut TestAppContext) { + let mut async_cx = cx.to_async(); + let http_client = client::test::FakeHttpClient::with_404_response(); + let client = client::Client::new(http_client.clone()); + let fake_fs = FakeFs::new(cx.background().clone()); + + let path = Path::new("/file/"); + fake_fs.insert_file(path, "a".to_string()).await; + + let worktree_handle = Worktree::local( + client, + path, + true, + fake_fs, + Arc::new(AtomicUsize::new(0)), + &mut async_cx, + ) + .await + .ok() + .unwrap(); + + async_cx.update(|cx| { + let wt = worktree_handle.read(cx).as_local().unwrap(); + let wd = get_working_directory(wt); + assert!(wd.is_some()); + let path = wd.unwrap(); + //This should be the system's working directory, so querying the real file system is probably ok. + assert!(path.is_dir()); + assert_eq!(path, home_dir().unwrap()); + }); + } + + #[gpui::test] + async fn test_worktree_directory(cx: &mut TestAppContext) { + let mut async_cx = cx.to_async(); + let http_client = client::test::FakeHttpClient::with_404_response(); + let client = client::Client::new(http_client.clone()); + + let fs = RealFs; + let mut test_wd = home_dir().unwrap(); + test_wd.push("dir"); + + fs.create_dir(test_wd.as_path()) + .await + .expect("File could not be created"); + + let worktree_handle = Worktree::local( + client, + test_wd.clone(), + true, + Arc::new(RealFs), + Arc::new(AtomicUsize::new(0)), + &mut async_cx, + ) + .await + .ok() + .unwrap(); + + async_cx.update(|cx| { + let wt = worktree_handle.read(cx).as_local().unwrap(); + let wd = get_working_directory(wt); + assert!(wd.is_some()); + let path = wd.unwrap(); + assert!(path.is_dir()); + assert_eq!(path, test_wd); + }); + + //Clean up after ourselves. + fs.remove_dir( + test_wd.as_path(), + RemoveOptions { + recursive: false, + ignore_if_not_exists: true, + }, + ) + .await + .ok() + .expect("Could not remove test directory"); + } } From 02525c5bbefe9ed28b228398042863eb7a20636f Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 7 Jul 2022 12:04:17 -0700 Subject: [PATCH 2/2] Added a way to change the timeout with state --- crates/gpui/src/app.rs | 23 +++++++++++++++++------ crates/terminal/src/terminal.rs | 5 +++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 505f609f5709f57b0c037ec5be2032729f736266..bcb8908629500c0916ea4110f28119b7e0189869 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -151,6 +151,7 @@ pub struct AsyncAppContext(Rc>); pub struct TestAppContext { cx: Rc>, foreground_platform: Rc, + condition_duration: Option, } impl App { @@ -337,6 +338,7 @@ impl TestAppContext { let cx = TestAppContext { cx: Rc::new(RefCell::new(cx)), foreground_platform, + condition_duration: None, }; cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx)); cx @@ -612,6 +614,19 @@ impl TestAppContext { test_window }) } + + pub fn set_condition_duration(&mut self, duration: Duration) { + self.condition_duration = Some(duration); + } + pub fn condition_duration(&self) -> Duration { + self.condition_duration.unwrap_or_else(|| { + if std::env::var("CI").is_ok() { + Duration::from_secs(2) + } else { + Duration::from_millis(500) + } + }) + } } impl AsyncAppContext { @@ -4398,6 +4413,7 @@ impl ViewHandle { use postage::prelude::{Sink as _, Stream as _}; let (tx, mut rx) = postage::mpsc::channel(1024); + let timeout_duration = cx.condition_duration(); let mut cx = cx.cx.borrow_mut(); let subscriptions = self.update(&mut *cx, |_, cx| { @@ -4419,14 +4435,9 @@ impl ViewHandle { let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap(); let handle = self.downgrade(); - let duration = if std::env::var("CI").is_ok() { - Duration::from_secs(2) - } else { - Duration::from_millis(500) - }; async move { - crate::util::timeout(duration, async move { + crate::util::timeout(timeout_duration, async move { loop { { let cx = cx.borrow(); diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 846ed2680665264c0dfa4d4d0c0d6af74000fc52..a99e211dca24eb8f9de3d182b48abdc443462c26 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -488,7 +488,7 @@ fn get_working_directory(wt: &LocalWorktree) -> Option { #[cfg(test)] mod tests { - use std::{path::Path, sync::atomic::AtomicUsize}; + use std::{path::Path, sync::atomic::AtomicUsize, time::Duration}; use super::*; use alacritty_terminal::{grid::GridIterator, term::cell::Cell}; @@ -501,6 +501,8 @@ mod tests { #[gpui::test] async fn test_terminal(cx: &mut TestAppContext) { let terminal = cx.add_view(Default::default(), |cx| Terminal::new(cx, None)); + cx.set_condition_duration(Duration::from_secs(2)); + terminal.update(cx, |terminal, cx| { terminal.write_to_pty(&Input(("expr 3 + 4".to_string()).to_string()), cx); terminal.carriage_return(&Return, cx); @@ -510,7 +512,6 @@ mod tests { .condition(cx, |terminal, _cx| { let term = terminal.term.clone(); let content = grid_as_str(term.lock().renderable_content().display_iter); - dbg!(&content); content.contains("7") }) .await;