use super::*;
#[test]
fn tracks_workspace_folder_changes() {
let workspace_root = std::env::temp_dir().join(format!(
"omena-lsp-server-added-workspace-{}",
std::process::id()
));
let src_dir = workspace_root.join("src");
let style_path = src_dir.join("Added.module.scss");
let _ = std::fs::remove_dir_all(&workspace_root);
let create_dir_result = std::fs::create_dir_all(&src_dir);
assert!(
create_dir_result.is_ok(),
"create added-workspace fixture directory: {:?}",
create_dir_result.err(),
);
let write_result = std::fs::write(&style_path, ".added { color: red; }");
assert!(
write_result.is_ok(),
"write added-workspace style fixture: {:?}",
write_result.err(),
);
let workspace_uri = format!("file://{}", workspace_root.display());
let style_uri = format!("file://{}", style_path.display());
let mut state = LspShellState::default();
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"workspaceFolders": [
{
"uri": "file:///workspace-a",
"name": "workspace-a",
},
],
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "workspace/didChangeWorkspaceFolders",
"params": {
"event": {
"removed": [
{
"uri": "file:///workspace-a",
"name": "workspace-a",
},
],
"added": [
{
"uri": workspace_uri,
"name": "workspace-b",
},
],
},
},
}),
);
assert_eq!(state.workspace_folder_count(), 1);
assert!(state.workspace_folder("file:///workspace-a").is_none());
assert!(state.workspace_folder(workspace_uri.as_str()).is_some());
let indexed = state
.document(style_uri.as_str())
.and_then(|document| document.style_summary.as_ref());
assert_eq!(
indexed.map(|summary| summary.selector_names.clone()),
Some(vec!["added".to_string()]),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "workspace/didChangeWorkspaceFolders",
"params": {
"event": {
"removed": [
{
"uri": workspace_uri,
"name": "workspace-b",
},
],
"added": [],
},
},
}),
);
assert!(state.workspace_folder(workspace_uri.as_str()).is_none());
assert!(state.document(style_uri.as_str()).is_none());
let _ = std::fs::remove_dir_all(&workspace_root);
}
#[test]
fn retargets_indexed_style_documents_after_nested_workspace_removal() {
let workspace_root = std::env::temp_dir().join(format!(
"omena-lsp-server-nested-workspace-retarget-{}",
std::process::id()
));
let nested_root = workspace_root.join("packages").join("app");
let src_dir = nested_root.join("src");
let style_path = src_dir.join("Nested.module.scss");
let _ = std::fs::remove_dir_all(&workspace_root);
let create_dir_result = std::fs::create_dir_all(&src_dir);
assert!(
create_dir_result.is_ok(),
"create nested-workspace fixture directory: {:?}",
create_dir_result.err(),
);
let write_result = std::fs::write(&style_path, ".nested { color: red; }");
assert!(
write_result.is_ok(),
"write nested-workspace style fixture: {:?}",
write_result.err(),
);
let workspace_uri = format!("file://{}", workspace_root.display());
let nested_workspace_uri = format!("file://{}", nested_root.display());
let style_uri = format!("file://{}", style_path.display());
let mut state = LspShellState::default();
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"workspaceFolders": [
{
"uri": workspace_uri,
"name": "workspace",
},
{
"uri": nested_workspace_uri,
"name": "app",
},
],
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "initialized",
"params": {},
}),
);
let indexed = state.document(style_uri.as_str());
assert_eq!(
indexed.and_then(|document| document.workspace_folder_uri.as_deref()),
Some(nested_workspace_uri.as_str()),
);
assert_eq!(
indexed
.and_then(|document| document.style_summary.as_ref())
.map(|summary| summary.selector_names.clone()),
Some(vec!["nested".to_string()]),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "workspace/didChangeWorkspaceFolders",
"params": {
"event": {
"removed": [
{
"uri": nested_workspace_uri,
"name": "app",
},
],
"added": [],
},
},
}),
);
let retargeted = state.document(style_uri.as_str());
assert_eq!(
retargeted.and_then(|document| document.workspace_folder_uri.as_deref()),
Some(workspace_uri.as_str()),
);
assert_eq!(
retargeted
.and_then(|document| document.style_summary.as_ref())
.map(|summary| summary.selector_names.clone()),
Some(vec!["nested".to_string()]),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "workspace/didChangeWorkspaceFolders",
"params": {
"event": {
"removed": [
{
"uri": workspace_uri,
"name": "workspace",
},
],
"added": [],
},
},
}),
);
assert!(state.document(style_uri.as_str()).is_none());
let _ = std::fs::remove_dir_all(&workspace_root);
}
#[test]
fn assigns_document_workspace_folder_by_longest_uri_prefix() {
let mut state = LspShellState::default();
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"workspaceFolders": [
{
"uri": "file:///workspace",
"name": "workspace",
},
{
"uri": "file:///workspace/packages/app",
"name": "app",
},
],
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "textDocument/didOpen",
"params": {
"textDocument": {
"uri": "file:///workspace/packages/app/src/App.tsx",
"languageId": "typescriptreact",
"version": 1,
"text": "export const App = () => null;",
},
},
}),
);
assert_eq!(
state
.document("file:///workspace/packages/app/src/App.tsx")
.and_then(|document| document.workspace_folder_uri.as_deref()),
Some("file:///workspace/packages/app"),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "workspace/didChangeWorkspaceFolders",
"params": {
"event": {
"removed": [
{
"uri": "file:///workspace/packages/app",
"name": "app",
},
],
"added": [],
},
},
}),
);
assert_eq!(
state
.document("file:///workspace/packages/app/src/App.tsx")
.and_then(|document| document.workspace_folder_uri.as_deref()),
Some("file:///workspace"),
);
}