256 lines · 8.1 KB · Rust
RawDownload
pub mod editor_lsp_test_context;pub mod editor_test_context; use std::{rc::Rc, sync::LazyLock}; pub use crate::rust_analyzer_ext::expand_macro_recursively;use crate::{    DisplayPoint, Editor, EditorMode, FoldPlaceholder, MultiBuffer,    display_map::{        Block, BlockPlacement, CustomBlockId, DisplayMap, DisplayRow, DisplaySnapshot,        ToDisplayPoint,    },};use collections::HashMap;use gpui::{    AppContext as _, Context, Entity, EntityId, Font, FontFeatures, FontStyle, FontWeight, Pixels,    VisualTestContext, Window, font, size,};use multi_buffer::ToPoint;use pretty_assertions::assert_eq;use project::{Project, project_settings::DiagnosticSeverity};use ui::{App, BorrowAppContext, px};use util::test::{marked_text_offsets, marked_text_ranges}; #[cfg(test)]#[ctor::ctor]fn init_logger() {    zlog::init_test();} pub fn test_font() -> Font {    static TEST_FONT: LazyLock<Font> = LazyLock::new(|| {        #[cfg(not(target_os = "windows"))]        {            font("Helvetica")        }         #[cfg(target_os = "windows")]        {            font("Courier New")        }    });     TEST_FONT.clone()} // Returns a snapshot from text containing '|' character markers with the markers removed, and DisplayPoints for each one.pub fn marked_display_snapshot(    text: &str,    cx: &mut gpui::App,) -> (DisplaySnapshot, Vec<DisplayPoint>) {    let (unmarked_text, markers) = marked_text_offsets(text);     let font = Font {        family: "Zed Plex Mono".into(),        features: FontFeatures::default(),        fallbacks: None,        weight: FontWeight::default(),        style: FontStyle::default(),    };    let font_size: Pixels = 14usize.into();     let buffer = MultiBuffer::build_simple(&unmarked_text, cx);    let display_map = cx.new(|cx| {        DisplayMap::new(            buffer,            font,            font_size,            None,            1,            1,            FoldPlaceholder::test(),            DiagnosticSeverity::Warning,            cx,        )    });    let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx));    let markers = markers        .into_iter()        .map(|offset| offset.to_display_point(&snapshot))        .collect();     (snapshot, markers)} pub fn select_ranges(    editor: &mut Editor,    marked_text: &str,    window: &mut Window,    cx: &mut Context<Editor>,) {    let (unmarked_text, text_ranges) = marked_text_ranges(marked_text, true);    assert_eq!(editor.text(cx), unmarked_text);    editor.change_selections(None, window, cx, |s| s.select_ranges(text_ranges));} #[track_caller]pub fn assert_text_with_selections(    editor: &mut Editor,    marked_text: &str,    cx: &mut Context<Editor>,) {    let (unmarked_text, text_ranges) = marked_text_ranges(marked_text, true);    assert_eq!(editor.text(cx), unmarked_text, "text doesn't match");    assert_eq!(        editor.selections.ranges(cx),        text_ranges,        "selections don't match",    );} // RA thinks this is dead code even though it is used in a whole lot of tests#[allow(dead_code)]#[cfg(any(test, feature = "test-support"))]pub(crate) fn build_editor(    buffer: Entity<MultiBuffer>,    window: &mut Window,    cx: &mut Context<Editor>,) -> Editor {    Editor::new(EditorMode::full(), buffer, None, window, cx)} pub(crate) fn build_editor_with_project(    project: Entity<Project>,    buffer: Entity<MultiBuffer>,    window: &mut Window,    cx: &mut Context<Editor>,) -> Editor {    Editor::new(EditorMode::full(), buffer, Some(project), window, cx)} #[derive(Default)]struct TestBlockContent(    HashMap<(EntityId, CustomBlockId), Rc<dyn Fn(&mut VisualTestContext) -> String>>,); impl gpui::Global for TestBlockContent {} pub fn set_block_content_for_tests(    editor: &Entity<Editor>,    id: CustomBlockId,    cx: &mut App,    f: impl Fn(&mut VisualTestContext) -> String + 'static,) {    cx.update_default_global::<TestBlockContent, _>(|bc, _| {        bc.0.insert((editor.entity_id(), id), Rc::new(f))    });} pub fn block_content_for_tests(    editor: &Entity<Editor>,    id: CustomBlockId,    cx: &mut VisualTestContext,) -> Option<String> {    let f = cx.update(|_, cx| {        cx.default_global::<TestBlockContent>()            .0            .get(&(editor.entity_id(), id))            .cloned()    })?;    Some(f(cx))} pub fn editor_content_with_blocks(editor: &Entity<Editor>, cx: &mut VisualTestContext) -> String {    cx.draw(        gpui::Point::default(),        size(px(3000.0), px(3000.0)),        |_, _| editor.clone(),    );    let (snapshot, mut lines, blocks) = editor.update_in(cx, |editor, window, cx| {        let snapshot = editor.snapshot(window, cx);        let text = editor.display_text(cx);        let lines = text.lines().map(|s| s.to_string()).collect::<Vec<String>>();        let blocks = snapshot            .blocks_in_range(DisplayRow(0)..snapshot.max_point().row())            .map(|(row, block)| (row, block.clone()))            .collect::<Vec<_>>();        (snapshot, lines, blocks)    });    for (row, block) in blocks {        match block {            Block::Custom(custom_block) => {                if let BlockPlacement::Near(x) = &custom_block.placement {                    if snapshot.intersects_fold(x.to_point(&snapshot.buffer_snapshot)) {                        continue;                    }                };                let content = block_content_for_tests(&editor, custom_block.id, cx)                    .expect("block content not found");                // 2: "related info 1 for diagnostic 0"                if let Some(height) = custom_block.height {                    if height == 0 {                        lines[row.0 as usize - 1].push_str(" § ");                        lines[row.0 as usize - 1].push_str(&content);                    } else {                        let block_lines = content.lines().collect::<Vec<_>>();                        assert_eq!(block_lines.len(), height as usize);                        lines[row.0 as usize].push_str("§ ");                        lines[row.0 as usize].push_str(block_lines[0].trim_end());                        for i in 1..height as usize {                            if row.0 as usize + i >= lines.len() {                                lines.push("".to_string());                            };                            lines[row.0 as usize + i].push_str("§ ");                            lines[row.0 as usize + i].push_str(block_lines[i].trim_end());                        }                    }                }            }            Block::FoldedBuffer {                first_excerpt,                height,            } => {                lines[row.0 as usize].push_str(&cx.update(|_, cx| {                    format!(                        "§ {}",                        first_excerpt                            .buffer                            .file()                            .unwrap()                            .file_name(cx)                            .to_string_lossy()                    )                }));                for row in row.0 + 1..row.0 + height {                    lines[row as usize].push_str("§ -----");                }            }            Block::ExcerptBoundary {                excerpt,                height,                starts_new_buffer,            } => {                if starts_new_buffer {                    lines[row.0 as usize].push_str(&cx.update(|_, cx| {                        format!(                            "§ {}",                            excerpt                                .buffer                                .file()                                .unwrap()                                .file_name(cx)                                .to_string_lossy()                        )                    }));                } else {                    lines[row.0 as usize].push_str("§ -----")                }                for row in row.0 + 1..row.0 + height {                    lines[row as usize].push_str("§ -----");                }            }        }    }    lines.join("\n")}