Leaky, but better, test abstraction

This commit is contained in:
Conrad Irwin 2023-11-15 14:00:46 -07:00
parent 19c0b390d2
commit 0a51784dd0
4 changed files with 54 additions and 77 deletions

View File

@ -385,8 +385,7 @@ mod tests {
let app_state = init_test(cx);
let project = Project::test(app_state.fs.clone(), [], cx).await;
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx));
let cx = &mut cx;
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx));
let editor = cx.build_view(|cx| {
let mut editor = Editor::single_line(cx);
@ -417,7 +416,7 @@ mod tests {
assert!(is_sorted(&palette.delegate.commands));
});
cx.simulate_keystrokes("b c k s p");
cx.simulate_input("bcksp");
palette.update(cx, |palette, _| {
assert_eq!(palette.delegate.matches[0].string, "editor: backspace");
@ -439,7 +438,7 @@ mod tests {
});
cx.simulate_keystrokes("cmd-shift-p");
cx.simulate_keystrokes("b c k s p");
cx.simulate_input("bcksp");
let palette = workspace.update(cx, |workspace, cx| {
workspace

View File

@ -3851,12 +3851,12 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
view.condition::<crate::Event>(&cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
.await;
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
@ -3867,7 +3867,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| { view.selections.display_ranges(cx) }),
view.update(cx, |view, cx| { view.selections.display_ranges(cx) }),
&[
DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27),
DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
@ -3875,50 +3875,50 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
]
);
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| view.selections.display_ranges(cx)),
view.update(cx, |view, cx| view.selections.display_ranges(cx)),
&[
DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0),
]
);
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| view.selections.display_ranges(cx)),
view.update(cx, |view, cx| view.selections.display_ranges(cx)),
&[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)]
);
// Trying to expand the selected syntax node one more time has no effect.
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| view.selections.display_ranges(cx)),
view.update(cx, |view, cx| view.selections.display_ranges(cx)),
&[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)]
);
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| view.selections.display_ranges(cx)),
view.update(cx, |view, cx| view.selections.display_ranges(cx)),
&[
DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0),
]
);
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| view.selections.display_ranges(cx)),
view.update(cx, |view, cx| view.selections.display_ranges(cx)),
&[
DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27),
DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
@ -3926,11 +3926,11 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
]
);
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| view.selections.display_ranges(cx)),
view.update(cx, |view, cx| view.selections.display_ranges(cx)),
&[
DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
@ -3939,11 +3939,11 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
);
// Trying to shrink the selected syntax node one more time has no effect.
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| view.selections.display_ranges(cx)),
view.update(cx, |view, cx| view.selections.display_ranges(cx)),
&[
DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
@ -3953,7 +3953,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
// Ensure that we keep expanding the selection if the larger selection starts or ends within
// a fold.
view.update(&mut cx, |view, cx| {
view.update(cx, |view, cx| {
view.fold_ranges(
vec![
Point::new(0, 21)..Point::new(0, 24),
@ -3965,7 +3965,7 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
});
assert_eq!(
view.update(&mut cx, |view, cx| view.selections.display_ranges(cx)),
view.update(cx, |view, cx| view.selections.display_ranges(cx)),
&[
DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
@ -4017,8 +4017,7 @@ async fn test_autoindent_selections(cx: &mut gpui::TestAppContext) {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let cx = &mut cx;
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor
.condition::<crate::Event>(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx))
.await;
@ -4583,8 +4582,7 @@ async fn test_surround_with_pair(cx: &mut gpui::TestAppContext) {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let cx = &mut cx;
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
view.condition::<crate::Event>(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
.await;
@ -4734,8 +4732,7 @@ async fn test_delete_autoclose_pair(cx: &mut gpui::TestAppContext) {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let cx = &mut cx;
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor
.condition::<crate::Event>(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
.await;
@ -4957,8 +4954,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
let fake_server = fake_servers.next().await.unwrap();
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let cx = &mut cx;
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
assert!(cx.read(|cx| editor.is_dirty(cx)));
@ -5077,8 +5073,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
let fake_server = fake_servers.next().await.unwrap();
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let cx = &mut cx;
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
assert!(cx.read(|cx| editor.is_dirty(cx)));
@ -5205,8 +5200,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
let fake_server = fake_servers.next().await.unwrap();
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let cx = &mut cx;
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
let format = editor
@ -5993,8 +5987,7 @@ fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) {
multibuffer
});
let (view, mut cx) = cx.add_window_view(|cx| build_editor(multibuffer, cx));
let cx = &mut cx;
let (view, cx) = cx.add_window_view(|cx| build_editor(multibuffer, cx));
view.update(cx, |view, cx| {
assert_eq!(view.text(cx), "aaaa\nbbbb");
view.change_selections(None, cx, |s| {
@ -6064,8 +6057,7 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
multibuffer
});
let (view, mut cx) = cx.add_window_view(|cx| build_editor(multibuffer, cx));
let cx = &mut cx;
let (view, cx) = cx.add_window_view(|cx| build_editor(multibuffer, cx));
view.update(cx, |view, cx| {
let (expected_text, selection_ranges) = marked_text_ranges(
indoc! {"
@ -6302,8 +6294,7 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let cx = &mut cx;
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
view.condition::<crate::Event>(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
.await;
@ -8112,8 +8103,7 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
let buffer_text = "one\ntwo\nthree\n";
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, mut cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
let cx = &mut cx;
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor.update(cx, |editor, cx| editor.set_text(buffer_text, cx));
editor

View File

@ -775,8 +775,7 @@ mod tests {
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
let (picker, workspace, mut cx) = build_find_picker(project, cx);
let cx = &mut cx;
let (picker, workspace, cx) = build_find_picker(project, cx);
cx.simulate_input("bna");
@ -815,8 +814,7 @@ mod tests {
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
let (picker, workspace, mut cx) = build_find_picker(project, cx);
let cx = &mut cx;
let (picker, workspace, cx) = build_find_picker(project, cx);
let file_query = &first_file_name[..3];
let file_row = 1;
@ -891,8 +889,7 @@ mod tests {
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
let (picker, workspace, mut cx) = build_find_picker(project, cx);
let cx = &mut cx;
let (picker, workspace, cx) = build_find_picker(project, cx);
let file_query = &first_file_name[..3];
let file_row = 200;
@ -967,8 +964,7 @@ mod tests {
let project = Project::test(app_state.fs.clone(), ["/dir".as_ref()], cx).await;
let (picker, _, mut cx) = build_find_picker(project, cx);
let cx = &mut cx;
let (picker, _, cx) = build_find_picker(project, cx);
let query = test_path_like("hi");
picker
@ -1055,8 +1051,7 @@ mod tests {
)
.await;
let (picker, _, mut cx) = build_find_picker(project, cx);
let cx = &mut cx;
let (picker, _, cx) = build_find_picker(project, cx);
picker
.update(cx, |picker, cx| {
@ -1082,8 +1077,7 @@ mod tests {
)
.await;
let (picker, _, mut cx) = build_find_picker(project, cx);
let cx = &mut cx;
let (picker, _, cx) = build_find_picker(project, cx);
// Even though there is only one worktree, that worktree's filename
// is included in the matching, because the worktree is a single file.
@ -1139,8 +1133,7 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let cx = &mut cx;
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let worktree_id = cx.read(|cx| {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
@ -1198,8 +1191,8 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
let (picker, _workspace, mut cx) = build_find_picker(project, cx);
let cx = &mut cx;
let (picker, _workspace, cx) = build_find_picker(project, cx);
picker
.update(cx, |f, cx| {
f.delegate.spawn_search(test_path_like("dir"), cx)
@ -1231,8 +1224,7 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let cx = &mut cx;
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let worktree_id = cx.read(|cx| {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
assert_eq!(worktrees.len(), 1);
@ -1395,8 +1387,7 @@ mod tests {
.detach();
cx.background_executor.run_until_parked();
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let cx = &mut cx;
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let worktree_id = cx.read(|cx| {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
assert_eq!(worktrees.len(), 1,);
@ -1488,8 +1479,7 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let cx = &mut cx;
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
// generate some history to select from
open_close_queried_buffer("fir", 1, "first.rs", &workspace, cx).await;
@ -1547,8 +1537,7 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let cx = &mut cx;
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let worktree_id = cx.read(|cx| {
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
assert_eq!(worktrees.len(), 1,);
@ -1652,8 +1641,7 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let cx = &mut cx;
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
// generate some history to select from
open_close_queried_buffer("fir", 1, "first.rs", &workspace, cx).await;
open_close_queried_buffer("sec", 1, "second.rs", &workspace, cx).await;
@ -1709,9 +1697,7 @@ mod tests {
.await;
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let cx = &mut cx;
// generate some history to select from
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx)); // generate some history to select from
open_close_queried_buffer("fir", 1, "first.rs", &workspace, cx).await;
open_close_queried_buffer("non", 1, "nonexistent.rs", &workspace, cx).await;
open_close_queried_buffer("thi", 1, "third.rs", &workspace, cx).await;
@ -1807,10 +1793,10 @@ mod tests {
) -> (
View<Picker<FileFinderDelegate>>,
View<Workspace>,
VisualTestContext,
&mut VisualTestContext,
) {
let (workspace, mut cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let picker = open_file_picker(&workspace, &mut cx);
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
let picker = open_file_picker(&workspace, cx);
(picker, workspace, cx)
}

View File

@ -140,7 +140,7 @@ impl TestAppContext {
.any_handle
}
pub fn add_window_view<F, V>(&mut self, build_window: F) -> (View<V>, VisualTestContext)
pub fn add_window_view<F, V>(&mut self, build_window: F) -> (View<V>, &mut VisualTestContext)
where
F: FnOnce(&mut ViewContext<V>) -> V,
V: Render,
@ -149,7 +149,9 @@ impl TestAppContext {
let window = cx.open_window(WindowOptions::default(), |cx| cx.build_view(build_window));
drop(cx);
let view = window.root_view(self).unwrap();
(view, VisualTestContext::from_window(*window.deref(), self))
let cx = Box::new(VisualTestContext::from_window(*window.deref(), self));
// it might be nice to try and cleanup these at the end of each test.
(view, Box::leak(cx))
}
pub fn simulate_new_path_selection(