Add Jupyter Notebook document change snapshot test (#11944)

## Summary

Closes #11914.

This PR introduces a snapshot test that replays the LSP requests made
during a document formatting request, and confirms that the notebook
document is updated in the expected way.
This commit is contained in:
Jane Lewis 2024-06-20 22:29:27 -07:00 committed by GitHub
parent 927069c12f
commit 3ab7a8da73
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 921 additions and 20 deletions

View file

@ -8,7 +8,7 @@ mod text_document;
use std::collections::HashMap;
use lsp_types::{PositionEncodingKind, Url};
pub(crate) use notebook::NotebookDocument;
pub use notebook::NotebookDocument;
pub(crate) use range::{NotebookRange, RangeExt, ToRangeExt};
pub(crate) use replacement::Replacement;
pub(crate) use text_document::DocumentVersion;
@ -34,7 +34,7 @@ pub enum PositionEncoding {
/// A unique document ID, derived from a URL passed as part of an LSP request.
/// This document ID can point to either be a standalone Python file, a full notebook, or a cell within a notebook.
#[derive(Clone, Debug)]
pub(crate) enum DocumentKey {
pub enum DocumentKey {
Notebook(Url),
NotebookCell(Url),
Text(Url),

View file

@ -13,7 +13,7 @@ pub(super) type CellId = usize;
/// The state of a notebook document in the server. Contains an array of cells whose
/// contents are internally represented by [`TextDocument`]s.
#[derive(Clone, Debug)]
pub(crate) struct NotebookDocument {
pub struct NotebookDocument {
cells: Vec<NotebookCell>,
metadata: ruff_notebook::RawNotebookMetadata,
version: DocumentVersion,
@ -30,7 +30,7 @@ struct NotebookCell {
}
impl NotebookDocument {
pub(crate) fn new(
pub fn new(
version: DocumentVersion,
cells: Vec<lsp_types::NotebookCell>,
metadata: serde_json::Map<String, serde_json::Value>,
@ -59,7 +59,7 @@ impl NotebookDocument {
/// Generates a pseudo-representation of a notebook that lacks per-cell metadata and contextual information
/// but should still work with Ruff's linter.
pub(crate) fn make_ruff_notebook(&self) -> ruff_notebook::Notebook {
pub fn make_ruff_notebook(&self) -> ruff_notebook::Notebook {
let cells = self
.cells
.iter()

View file

@ -1,8 +1,9 @@
//! ## The Ruff Language Server
pub use edit::{PositionEncoding, TextDocument};
pub use edit::{DocumentKey, NotebookDocument, PositionEncoding, TextDocument};
use lsp_types::CodeActionKind;
pub use server::Server;
pub use session::{ClientSettings, DocumentQuery, DocumentSnapshot, Session};
#[macro_use]
mod message;

View file

@ -8,15 +8,16 @@ use crate::edit::{DocumentKey, DocumentVersion, NotebookDocument};
use crate::{PositionEncoding, TextDocument};
pub(crate) use self::capabilities::ResolvedClientCapabilities;
pub(crate) use self::index::DocumentQuery;
pub(crate) use self::settings::{AllSettings, ClientSettings};
pub use self::index::DocumentQuery;
pub(crate) use self::settings::AllSettings;
pub use self::settings::ClientSettings;
mod capabilities;
mod index;
mod settings;
/// The global state for the LSP
pub(crate) struct Session {
pub struct Session {
/// Used to retrieve information about open documents and settings.
index: index::Index,
/// The global position encoding, negotiated during LSP initialization.
@ -29,7 +30,7 @@ pub(crate) struct Session {
/// An immutable snapshot of `Session` that references
/// a specific document.
pub(crate) struct DocumentSnapshot {
pub struct DocumentSnapshot {
resolved_client_capabilities: Arc<ResolvedClientCapabilities>,
client_settings: settings::ResolvedClientSettings,
document_ref: index::DocumentQuery,
@ -37,7 +38,7 @@ pub(crate) struct DocumentSnapshot {
}
impl Session {
pub(crate) fn new(
pub fn new(
client_capabilities: &ClientCapabilities,
position_encoding: PositionEncoding,
global_settings: ClientSettings,
@ -53,12 +54,12 @@ impl Session {
})
}
pub(crate) fn key_from_url(&self, url: Url) -> DocumentKey {
pub fn key_from_url(&self, url: Url) -> DocumentKey {
self.index.key_from_url(url)
}
/// Creates a document snapshot with the URL referencing the document to snapshot.
pub(crate) fn take_snapshot(&self, url: Url) -> Option<DocumentSnapshot> {
pub fn take_snapshot(&self, url: Url) -> Option<DocumentSnapshot> {
let key = self.key_from_url(url);
Some(DocumentSnapshot {
resolved_client_capabilities: self.resolved_client_capabilities.clone(),
@ -98,7 +99,7 @@ impl Session {
///
/// The document key must point to a notebook document or cell, or this will
/// throw an error.
pub(crate) fn update_notebook_document(
pub fn update_notebook_document(
&mut self,
key: &DocumentKey,
cells: Option<NotebookDocumentCellChange>,
@ -112,7 +113,7 @@ impl Session {
/// Registers a notebook document at the provided `url`.
/// If a document is already open here, it will be overwritten.
pub(crate) fn open_notebook_document(&mut self, url: Url, document: NotebookDocument) {
pub fn open_notebook_document(&mut self, url: Url, document: NotebookDocument) {
self.index.open_notebook_document(url, document);
}
@ -175,7 +176,7 @@ impl DocumentSnapshot {
&self.client_settings
}
pub(crate) fn query(&self) -> &index::DocumentQuery {
pub fn query(&self) -> &index::DocumentQuery {
&self.document_ref
}

View file

@ -49,7 +49,7 @@ enum DocumentController {
/// This query can 'select' a text document, full notebook, or a specific notebook cell.
/// It also includes document settings.
#[derive(Clone)]
pub(crate) enum DocumentQuery {
pub enum DocumentQuery {
Text {
file_url: Url,
document: Arc<TextDocument>,
@ -519,7 +519,7 @@ impl DocumentQuery {
}
/// Attempts to access the underlying notebook document that this query is selecting.
pub(crate) fn as_notebook(&self) -> Option<&NotebookDocument> {
pub fn as_notebook(&self) -> Option<&NotebookDocument> {
match self {
Self::Notebook { notebook, .. } => Some(notebook),
Self::Text { .. } => None,

View file

@ -18,7 +18,7 @@ use walkdir::WalkDir;
use crate::session::settings::{ConfigurationPreference, ResolvedEditorSettings};
pub(crate) struct RuffSettings {
pub struct RuffSettings {
/// The path to this configuration file, used for debugging.
/// The default fallback configuration does not have a file path.
path: Option<PathBuf>,

View file

@ -60,7 +60,7 @@ pub(crate) enum ConfigurationPreference {
#[derive(Debug, Deserialize, Default)]
#[cfg_attr(test, derive(PartialEq, Eq))]
#[serde(rename_all = "camelCase")]
pub(crate) struct ClientSettings {
pub struct ClientSettings {
configuration: Option<String>,
fix_all: Option<bool>,
organize_imports: Option<bool>,