use super::*;
use expect_test::expect;
use serde_json::json;
fn copy_dir_all(src: &std::path::Path, dst: &std::path::Path) -> std::io::Result<()> {
std::fs::create_dir_all(dst)?;
for entry in std::fs::read_dir(src)? {
let entry = entry?;
let from = entry.path();
let to = dst.join(entry.file_name());
if entry.file_type()?.is_dir() {
copy_dir_all(&from, &to)?;
} else {
std::fs::copy(&from, &to)?;
}
}
Ok(())
}
fn fixture_path(name: &str) -> std::path::PathBuf {
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures")
.join(name)
}
#[tokio::test]
async fn warm_start_serves_symbols_correctly() {
let workspace = tempfile::tempdir().expect("workspace tempdir");
let cache_dir = tempfile::tempdir().expect("cache tempdir");
copy_dir_all(&fixture_path("psr4-mini"), workspace.path()).expect("copy fixture");
let opts = json!({
"cachePath": cache_dir.path().to_str().unwrap(),
"diagnostics": {"enabled": false},
});
{
let mut s = TestServer::with_root_and_options(workspace.path(), opts.clone()).await;
s.wait_for_index_ready().await;
let syms = s.snapshot_workspace_symbols("User").await;
expect![[r#"Class User @ src/Model/User.php:4"#]].assert_eq(&syms);
}
{
let mut s = TestServer::with_root_and_options(workspace.path(), opts).await;
s.wait_for_index_ready().await;
let syms = s.snapshot_workspace_symbols("User").await;
expect![[r#"Class User @ src/Model/User.php:4"#]].assert_eq(&syms);
}
}
#[tokio::test]
async fn warm_start_detects_changed_file_content() {
let workspace = tempfile::tempdir().expect("workspace tempdir");
let cache_dir = tempfile::tempdir().expect("cache tempdir");
copy_dir_all(&fixture_path("psr4-mini"), workspace.path()).expect("copy fixture");
let opts = json!({
"cachePath": cache_dir.path().to_str().unwrap(),
"diagnostics": {"enabled": false},
});
{
let mut s = TestServer::with_root_and_options(workspace.path(), opts.clone()).await;
s.wait_for_index_ready().await;
let syms = s.snapshot_workspace_symbols("Widget").await;
expect![[r#"<no symbols>"#]].assert_eq(&syms);
}
let user_php = workspace.path().join("src/Model/User.php");
std::fs::write(
&user_php,
"<?php\nnamespace App\\Model;\n\nclass Widget {}\n",
)
.expect("overwrite User.php");
{
let mut s = TestServer::with_root_and_options(workspace.path(), opts).await;
s.wait_for_index_ready().await;
let syms = s.snapshot_workspace_symbols("Widget").await;
expect![[r#"Class Widget @ src/Model/User.php:3"#]].assert_eq(&syms);
}
}
#[tokio::test]
async fn did_save_cache_is_found_by_subsequent_scan() {
let workspace = tempfile::tempdir().expect("workspace tempdir");
let cache_dir = tempfile::tempdir().expect("cache tempdir");
copy_dir_all(&fixture_path("psr4-mini"), workspace.path()).expect("copy fixture");
let opts = json!({
"cachePath": cache_dir.path().to_str().unwrap(),
"diagnostics": {"enabled": false},
});
{
let mut s = TestServer::with_root_and_options(workspace.path(), opts.clone()).await;
s.wait_for_index_ready().await;
let user_content = "<?php\nnamespace App\\Model;\n\nclass User { public int $id; }\n";
let user_php = workspace.path().join("src/Model/User.php");
std::fs::write(&user_php, user_content).expect("write User.php");
let uri = s.uri("src/Model/User.php");
s.client()
.notify(
"textDocument/didSave",
serde_json::json!({ "textDocument": { "uri": uri } }),
)
.await;
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
}
{
let mut s = TestServer::with_root_and_options(workspace.path(), opts).await;
s.wait_for_index_ready().await;
let syms = s.snapshot_workspace_symbols("User").await;
expect![[r#"Class User @ src/Model/User.php:3"#]].assert_eq(&syms);
}
}