Start work on an integration test for following
This commit is contained in:
parent
845457e2c4
commit
5702737de2
2 changed files with 177 additions and 7 deletions
|
@ -112,6 +112,7 @@ impl Server {
|
|||
.add_request_handler(Server::join_channel)
|
||||
.add_message_handler(Server::leave_channel)
|
||||
.add_request_handler(Server::send_channel_message)
|
||||
.add_request_handler(Server::follow)
|
||||
.add_request_handler(Server::get_channel_messages);
|
||||
|
||||
Arc::new(server)
|
||||
|
@ -669,6 +670,25 @@ impl Server {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn follow(
|
||||
self: Arc<Self>,
|
||||
request: TypedEnvelope<proto::Follow>,
|
||||
) -> tide::Result<proto::FollowResponse> {
|
||||
let leader_id = ConnectionId(request.payload.leader_id);
|
||||
if !self
|
||||
.state()
|
||||
.project_connection_ids(request.payload.project_id, request.sender_id)?
|
||||
.contains(&leader_id)
|
||||
{
|
||||
Err(anyhow!("no such peer"))?;
|
||||
}
|
||||
let response = self
|
||||
.peer
|
||||
.forward_request(request.sender_id, leader_id, request.payload)
|
||||
.await?;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
async fn get_channels(
|
||||
self: Arc<Server>,
|
||||
request: TypedEnvelope<proto::GetChannels>,
|
||||
|
@ -1016,7 +1036,7 @@ mod tests {
|
|||
self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, Input, Redo, Rename,
|
||||
ToOffset, ToggleCodeActions, Undo,
|
||||
};
|
||||
use gpui::{executor, ModelHandle, TestAppContext};
|
||||
use gpui::{executor, ModelHandle, TestAppContext, ViewHandle};
|
||||
use language::{
|
||||
tree_sitter_rust, Diagnostic, DiagnosticEntry, Language, LanguageConfig, LanguageRegistry,
|
||||
LanguageServerConfig, OffsetRangeExt, Point, ToLspPosition,
|
||||
|
@ -1028,7 +1048,7 @@ mod tests {
|
|||
fs::{FakeFs, Fs as _},
|
||||
search::SearchQuery,
|
||||
worktree::WorktreeHandle,
|
||||
DiagnosticSummary, Project, ProjectPath,
|
||||
DiagnosticSummary, Project, ProjectPath, WorktreeId,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use rpc::PeerId;
|
||||
|
@ -1046,7 +1066,7 @@ mod tests {
|
|||
},
|
||||
time::Duration,
|
||||
};
|
||||
use workspace::{Settings, Workspace, WorkspaceParams};
|
||||
use workspace::{Settings, SplitDirection, Workspace, WorkspaceParams};
|
||||
|
||||
#[cfg(test)]
|
||||
#[ctor::ctor]
|
||||
|
@ -3225,7 +3245,7 @@ mod tests {
|
|||
let (_window_b, workspace_b) = cx_b.add_window(|cx| Workspace::new(¶ms, cx));
|
||||
let editor_b = workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "main.rs").into(), cx)
|
||||
workspace.open_path((worktree_id, "main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -3459,7 +3479,7 @@ mod tests {
|
|||
let (_window_b, workspace_b) = cx_b.add_window(|cx| Workspace::new(¶ms, cx));
|
||||
let editor_b = workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "one.rs").into(), cx)
|
||||
workspace.open_path((worktree_id, "one.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -4148,6 +4168,80 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[gpui::test(iterations = 10)]
|
||||
async fn test_following(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
|
||||
cx_a.foreground().forbid_parking();
|
||||
let fs = FakeFs::new(cx_a.background());
|
||||
|
||||
// 2 clients connect to a server.
|
||||
let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
|
||||
let mut client_a = server.create_client(cx_a, "user_a").await;
|
||||
let mut client_b = server.create_client(cx_b, "user_b").await;
|
||||
cx_a.update(editor::init);
|
||||
cx_b.update(editor::init);
|
||||
|
||||
// Client A shares a project.
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
json!({
|
||||
".zed.toml": r#"collaborators = ["user_b"]"#,
|
||||
"1.txt": "one",
|
||||
"2.txt": "two",
|
||||
"3.txt": "three",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let (project_a, worktree_id) = client_a.build_local_project(fs.clone(), "/a", cx_a).await;
|
||||
project_a
|
||||
.update(cx_a, |project, cx| project.share(cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Client B joins the project.
|
||||
let project_b = client_b
|
||||
.build_remote_project(
|
||||
project_a
|
||||
.read_with(cx_a, |project, _| project.remote_id())
|
||||
.unwrap(),
|
||||
cx_b,
|
||||
)
|
||||
.await;
|
||||
|
||||
// Client A opens some editors.
|
||||
let workspace_a = client_a.build_workspace(&project_a, cx_a);
|
||||
let editor_a1 = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let editor_a2 = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "2.txt"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Client B opens an editor.
|
||||
let workspace_b = client_b.build_workspace(&project_b, cx_b);
|
||||
let editor_b1 = workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "1.txt"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Client B starts following client A.
|
||||
workspace_b
|
||||
.update(cx_b, |workspace, cx| {
|
||||
workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, cx);
|
||||
let leader_id = project_b.read(cx).collaborators().keys().next().unwrap();
|
||||
workspace.follow(*leader_id, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[gpui::test(iterations = 100)]
|
||||
async fn test_random_collaboration(cx: &mut TestAppContext, rng: StdRng) {
|
||||
cx.foreground().forbid_parking();
|
||||
|
@ -4477,6 +4571,7 @@ mod tests {
|
|||
client,
|
||||
peer_id,
|
||||
user_store,
|
||||
language_registry: Arc::new(LanguageRegistry::test()),
|
||||
project: Default::default(),
|
||||
buffers: Default::default(),
|
||||
};
|
||||
|
@ -4541,6 +4636,7 @@ mod tests {
|
|||
client: Arc<Client>,
|
||||
pub peer_id: PeerId,
|
||||
pub user_store: ModelHandle<UserStore>,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
project: Option<ModelHandle<Project>>,
|
||||
buffers: HashSet<ModelHandle<language::Buffer>>,
|
||||
}
|
||||
|
@ -4568,6 +4664,80 @@ mod tests {
|
|||
while authed_user.next().await.unwrap().is_none() {}
|
||||
}
|
||||
|
||||
async fn build_local_project(
|
||||
&mut self,
|
||||
fs: Arc<FakeFs>,
|
||||
root_path: impl AsRef<Path>,
|
||||
cx: &mut TestAppContext,
|
||||
) -> (ModelHandle<Project>, WorktreeId) {
|
||||
let project = cx.update(|cx| {
|
||||
Project::local(
|
||||
self.client.clone(),
|
||||
self.user_store.clone(),
|
||||
self.language_registry.clone(),
|
||||
fs,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
self.project = Some(project.clone());
|
||||
let (worktree, _) = project
|
||||
.update(cx, |p, cx| {
|
||||
p.find_or_create_local_worktree(root_path, true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
worktree
|
||||
.read_with(cx, |tree, _| tree.as_local().unwrap().scan_complete())
|
||||
.await;
|
||||
project
|
||||
.update(cx, |project, _| project.next_remote_id())
|
||||
.await;
|
||||
(project, worktree.read_with(cx, |tree, _| tree.id()))
|
||||
}
|
||||
|
||||
async fn build_remote_project(
|
||||
&mut self,
|
||||
project_id: u64,
|
||||
cx: &mut TestAppContext,
|
||||
) -> ModelHandle<Project> {
|
||||
let project = Project::remote(
|
||||
project_id,
|
||||
self.client.clone(),
|
||||
self.user_store.clone(),
|
||||
self.language_registry.clone(),
|
||||
FakeFs::new(cx.background()),
|
||||
&mut cx.to_async(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
self.project = Some(project.clone());
|
||||
project
|
||||
}
|
||||
|
||||
fn build_workspace(
|
||||
&self,
|
||||
project: &ModelHandle<Project>,
|
||||
cx: &mut TestAppContext,
|
||||
) -> ViewHandle<Workspace> {
|
||||
let (window_id, _) = cx.add_window(|cx| EmptyView);
|
||||
cx.add_view(window_id, |cx| {
|
||||
let fs = project.read(cx).fs().clone();
|
||||
Workspace::new(
|
||||
&WorkspaceParams {
|
||||
fs,
|
||||
project: project.clone(),
|
||||
user_store: self.user_store.clone(),
|
||||
languages: self.language_registry.clone(),
|
||||
channel_list: cx.add_model(|cx| {
|
||||
ChannelList::new(self.user_store.clone(), self.client.clone(), cx)
|
||||
}),
|
||||
client: self.client.clone(),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn simulate_host(
|
||||
mut self,
|
||||
project: ModelHandle<Project>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue