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