From d81fb3680ec47583aedd91da32e17972d80179bc Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 1 Dec 2023 22:04:43 +0100 Subject: [PATCH] Uncomment copilot2 tests --- Cargo.lock | 2 +- crates/copilot2/Cargo.toml | 2 +- crates/copilot2/src/copilot2.rs | 454 ++++++++++++++++---------------- 3 files changed, 230 insertions(+), 228 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3110a9ff43e75bc698b782d3ec4d79383851fca3..299ff4203bfdaeb54608d63e01d6fa2cf756a69a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2098,7 +2098,7 @@ dependencies = [ "lsp2", "node_runtime", "parking_lot 0.11.2", - "rpc", + "rpc2", "serde", "serde_derive", "settings2", diff --git a/crates/copilot2/Cargo.toml b/crates/copilot2/Cargo.toml index 68b56a6c018b5108c841c37e83f68c0877ee77f5..9a9243b32eecb766451a3f7f89940227fe6059fa 100644 --- a/crates/copilot2/Cargo.toml +++ b/crates/copilot2/Cargo.toml @@ -45,6 +45,6 @@ fs = { path = "../fs", features = ["test-support"] } gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] } language = { package = "language2", path = "../language2", features = ["test-support"] } lsp = { package = "lsp2", path = "../lsp2", features = ["test-support"] } -rpc = { path = "../rpc", features = ["test-support"] } +rpc = { package = "rpc2", path = "../rpc2", features = ["test-support"] } settings = { package = "settings2", path = "../settings2", features = ["test-support"] } util = { path = "../util", features = ["test-support"] } diff --git a/crates/copilot2/src/copilot2.rs b/crates/copilot2/src/copilot2.rs index 53d802dd037f51c3df4183ba57bda44a1ea18e7f..01ee77369adce1bfe29d242ef79ffb4c2b570967 100644 --- a/crates/copilot2/src/copilot2.rs +++ b/crates/copilot2/src/copilot2.rs @@ -1002,229 +1002,231 @@ async fn get_copilot_lsp(http: Arc) -> anyhow::Result { } } -// #[cfg(test)] -// mod tests { -// use super::*; -// use gpui::{executor::Deterministic, TestAppContext}; - -// #[gpui::test(iterations = 10)] -// async fn test_buffer_management(deterministic: Arc, cx: &mut TestAppContext) { -// deterministic.forbid_parking(); -// let (copilot, mut lsp) = Copilot::fake(cx); - -// let buffer_1 = cx.add_model(|cx| Buffer::new(0, cx.model_id() as u64, "Hello")); -// let buffer_1_uri: lsp::Url = format!("buffer://{}", buffer_1.id()).parse().unwrap(); -// copilot.update(cx, |copilot, cx| copilot.register_buffer(&buffer_1, cx)); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidOpenTextDocumentParams { -// text_document: lsp::TextDocumentItem::new( -// buffer_1_uri.clone(), -// "plaintext".into(), -// 0, -// "Hello".into() -// ), -// } -// ); - -// let buffer_2 = cx.add_model(|cx| Buffer::new(0, cx.model_id() as u64, "Goodbye")); -// let buffer_2_uri: lsp::Url = format!("buffer://{}", buffer_2.id()).parse().unwrap(); -// copilot.update(cx, |copilot, cx| copilot.register_buffer(&buffer_2, cx)); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidOpenTextDocumentParams { -// text_document: lsp::TextDocumentItem::new( -// buffer_2_uri.clone(), -// "plaintext".into(), -// 0, -// "Goodbye".into() -// ), -// } -// ); - -// buffer_1.update(cx, |buffer, cx| buffer.edit([(5..5, " world")], None, cx)); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidChangeTextDocumentParams { -// text_document: lsp::VersionedTextDocumentIdentifier::new(buffer_1_uri.clone(), 1), -// content_changes: vec![lsp::TextDocumentContentChangeEvent { -// range: Some(lsp::Range::new( -// lsp::Position::new(0, 5), -// lsp::Position::new(0, 5) -// )), -// range_length: None, -// text: " world".into(), -// }], -// } -// ); - -// // Ensure updates to the file are reflected in the LSP. -// buffer_1 -// .update(cx, |buffer, cx| { -// buffer.file_updated( -// Arc::new(File { -// abs_path: "/root/child/buffer-1".into(), -// path: Path::new("child/buffer-1").into(), -// }), -// cx, -// ) -// }) -// .await; -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidCloseTextDocumentParams { -// text_document: lsp::TextDocumentIdentifier::new(buffer_1_uri), -// } -// ); -// let buffer_1_uri = lsp::Url::from_file_path("/root/child/buffer-1").unwrap(); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidOpenTextDocumentParams { -// text_document: lsp::TextDocumentItem::new( -// buffer_1_uri.clone(), -// "plaintext".into(), -// 1, -// "Hello world".into() -// ), -// } -// ); - -// // Ensure all previously-registered buffers are closed when signing out. -// lsp.handle_request::(|_, _| async { -// Ok(request::SignOutResult {}) -// }); -// copilot -// .update(cx, |copilot, cx| copilot.sign_out(cx)) -// .await -// .unwrap(); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidCloseTextDocumentParams { -// text_document: lsp::TextDocumentIdentifier::new(buffer_2_uri.clone()), -// } -// ); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidCloseTextDocumentParams { -// text_document: lsp::TextDocumentIdentifier::new(buffer_1_uri.clone()), -// } -// ); - -// // Ensure all previously-registered buffers are re-opened when signing in. -// lsp.handle_request::(|_, _| async { -// Ok(request::SignInInitiateResult::AlreadySignedIn { -// user: "user-1".into(), -// }) -// }); -// copilot -// .update(cx, |copilot, cx| copilot.sign_in(cx)) -// .await -// .unwrap(); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidOpenTextDocumentParams { -// text_document: lsp::TextDocumentItem::new( -// buffer_2_uri.clone(), -// "plaintext".into(), -// 0, -// "Goodbye".into() -// ), -// } -// ); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidOpenTextDocumentParams { -// text_document: lsp::TextDocumentItem::new( -// buffer_1_uri.clone(), -// "plaintext".into(), -// 0, -// "Hello world".into() -// ), -// } -// ); - -// // Dropping a buffer causes it to be closed on the LSP side as well. -// cx.update(|_| drop(buffer_2)); -// assert_eq!( -// lsp.receive_notification::() -// .await, -// lsp::DidCloseTextDocumentParams { -// text_document: lsp::TextDocumentIdentifier::new(buffer_2_uri), -// } -// ); -// } - -// struct File { -// abs_path: PathBuf, -// path: Arc, -// } - -// impl language2::File for File { -// fn as_local(&self) -> Option<&dyn language2::LocalFile> { -// Some(self) -// } - -// fn mtime(&self) -> std::time::SystemTime { -// unimplemented!() -// } - -// fn path(&self) -> &Arc { -// &self.path -// } - -// fn full_path(&self, _: &AppContext) -> PathBuf { -// unimplemented!() -// } - -// fn file_name<'a>(&'a self, _: &'a AppContext) -> &'a std::ffi::OsStr { -// unimplemented!() -// } - -// fn is_deleted(&self) -> bool { -// unimplemented!() -// } - -// fn as_any(&self) -> &dyn std::any::Any { -// unimplemented!() -// } - -// fn to_proto(&self) -> rpc::proto::File { -// unimplemented!() -// } - -// fn worktree_id(&self) -> usize { -// 0 -// } -// } - -// impl language::LocalFile for File { -// fn abs_path(&self, _: &AppContext) -> PathBuf { -// self.abs_path.clone() -// } - -// fn load(&self, _: &AppContext) -> Task> { -// unimplemented!() -// } - -// fn buffer_reloaded( -// &self, -// _: u64, -// _: &clock::Global, -// _: language::RopeFingerprint, -// _: language::LineEnding, -// _: std::time::SystemTime, -// _: &mut AppContext, -// ) { -// unimplemented!() -// } -// } -// } +#[cfg(test)] +mod tests { + use super::*; + use gpui::TestAppContext; + + #[gpui::test(iterations = 10)] + async fn test_buffer_management(cx: &mut TestAppContext) { + let (copilot, mut lsp) = Copilot::fake(cx); + + let buffer_1 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "Hello")); + let buffer_1_uri: lsp::Url = format!("buffer://{}", buffer_1.entity_id().as_u64()) + .parse() + .unwrap(); + copilot.update(cx, |copilot, cx| copilot.register_buffer(&buffer_1, cx)); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidOpenTextDocumentParams { + text_document: lsp::TextDocumentItem::new( + buffer_1_uri.clone(), + "plaintext".into(), + 0, + "Hello".into() + ), + } + ); + + let buffer_2 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "Goodbye")); + let buffer_2_uri: lsp::Url = format!("buffer://{}", buffer_2.entity_id().as_u64()) + .parse() + .unwrap(); + copilot.update(cx, |copilot, cx| copilot.register_buffer(&buffer_2, cx)); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidOpenTextDocumentParams { + text_document: lsp::TextDocumentItem::new( + buffer_2_uri.clone(), + "plaintext".into(), + 0, + "Goodbye".into() + ), + } + ); + + buffer_1.update(cx, |buffer, cx| buffer.edit([(5..5, " world")], None, cx)); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidChangeTextDocumentParams { + text_document: lsp::VersionedTextDocumentIdentifier::new(buffer_1_uri.clone(), 1), + content_changes: vec![lsp::TextDocumentContentChangeEvent { + range: Some(lsp::Range::new( + lsp::Position::new(0, 5), + lsp::Position::new(0, 5) + )), + range_length: None, + text: " world".into(), + }], + } + ); + + // Ensure updates to the file are reflected in the LSP. + buffer_1.update(cx, |buffer, cx| { + buffer.file_updated( + Arc::new(File { + abs_path: "/root/child/buffer-1".into(), + path: Path::new("child/buffer-1").into(), + }), + cx, + ) + }); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidCloseTextDocumentParams { + text_document: lsp::TextDocumentIdentifier::new(buffer_1_uri), + } + ); + let buffer_1_uri = lsp::Url::from_file_path("/root/child/buffer-1").unwrap(); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidOpenTextDocumentParams { + text_document: lsp::TextDocumentItem::new( + buffer_1_uri.clone(), + "plaintext".into(), + 1, + "Hello world".into() + ), + } + ); + + // Ensure all previously-registered buffers are closed when signing out. + lsp.handle_request::(|_, _| async { + Ok(request::SignOutResult {}) + }); + copilot + .update(cx, |copilot, cx| copilot.sign_out(cx)) + .await + .unwrap(); + // todo!() po: these notifications now happen in reverse order? + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidCloseTextDocumentParams { + text_document: lsp::TextDocumentIdentifier::new(buffer_2_uri.clone()), + } + ); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidCloseTextDocumentParams { + text_document: lsp::TextDocumentIdentifier::new(buffer_1_uri.clone()), + } + ); + + // Ensure all previously-registered buffers are re-opened when signing in. + lsp.handle_request::(|_, _| async { + Ok(request::SignInInitiateResult::AlreadySignedIn { + user: "user-1".into(), + }) + }); + copilot + .update(cx, |copilot, cx| copilot.sign_in(cx)) + .await + .unwrap(); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidOpenTextDocumentParams { + text_document: lsp::TextDocumentItem::new( + buffer_2_uri.clone(), + "plaintext".into(), + 0, + "Goodbye".into() + ), + } + ); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidOpenTextDocumentParams { + text_document: lsp::TextDocumentItem::new( + buffer_1_uri.clone(), + "plaintext".into(), + 0, + "Hello world".into() + ), + } + ); + + // Dropping a buffer causes it to be closed on the LSP side as well. + cx.update(|_| drop(buffer_2)); + assert_eq!( + lsp.receive_notification::() + .await, + lsp::DidCloseTextDocumentParams { + text_document: lsp::TextDocumentIdentifier::new(buffer_2_uri), + } + ); + } + + struct File { + abs_path: PathBuf, + path: Arc, + } + + impl language::File for File { + fn as_local(&self) -> Option<&dyn language::LocalFile> { + Some(self) + } + + fn mtime(&self) -> std::time::SystemTime { + unimplemented!() + } + + fn path(&self) -> &Arc { + &self.path + } + + fn full_path(&self, _: &AppContext) -> PathBuf { + unimplemented!() + } + + fn file_name<'a>(&'a self, _: &'a AppContext) -> &'a std::ffi::OsStr { + unimplemented!() + } + + fn is_deleted(&self) -> bool { + unimplemented!() + } + + fn as_any(&self) -> &dyn std::any::Any { + unimplemented!() + } + + fn to_proto(&self) -> rpc::proto::File { + unimplemented!() + } + + fn worktree_id(&self) -> usize { + 0 + } + } + + impl language::LocalFile for File { + fn abs_path(&self, _: &AppContext) -> PathBuf { + self.abs_path.clone() + } + + fn load(&self, _: &AppContext) -> Task> { + unimplemented!() + } + + fn buffer_reloaded( + &self, + _: u64, + _: &clock::Global, + _: language::RopeFingerprint, + _: language::LineEnding, + _: std::time::SystemTime, + _: &mut AppContext, + ) { + unimplemented!() + } + } +}