test(stage2a): the reconciliation acceptance suite

`tests/resource_reconciliation_acceptance.rs`, 23 rows, no dired
content — items 23–37 and 50–55 driven through the real entry points:
`pmacs.fs.rename` / `pmacs.fs.remove` fire-and-forget for the drain
harvest, `pmacs.buffer.apply_resource_op` for the synchronous arm, and
the fake server's `workspace/applyEdit` for the applier.

The rows that took design rather than transcription:

Item 27 opens two descendants AND two buffers on one exact path, since
one child would not defeat a first-match lookup. Item 29 tests name
provenance in both directions, including a name explicitly set to a
string that normalizes to the file's own path — the case a
path-equivalence heuristic gets wrong. Item 30 paints a real frame and
counts diagnostic underlines per window rect, because
`DiagnosticView.uri` is private and a store assertion would prove
nothing about re-rooting; it also pins each overlay's index in the
composition order, which is what a remove-and-re-push breaks. Item 53b
states its three assertions individually, since a compound check can
pass on two of the three.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lv428Fth9LRtffwJSsqH7T
This commit is contained in:
Levi Neuwirth 2026-07-29 18:40:38 -04:00
parent aa813ec3b6
commit 3c66370b8c
3 changed files with 1757 additions and 11 deletions

View File

@ -512,7 +512,7 @@ impl View for DiagnosticView {
/// position in the window's composition order.
fn rename_resource(&mut self, old_uri: &str, new_uri: &str) {
if self.uri == old_uri {
self.uri = new_uri.to_owned();
new_uri.clone_into(&mut self.uri);
}
}
@ -781,7 +781,10 @@ mod tests {
#[test]
fn forget_drops_the_epoch_while_clear_deliberately_bumps_it() {
let mut store = DiagnosticStore::new();
store.set("file:///a.rs", vec![diag(0, DiagnosticSeverity::Error, "boom")]);
store.set(
"file:///a.rs",
vec![diag(0, DiagnosticSeverity::Error, "boom")],
);
store.mark_stale("file:///a.rs");
assert_eq!(store.epoch_for("file:///a.rs"), 1);
@ -792,7 +795,10 @@ mod tests {
"clear announces the removal to epoch-keyed caches"
);
store.set("file:///a.rs", vec![diag(0, DiagnosticSeverity::Error, "boom")]);
store.set(
"file:///a.rs",
vec![diag(0, DiagnosticSeverity::Error, "boom")],
);
store.mark_stale("file:///a.rs");
store.forget("file:///a.rs");
assert!(store.for_uri("file:///a.rs").is_empty(), "diagnostics");

View File

@ -3171,6 +3171,10 @@ impl LspManager {
/// attachment need not have any pending route or populated result
/// store, and cleanup can be repeated after an earlier partial
/// teardown.
#[allow(
clippy::too_many_lines,
reason = "the fourteen store families are a flat inventory; splitting it is how one of them gets forgotten, which is the defect this method exists to prevent"
)]
pub fn forget_uri(&mut self, sid: LspServerId, uri: &str) -> Result<(), String> {
if !self.clients.contains_key(&sid) {
return Err(format!("unknown server: {sid}"));
@ -4233,13 +4237,18 @@ mod resource_reconciliation_tests {
"data": [0, 0, 1, 0, 0],
})),
);
mgr.documents.insert((sid, uri.to_owned()), "text".to_owned());
mgr.documents
.insert((sid, uri.to_owned()), "text".to_owned());
}
/// Which of the fourteen families still hold an entry for
/// `(sid, uri)`, by name. An empty vector is the post-forget
/// expectation; naming the survivors is what makes a failure
/// actionable instead of "assert!(false)".
#[allow(
clippy::too_many_lines,
reason = "one probe per store family, mirroring the inventory under test"
)]
fn populated_families(mgr: &LspManager, sid: LspServerId, uri: &str) -> Vec<&'static str> {
let server = sid.raw().to_string();
let mut out = Vec::new();
@ -4560,9 +4569,10 @@ mod resource_reconciliation_tests {
.expect_err("unknown server must raise, matching `forget`");
assert!(err.contains("unknown server"), "{err}");
mgr.forget_uri(a, "file:///tmp/never-touched.rs")
.expect("a URI with no state under a known server is an \
idempotent success, not an error");
mgr.forget_uri(a, "file:///tmp/never-touched.rs").expect(
"a URI with no state under a known server is an \
idempotent success, not an error",
);
mgr.forget_uri(a, "file:///tmp/never-touched.rs")
.expect("and repeating it stays safe");
}
@ -4613,10 +4623,7 @@ mod resource_reconciliation_tests {
mgr.mark_document_stale(a, old);
assert!(
!mgr.diag_store.lock().unwrap().is_stale(old),
"diagnostics"
);
assert!(!mgr.diag_store.lock().unwrap().is_stale(old), "diagnostics");
assert!(
!mgr.semantic_token_store.lock().unwrap().is_stale(old),
"semantic tokens"

File diff suppressed because it is too large Load Diff