Files
Aura/crates/aura-engine/tests/flat_taps_e2e.rs
T
claude 17e125a90a feat(engine): FlatTap type + FlatGraph.taps field (#282)
Second slice: the resolved-tap carrier. FlatTap { name, node, field } is the
output-side twin of SourceSpec — its name survives compile, load-bearing for
by-name binding (#275). FlatGraph gains a taps field, threaded (empty) through
every construction site the compiler enumerates. Bootstrap ignores it (taps
materialize as real recorder nodes/edges before bootstrap in a later slice).
Purely additive: the inert-producer pin and full suite stay green.

refs #282
2026-07-17 22:52:21 +02:00

71 lines
3.7 KiB
Rust

//! End-to-end coverage for the `FlatTap` / `FlatGraph.taps` plumbing (#282,
//! "thread all literal sites"): a `Composite` can declare a `Tap` (via
//! `with_taps`), but this slice adds only the flat-graph *carrier* — no
//! resolution step exists yet. These tests pin the two halves of that
//! contract at the public `aura_engine` boundary: `compile()` never surfaces
//! a declared `Tap` into the flat graph it hands to `Harness::bootstrap`
//! (`compile_never_resolves_declared_taps_yet`), and the field's presence is
//! otherwise perfectly transparent to compilation of the rest of the graph
//! (`tapped_composite_compiles_identically_to_untapped_besides_the_taps_list`)
//! — a future resolving slice (`bind_tap`) is expected to flip the first of
//! these; until it does, a regression that started eagerly resolving taps,
//! or one that let a `Tap` perturb node/edge flattening, would be caught
//! here.
use aura_core::ScalarKind;
use aura_engine::{Composite, OutField, Role, Tap, TapWire, Target};
use aura_std::Sub;
/// A trivial one-node composite with a single declared output (`Sub`'s
/// difference), matching the `taps` argument requested by each test. Both of
/// `Sub`'s input slots are fed by one root-bound (source) role — enough to
/// satisfy `compile()`'s port-connectivity + root-binding checks.
fn leaf(taps: Vec<Tap>) -> Composite {
Composite::new(
"leaf",
vec![Sub::builder().into()],
vec![],
vec![Role {
name: "price".into(),
targets: vec![Target { node: 0, slot: 0 }, Target { node: 0, slot: 1 }],
source: Some(ScalarKind::F64),
}],
vec![OutField { node: 0, field: 0, name: "o".into() }],
)
.with_taps(taps)
}
/// Property: **`compile()` resolves no `Tap`s in this slice.** A composite
/// declaring a valid `Tap` (naming a real interior producer, `node: 0, field:
/// 0`) still compiles to a `FlatGraph` whose `taps` list is empty — the
/// declaration is carried on the `Composite` only; nothing yet lowers it into
/// the flat `FlatTap` the run loop could someday read. If a later change
/// started eagerly resolving `Tap`s into `FlatGraph.taps` inside `compile()`
/// without an explicit opt-in (`bind_tap`), this test would flip green->red,
/// flagging the design-changing move for the ledger instead of it happening
/// silently.
#[test]
fn compile_never_resolves_declared_taps_yet() {
let tapped = leaf(vec![Tap { name: "spread".into(), from: TapWire { node: 0, field: 0 } }]);
let flat = tapped.compile().expect("a tap-bearing composite still compiles");
assert!(flat.taps.is_empty(), "compile() must not resolve declared Taps in this slice: {:?}", flat.taps);
}
/// Property: **a declared `Tap` is otherwise inert at compile time** — it
/// changes nothing about the flattened node/edge structure. Compiling the
/// same composite with and without a `Tap` declaration must produce
/// structurally identical flat graphs (same node count, same edges); the
/// only difference tap-bearing scaffolding is *allowed* to make is the (here,
/// still-empty) `taps` list itself.
#[test]
fn tapped_composite_compiles_identically_to_untapped_besides_the_taps_list() {
let untapped = leaf(vec![]).compile().expect("untapped compiles");
let tapped = leaf(vec![Tap { name: "spread".into(), from: TapWire { node: 0, field: 0 } }])
.compile()
.expect("tapped compiles");
assert_eq!(untapped.nodes.len(), tapped.nodes.len(), "tap declaration must not add/remove flat nodes");
assert_eq!(untapped.edges, tapped.edges, "tap declaration must not perturb flat edges");
assert_eq!(untapped.taps, tapped.taps, "both compile to the same (empty) taps list in this slice");
}