terminal_test_context.rs

  1use std::{path::Path, time::Duration};
  2
  3use alacritty_terminal::{
  4    index::{Column, Line, Point},
  5    term::cell::Cell,
  6};
  7use gpui::{ModelHandle, TestAppContext, ViewHandle};
  8
  9use project::{Entry, Project, ProjectPath, Worktree};
 10use rand::{rngs::ThreadRng, Rng};
 11use workspace::{AppState, Workspace};
 12
 13use crate::{IndexedCell, TerminalContent, TerminalSize};
 14
 15pub struct TerminalTestContext<'a> {
 16    pub cx: &'a mut TestAppContext,
 17}
 18
 19impl<'a> TerminalTestContext<'a> {
 20    pub fn new(cx: &'a mut TestAppContext) -> Self {
 21        cx.set_condition_duration(Some(Duration::from_secs(5)));
 22
 23        TerminalTestContext { cx }
 24    }
 25
 26    ///Creates a worktree with 1 file: /root.txt
 27    pub async fn blank_workspace(&mut self) -> (ModelHandle<Project>, ViewHandle<Workspace>) {
 28        let params = self.cx.update(AppState::test);
 29
 30        let project = Project::test(params.fs.clone(), [], self.cx).await;
 31        let (_, workspace) = self
 32            .cx
 33            .add_window(|cx| Workspace::new(project.clone(), |_, _| unimplemented!(), cx));
 34
 35        (project, workspace)
 36    }
 37
 38    ///Creates a worktree with 1 folder: /root{suffix}/
 39    pub async fn create_folder_wt(
 40        &mut self,
 41        project: ModelHandle<Project>,
 42        path: impl AsRef<Path>,
 43    ) -> (ModelHandle<Worktree>, Entry) {
 44        self.create_wt(project, true, path).await
 45    }
 46
 47    ///Creates a worktree with 1 file: /root{suffix}.txt
 48    pub async fn create_file_wt(
 49        &mut self,
 50        project: ModelHandle<Project>,
 51        path: impl AsRef<Path>,
 52    ) -> (ModelHandle<Worktree>, Entry) {
 53        self.create_wt(project, false, path).await
 54    }
 55
 56    async fn create_wt(
 57        &mut self,
 58        project: ModelHandle<Project>,
 59        is_dir: bool,
 60        path: impl AsRef<Path>,
 61    ) -> (ModelHandle<Worktree>, Entry) {
 62        let (wt, _) = project
 63            .update(self.cx, |project, cx| {
 64                project.find_or_create_local_worktree(path, true, cx)
 65            })
 66            .await
 67            .unwrap();
 68
 69        let entry = self
 70            .cx
 71            .update(|cx| {
 72                wt.update(cx, |wt, cx| {
 73                    wt.as_local()
 74                        .unwrap()
 75                        .create_entry(Path::new(""), is_dir, cx)
 76                })
 77            })
 78            .await
 79            .unwrap();
 80
 81        (wt, entry)
 82    }
 83
 84    pub fn insert_active_entry_for(
 85        &mut self,
 86        wt: ModelHandle<Worktree>,
 87        entry: Entry,
 88        project: ModelHandle<Project>,
 89    ) {
 90        self.cx.update(|cx| {
 91            let p = ProjectPath {
 92                worktree_id: wt.read(cx).id(),
 93                path: entry.path,
 94            };
 95            project.update(cx, |project, cx| project.set_active_path(Some(p), cx));
 96        });
 97    }
 98
 99    pub fn create_terminal_content(
100        size: TerminalSize,
101        rng: &mut ThreadRng,
102    ) -> (TerminalContent, Vec<Vec<char>>) {
103        let mut ic = Vec::new();
104        let mut cells = Vec::new();
105
106        for row in 0..((size.height() / size.line_height()) as usize) {
107            let mut row_vec = Vec::new();
108            for col in 0..((size.width() / size.cell_width()) as usize) {
109                let cell_char = rng.gen();
110                ic.push(IndexedCell {
111                    point: Point::new(Line(row as i32), Column(col)),
112                    cell: Cell {
113                        c: cell_char,
114                        ..Default::default()
115                    },
116                });
117                row_vec.push(cell_char)
118            }
119            cells.push(row_vec)
120        }
121
122        (
123            TerminalContent {
124                cells: ic,
125                size,
126                ..Default::default()
127            },
128            cells,
129        )
130    }
131}
132
133impl<'a> Drop for TerminalTestContext<'a> {
134    fn drop(&mut self) {
135        self.cx.set_condition_duration(None);
136    }
137}