Better tests

This commit is contained in:
Conrad Irwin 2023-08-14 15:03:16 -06:00
parent 19eb280351
commit 5b37cdcb04
2 changed files with 114 additions and 7 deletions

View file

@ -81,11 +81,13 @@ impl SelectionLayout {
let mut active_rows = map.prev_line_boundary(point_selection.start).1.row() let mut active_rows = map.prev_line_boundary(point_selection.start).1.row()
..map.next_line_boundary(point_selection.end).1.row(); ..map.next_line_boundary(point_selection.end).1.row();
// vim visual line mode
if line_mode { if line_mode {
let point_range = map.expand_to_line(point_selection.range()); let point_range = map.expand_to_line(point_selection.range());
range = point_range.start.to_display_point(map)..point_range.end.to_display_point(map); range = point_range.start.to_display_point(map)..point_range.end.to_display_point(map);
} }
// any vim visual mode (including line mode)
if cursor_shape == CursorShape::Block && !range.is_empty() && !selection.reversed { if cursor_shape == CursorShape::Block && !range.is_empty() && !selection.reversed {
if head.column() > 0 { if head.column() > 0 {
head = map.clip_point(DisplayPoint::new(head.row(), head.column() - 1), Bias::Left) head = map.clip_point(DisplayPoint::new(head.row(), head.column() - 1), Bias::Left)
@ -94,8 +96,8 @@ impl SelectionLayout {
DisplayPoint::new(head.row() - 1, map.line_len(head.row() - 1)), DisplayPoint::new(head.row() - 1, map.line_len(head.row() - 1)),
Bias::Left, Bias::Left,
); );
// updating range.end is a no-op unless you're cursor is
// updating range.end is a no-op unless you're on a multi-buffer divider // on the newline containing a multi-buffer divider
// in which case the clip_point may have moved the head up // in which case the clip_point may have moved the head up
// an additional row. // an additional row.
range.end = DisplayPoint::new(head.row() + 1, 0); range.end = DisplayPoint::new(head.row() + 1, 0);
@ -2996,7 +2998,7 @@ mod tests {
use language::language_settings; use language::language_settings;
use log::info; use log::info;
use std::{num::NonZeroU32, sync::Arc}; use std::{num::NonZeroU32, sync::Arc};
use util::test::sample_text; use util::test::{generate_marked_text, sample_text};
#[gpui::test] #[gpui::test]
fn test_layout_line_numbers(cx: &mut TestAppContext) { fn test_layout_line_numbers(cx: &mut TestAppContext) {
@ -3018,7 +3020,7 @@ mod tests {
} }
#[gpui::test] #[gpui::test]
fn test_vim_visual_selections(cx: &mut TestAppContext) { async fn test_vim_visual_selections(cx: &mut TestAppContext) {
init_test(cx, |_| {}); init_test(cx, |_| {});
let (_, editor) = cx.add_window(|cx| { let (_, editor) = cx.add_window(|cx| {
@ -3053,26 +3055,112 @@ mod tests {
let local_selections = &state.selections[0].1; let local_selections = &state.selections[0].1;
assert_eq!(local_selections.len(), 3); assert_eq!(local_selections.len(), 3);
// moves cursor back one line // moves cursor back one line
assert_eq!(local_selections[0].head, DisplayPoint::new(0, 6));
assert_eq!( assert_eq!(
local_selections[0].range, local_selections[0].range,
DisplayPoint::new(0, 0)..DisplayPoint::new(0, 6) DisplayPoint::new(0, 0)..DisplayPoint::new(1, 0)
); );
// moves cursor back one column // moves cursor back one column
assert_eq!( assert_eq!(
local_selections[1].range, local_selections[1].range,
DisplayPoint::new(3, 2)..DisplayPoint::new(3, 2) DisplayPoint::new(3, 2)..DisplayPoint::new(3, 3)
); );
assert_eq!(local_selections[1].head, DisplayPoint::new(3, 2));
// leaves cursor on the max point // leaves cursor on the max point
assert_eq!( assert_eq!(
local_selections[2].range, local_selections[2].range,
DisplayPoint::new(5, 6)..DisplayPoint::new(6, 0) DisplayPoint::new(5, 6)..DisplayPoint::new(6, 0)
); );
assert_eq!(local_selections[2].head, DisplayPoint::new(6, 0));
// active lines does not include 1 // active lines does not include 1 (even though the range of the selection does)
assert_eq!( assert_eq!(
state.active_rows.keys().cloned().collect::<Vec<u32>>(), state.active_rows.keys().cloned().collect::<Vec<u32>>(),
vec![0, 3, 5, 6] vec![0, 3, 5, 6]
); );
// multi-buffer support
// in DisplayPoint co-ordinates, this is what we're dealing with:
// 0: [[file
// 1: header]]
// 2: aaaaaa
// 3: bbbbbb
// 4: cccccc
// 5:
// 6: ...
// 7: ffffff
// 8: gggggg
// 9: hhhhhh
// 10:
// 11: [[file
// 12: header]]
// 13: bbbbbb
// 14: cccccc
// 15: dddddd
let (_, editor) = cx.add_window(|cx| {
let buffer = MultiBuffer::build_multi(
[
(
&(sample_text(8, 6, 'a') + "\n"),
vec![
Point::new(0, 0)..Point::new(3, 0),
Point::new(4, 0)..Point::new(7, 0),
],
),
(
&(sample_text(8, 6, 'a') + "\n"),
vec![Point::new(1, 0)..Point::new(3, 0)],
),
],
cx,
);
Editor::new(EditorMode::Full, buffer, None, None, cx)
});
let mut element = EditorElement::new(editor.read_with(cx, |editor, cx| editor.style(cx)));
let (_, state) = editor.update(cx, |editor, cx| {
editor.cursor_shape = CursorShape::Block;
editor.change_selections(None, cx, |s| {
s.select_display_ranges([
DisplayPoint::new(4, 0)..DisplayPoint::new(7, 0),
DisplayPoint::new(10, 0)..DisplayPoint::new(13, 0),
]);
});
let mut new_parents = Default::default();
let mut notify_views_if_parents_change = Default::default();
let mut layout_cx = LayoutContext::new(
cx,
&mut new_parents,
&mut notify_views_if_parents_change,
false,
);
element.layout(
SizeConstraint::new(vec2f(500., 500.), vec2f(500., 500.)),
editor,
&mut layout_cx,
)
});
assert_eq!(state.selections.len(), 1);
let local_selections = &state.selections[0].1;
assert_eq!(local_selections.len(), 2);
// moves cursor on excerpt boundary back a line
// and doesn't allow selection to bleed through
assert_eq!(
local_selections[0].range,
DisplayPoint::new(4, 0)..DisplayPoint::new(6, 0)
);
assert_eq!(local_selections[0].head, DisplayPoint::new(5, 0));
// moves cursor on buffer boundary back two lines
// and doesn't allow selection to bleed through
assert_eq!(
local_selections[1].range,
DisplayPoint::new(10, 0)..DisplayPoint::new(11, 0)
);
assert_eq!(local_selections[1].head, DisplayPoint::new(10, 0));
} }
#[gpui::test] #[gpui::test]

View file

@ -1565,6 +1565,25 @@ impl MultiBuffer {
cx.add_model(|cx| Self::singleton(buffer, cx)) cx.add_model(|cx| Self::singleton(buffer, cx))
} }
pub fn build_multi<const COUNT: usize>(
excerpts: [(&str, Vec<Range<Point>>); COUNT],
cx: &mut gpui::AppContext,
) -> ModelHandle<Self> {
let multi = cx.add_model(|_| Self::new(0));
for (text, ranges) in excerpts {
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx));
let excerpt_ranges = ranges.into_iter().map(|range| ExcerptRange {
context: range,
primary: None,
});
multi.update(cx, |multi, cx| {
multi.push_excerpts(buffer, excerpt_ranges, cx)
});
}
multi
}
pub fn build_from_buffer( pub fn build_from_buffer(
buffer: ModelHandle<Buffer>, buffer: ModelHandle<Buffer>,
cx: &mut gpui::AppContext, cx: &mut gpui::AppContext,