From 9c518085aeed7b388035c494bc8c1b27421fa253 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 7 Jul 2022 11:01:26 -0700 Subject: [PATCH] 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 f5dbc470f5..634797507b 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 0bbc056922..b44b93e745 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 eb7f2a0a90..846ed26806 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"); + } }