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.cx.add_window(|cx| {
 32            Workspace::new(
 33                Default::default(),
 34                0,
 35                project.clone(),
 36                |_, _| unimplemented!(),
 37                cx,
 38            )
 39        });
 40
 41        (project, workspace)
 42    }
 43
 44    ///Creates a worktree with 1 folder: /root{suffix}/
 45    pub async fn create_folder_wt(
 46        &mut self,
 47        project: ModelHandle<Project>,
 48        path: impl AsRef<Path>,
 49    ) -> (ModelHandle<Worktree>, Entry) {
 50        self.create_wt(project, true, path).await
 51    }
 52
 53    ///Creates a worktree with 1 file: /root{suffix}.txt
 54    pub async fn create_file_wt(
 55        &mut self,
 56        project: ModelHandle<Project>,
 57        path: impl AsRef<Path>,
 58    ) -> (ModelHandle<Worktree>, Entry) {
 59        self.create_wt(project, false, path).await
 60    }
 61
 62    async fn create_wt(
 63        &mut self,
 64        project: ModelHandle<Project>,
 65        is_dir: bool,
 66        path: impl AsRef<Path>,
 67    ) -> (ModelHandle<Worktree>, Entry) {
 68        let (wt, _) = project
 69            .update(self.cx, |project, cx| {
 70                project.find_or_create_local_worktree(path, true, cx)
 71            })
 72            .await
 73            .unwrap();
 74
 75        let entry = self
 76            .cx
 77            .update(|cx| {
 78                wt.update(cx, |wt, cx| {
 79                    wt.as_local()
 80                        .unwrap()
 81                        .create_entry(Path::new(""), is_dir, cx)
 82                })
 83            })
 84            .await
 85            .unwrap();
 86
 87        (wt, entry)
 88    }
 89
 90    pub fn insert_active_entry_for(
 91        &mut self,
 92        wt: ModelHandle<Worktree>,
 93        entry: Entry,
 94        project: ModelHandle<Project>,
 95    ) {
 96        self.cx.update(|cx| {
 97            let p = ProjectPath {
 98                worktree_id: wt.read(cx).id(),
 99                path: entry.path,
100            };
101            project.update(cx, |project, cx| project.set_active_path(Some(p), cx));
102        });
103    }
104
105    pub fn create_terminal_content(
106        size: TerminalSize,
107        rng: &mut ThreadRng,
108    ) -> (TerminalContent, Vec<Vec<char>>) {
109        let mut ic = Vec::new();
110        let mut cells = Vec::new();
111
112        for row in 0..((size.height() / size.line_height()) as usize) {
113            let mut row_vec = Vec::new();
114            for col in 0..((size.width() / size.cell_width()) as usize) {
115                let cell_char = rng.gen();
116                ic.push(IndexedCell {
117                    point: Point::new(Line(row as i32), Column(col)),
118                    cell: Cell {
119                        c: cell_char,
120                        ..Default::default()
121                    },
122                });
123                row_vec.push(cell_char)
124            }
125            cells.push(row_vec)
126        }
127
128        (
129            TerminalContent {
130                cells: ic,
131                size,
132                ..Default::default()
133            },
134            cells,
135        )
136    }
137}
138
139impl<'a> Drop for TerminalTestContext<'a> {
140    fn drop(&mut self) {
141        self.cx.set_condition_duration(None);
142    }
143}