Use run_until_parked instead of 'condition' in all integration tests

Max Brunsfeld created

Change summary

crates/collab/src/integration_tests.rs | 185 +++++++++++++--------------
1 file changed, 88 insertions(+), 97 deletions(-)

Detailed changes

crates/collab/src/integration_tests.rs 🔗

@@ -25,7 +25,7 @@ use gpui::{
     ModelHandle, Task, TestAppContext, ViewHandle,
 };
 use language::{
-    range_to_lsp, tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language,
+    range_to_lsp, tree_sitter_rust, Anchor, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language,
     LanguageConfig, LanguageRegistry, OffsetRangeExt, Point, PointUtf16, Rope,
 };
 use live_kit_client::MacOSDisplay;
@@ -764,17 +764,22 @@ async fn test_share_project(
 
     let editor_b = cx_b.add_view(&window_b, |cx| Editor::for_buffer(buffer_b, None, cx));
 
-    // TODO
-    // // Create a selection set as client B and see that selection set as client A.
-    // buffer_a
-    //     .condition(&cx_a, |buffer, _| buffer.selection_sets().count() == 1)
-    //     .await;
+    // Client A sees client B's selection
+    deterministic.run_until_parked();
+    buffer_a.read_with(cx_a, |buffer, _| {
+        buffer
+            .snapshot()
+            .remote_selections_in_range(Anchor::MIN..Anchor::MAX)
+            .count()
+            == 1
+    });
 
     // Edit the buffer as client B and see that edit as client A.
     editor_b.update(cx_b, |editor, cx| editor.handle_input("ok, ", cx));
-    buffer_a
-        .condition(cx_a, |buffer, _| buffer.text() == "ok, b-contents")
-        .await;
+    deterministic.run_until_parked();
+    buffer_a.read_with(cx_a, |buffer, _| {
+        assert_eq!(buffer.text(), "ok, b-contents")
+    });
 
     // Client B can invite client C on a project shared by client A.
     active_call_b
@@ -797,12 +802,16 @@ async fn test_share_project(
         .build_remote_project(initial_project.id, cx_c)
         .await;
 
-    // TODO
-    // // Remove the selection set as client B, see those selections disappear as client A.
+    // Client B closes the editor, and client A sees client B's selections removed.
     cx_b.update(move |_| drop(editor_b));
-    // buffer_a
-    //     .condition(&cx_a, |buffer, _| buffer.selection_sets().count() == 0)
-    //     .await;
+    deterministic.run_until_parked();
+    buffer_a.read_with(cx_a, |buffer, _| {
+        buffer
+            .snapshot()
+            .remote_selections_in_range(Anchor::MIN..Anchor::MAX)
+            .count()
+            == 0
+    });
 }
 
 #[gpui::test(iterations = 10)]
@@ -956,13 +965,9 @@ async fn test_host_disconnect(
     server.forbid_connections();
     server.disconnect_client(client_a.peer_id().unwrap());
     deterministic.advance_clock(RECEIVE_TIMEOUT + RECONNECT_TIMEOUT);
-    project_a
-        .condition(cx_a, |project, _| project.collaborators().is_empty())
-        .await;
+    project_a.read_with(cx_a, |project, _| project.collaborators().is_empty());
     project_a.read_with(cx_a, |project, _| assert!(!project.is_shared()));
-    project_b
-        .condition(cx_b, |project, _| project.is_read_only())
-        .await;
+    project_b.read_with(cx_b, |project, _| project.is_read_only());
     assert!(worktree_a.read_with(cx_a, |tree, _| !tree.as_local().unwrap().is_shared()));
 
     // Ensure client B's edited state is reset and that the whole window is blurred.
@@ -1347,9 +1352,8 @@ async fn test_propagate_saves_and_fs_changes(
         .await
         .unwrap();
 
-    buffer_a
-        .condition(cx_a, |buf, _| buf.text() == "i-am-c, i-am-b, ")
-        .await;
+    deterministic.run_until_parked();
+    buffer_a.read_with(cx_a, |buf, _| assert_eq!(buf.text(), "i-am-c, i-am-b, "));
     buffer_a.update(cx_a, |buf, cx| {
         buf.edit([(buf.len()..buf.len(), "i-am-a")], None, cx)
     });
@@ -1999,9 +2003,8 @@ async fn test_buffer_conflict_after_save(cx_a: &mut TestAppContext, cx_b: &mut T
     });
 
     buffer_b.update(cx_b, |buf, cx| buf.save(cx)).await.unwrap();
-    buffer_b
-        .condition(cx_b, |buffer_b, _| !buffer_b.is_dirty())
-        .await;
+    cx_a.foreground().forbid_parking();
+    buffer_b.read_with(cx_b, |buffer_b, _| assert!(!buffer_b.is_dirty()));
     buffer_b.read_with(cx_b, |buf, _| {
         assert!(!buf.has_conflict());
     });
@@ -2057,12 +2060,9 @@ async fn test_buffer_reloading(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
         .save("/dir/a.txt".as_ref(), &new_contents, LineEnding::Windows)
         .await
         .unwrap();
-    buffer_b
-        .condition(cx_b, |buf, _| {
-            buf.text() == new_contents.to_string() && !buf.is_dirty()
-        })
-        .await;
+    cx_a.foreground().run_until_parked();
     buffer_b.read_with(cx_b, |buf, _| {
+        assert_eq!(buf.text(), new_contents.to_string());
         assert!(!buf.is_dirty());
         assert!(!buf.has_conflict());
         assert_eq!(buf.line_ending(), LineEnding::Windows);
@@ -2113,7 +2113,8 @@ async fn test_editing_while_guest_opens_buffer(
 
     let text = buffer_a.read_with(cx_a, |buf, _| buf.text());
     let buffer_b = buffer_b.await.unwrap();
-    buffer_b.condition(cx_b, |buf, _| buf.text() == text).await;
+    cx_a.foreground().run_until_parked();
+    buffer_b.read_with(cx_b, |buf, _| assert_eq!(buf.text(), text));
 }
 
 #[gpui::test(iterations = 10)]
@@ -2142,9 +2143,8 @@ async fn test_leaving_worktree_while_opening_buffer(
     let project_b = client_b.build_remote_project(project_id, cx_b).await;
 
     // See that a guest has joined as client A.
-    project_a
-        .condition(cx_a, |p, _| p.collaborators().len() == 1)
-        .await;
+    cx_a.foreground().run_until_parked();
+    project_a.read_with(cx_a, |p, _| assert_eq!(p.collaborators().len(), 1));
 
     // Begin opening a buffer as client B, but leave the project before the open completes.
     let buffer_b = cx_b
@@ -2154,9 +2154,8 @@ async fn test_leaving_worktree_while_opening_buffer(
     drop(buffer_b);
 
     // See that the guest has left.
-    project_a
-        .condition(cx_a, |p, _| p.collaborators().is_empty())
-        .await;
+    cx_a.foreground().run_until_parked();
+    project_a.read_with(cx_a, |p, _| assert!(p.collaborators().is_empty()));
 }
 
 #[gpui::test(iterations = 10)]
@@ -2671,9 +2670,10 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu
     });
 
     let fake_language_server = fake_language_servers.next().await.unwrap();
-    buffer_b
-        .condition(cx_b, |buffer, _| !buffer.completion_triggers().is_empty())
-        .await;
+    cx_a.foreground().run_until_parked();
+    buffer_b.read_with(cx_b, |buffer, _| {
+        assert!(!buffer.completion_triggers().is_empty())
+    });
 
     // Type a completion trigger character as the guest.
     editor_b.update(cx_b, |editor, cx| {
@@ -2735,14 +2735,13 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu
         .update(cx_a, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx))
         .await
         .unwrap();
-    buffer_a
-        .condition(cx_a, |buffer, _| buffer.text() == "fn main() { a. }")
-        .await;
+    cx_a.foreground().run_until_parked();
+    buffer_a.read_with(cx_a, |buffer, _| {
+        assert_eq!(buffer.text(), "fn main() { a. }")
+    });
 
     // Confirm a completion on the guest.
-    editor_b
-        .condition(cx_b, |editor, _| editor.context_menu_visible())
-        .await;
+    editor_b.read_with(cx_b, |editor, _| assert!(editor.context_menu_visible()));
     editor_b.update(cx_b, |editor, cx| {
         editor.confirm_completion(&ConfirmCompletion { item_ix: Some(0) }, cx);
         assert_eq!(editor.text(cx), "fn main() { a.first_method() }");
@@ -2771,16 +2770,19 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu
     );
 
     // The additional edit is applied.
-    buffer_a
-        .condition(cx_a, |buffer, _| {
-            buffer.text() == "use d::SomeTrait;\nfn main() { a.first_method() }"
-        })
-        .await;
-    buffer_b
-        .condition(cx_b, |buffer, _| {
-            buffer.text() == "use d::SomeTrait;\nfn main() { a.first_method() }"
-        })
-        .await;
+    cx_a.foreground().run_until_parked();
+    buffer_a.read_with(cx_a, |buffer, _| {
+        assert_eq!(
+            buffer.text(),
+            "use d::SomeTrait;\nfn main() { a.first_method() }"
+        );
+    });
+    buffer_b.read_with(cx_b, |buffer, _| {
+        assert_eq!(
+            buffer.text(),
+            "use d::SomeTrait;\nfn main() { a.first_method() }"
+        );
+    });
 }
 
 #[gpui::test(iterations = 10)]
@@ -2822,9 +2824,8 @@ async fn test_reloading_buffer_manually(cx_a: &mut TestAppContext, cx_b: &mut Te
         assert!(buffer.is_dirty());
         assert!(!buffer.has_conflict());
     });
-    buffer_a
-        .condition(cx_a, |buffer, _| buffer.text() == "let six = 6;")
-        .await;
+    cx_a.foreground().run_until_parked();
+    buffer_a.read_with(cx_a, |buffer, _| assert_eq!(buffer.text(), "let six = 6;"));
 
     client_a
         .fs
@@ -2835,12 +2836,9 @@ async fn test_reloading_buffer_manually(cx_a: &mut TestAppContext, cx_b: &mut Te
         )
         .await
         .unwrap();
-    buffer_a
-        .condition(cx_a, |buffer, _| buffer.has_conflict())
-        .await;
-    buffer_b
-        .condition(cx_b, |buffer, _| buffer.has_conflict())
-        .await;
+    cx_a.foreground().run_until_parked();
+    buffer_a.read_with(cx_a, |buffer, _| assert!(buffer.has_conflict()));
+    buffer_b.read_with(cx_b, |buffer, _| assert!(buffer.has_conflict()));
 
     project_b
         .update(cx_b, |project, cx| {
@@ -3836,9 +3834,8 @@ async fn test_collaborating_with_code_actions(
             cx,
         );
     });
-    editor_b
-        .condition(cx_b, |editor, _| editor.context_menu_visible())
-        .await;
+    cx_a.foreground().run_until_parked();
+    editor_b.read_with(cx_b, |editor, _| assert!(editor.context_menu_visible()));
 
     fake_language_server.remove_request_handler::<lsp::request::CodeActionRequest>();
 
@@ -4917,11 +4914,10 @@ async fn test_following(
     workspace_a.update(cx_a, |workspace, cx| {
         workspace.activate_item(&editor_a1, cx)
     });
-    workspace_b
-        .condition(cx_b, |workspace, cx| {
-            workspace.active_item(cx).unwrap().id() == editor_b1.id()
-        })
-        .await;
+    deterministic.run_until_parked();
+    workspace_b.read_with(cx_b, |workspace, cx| {
+        assert_eq!(workspace.active_item(cx).unwrap().id(), editor_b1.id());
+    });
 
     // When client A navigates back and forth, client B does so as well.
     workspace_a
@@ -4929,47 +4925,42 @@ async fn test_following(
             workspace::Pane::go_back(workspace, None, cx)
         })
         .await;
-    workspace_b
-        .condition(cx_b, |workspace, cx| {
-            workspace.active_item(cx).unwrap().id() == editor_b2.id()
-        })
-        .await;
+    deterministic.run_until_parked();
+    workspace_b.read_with(cx_b, |workspace, cx| {
+        assert_eq!(workspace.active_item(cx).unwrap().id(), editor_b2.id());
+    });
 
     workspace_a
         .update(cx_a, |workspace, cx| {
             workspace::Pane::go_forward(workspace, None, cx)
         })
         .await;
-    workspace_b
-        .condition(cx_b, |workspace, cx| {
-            workspace.active_item(cx).unwrap().id() == editor_b1.id()
-        })
-        .await;
+    deterministic.run_until_parked();
+    workspace_b.read_with(cx_b, |workspace, cx| {
+        assert_eq!(workspace.active_item(cx).unwrap().id(), editor_b1.id());
+    });
 
     // Changes to client A's editor are reflected on client B.
     editor_a1.update(cx_a, |editor, cx| {
         editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2]));
     });
-    editor_b1
-        .condition(cx_b, |editor, cx| {
-            editor.selections.ranges(cx) == vec![1..1, 2..2]
-        })
-        .await;
+    deterministic.run_until_parked();
+    editor_b1.read_with(cx_b, |editor, cx| {
+        assert_eq!(editor.selections.ranges(cx), &[1..1, 2..2]);
+    });
 
     editor_a1.update(cx_a, |editor, cx| editor.set_text("TWO", cx));
-    editor_b1
-        .condition(cx_b, |editor, cx| editor.text(cx) == "TWO")
-        .await;
+    deterministic.run_until_parked();
+    editor_b1.read_with(cx_b, |editor, cx| assert_eq!(editor.text(cx), "TWO"));
 
     editor_a1.update(cx_a, |editor, cx| {
         editor.change_selections(None, cx, |s| s.select_ranges([3..3]));
         editor.set_scroll_position(vec2f(0., 100.), cx);
     });
-    editor_b1
-        .condition(cx_b, |editor, cx| {
-            editor.selections.ranges(cx) == vec![3..3]
-        })
-        .await;
+    deterministic.run_until_parked();
+    editor_b1.read_with(cx_b, |editor, cx| {
+        assert_eq!(editor.selections.ranges(cx), &[3..3]);
+    });
 
     // After unfollowing, client B stops receiving updates from client A.
     workspace_b.update(cx_b, |workspace, cx| {