use {
laburnum::{
Laburnum,
Uri,
protocol::lsp::{
DidChangeNotebookDocumentParams,
DidCloseNotebookDocumentParams,
DidOpenNotebookDocumentParams,
DidSaveNotebookDocumentParams,
InitializeParams,
NotebookCell,
NotebookCellArrayChange,
NotebookCellKind,
NotebookDocument,
NotebookDocumentCellChange,
NotebookDocumentCellChangeStructure,
NotebookDocumentChangeEvent,
NotebookDocumentChangeTextContent,
NotebookDocumentIdentifier,
TextDocumentContentChangeEvent,
TextDocumentIdentifier,
TextDocumentItem,
VersionedNotebookDocumentIdentifier,
VersionedTextDocumentIdentifier,
},
},
macro_rules_attribute::apply,
smol_macros::test,
};
mod common;
use common::TestPartitions;
#[apply(test!)]
#[test_log::test]
async fn test_notebook_did_open() {
let (server, client) = Laburnum::<TestPartitions, _>::example().build_test();
let mut snapshot = ferrotype::Ferrotype::new();
client.start(InitializeParams::default()).await.ok();
let notebook_uri = Uri::parse("file:///test.ipynb").unwrap();
let cell_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell1").unwrap();
let params = DidOpenNotebookDocumentParams {
notebook_document: NotebookDocument {
uri: notebook_uri.clone(),
notebook_type: "jupyter-notebook".to_string(),
version: 1.into(),
metadata: None,
cells: vec![NotebookCell {
kind: NotebookCellKind::CODE,
document: cell_uri.clone(),
metadata: None,
execution_summary: None,
}],
},
cell_text_documents: vec![TextDocumentItem {
uri: cell_uri,
language_id: "python".to_string(),
version: 1.into(),
text: "print('hello')".to_string(),
}],
};
let result = client.did_open_notebook_document(params).await;
assert!(
result.is_ok(),
"did_open_notebook_document should succeed: {:?}",
result
);
client.stop_test(&mut snapshot).await.ok();
server.close().expect("Failed to close server");
ferrotype::assert!(snapshot);
}
#[apply(test!)]
#[test_log::test]
async fn test_notebook_did_close() {
let (server, client) = Laburnum::<TestPartitions, _>::example().build_test();
let mut snapshot = ferrotype::Ferrotype::new();
client.start(InitializeParams::default()).await.ok();
let notebook_uri = Uri::parse("file:///test.ipynb").unwrap();
let cell_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell1").unwrap();
let open_params = DidOpenNotebookDocumentParams {
notebook_document: NotebookDocument {
uri: notebook_uri.clone(),
notebook_type: "jupyter-notebook".to_string(),
version: 1.into(),
metadata: None,
cells: vec![NotebookCell {
kind: NotebookCellKind::CODE,
document: cell_uri.clone(),
metadata: None,
execution_summary: None,
}],
},
cell_text_documents: vec![TextDocumentItem {
uri: cell_uri.clone(),
language_id: "python".to_string(),
version: 1.into(),
text: "print('hello')".to_string(),
}],
};
client.did_open_notebook_document(open_params).await.ok();
let close_params = DidCloseNotebookDocumentParams {
notebook_document: NotebookDocumentIdentifier { uri: notebook_uri },
cell_text_documents: vec![TextDocumentIdentifier { uri: cell_uri }],
};
let result = client.did_close_notebook_document(close_params).await;
assert!(
result.is_ok(),
"did_close_notebook_document should succeed: {:?}",
result
);
client.stop_test(&mut snapshot).await.ok();
server.close().expect("Failed to close server");
ferrotype::assert!(snapshot);
}
#[apply(test!)]
#[test_log::test]
async fn test_notebook_did_save() {
let (server, client) = Laburnum::<TestPartitions, _>::example().build_test();
let mut snapshot = ferrotype::Ferrotype::new();
client.start(InitializeParams::default()).await.ok();
let notebook_uri = Uri::parse("file:///test.ipynb").unwrap();
let cell_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell1").unwrap();
let open_params = DidOpenNotebookDocumentParams {
notebook_document: NotebookDocument {
uri: notebook_uri.clone(),
notebook_type: "jupyter-notebook".to_string(),
version: 1.into(),
metadata: None,
cells: vec![NotebookCell {
kind: NotebookCellKind::CODE,
document: cell_uri.clone(),
metadata: None,
execution_summary: None,
}],
},
cell_text_documents: vec![TextDocumentItem {
uri: cell_uri,
language_id: "python".to_string(),
version: 1.into(),
text: "print('hello')".to_string(),
}],
};
client.did_open_notebook_document(open_params).await.ok();
let save_params = DidSaveNotebookDocumentParams {
notebook_document: NotebookDocumentIdentifier { uri: notebook_uri },
};
let result = client.did_save_notebook_document(save_params).await;
assert!(
result.is_ok(),
"did_save_notebook_document should succeed: {:?}",
result
);
client.stop_test(&mut snapshot).await.ok();
server.close().expect("Failed to close server");
ferrotype::assert!(snapshot);
}
#[apply(test!)]
#[test_log::test]
async fn test_notebook_did_change_metadata() {
let (server, client) = Laburnum::<TestPartitions, _>::example().build_test();
let mut snapshot = ferrotype::Ferrotype::new();
client.start(InitializeParams::default()).await.ok();
let notebook_uri = Uri::parse("file:///test.ipynb").unwrap();
let cell_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell1").unwrap();
let open_params = DidOpenNotebookDocumentParams {
notebook_document: NotebookDocument {
uri: notebook_uri.clone(),
notebook_type: "jupyter-notebook".to_string(),
version: 1.into(),
metadata: None,
cells: vec![NotebookCell {
kind: NotebookCellKind::CODE,
document: cell_uri.clone(),
metadata: None,
execution_summary: None,
}],
},
cell_text_documents: vec![TextDocumentItem {
uri: cell_uri,
language_id: "python".to_string(),
version: 1.into(),
text: "print('hello')".to_string(),
}],
};
client.did_open_notebook_document(open_params).await.ok();
let mut metadata = serde_json::Map::new();
metadata.insert(
"kernel".to_string(),
serde_json::Value::String("python3".to_string()),
);
let change_params = DidChangeNotebookDocumentParams {
notebook_document: VersionedNotebookDocumentIdentifier {
version: 2.into(),
uri: notebook_uri,
},
change: NotebookDocumentChangeEvent {
metadata: Some(metadata),
cells: None,
},
};
let result = client.did_change_notebook_document(change_params).await;
assert!(
result.is_ok(),
"did_change_notebook_document should succeed: {:?}",
result
);
client.stop_test(&mut snapshot).await.ok();
server.close().expect("Failed to close server");
ferrotype::assert!(snapshot);
}
#[apply(test!)]
#[test_log::test]
async fn test_notebook_did_change_add_cell() {
let (server, client) = Laburnum::<TestPartitions, _>::example().build_test();
let mut snapshot = ferrotype::Ferrotype::new();
client.start(InitializeParams::default()).await.ok();
let notebook_uri = Uri::parse("file:///test.ipynb").unwrap();
let cell1_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell1").unwrap();
let cell2_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell2").unwrap();
let open_params = DidOpenNotebookDocumentParams {
notebook_document: NotebookDocument {
uri: notebook_uri.clone(),
notebook_type: "jupyter-notebook".to_string(),
version: 1.into(),
metadata: None,
cells: vec![NotebookCell {
kind: NotebookCellKind::CODE,
document: cell1_uri.clone(),
metadata: None,
execution_summary: None,
}],
},
cell_text_documents: vec![TextDocumentItem {
uri: cell1_uri,
language_id: "python".to_string(),
version: 1.into(),
text: "print('hello')".to_string(),
}],
};
client.did_open_notebook_document(open_params).await.ok();
let change_params = DidChangeNotebookDocumentParams {
notebook_document: VersionedNotebookDocumentIdentifier {
version: 2.into(),
uri: notebook_uri,
},
change: NotebookDocumentChangeEvent {
metadata: None,
cells: Some(NotebookDocumentCellChange {
structure: Some(NotebookDocumentCellChangeStructure {
array: NotebookCellArrayChange {
start: 1,
delete_count: 0,
cells: Some(vec![NotebookCell {
kind: NotebookCellKind::CODE,
document: cell2_uri.clone(),
metadata: None,
execution_summary: None,
}]),
},
did_open: Some(vec![TextDocumentItem {
uri: cell2_uri,
language_id: "python".to_string(),
version: 1.into(),
text: "print('world')".to_string(),
}]),
did_close: None,
}),
data: None,
text_content: None,
}),
},
};
let result = client.did_change_notebook_document(change_params).await;
assert!(
result.is_ok(),
"did_change_notebook_document (add cell) should succeed: {:?}",
result
);
client.stop_test(&mut snapshot).await.ok();
server.close().expect("Failed to close server");
ferrotype::assert!(snapshot);
}
#[apply(test!)]
#[test_log::test]
async fn test_notebook_did_change_remove_cell() {
let (server, client) = Laburnum::<TestPartitions, _>::example().build_test();
let mut snapshot = ferrotype::Ferrotype::new();
client.start(InitializeParams::default()).await.ok();
let notebook_uri = Uri::parse("file:///test.ipynb").unwrap();
let cell1_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell1").unwrap();
let cell2_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell2").unwrap();
let open_params = DidOpenNotebookDocumentParams {
notebook_document: NotebookDocument {
uri: notebook_uri.clone(),
notebook_type: "jupyter-notebook".to_string(),
version: 1.into(),
metadata: None,
cells: vec![
NotebookCell {
kind: NotebookCellKind::CODE,
document: cell1_uri.clone(),
metadata: None,
execution_summary: None,
},
NotebookCell {
kind: NotebookCellKind::CODE,
document: cell2_uri.clone(),
metadata: None,
execution_summary: None,
},
],
},
cell_text_documents: vec![
TextDocumentItem {
uri: cell1_uri,
language_id: "python".to_string(),
version: 1.into(),
text: "print('hello')".to_string(),
},
TextDocumentItem {
uri: cell2_uri.clone(),
language_id: "python".to_string(),
version: 1.into(),
text: "print('world')".to_string(),
},
],
};
client.did_open_notebook_document(open_params).await.ok();
let change_params = DidChangeNotebookDocumentParams {
notebook_document: VersionedNotebookDocumentIdentifier {
version: 2.into(),
uri: notebook_uri,
},
change: NotebookDocumentChangeEvent {
metadata: None,
cells: Some(NotebookDocumentCellChange {
structure: Some(NotebookDocumentCellChangeStructure {
array: NotebookCellArrayChange {
start: 1,
delete_count: 1,
cells: None,
},
did_open: None,
did_close: Some(vec![TextDocumentIdentifier { uri: cell2_uri }]),
}),
data: None,
text_content: None,
}),
},
};
let result = client.did_change_notebook_document(change_params).await;
assert!(
result.is_ok(),
"did_change_notebook_document (remove cell) should succeed: {:?}",
result
);
client.stop_test(&mut snapshot).await.ok();
server.close().expect("Failed to close server");
ferrotype::assert!(snapshot);
}
#[apply(test!)]
#[test_log::test]
async fn test_notebook_did_change_text_content() {
let (server, client) = Laburnum::<TestPartitions, _>::example().build_test();
let mut snapshot = ferrotype::Ferrotype::new();
client.start(InitializeParams::default()).await.ok();
let notebook_uri = Uri::parse("file:///test.ipynb").unwrap();
let cell_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell1").unwrap();
let open_params = DidOpenNotebookDocumentParams {
notebook_document: NotebookDocument {
uri: notebook_uri.clone(),
notebook_type: "jupyter-notebook".to_string(),
version: 1.into(),
metadata: None,
cells: vec![NotebookCell {
kind: NotebookCellKind::CODE,
document: cell_uri.clone(),
metadata: None,
execution_summary: None,
}],
},
cell_text_documents: vec![TextDocumentItem {
uri: cell_uri.clone(),
language_id: "python".to_string(),
version: 1.into(),
text: "print('hello')".to_string(),
}],
};
client.did_open_notebook_document(open_params).await.ok();
let change_params = DidChangeNotebookDocumentParams {
notebook_document: VersionedNotebookDocumentIdentifier {
version: 2.into(),
uri: notebook_uri,
},
change: NotebookDocumentChangeEvent {
metadata: None,
cells: Some(NotebookDocumentCellChange {
structure: None,
data: None,
text_content: Some(vec![NotebookDocumentChangeTextContent {
document: VersionedTextDocumentIdentifier {
uri: cell_uri,
version: 2.into(),
},
changes: vec![TextDocumentContentChangeEvent {
range: None,
range_length: None,
text: "print('hello world')".to_string(),
}],
}]),
}),
},
};
let result = client.did_change_notebook_document(change_params).await;
assert!(
result.is_ok(),
"did_change_notebook_document (text content) should succeed: {:?}",
result
);
client.stop_test(&mut snapshot).await.ok();
server.close().expect("Failed to close server");
ferrotype::assert!(snapshot);
}
#[apply(test!)]
#[test_log::test]
async fn test_notebook_lifecycle() {
let (server, client) = Laburnum::<TestPartitions, _>::example().build_test();
let mut snapshot = ferrotype::Ferrotype::new();
client.start(InitializeParams::default()).await.ok();
let notebook_uri = Uri::parse("file:///test.ipynb").unwrap();
let cell_uri = Uri::parse("vscode-notebook-cell:/test.ipynb#cell1").unwrap();
let open_params = DidOpenNotebookDocumentParams {
notebook_document: NotebookDocument {
uri: notebook_uri.clone(),
notebook_type: "jupyter-notebook".to_string(),
version: 1.into(),
metadata: None,
cells: vec![NotebookCell {
kind: NotebookCellKind::CODE,
document: cell_uri.clone(),
metadata: None,
execution_summary: None,
}],
},
cell_text_documents: vec![TextDocumentItem {
uri: cell_uri.clone(),
language_id: "python".to_string(),
version: 1.into(),
text: "print('hello')".to_string(),
}],
};
client.did_open_notebook_document(open_params).await.ok();
let change_params = DidChangeNotebookDocumentParams {
notebook_document: VersionedNotebookDocumentIdentifier {
version: 2.into(),
uri: notebook_uri.clone(),
},
change: NotebookDocumentChangeEvent {
metadata: None,
cells: Some(NotebookDocumentCellChange {
structure: None,
data: None,
text_content: Some(vec![NotebookDocumentChangeTextContent {
document: VersionedTextDocumentIdentifier {
uri: cell_uri.clone(),
version: 2.into(),
},
changes: vec![TextDocumentContentChangeEvent {
range: None,
range_length: None,
text: "print('modified')".to_string(),
}],
}]),
}),
},
};
client
.did_change_notebook_document(change_params)
.await
.ok();
let save_params = DidSaveNotebookDocumentParams {
notebook_document: NotebookDocumentIdentifier {
uri: notebook_uri.clone(),
},
};
client.did_save_notebook_document(save_params).await.ok();
let close_params = DidCloseNotebookDocumentParams {
notebook_document: NotebookDocumentIdentifier { uri: notebook_uri },
cell_text_documents: vec![TextDocumentIdentifier { uri: cell_uri }],
};
let result = client.did_close_notebook_document(close_params).await;
assert!(
result.is_ok(),
"notebook lifecycle should complete successfully: {:?}",
result
);
client.stop_test(&mut snapshot).await.ok();
server.close().expect("Failed to close server");
ferrotype::assert!(snapshot);
}