5043 lines · 158.4 KB · Rust
RawDownload
use super::*;use buffer_diff::{DiffHunkStatus, DiffHunkStatusKind};use gpui::{App, TestAppContext};use indoc::indoc;use language::{Buffer, Rope};use parking_lot::RwLock;use rand::prelude::*;use settings::SettingsStore;use std::env;use std::time::{Duration, Instant};use util::RandomCharIter;use util::rel_path::rel_path;use util::test::sample_text; #[ctor::ctor]fn init_logger() {    zlog::init_test();} #[gpui::test]fn test_empty_singleton(cx: &mut App) {    let buffer = cx.new(|cx| Buffer::local("", cx));    let buffer_id = buffer.read(cx).remote_id();    let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer.clone(), cx));    let snapshot = multibuffer.read(cx).snapshot(cx);    assert_eq!(snapshot.text(), "");    assert_eq!(        snapshot.row_infos(MultiBufferRow(0)).collect::<Vec<_>>(),        [RowInfo {            buffer_id: Some(buffer_id),            buffer_row: Some(0),            multibuffer_row: Some(MultiBufferRow(0)),            diff_status: None,            expand_info: None,            wrapped_buffer_row: None,        }]    );} #[gpui::test]fn test_singleton(cx: &mut App) {    let buffer = cx.new(|cx| Buffer::local(sample_text(6, 6, 'a'), cx));    let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer.clone(), cx));     let snapshot = multibuffer.read(cx).snapshot(cx);    assert_eq!(snapshot.text(), buffer.read(cx).text());     assert_eq!(        snapshot            .row_infos(MultiBufferRow(0))            .map(|info| info.buffer_row)            .collect::<Vec<_>>(),        (0..buffer.read(cx).row_count())            .map(Some)            .collect::<Vec<_>>()    );    assert_consistent_line_numbers(&snapshot);     buffer.update(cx, |buffer, cx| buffer.edit([(1..3, "XXX\n")], None, cx));    let snapshot = multibuffer.read(cx).snapshot(cx);     assert_eq!(snapshot.text(), buffer.read(cx).text());    assert_eq!(        snapshot            .row_infos(MultiBufferRow(0))            .map(|info| info.buffer_row)            .collect::<Vec<_>>(),        (0..buffer.read(cx).row_count())            .map(Some)            .collect::<Vec<_>>()    );    assert_consistent_line_numbers(&snapshot);} #[gpui::test]fn test_remote(cx: &mut App) {    let host_buffer = cx.new(|cx| Buffer::local("a", cx));    let guest_buffer = cx.new(|cx| {        let state = host_buffer.read(cx).to_proto(cx);        let ops = cx            .foreground_executor()            .block_on(host_buffer.read(cx).serialize_ops(None, cx));        let mut buffer =            Buffer::from_proto(ReplicaId::REMOTE_SERVER, Capability::ReadWrite, state, None)                .unwrap();        buffer.apply_ops(            ops.into_iter()                .map(|op| language::proto::deserialize_operation(op).unwrap()),            cx,        );        buffer    });    let multibuffer = cx.new(|cx| MultiBuffer::singleton(guest_buffer.clone(), cx));    let snapshot = multibuffer.read(cx).snapshot(cx);    assert_eq!(snapshot.text(), "a");     guest_buffer.update(cx, |buffer, cx| buffer.edit([(1..1, "b")], None, cx));    let snapshot = multibuffer.read(cx).snapshot(cx);    assert_eq!(snapshot.text(), "ab");     guest_buffer.update(cx, |buffer, cx| buffer.edit([(2..2, "c")], None, cx));    let snapshot = multibuffer.read(cx).snapshot(cx);    assert_eq!(snapshot.text(), "abc");} #[gpui::test]fn test_excerpt_boundaries_and_clipping(cx: &mut App) {    let buffer_1 = cx.new(|cx| Buffer::local(sample_text(6, 6, 'a'), cx));    let buffer_2 = cx.new(|cx| Buffer::local(sample_text(6, 6, 'g'), cx));    let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));     let events = Arc::new(RwLock::new(Vec::<Event>::new()));    multibuffer.update(cx, |_, cx| {        let events = events.clone();        cx.subscribe(&multibuffer, move |_, _, event, _| {            if let Event::Edited { .. } = event {                events.write().push(event.clone())            }        })        .detach();    });     let subscription = multibuffer.update(cx, |multibuffer, cx| {        let subscription = multibuffer.subscribe();        multibuffer.push_excerpts(            buffer_1.clone(),            [ExcerptRange::new(Point::new(1, 2)..Point::new(2, 5))],            cx,        );        assert_eq!(            subscription.consume().into_inner(),            [Edit {                old: MultiBufferOffset(0)..MultiBufferOffset(0),                new: MultiBufferOffset(0)..MultiBufferOffset(10)            }]        );         multibuffer.push_excerpts(            buffer_1.clone(),            [ExcerptRange::new(Point::new(3, 3)..Point::new(4, 4))],            cx,        );        multibuffer.push_excerpts(            buffer_2.clone(),            [ExcerptRange::new(Point::new(3, 1)..Point::new(3, 3))],            cx,        );        assert_eq!(            subscription.consume().into_inner(),            [Edit {                old: MultiBufferOffset(10)..MultiBufferOffset(10),                new: MultiBufferOffset(10)..MultiBufferOffset(22)            }]        );         subscription    });     // Adding excerpts emits an edited event.    assert_eq!(        events.read().as_slice(),        &[            Event::Edited {                edited_buffer: None,            },            Event::Edited {                edited_buffer: None,            },            Event::Edited {                edited_buffer: None,            }        ]    );     let snapshot = multibuffer.read(cx).snapshot(cx);    assert_eq!(        snapshot.text(),        indoc!(            "            bbbb            ccccc            ddd            eeee            jj"        ),    );    assert_eq!(        snapshot            .row_infos(MultiBufferRow(0))            .map(|info| info.buffer_row)            .collect::<Vec<_>>(),        [Some(1), Some(2), Some(3), Some(4), Some(3)]    );    assert_eq!(        snapshot            .row_infos(MultiBufferRow(2))            .map(|info| info.buffer_row)            .collect::<Vec<_>>(),        [Some(3), Some(4), Some(3)]    );    assert_eq!(        snapshot            .row_infos(MultiBufferRow(4))            .map(|info| info.buffer_row)            .collect::<Vec<_>>(),        [Some(3)]    );    assert!(        snapshot            .row_infos(MultiBufferRow(5))            .map(|info| info.buffer_row)            .collect::<Vec<_>>()            .is_empty()    );     assert_eq!(        boundaries_in_range(Point::new(0, 0)..Point::new(4, 2), &snapshot),        &[            (MultiBufferRow(0), "bbbb\nccccc".to_string(), true),            (MultiBufferRow(2), "ddd\neeee".to_string(), false),            (MultiBufferRow(4), "jj".to_string(), true),        ]    );    assert_eq!(        boundaries_in_range(Point::new(0, 0)..Point::new(2, 0), &snapshot),        &[(MultiBufferRow(0), "bbbb\nccccc".to_string(), true)]    );    assert_eq!(        boundaries_in_range(Point::new(1, 0)..Point::new(1, 5), &snapshot),        &[]    );    assert_eq!(        boundaries_in_range(Point::new(1, 0)..Point::new(2, 0), &snapshot),        &[]    );    assert_eq!(        boundaries_in_range(Point::new(1, 0)..Point::new(4, 0), &snapshot),        &[(MultiBufferRow(2), "ddd\neeee".to_string(), false)]    );    assert_eq!(        boundaries_in_range(Point::new(1, 0)..Point::new(4, 0), &snapshot),        &[(MultiBufferRow(2), "ddd\neeee".to_string(), false)]    );    assert_eq!(        boundaries_in_range(Point::new(2, 0)..Point::new(3, 0), &snapshot),        &[(MultiBufferRow(2), "ddd\neeee".to_string(), false)]    );    assert_eq!(        boundaries_in_range(Point::new(4, 0)..Point::new(4, 2), &snapshot),        &[(MultiBufferRow(4), "jj".to_string(), true)]    );    assert_eq!(        boundaries_in_range(Point::new(4, 2)..Point::new(4, 2), &snapshot),        &[]    );     buffer_1.update(cx, |buffer, cx| {        let text = "\n";        buffer.edit(            [                (Point::new(0, 0)..Point::new(0, 0), text),                (Point::new(2, 1)..Point::new(2, 3), text),            ],            None,            cx,        );    });     let snapshot = multibuffer.read(cx).snapshot(cx);    assert_eq!(        snapshot.text(),        concat!(            "bbbb\n", // Preserve newlines            "c\n",    //            "cc\n",   //            "ddd\n",  //            "eeee\n", //            "jj"      //        )    );     assert_eq!(        subscription.consume().into_inner(),        [Edit {            old: MultiBufferOffset(6)..MultiBufferOffset(8),            new: MultiBufferOffset(6)..MultiBufferOffset(7)        }]    );     let snapshot = multibuffer.read(cx).snapshot(cx);    assert_eq!(        snapshot.clip_point(Point::new(0, 5), Bias::Left),        Point::new(0, 4)    );    assert_eq!(        snapshot.clip_point(Point::new(0, 5), Bias::Right),        Point::new(0, 4)    );    assert_eq!(        snapshot.clip_point(Point::new(5, 1), Bias::Right),        Point::new(5, 1)    );    assert_eq!(        snapshot.clip_point(Point::new(5, 2), Bias::Right),        Point::new(5, 2)    );    assert_eq!(        snapshot.clip_point(Point::new(5, 3), Bias::Right),        Point::new(5, 2)    );     let snapshot = multibuffer.update(cx, |multibuffer, cx| {        let (buffer_2_excerpt_id, _) =            multibuffer.excerpts_for_buffer(buffer_2.read(cx).remote_id(), cx)[0].clone();        multibuffer.remove_excerpts([buffer_2_excerpt_id], cx);        multibuffer.snapshot(cx)    });     assert_eq!(        snapshot.text(),        concat!(            "bbbb\n", // Preserve newlines            "c\n",    //            "cc\n",   //            "ddd\n",  //            "eeee",   //        )    );     fn boundaries_in_range(        range: Range<Point>,        snapshot: &MultiBufferSnapshot,    ) -> Vec<(MultiBufferRow, String, bool)> {        snapshot            .excerpt_boundaries_in_range(range)            .map(|boundary| {                let starts_new_buffer = boundary.starts_new_buffer();                (                    boundary.row,                    boundary                        .next                        .buffer                        .text_for_range(boundary.next.range.context)                        .collect::<String>(),                    starts_new_buffer,                )            })            .collect::<Vec<_>>()    }} #[gpui::test]async fn test_diff_boundary_anchors(cx: &mut TestAppContext) {    let base_text = "one\ntwo\nthree\n";    let text = "one\nthree\n";    let buffer = cx.new(|cx| Buffer::local(text, cx));    let diff = cx        .new(|cx| BufferDiff::new_with_base_text(base_text, &buffer.read(cx).text_snapshot(), cx));    let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));    multibuffer.update(cx, |multibuffer, cx| multibuffer.add_diff(diff, cx));     let (before, after) = multibuffer.update(cx, |multibuffer, cx| {        let before = multibuffer.snapshot(cx).anchor_before(Point::new(1, 0));        let after = multibuffer.snapshot(cx).anchor_after(Point::new(1, 0));        multibuffer.set_all_diff_hunks_expanded(cx);        (before, after)    });    cx.run_until_parked();     let snapshot = multibuffer.read_with(cx, |multibuffer, cx| multibuffer.snapshot(cx));    let actual_text = snapshot.text();    let actual_row_infos = snapshot.row_infos(MultiBufferRow(0)).collect::<Vec<_>>();    let actual_diff = format_diff(&actual_text, &actual_row_infos, &Default::default(), None);    pretty_assertions::assert_eq!(        actual_diff,        indoc! {            "  one             - two               three             "        },    );     multibuffer.update(cx, |multibuffer, cx| {        let snapshot = multibuffer.snapshot(cx);        assert_eq!(before.to_point(&snapshot), Point::new(1, 0));        assert_eq!(after.to_point(&snapshot), Point::new(2, 0));        assert_eq!(            vec![Point::new(1, 0), Point::new(2, 0),],            snapshot.summaries_for_anchors::<Point, _>(&[before, after]),        )    })} #[gpui::test]async fn test_diff_hunks_in_range(cx: &mut TestAppContext) {    let base_text = "one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\n";    let text = "one\nfour\nseven\n";    let buffer = cx.new(|cx| Buffer::local(text, cx));    let diff = cx        .new(|cx| BufferDiff::new_with_base_text(base_text, &buffer.read(cx).text_snapshot(), cx));    let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));    let (mut snapshot, mut subscription) = multibuffer.update(cx, |multibuffer, cx| {        (multibuffer.snapshot(cx), multibuffer.subscribe())    });     multibuffer.update(cx, |multibuffer, cx| {        multibuffer.add_diff(diff, cx);        multibuffer.expand_diff_hunks(vec![Anchor::min()..Anchor::max()], cx);    });     assert_new_snapshot(        &multibuffer,        &mut snapshot,        &mut subscription,        cx,        indoc! {            "  one             - two             - three               four             - five             - six               seven             - eight            "        },    );     assert_eq!(        snapshot            .diff_hunks_in_range(Point::new(1, 0)..Point::MAX)            .map(|hunk| hunk.row_range.start.0..hunk.row_range.end.0)            .collect::<Vec<_>>(),        vec![1..3, 4..6, 7..8]    );     assert_eq!(snapshot.diff_hunk_before(Point::new(1, 1)), None,);    assert_eq!(        snapshot.diff_hunk_before(Point::new(7, 0)),        Some(MultiBufferRow(4))    );    assert_eq!(        snapshot.diff_hunk_before(Point::new(4, 0)),        Some(MultiBufferRow(1))    );     multibuffer.update(cx, |multibuffer, cx| {        multibuffer.collapse_diff_hunks(vec![Anchor::min()..Anchor::max()], cx);    });     assert_new_snapshot(        &multibuffer,        &mut snapshot,        &mut subscription,        cx,        indoc! {            "            one            four            seven            "        },    );     assert_eq!(        snapshot.diff_hunk_before(Point::new(2, 0)),        Some(MultiBufferRow(1)),    );    assert_eq!(        snapshot.diff_hunk_before(Point::new(4, 0)),        Some(MultiBufferRow(2))    );} #[gpui::test]async fn test_diff_hunks_in_range_query_starting_at_added_row(cx: &mut TestAppContext) {    let base_text = "one\ntwo\nthree\n";    let text = "one\nTWO\nthree\n";    let buffer = cx.new(|cx| Buffer::local(text, cx));    let diff = cx        .new(|cx| BufferDiff::new_with_base_text(base_text, &buffer.read(cx).text_snapshot(), cx));    let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));    let (mut snapshot, mut subscription) = multibuffer.update(cx, |multibuffer, cx| {        (multibuffer.snapshot(cx), multibuffer.subscribe())    });     multibuffer.update(cx, |multibuffer, cx| {        multibuffer.add_diff(diff, cx);        multibuffer.expand_diff_hunks(vec![Anchor::min()..Anchor::max()], cx);    });     assert_new_snapshot(        &multibuffer,        &mut snapshot,        &mut subscription,        cx,        indoc! {            "  one             - two

Lines 1–500 of 5043.