Add simulate_window_resize.

Fixes up tests for movement in editor/scrolling.

Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
Piotr Osiewicz 2023-12-04 17:27:48 +01:00
parent 68d309e79c
commit b5924d6b11
8 changed files with 399 additions and 334 deletions

View file

@ -8243,6 +8243,11 @@ impl Editor {
self.style = Some(style);
}
#[cfg(any(test, feature = "test-support"))]
pub fn style(&self) -> Option<&EditorStyle> {
self.style.as_ref()
}
pub fn set_wrap_width(&self, width: Option<Pixels>, cx: &mut AppContext) -> bool {
self.display_map
.update(cx, |map, cx| map.set_wrap_width(width, cx))

View file

@ -1283,357 +1283,376 @@ fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) {
}
//todo!(simulate_resize)
// #[gpui::test]
// async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut gpui::TestAppContext) {
// init_test(cx, |_| {});
// let mut cx = EditorTestContext::new(cx).await;
#[gpui::test]
async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
// let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
// let window = cx.window;
// window.simulate_resize(gpui::Point::new(100., 4. * line_height), &mut cx);
let line_height = cx.editor(|editor, cx| {
editor
.style()
.unwrap()
.text
.line_height_in_pixels(cx.rem_size())
});
cx.simulate_window_resize(cx.window, size(px(100.), 4. * line_height));
// cx.set_state(
// &r#"ˇone
// two
cx.set_state(
&r#"ˇone
two
// three
// fourˇ
// five
three
fourˇ
five
// six"#
// .unindent(),
// );
six"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_to_end_of_paragraph(&MoveToEndOfParagraph, cx));
// cx.assert_editor_state(
// &r#"one
// two
// ˇ
// three
// four
// five
// ˇ
// six"#
// .unindent(),
// );
cx.update_editor(|editor, cx| editor.move_to_end_of_paragraph(&MoveToEndOfParagraph, cx));
cx.assert_editor_state(
&r#"one
two
ˇ
three
four
five
ˇ
six"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_to_end_of_paragraph(&MoveToEndOfParagraph, cx));
// cx.assert_editor_state(
// &r#"one
// two
cx.update_editor(|editor, cx| editor.move_to_end_of_paragraph(&MoveToEndOfParagraph, cx));
cx.assert_editor_state(
&r#"one
two
// three
// four
// five
// ˇ
// sixˇ"#
// .unindent(),
// );
three
four
five
ˇ
sixˇ"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_to_end_of_paragraph(&MoveToEndOfParagraph, cx));
// cx.assert_editor_state(
// &r#"one
// two
cx.update_editor(|editor, cx| editor.move_to_end_of_paragraph(&MoveToEndOfParagraph, cx));
cx.assert_editor_state(
&r#"one
two
// three
// four
// five
three
four
five
// sixˇ"#
// .unindent(),
// );
sixˇ"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_to_start_of_paragraph(&MoveToStartOfParagraph, cx));
// cx.assert_editor_state(
// &r#"one
// two
cx.update_editor(|editor, cx| editor.move_to_start_of_paragraph(&MoveToStartOfParagraph, cx));
cx.assert_editor_state(
&r#"one
two
// three
// four
// five
// ˇ
// six"#
// .unindent(),
// );
three
four
five
ˇ
six"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_to_start_of_paragraph(&MoveToStartOfParagraph, cx));
// cx.assert_editor_state(
// &r#"one
// two
// ˇ
// three
// four
// five
cx.update_editor(|editor, cx| editor.move_to_start_of_paragraph(&MoveToStartOfParagraph, cx));
cx.assert_editor_state(
&r#"one
two
ˇ
three
four
five
// six"#
// .unindent(),
// );
six"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_to_start_of_paragraph(&MoveToStartOfParagraph, cx));
// cx.assert_editor_state(
// &r#"ˇone
// two
cx.update_editor(|editor, cx| editor.move_to_start_of_paragraph(&MoveToStartOfParagraph, cx));
cx.assert_editor_state(
&r#"ˇone
two
// three
// four
// five
three
four
five
// six"#
// .unindent(),
// );
// }
six"#
.unindent(),
);
}
// #[gpui::test]
// async fn test_scroll_page_up_page_down(cx: &mut gpui::TestAppContext) {
// init_test(cx, |_| {});
// let mut cx = EditorTestContext::new(cx).await;
// let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
// let window = cx.window;
// window.simulate_resize(Point::new(1000., 4. * line_height + 0.5), &mut cx);
#[gpui::test]
async fn test_scroll_page_up_page_down(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
let line_height = cx.editor(|editor, cx| {
editor
.style()
.unwrap()
.text
.line_height_in_pixels(cx.rem_size())
});
let window = cx.window;
cx.simulate_window_resize(window, size(px(1000.), 4. * line_height + px(0.5)));
// cx.set_state(
// &r#"ˇone
// two
// three
// four
// five
// six
// seven
// eight
// nine
// ten
// "#,
// );
cx.set_state(
&r#"ˇone
two
three
four
five
six
seven
eight
nine
ten
"#,
);
// cx.update_editor(|editor, cx| {
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 0.)
// );
// editor.scroll_screen(&ScrollAmount::Page(1.), cx);
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 3.)
// );
// editor.scroll_screen(&ScrollAmount::Page(1.), cx);
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 6.)
// );
// editor.scroll_screen(&ScrollAmount::Page(-1.), cx);
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 3.)
// );
cx.update_editor(|editor, cx| {
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 0.)
);
editor.scroll_screen(&ScrollAmount::Page(1.), cx);
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 3.)
);
editor.scroll_screen(&ScrollAmount::Page(1.), cx);
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 6.)
);
editor.scroll_screen(&ScrollAmount::Page(-1.), cx);
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 3.)
);
// editor.scroll_screen(&ScrollAmount::Page(-0.5), cx);
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 1.)
// );
// editor.scroll_screen(&ScrollAmount::Page(0.5), cx);
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 3.)
// );
// });
// }
editor.scroll_screen(&ScrollAmount::Page(-0.5), cx);
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 1.)
);
editor.scroll_screen(&ScrollAmount::Page(0.5), cx);
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 3.)
);
});
}
// #[gpui::test]
// async fn test_autoscroll(cx: &mut gpui::TestAppContext) {
// init_test(cx, |_| {});
// let mut cx = EditorTestContext::new(cx).await;
#[gpui::test]
async fn test_autoscroll(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
// let line_height = cx.update_editor(|editor, cx| {
// editor.set_vertical_scroll_margin(2, cx);
// editor.style(cx).text.line_height(cx.font_cache())
// });
let line_height = cx.update_editor(|editor, cx| {
editor.set_vertical_scroll_margin(2, cx);
editor
.style()
.unwrap()
.text
.line_height_in_pixels(cx.rem_size())
});
let window = cx.window;
cx.simulate_window_resize(window, size(px(1000.), 6. * line_height));
// let window = cx.window;
// window.simulate_resize(gpui::Point::new(1000., 6.0 * line_height), &mut cx);
cx.set_state(
&r#"ˇone
two
three
four
five
six
seven
eight
nine
ten
"#,
);
cx.update_editor(|editor, cx| {
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 0.0)
);
});
// cx.set_state(
// &r#"ˇone
// two
// three
// four
// five
// six
// seven
// eight
// nine
// ten
// "#,
// );
// cx.update_editor(|editor, cx| {
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 0.0)
// );
// });
// Add a cursor below the visible area. Since both cursors cannot fit
// on screen, the editor autoscrolls to reveal the newest cursor, and
// allows the vertical scroll margin below that cursor.
cx.update_editor(|editor, cx| {
editor.change_selections(Some(Autoscroll::fit()), cx, |selections| {
selections.select_ranges([
Point::new(0, 0)..Point::new(0, 0),
Point::new(6, 0)..Point::new(6, 0),
]);
})
});
cx.update_editor(|editor, cx| {
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 3.0)
);
});
// // Add a cursor below the visible area. Since both cursors cannot fit
// // on screen, the editor autoscrolls to reveal the newest cursor, and
// // allows the vertical scroll margin below that cursor.
// cx.update_editor(|editor, cx| {
// editor.change_selections(Some(Autoscroll::fit()), cx, |selections| {
// selections.select_ranges([
// Point::new(0, 0)..Point::new(0, 0),
// Point::new(6, 0)..Point::new(6, 0),
// ]);
// })
// });
// cx.update_editor(|editor, cx| {
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 3.0)
// );
// });
// Move down. The editor cursor scrolls down to track the newest cursor.
cx.update_editor(|editor, cx| {
editor.move_down(&Default::default(), cx);
});
cx.update_editor(|editor, cx| {
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 4.0)
);
});
// // Move down. The editor cursor scrolls down to track the newest cursor.
// cx.update_editor(|editor, cx| {
// editor.move_down(&Default::default(), cx);
// });
// cx.update_editor(|editor, cx| {
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 4.0)
// );
// });
// Add a cursor above the visible area. Since both cursors fit on screen,
// the editor scrolls to show both.
cx.update_editor(|editor, cx| {
editor.change_selections(Some(Autoscroll::fit()), cx, |selections| {
selections.select_ranges([
Point::new(1, 0)..Point::new(1, 0),
Point::new(6, 0)..Point::new(6, 0),
]);
})
});
cx.update_editor(|editor, cx| {
assert_eq!(
editor.snapshot(cx).scroll_position(),
gpui::Point::new(0., 1.0)
);
});
}
// // Add a cursor above the visible area. Since both cursors fit on screen,
// // the editor scrolls to show both.
// cx.update_editor(|editor, cx| {
// editor.change_selections(Some(Autoscroll::fit()), cx, |selections| {
// selections.select_ranges([
// Point::new(1, 0)..Point::new(1, 0),
// Point::new(6, 0)..Point::new(6, 0),
// ]);
// })
// });
// cx.update_editor(|editor, cx| {
// assert_eq!(
// editor.snapshot(cx).scroll_position(),
// gpui::Point::new(0., 1.0)
// );
// });
// }
#[gpui::test]
async fn test_move_page_up_page_down(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
// #[gpui::test]
// async fn test_move_page_up_page_down(cx: &mut gpui::TestAppContext) {
// init_test(cx, |_| {});
// let mut cx = EditorTestContext::new(cx).await;
let line_height = cx.editor(|editor, cx| {
editor
.style()
.unwrap()
.text
.line_height_in_pixels(cx.rem_size())
});
let window = cx.window;
cx.simulate_window_resize(window, size(px(100.), 4. * line_height));
cx.set_state(
&r#"
ˇone
two
threeˇ
four
five
six
seven
eight
nine
ten
"#
.unindent(),
);
// let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
// let window = cx.window;
// window.simulate_resize(gpui::Point::new(100., 4. * line_height), &mut cx);
cx.update_editor(|editor, cx| editor.move_page_down(&MovePageDown::default(), cx));
cx.assert_editor_state(
&r#"
one
two
three
ˇfour
five
sixˇ
seven
eight
nine
ten
"#
.unindent(),
);
// cx.set_state(
// &r#"
// ˇone
// two
// threeˇ
// four
// five
// six
// seven
// eight
// nine
// ten
// "#
// .unindent(),
// );
cx.update_editor(|editor, cx| editor.move_page_down(&MovePageDown::default(), cx));
cx.assert_editor_state(
&r#"
one
two
three
four
five
six
ˇseven
eight
nineˇ
ten
"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_page_down(&MovePageDown::default(), cx));
// cx.assert_editor_state(
// &r#"
// one
// two
// three
// ˇfour
// five
// sixˇ
// seven
// eight
// nine
// ten
// "#
// .unindent(),
// );
cx.update_editor(|editor, cx| editor.move_page_up(&MovePageUp::default(), cx));
cx.assert_editor_state(
&r#"
one
two
three
ˇfour
five
sixˇ
seven
eight
nine
ten
"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_page_down(&MovePageDown::default(), cx));
// cx.assert_editor_state(
// &r#"
// one
// two
// three
// four
// five
// six
// ˇseven
// eight
// nineˇ
// ten
// "#
// .unindent(),
// );
cx.update_editor(|editor, cx| editor.move_page_up(&MovePageUp::default(), cx));
cx.assert_editor_state(
&r#"
ˇone
two
threeˇ
four
five
six
seven
eight
nine
ten
"#
.unindent(),
);
// cx.update_editor(|editor, cx| editor.move_page_up(&MovePageUp::default(), cx));
// cx.assert_editor_state(
// &r#"
// one
// two
// three
// ˇfour
// five
// sixˇ
// seven
// eight
// nine
// ten
// "#
// .unindent(),
// );
// cx.update_editor(|editor, cx| editor.move_page_up(&MovePageUp::default(), cx));
// cx.assert_editor_state(
// &r#"
// ˇone
// two
// threeˇ
// four
// five
// six
// seven
// eight
// nine
// ten
// "#
// .unindent(),
// );
// // Test select collapsing
// cx.update_editor(|editor, cx| {
// editor.move_page_down(&MovePageDown::default(), cx);
// editor.move_page_down(&MovePageDown::default(), cx);
// editor.move_page_down(&MovePageDown::default(), cx);
// });
// cx.assert_editor_state(
// &r#"
// one
// two
// three
// four
// five
// six
// seven
// eight
// nine
// ˇten
// ˇ"#
// .unindent(),
// );
// }
// Test select collapsing
cx.update_editor(|editor, cx| {
editor.move_page_down(&MovePageDown::default(), cx);
editor.move_page_down(&MovePageDown::default(), cx);
editor.move_page_down(&MovePageDown::default(), cx);
});
cx.assert_editor_state(
&r#"
one
two
three
four
five
six
seven
eight
nine
ˇten
ˇ"#
.unindent(),
);
}
#[gpui::test]
async fn test_delete_to_beginning_of_line(cx: &mut gpui::TestAppContext) {

View file

@ -88,7 +88,7 @@ pub fn diff_hunk_to_display(hunk: DiffHunk<u32>, snapshot: &DisplaySnapshot) ->
}
}
#[cfg(any(test, feature = "test_support"))]
#[cfg(any(test, feature = "test-support"))]
mod tests {
use crate::editor_tests::init_test;
use crate::Point;

View file

@ -1,13 +1,13 @@
use crate::{
div, Action, AnyView, AnyWindowHandle, AppCell, AppContext, AsyncAppContext,
BackgroundExecutor, Context, Div, Entity, EventEmitter, ForegroundExecutor, InputEvent,
KeyDownEvent, Keystroke, Model, ModelContext, Render, Result, Task, TestDispatcher,
TestPlatform, TestWindow, TestWindowHandlers, View, ViewContext, VisualContext, WindowContext,
WindowHandle, WindowOptions,
BackgroundExecutor, Bounds, Context, Div, Entity, EventEmitter, ForegroundExecutor, InputEvent,
KeyDownEvent, Keystroke, Model, ModelContext, Pixels, PlatformWindow, Point, Render, Result,
Size, Task, TestDispatcher, TestPlatform, TestWindow, TestWindowHandlers, View, ViewContext,
VisualContext, WindowBounds, WindowContext, WindowHandle, WindowOptions,
};
use anyhow::{anyhow, bail};
use futures::{Stream, StreamExt};
use std::{future::Future, ops::Deref, rc::Rc, sync::Arc, time::Duration};
use std::{future::Future, mem, ops::Deref, rc::Rc, sync::Arc, time::Duration};
#[derive(Clone)]
pub struct TestAppContext {
@ -170,6 +170,45 @@ impl TestAppContext {
self.test_platform.has_pending_prompt()
}
pub fn simulate_window_resize(&self, window_handle: AnyWindowHandle, size: Size<Pixels>) {
let (mut handlers, scale_factor) = self
.app
.borrow_mut()
.update_window(window_handle, |_, cx| {
let platform_window = cx.window.platform_window.as_test().unwrap();
let scale_factor = platform_window.scale_factor();
match &mut platform_window.bounds {
WindowBounds::Fullscreen | WindowBounds::Maximized => {
platform_window.bounds = WindowBounds::Fixed(Bounds {
origin: Point::default(),
size: size.map(|pixels| f64::from(pixels).into()),
});
}
WindowBounds::Fixed(bounds) => {
bounds.size = size.map(|pixels| f64::from(pixels).into());
}
}
(
mem::take(&mut platform_window.handlers.lock().resize),
scale_factor,
)
})
.unwrap();
for handler in &mut handlers {
handler(size, scale_factor);
}
self.app
.borrow_mut()
.update_window(window_handle, |_, cx| {
let platform_window = cx.window.platform_window.as_test().unwrap();
platform_window.handlers.lock().resize = handlers;
})
.unwrap();
}
pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>
where
Fut: Future<Output = R> + 'static,

View file

@ -206,13 +206,14 @@ impl BackgroundExecutor {
return Err(future);
}
let max_ticks = if cfg!(any(test, feature = "test-support")) {
self.dispatcher
.as_test()
.map_or(usize::MAX, |dispatcher| dispatcher.gen_block_on_ticks())
} else {
usize::MAX
};
#[cfg(any(test, feature = "test-support"))]
let max_ticks = self
.dispatcher
.as_test()
.map_or(usize::MAX, |dispatcher| dispatcher.gen_block_on_ticks());
#[cfg(not(any(test, feature = "test-support")))]
let max_ticks = usize::MAX;
let mut timer = self.timer(duration).fuse();
let timeout = async {

View file

@ -160,7 +160,7 @@ pub trait PlatformWindow {
fn sprite_atlas(&self) -> Arc<dyn PlatformAtlas>;
#[cfg(any(test, feature = "test-support"))]
fn as_test(&self) -> Option<&TestWindow> {
fn as_test(&mut self) -> Option<&mut TestWindow> {
None
}
}

View file

@ -19,7 +19,7 @@ pub(crate) struct TestWindowHandlers {
}
pub struct TestWindow {
bounds: WindowBounds,
pub(crate) bounds: WindowBounds,
current_scene: Mutex<Option<Scene>>,
display: Rc<dyn PlatformDisplay>,
pub(crate) window_title: Option<String>,
@ -170,7 +170,7 @@ impl PlatformWindow for TestWindow {
self.sprite_atlas.clone()
}
fn as_test(&self) -> Option<&TestWindow> {
fn as_test(&mut self) -> Option<&mut TestWindow> {
Some(self)
}
}

View file

@ -208,8 +208,9 @@ impl TextStyle {
}
}
/// Returns the rounded line height in pixels.
pub fn line_height_in_pixels(&self, rem_size: Pixels) -> Pixels {
self.line_height.to_pixels(self.font_size, rem_size)
self.line_height.to_pixels(self.font_size, rem_size).round()
}
pub fn to_run(&self, len: usize) -> TextRun {