From 00663a870b091ff9407e6cfc03c37d0fa989d94a Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 22 Aug 2026 19:14:54 +0200 Subject: [PATCH] Teach the chain test that a detail node has no fused fragment every_operation_can_be_activated_together counted one block per operation in the chain, which was true only while every operation was a point function. A neighbourhood operation is a dispatch of its own and emits no fused block, so the count now excludes the operations the detail chain names, and each of them is separately asserted absent rather than the comparison being loosened. Co-Authored-By: Claude Opus 5 (1M context) --- core/dr-pipeline/src/lib.rs | 40 +++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/core/dr-pipeline/src/lib.rs b/core/dr-pipeline/src/lib.rs index a763ef9..68545e9 100644 --- a/core/dr-pipeline/src/lib.rs +++ b/core/dr-pipeline/src/lib.rs @@ -107,13 +107,45 @@ mod tests { let g = fully_active(); assert!(!g.is_neutral()); let shader = g.compose(); - // Counted against the chain rather than a literal, so adding an - // operation does not require editing this test. + + // A neighbourhood operation contributes no fused fragment. That is not + // an omission: it reads pixels it is not writing, the fused contract + // hands a fragment a colour with no way back to a coordinate, and + // `compose_full` filters it out rather than emitting an empty block + // that would read as an operation doing nothing (see `crate::detail`). + // + // So the count is against the operations that *can* be fused, and the + // ones that cannot are named by the detail chain rather than by a list + // written here — which is what keeps this test correct as sharpening, + // noise reduction and clarity arrive, rather than weakening it into + // "most of them appear". + // + // Composed at source resolution deliberately: an acutance operation's + // radius is in source pixels, and on a proxy it may honestly decline + // to draw at all (`RenderScale::resolves`), which would leave it out + // of both halves and make this count agree for the wrong reason. + let detail = g.compose_detail(crate::detail::RenderScale::full((4096, 4096))); + let neighbourhood: std::collections::BTreeSet<&str> = detail + .passes + .iter() + .map(|p| p.label.split('/').next().expect("/")) + .collect(); + assert_eq!( shader.source.matches("---- ").count(), - g.descriptors().len(), - "every operation in the chain should appear" + g.descriptors().len() - neighbourhood.len(), + "every operation that can be a fused fragment should appear" ); + + // And each neighbourhood operation is genuinely absent from the fused + // shader rather than merely uncounted — the arithmetic above would be + // satisfied just as well by two errors that cancelled. + for id in &neighbourhood { + assert!( + !shader.source.contains(&format!("---- {id} ----")), + "{id} reads its neighbours and cannot be a fused fragment" + ); + } } #[test]