mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 22:54:42 +00:00
[ty] Move server tests as integration tests (#19522)
## Summary Reference: https://github.com/astral-sh/ruff/pull/19391#discussion_r2222780892
This commit is contained in:
parent
1d2181623c
commit
f9091ea8bb
15 changed files with 172 additions and 128 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -4344,6 +4344,7 @@ dependencies = [
|
|||
"ty_ide",
|
||||
"ty_project",
|
||||
"ty_python_semantic",
|
||||
"ty_server",
|
||||
"ty_vendored",
|
||||
]
|
||||
|
||||
|
|
|
@ -38,11 +38,16 @@ tracing = { workspace = true }
|
|||
tracing-subscriber = { workspace = true, features = ["chrono"] }
|
||||
|
||||
[dev-dependencies]
|
||||
ty_server = { workspace = true, features = ["testing"] }
|
||||
|
||||
dunce = { workspace = true }
|
||||
insta = { workspace = true, features = ["filters", "json"] }
|
||||
regex = { workspace = true }
|
||||
tempfile = { workspace = true }
|
||||
|
||||
[features]
|
||||
testing = []
|
||||
|
||||
[target.'cfg(target_vendor = "apple")'.dependencies]
|
||||
libc = { workspace = true }
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@ use anyhow::Context;
|
|||
use lsp_server::Connection;
|
||||
use ruff_db::system::{OsSystem, SystemPathBuf};
|
||||
|
||||
use crate::server::Server;
|
||||
pub use crate::logging::{LogLevel, init_logging};
|
||||
pub use crate::server::Server;
|
||||
pub use crate::session::ClientOptions;
|
||||
pub use document::{NotebookDocument, PositionEncoding, TextDocument};
|
||||
pub(crate) use session::{DocumentQuery, Session};
|
||||
|
||||
|
@ -14,9 +16,6 @@ mod server;
|
|||
mod session;
|
||||
mod system;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test;
|
||||
|
||||
pub(crate) const SERVER_NAME: &str = "ty";
|
||||
pub(crate) const DIAGNOSTIC_NAME: &str = "ty";
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use tracing_subscriber::fmt::time::ChronoLocal;
|
|||
use tracing_subscriber::fmt::writer::BoxMakeWriter;
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
|
||||
pub(crate) fn init_logging(log_level: LogLevel, log_file: Option<&SystemPath>) {
|
||||
pub fn init_logging(log_level: LogLevel, log_file: Option<&SystemPath>) {
|
||||
let log_file = log_file
|
||||
.map(|path| {
|
||||
// this expands `logFile` so that tildes and environment variables
|
||||
|
@ -66,7 +66,7 @@ pub(crate) fn init_logging(log_level: LogLevel, log_file: Option<&SystemPath>) {
|
|||
/// The default log level is `info`.
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Default, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub(crate) enum LogLevel {
|
||||
pub enum LogLevel {
|
||||
Error,
|
||||
Warn,
|
||||
#[default]
|
||||
|
|
|
@ -26,7 +26,7 @@ pub(crate) use api::publish_settings_diagnostics;
|
|||
pub(crate) use main_loop::{Action, ConnectionSender, Event, MainLoopReceiver, MainLoopSender};
|
||||
pub(crate) type Result<T> = std::result::Result<T, api::Error>;
|
||||
|
||||
pub(crate) struct Server {
|
||||
pub struct Server {
|
||||
connection: Connection,
|
||||
client_capabilities: ClientCapabilities,
|
||||
worker_threads: NonZeroUsize,
|
||||
|
@ -36,7 +36,7 @@ pub(crate) struct Server {
|
|||
}
|
||||
|
||||
impl Server {
|
||||
pub(crate) fn new(
|
||||
pub fn new(
|
||||
worker_threads: NonZeroUsize,
|
||||
connection: Connection,
|
||||
native_system: Arc<dyn System + 'static + Send + Sync + RefUnwindSafe>,
|
||||
|
@ -161,7 +161,7 @@ impl Server {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn run(mut self) -> crate::Result<()> {
|
||||
pub fn run(mut self) -> crate::Result<()> {
|
||||
let client = Client::new(
|
||||
self.main_loop_sender.clone(),
|
||||
self.connection.sender.clone(),
|
||||
|
@ -302,89 +302,3 @@ impl Drop for ServerPanicHookHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
use lsp_types::notification::PublishDiagnostics;
|
||||
use ruff_db::system::SystemPath;
|
||||
|
||||
use crate::session::ClientOptions;
|
||||
use crate::test::TestServerBuilder;
|
||||
|
||||
#[test]
|
||||
fn initialization() -> Result<()> {
|
||||
let server = TestServerBuilder::new()?
|
||||
.build()?
|
||||
.wait_until_workspaces_are_initialized()?;
|
||||
|
||||
let initialization_result = server.initialization_result().unwrap();
|
||||
|
||||
insta::assert_json_snapshot!("initialization", initialization_result);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initialization_with_workspace() -> Result<()> {
|
||||
let workspace_root = SystemPath::new("foo");
|
||||
let server = TestServerBuilder::new()?
|
||||
.with_workspace(workspace_root, ClientOptions::default())?
|
||||
.build()?
|
||||
.wait_until_workspaces_are_initialized()?;
|
||||
|
||||
let initialization_result = server.initialization_result().unwrap();
|
||||
|
||||
insta::assert_json_snapshot!("initialization_with_workspace", initialization_result);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn publish_diagnostics_on_did_open() -> Result<()> {
|
||||
let workspace_root = SystemPath::new("src");
|
||||
let foo = SystemPath::new("src/foo.py");
|
||||
let foo_content = "\
|
||||
def foo() -> str:
|
||||
return 42
|
||||
";
|
||||
|
||||
let mut server = TestServerBuilder::new()?
|
||||
.with_workspace(workspace_root, ClientOptions::default())?
|
||||
.with_file(foo, foo_content)?
|
||||
.enable_pull_diagnostics(false)
|
||||
.build()?
|
||||
.wait_until_workspaces_are_initialized()?;
|
||||
|
||||
server.open_text_document(foo, &foo_content, 1);
|
||||
let diagnostics = server.await_notification::<PublishDiagnostics>()?;
|
||||
|
||||
insta::assert_debug_snapshot!(diagnostics);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pull_diagnostics_on_did_open() -> Result<()> {
|
||||
let workspace_root = SystemPath::new("src");
|
||||
let foo = SystemPath::new("src/foo.py");
|
||||
let foo_content = "\
|
||||
def foo() -> str:
|
||||
return 42
|
||||
";
|
||||
|
||||
let mut server = TestServerBuilder::new()?
|
||||
.with_workspace(workspace_root, ClientOptions::default())?
|
||||
.with_file(foo, foo_content)?
|
||||
.enable_pull_diagnostics(true)
|
||||
.build()?
|
||||
.wait_until_workspaces_are_initialized()?;
|
||||
|
||||
server.open_text_document(foo, &foo_content, 1);
|
||||
let diagnostics = server.document_diagnostic_request(foo)?;
|
||||
|
||||
insta::assert_debug_snapshot!(diagnostics);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ use ty_project::{ChangeResult, Db as _, ProjectDatabase, ProjectMetadata};
|
|||
|
||||
pub(crate) use self::capabilities::ResolvedClientCapabilities;
|
||||
pub(crate) use self::index::DocumentQuery;
|
||||
pub(crate) use self::options::{AllOptions, ClientOptions, DiagnosticMode};
|
||||
pub use self::options::ClientOptions;
|
||||
pub(crate) use self::options::{AllOptions, DiagnosticMode};
|
||||
pub(crate) use self::settings::ClientSettings;
|
||||
use crate::document::{DocumentKey, DocumentVersion, NotebookDocument};
|
||||
use crate::server::publish_settings_diagnostics;
|
||||
|
|
|
@ -49,9 +49,10 @@ struct WorkspaceOptions {
|
|||
|
||||
/// This is a direct representation of the settings schema sent by the client.
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct ClientOptions {
|
||||
pub struct ClientOptions {
|
||||
/// Settings under the `python.*` namespace in VS Code that are useful for the ty language
|
||||
/// server.
|
||||
python: Option<Python>,
|
||||
|
@ -63,7 +64,8 @@ pub(crate) struct ClientOptions {
|
|||
|
||||
/// Diagnostic mode for the language server.
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) enum DiagnosticMode {
|
||||
/// Check only currently open files.
|
||||
|
@ -147,21 +149,24 @@ impl ClientOptions {
|
|||
// all settings and not just the ones in "python.*".
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Python {
|
||||
ty: Option<Ty>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct PythonExtension {
|
||||
active_environment: Option<ActiveEnvironment>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct ActiveEnvironment {
|
||||
pub(crate) executable: PythonExecutable,
|
||||
|
@ -170,7 +175,8 @@ pub(crate) struct ActiveEnvironment {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct EnvironmentVersion {
|
||||
pub(crate) major: i64,
|
||||
|
@ -182,7 +188,8 @@ pub(crate) struct EnvironmentVersion {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct PythonEnvironment {
|
||||
pub(crate) folder_uri: Url,
|
||||
|
@ -194,7 +201,8 @@ pub(crate) struct PythonEnvironment {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct PythonExecutable {
|
||||
#[allow(dead_code)]
|
||||
|
@ -203,7 +211,8 @@ pub(crate) struct PythonExecutable {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, PartialEq, Eq))]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[cfg_attr(feature = "testing", derive(serde::Serialize))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Ty {
|
||||
disable_language_services: Option<bool>,
|
||||
|
|
33
crates/ty_server/tests/e2e/initialize.rs
Normal file
33
crates/ty_server/tests/e2e/initialize.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
use anyhow::Result;
|
||||
use ruff_db::system::SystemPath;
|
||||
use ty_server::ClientOptions;
|
||||
|
||||
use crate::TestServerBuilder;
|
||||
|
||||
#[test]
|
||||
fn empty_workspace_folders() -> Result<()> {
|
||||
let server = TestServerBuilder::new()?
|
||||
.build()?
|
||||
.wait_until_workspaces_are_initialized()?;
|
||||
|
||||
let initialization_result = server.initialization_result().unwrap();
|
||||
|
||||
insta::assert_json_snapshot!("initialization", initialization_result);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_workspace_folder() -> Result<()> {
|
||||
let workspace_root = SystemPath::new("foo");
|
||||
let server = TestServerBuilder::new()?
|
||||
.with_workspace(workspace_root, ClientOptions::default())?
|
||||
.build()?
|
||||
.wait_until_workspaces_are_initialized()?;
|
||||
|
||||
let initialization_result = server.initialization_result().unwrap();
|
||||
|
||||
insta::assert_json_snapshot!("initialization_with_workspace", initialization_result);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,9 +1,35 @@
|
|||
//! Testing server for the ty language server.
|
||||
//!
|
||||
//! This module provides mock server infrastructure for testing LSP functionality using
|
||||
//! temporary directories on the real filesystem.
|
||||
//! This module provides mock server infrastructure for testing LSP functionality using a
|
||||
//! temporary directory on the real filesystem.
|
||||
//!
|
||||
//! The design is inspired by the Starlark LSP test server but adapted for ty server architecture.
|
||||
//!
|
||||
//! To get started, use the [`TestServerBuilder`] to configure the server with workspace folders,
|
||||
//! enable or disable specific client capabilities, and add test files. Then, use the [`build`]
|
||||
//! method to create the [`TestServer`]. This will start the server and perform the initialization
|
||||
//! handshake. It might be useful to call [`wait_until_workspaces_are_initialized`] to ensure that
|
||||
//! the server side initialization is complete before sending any requests.
|
||||
//!
|
||||
//! Once the setup is done, you can use the server to [`send_request`] and [`send_notification`] to
|
||||
//! send messages to the server and [`await_response`], [`await_request`], and
|
||||
//! [`await_notification`] to wait for responses, requests, and notifications from the server.
|
||||
//!
|
||||
//! The [`Drop`] implementation of the [`TestServer`] ensures that the server is shut down
|
||||
//! gracefully using the LSP protocol. It also asserts that all messages sent by the server
|
||||
//! have been handled by the test client before the server is dropped.
|
||||
//!
|
||||
//! [`build`]: TestServerBuilder::build
|
||||
//! [`wait_until_workspaces_are_initialized`]: TestServer::wait_until_workspaces_are_initialized
|
||||
//! [`send_request`]: TestServer::send_request
|
||||
//! [`send_notification`]: TestServer::send_notification
|
||||
//! [`await_response`]: TestServer::await_response
|
||||
//! [`await_request`]: TestServer::await_request
|
||||
//! [`await_notification`]: TestServer::await_notification
|
||||
|
||||
mod initialize;
|
||||
mod publish_diagnostics;
|
||||
mod pull_diagnostics;
|
||||
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
|
@ -39,9 +65,7 @@ use rustc_hash::FxHashMap;
|
|||
use serde::de::DeserializeOwned;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::logging::{LogLevel, init_logging};
|
||||
use crate::server::Server;
|
||||
use crate::session::ClientOptions;
|
||||
use ty_server::{ClientOptions, LogLevel, Server, init_logging};
|
||||
|
||||
/// Number of times to retry receiving a message before giving up
|
||||
const RETRY_COUNT: usize = 5;
|
||||
|
@ -86,10 +110,6 @@ impl TestServerError {
|
|||
|
||||
/// A test server for the ty language server that provides helpers for sending requests,
|
||||
/// correlating responses, and handling notifications.
|
||||
///
|
||||
/// The [`Drop`] implementation ensures that the server is shut down gracefully using the described
|
||||
/// protocol in the LSP specification. It also ensures that all messages sent by the server have
|
||||
/// been handled by the test client before the server is dropped.
|
||||
pub(crate) struct TestServer {
|
||||
/// The thread that's actually running the server.
|
||||
///
|
||||
|
@ -103,10 +123,10 @@ pub(crate) struct TestServer {
|
|||
/// the connection to be cleaned up properly.
|
||||
client_connection: Option<Connection>,
|
||||
|
||||
/// Test directory that holds all test files.
|
||||
/// Test context that provides the project root directory that holds all test files.
|
||||
///
|
||||
/// This directory is automatically cleaned up when the [`TestServer`] is dropped.
|
||||
test_dir: TestContext,
|
||||
test_context: TestContext,
|
||||
|
||||
/// Incrementing counter to automatically generate request IDs
|
||||
request_counter: i32,
|
||||
|
@ -175,7 +195,7 @@ impl TestServer {
|
|||
Self {
|
||||
server_thread: Some(server_thread),
|
||||
client_connection: Some(client_connection),
|
||||
test_dir,
|
||||
test_context: test_dir,
|
||||
request_counter: 0,
|
||||
responses: FxHashMap::default(),
|
||||
notifications: VecDeque::new(),
|
||||
|
@ -297,9 +317,9 @@ impl TestServer {
|
|||
|
||||
/// Send a request to the server and return the request ID.
|
||||
///
|
||||
/// The caller can use this ID to later retrieve the response using [`get_response`].
|
||||
/// The caller can use this ID to later retrieve the response using [`await_response`].
|
||||
///
|
||||
/// [`get_response`]: TestServer::get_response
|
||||
/// [`await_response`]: TestServer::await_response
|
||||
pub(crate) fn send_request<R>(&mut self, params: R::Params) -> RequestId
|
||||
where
|
||||
R: Request,
|
||||
|
@ -505,7 +525,7 @@ impl TestServer {
|
|||
/// Use the [`get_request`] method to wait for the server to send this request.
|
||||
///
|
||||
/// [`get_request`]: TestServer::get_request
|
||||
pub(crate) fn handle_workspace_configuration_request(
|
||||
fn handle_workspace_configuration_request(
|
||||
&mut self,
|
||||
request_id: RequestId,
|
||||
params: &ConfigurationParams,
|
||||
|
@ -548,7 +568,7 @@ impl TestServer {
|
|||
}
|
||||
|
||||
fn file_uri(&self, path: impl AsRef<SystemPath>) -> Url {
|
||||
Url::from_file_path(self.test_dir.root().join(path.as_ref()).as_std_path())
|
||||
Url::from_file_path(self.test_context.root().join(path.as_ref()).as_std_path())
|
||||
.expect("Path must be a valid URL")
|
||||
}
|
||||
|
||||
|
@ -628,7 +648,7 @@ impl TestServer {
|
|||
impl fmt::Debug for TestServer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("TestServer")
|
||||
.field("temp_dir", &self.test_dir.root())
|
||||
.field("temp_dir", &self.test_context.root())
|
||||
.field("request_counter", &self.request_counter)
|
||||
.field("responses", &self.responses)
|
||||
.field("notifications", &self.notifications)
|
||||
|
@ -750,6 +770,7 @@ impl TestServerBuilder {
|
|||
}
|
||||
|
||||
/// Enable or disable pull diagnostics capability
|
||||
#[must_use]
|
||||
pub(crate) fn enable_pull_diagnostics(mut self, enabled: bool) -> Self {
|
||||
self.client_capabilities
|
||||
.text_document
|
||||
|
@ -763,6 +784,7 @@ impl TestServerBuilder {
|
|||
}
|
||||
|
||||
/// Enable or disable file watching capability
|
||||
#[must_use]
|
||||
#[expect(dead_code)]
|
||||
pub(crate) fn enable_did_change_watched_files(mut self, enabled: bool) -> Self {
|
||||
self.client_capabilities
|
||||
|
@ -777,6 +799,7 @@ impl TestServerBuilder {
|
|||
}
|
||||
|
||||
/// Set custom client capabilities (overrides any previously set capabilities)
|
||||
#[must_use]
|
||||
#[expect(dead_code)]
|
||||
pub(crate) fn with_client_capabilities(mut self, capabilities: ClientCapabilities) -> Self {
|
||||
self.client_capabilities = capabilities;
|
||||
|
@ -798,7 +821,7 @@ impl TestServerBuilder {
|
|||
Ok(self)
|
||||
}
|
||||
|
||||
/// Write multiple files to the temporary directory
|
||||
/// Write multiple files to the test directory
|
||||
#[expect(dead_code)]
|
||||
pub(crate) fn with_files<P, C, I>(mut self, files: I) -> Result<Self>
|
||||
where
|
30
crates/ty_server/tests/e2e/publish_diagnostics.rs
Normal file
30
crates/ty_server/tests/e2e/publish_diagnostics.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use anyhow::Result;
|
||||
use lsp_types::notification::PublishDiagnostics;
|
||||
use ruff_db::system::SystemPath;
|
||||
use ty_server::ClientOptions;
|
||||
|
||||
use crate::TestServerBuilder;
|
||||
|
||||
#[test]
|
||||
fn on_did_open() -> Result<()> {
|
||||
let workspace_root = SystemPath::new("src");
|
||||
let foo = SystemPath::new("src/foo.py");
|
||||
let foo_content = "\
|
||||
def foo() -> str:
|
||||
return 42
|
||||
";
|
||||
|
||||
let mut server = TestServerBuilder::new()?
|
||||
.with_workspace(workspace_root, ClientOptions::default())?
|
||||
.with_file(foo, foo_content)?
|
||||
.enable_pull_diagnostics(false)
|
||||
.build()?
|
||||
.wait_until_workspaces_are_initialized()?;
|
||||
|
||||
server.open_text_document(foo, &foo_content, 1);
|
||||
let diagnostics = server.await_notification::<PublishDiagnostics>()?;
|
||||
|
||||
insta::assert_debug_snapshot!(diagnostics);
|
||||
|
||||
Ok(())
|
||||
}
|
29
crates/ty_server/tests/e2e/pull_diagnostics.rs
Normal file
29
crates/ty_server/tests/e2e/pull_diagnostics.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use anyhow::Result;
|
||||
use ruff_db::system::SystemPath;
|
||||
use ty_server::ClientOptions;
|
||||
|
||||
use crate::TestServerBuilder;
|
||||
|
||||
#[test]
|
||||
fn on_did_open() -> Result<()> {
|
||||
let workspace_root = SystemPath::new("src");
|
||||
let foo = SystemPath::new("src/foo.py");
|
||||
let foo_content = "\
|
||||
def foo() -> str:
|
||||
return 42
|
||||
";
|
||||
|
||||
let mut server = TestServerBuilder::new()?
|
||||
.with_workspace(workspace_root, ClientOptions::default())?
|
||||
.with_file(foo, foo_content)?
|
||||
.enable_pull_diagnostics(true)
|
||||
.build()?
|
||||
.wait_until_workspaces_are_initialized()?;
|
||||
|
||||
server.open_text_document(foo, &foo_content, 1);
|
||||
let diagnostics = server.document_diagnostic_request(foo)?;
|
||||
|
||||
insta::assert_debug_snapshot!(diagnostics);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
source: crates/ty_server/src/server.rs
|
||||
source: crates/ty_server/tests/e2e/initialize.rs
|
||||
expression: initialization_result
|
||||
---
|
||||
{
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
source: crates/ty_server/src/server.rs
|
||||
source: crates/ty_server/tests/e2e/initialize.rs
|
||||
expression: initialization_result
|
||||
---
|
||||
{
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
source: crates/ty_server/src/server.rs
|
||||
source: crates/ty_server/tests/e2e/publish_diagnostics.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
PublishDiagnosticsParams {
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
source: crates/ty_server/src/server.rs
|
||||
source: crates/ty_server/tests/e2e/pull_diagnostics.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
Report(
|
Loading…
Add table
Add a link
Reference in a new issue