use super::*;
use serde_json::json;
const ROUNDS: i32 = 16;
const PRE_OPENED: usize = 8;
fn fixture_text(name: &str) -> String {
let path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/references_stress/src")
.join(name);
std::fs::read_to_string(path).expect("read references_stress fixture")
}
fn wide_body(class: &str, marker: i32) -> String {
let mut src = format!("<?php\n\nnamespace App;\n\nclass {class}\n{{\n");
src.push_str(&format!(
" private function compute(): int {{ return {marker}; }}\n"
));
for m in 0..120 {
src.push_str(&format!(
" public function process{m}(Target $t): int {{ return $t->process() + $this->compute() + {m}; }}\n"
));
}
src.push_str("}\n");
src
}
#[tokio::test]
async fn interleaved_edits_and_opens_keep_publishing() {
let mut s = TestServer::with_fixture("references_stress").await;
s.wait_for_index_ready().await;
let target = fixture_text("Target.php");
s.open("src/Target.php", &target).await;
for i in 0..PRE_OPENED {
let name = format!("Noise{i}.php");
s.open(&format!("src/{name}"), &wide_body(&format!("Noise{i}"), 0))
.await;
}
let target_uri = s.uri("src/Target.php");
for round in 0..ROUNDS {
let version = 2 + round;
s.client()
.notify(
"textDocument/didChange",
json!({
"textDocument": { "uri": target_uri, "version": version },
"contentChanges": [{ "text": format!("{target}\n// edit {round}\n") }],
}),
)
.await;
s.client()
.wait_for_diagnostics_version(&target_uri, version)
.await;
let name = format!("Noise{}.php", PRE_OPENED + round as usize);
let uri = s.uri(&format!("src/{name}"));
s.client()
.notify(
"textDocument/didOpen",
json!({
"textDocument": {
"uri": uri,
"languageId": "php",
"version": 1,
"text": wide_body(&name.replace(".php", ""), round),
}
}),
)
.await;
s.client().wait_for_diagnostics_version(&uri, 1).await;
}
s.hover("src/Target.php", 4, 6).await;
}