refactor(aura-std, aura-runner): retire the orphaned FoldSchema table
Review finding on the #332 fix: rendering --folds from the fold-registry roster removed fold_vocabulary()/FoldSchema's last production consumer, leaving a second, unsurfaced source of fold docs whose wording had already diverged from the registry. The table and its two tests are gone; the discipline they carried moves onto the surviving surface: the registry tests now doc-gate every roster entry (C29 entry seam) and pin the bind/output prose inside each doc line against the entry's executable binds_at/output rules, so the roster cannot drift from what the wiring enforces. refs #332
This commit is contained in:
@@ -526,6 +526,64 @@ mod tests {
|
|||||||
assert!(r.roster().iter().all(|(_, doc)| !doc.is_empty()), "every entry documents itself");
|
assert!(r.roster().iter().all(|(_, doc)| !doc.is_empty()), "every entry documents itself");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// C29 entry seam for the registry roster: every entry ships a gate-clean
|
||||||
|
/// one-line meaning, and the bind/output prose inside it matches the
|
||||||
|
/// entry's executable rules — the drift-pin the retired aura-std
|
||||||
|
/// `fold_vocabulary` table carried, moved here with the surface (#332).
|
||||||
|
#[test]
|
||||||
|
fn roster_docs_pass_the_doc_gate_and_match_the_executable_rules() {
|
||||||
|
let r = FoldRegistry::core();
|
||||||
|
for entry in r.entries.values() {
|
||||||
|
aura_core::doc_gate(entry.label, entry.doc)
|
||||||
|
.unwrap_or_else(|f| panic!("fold {} doc fails the gate: {f:?}", entry.label));
|
||||||
|
if entry.doc.contains("f64 taps") {
|
||||||
|
assert!(
|
||||||
|
(entry.binds_at)(ScalarKind::F64) && !(entry.binds_at)(ScalarKind::I64),
|
||||||
|
"{} claims f64-only but binds wider",
|
||||||
|
entry.label
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assert!(
|
||||||
|
entry.doc.contains("any kind"),
|
||||||
|
"{}: bind prose must be 'f64 taps' or 'any kind': {}",
|
||||||
|
entry.label,
|
||||||
|
entry.doc
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
(entry.binds_at)(ScalarKind::I64) && (entry.binds_at)(ScalarKind::Bool),
|
||||||
|
"{} claims any-kind but refuses a kind",
|
||||||
|
entry.label
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if entry.doc.contains("i64 row") {
|
||||||
|
assert!(
|
||||||
|
matches!((entry.output)(ScalarKind::F64), FoldOutput::Row(ScalarKind::I64)),
|
||||||
|
"{} claims an i64 row but outputs otherwise",
|
||||||
|
entry.label
|
||||||
|
);
|
||||||
|
} else if entry.doc.contains("f64 row") {
|
||||||
|
assert!(
|
||||||
|
matches!((entry.output)(ScalarKind::F64), FoldOutput::Row(ScalarKind::F64)),
|
||||||
|
"{} claims an f64 row but outputs otherwise",
|
||||||
|
entry.label
|
||||||
|
);
|
||||||
|
} else if entry.doc.contains("kind-preserving row") {
|
||||||
|
assert!(
|
||||||
|
matches!((entry.output)(ScalarKind::F64), FoldOutput::Row(ScalarKind::F64))
|
||||||
|
&& matches!((entry.output)(ScalarKind::I64), FoldOutput::Row(ScalarKind::I64)),
|
||||||
|
"{} claims kind-preserving but outputs otherwise",
|
||||||
|
entry.label
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assert!(
|
||||||
|
matches!((entry.output)(ScalarKind::F64), FoldOutput::Series),
|
||||||
|
"{}: doc names no row kind, so it must be the series entry",
|
||||||
|
entry.label
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unknown_label_refusal_enumerates_the_roster() {
|
fn unknown_label_refusal_enumerates_the_roster() {
|
||||||
let r = FoldRegistry::core();
|
let r = FoldRegistry::core();
|
||||||
|
|||||||
@@ -74,6 +74,6 @@ pub use sma::Sma;
|
|||||||
pub use sqrt::Sqrt;
|
pub use sqrt::Sqrt;
|
||||||
pub use sub::Sub;
|
pub use sub::Sub;
|
||||||
pub use tap_cell::newest_cell;
|
pub use tap_cell::newest_cell;
|
||||||
pub use tap_fold::{fold_binds_at, fold_output_kind, fold_vocabulary, FoldKind, FoldSchema, TapFold};
|
pub use tap_fold::{fold_binds_at, fold_output_kind, FoldKind, TapFold};
|
||||||
pub use tap_live::TapLive;
|
pub use tap_live::TapLive;
|
||||||
pub use when::When;
|
pub use when::When;
|
||||||
|
|||||||
@@ -45,32 +45,6 @@ pub fn fold_output_kind(fold: FoldKind, kind: ScalarKind) -> ScalarKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One fold entry's introspection row (C29): id, bind/output rules in prose,
|
|
||||||
/// one-line meaning. `fold_vocabulary` is the binary's discovery surface for
|
|
||||||
/// [`FoldKind`] (`aura graph introspect --folds`, #315); the unit tests pin
|
|
||||||
/// each row's rule prose against [`fold_binds_at`] / [`fold_output_kind`] so
|
|
||||||
/// the table cannot drift from the executable rules.
|
|
||||||
pub struct FoldSchema {
|
|
||||||
pub id: &'static str,
|
|
||||||
pub kind: FoldKind,
|
|
||||||
pub binds: &'static str,
|
|
||||||
pub out: &'static str,
|
|
||||||
pub doc: &'static str,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The closed fold vocabulary as introspection rows, in [`FoldKind`] order.
|
|
||||||
pub fn fold_vocabulary() -> &'static [FoldSchema] {
|
|
||||||
&[
|
|
||||||
FoldSchema { id: "Count", kind: FoldKind::Count, binds: "any tap", out: "i64", doc: "number of rows the tap recorded" },
|
|
||||||
FoldSchema { id: "Sum", kind: FoldKind::Sum, binds: "f64 taps", out: "f64", doc: "sum of the tap's recorded values" },
|
|
||||||
FoldSchema { id: "Mean", kind: FoldKind::Mean, binds: "f64 taps", out: "f64", doc: "arithmetic mean of the tap's recorded values" },
|
|
||||||
FoldSchema { id: "Min", kind: FoldKind::Min, binds: "f64 taps", out: "f64", doc: "smallest recorded value" },
|
|
||||||
FoldSchema { id: "Max", kind: FoldKind::Max, binds: "f64 taps", out: "f64", doc: "largest recorded value" },
|
|
||||||
FoldSchema { id: "First", kind: FoldKind::First, binds: "any tap", out: "tap kind", doc: "earliest recorded value, kind-preserving" },
|
|
||||||
FoldSchema { id: "Last", kind: FoldKind::Last, binds: "any tap", out: "tap kind", doc: "latest recorded value, kind-preserving" },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Owned accumulator for every fold kind at once (a handful of words; keeping
|
/// Owned accumulator for every fold kind at once (a handful of words; keeping
|
||||||
/// it total avoids a per-kind state enum). Sequential `sum += v` matches a
|
/// it total avoids a per-kind state enum). Sequential `sum += v` matches a
|
||||||
/// slice-driven mean's operation order, so streamed and slice `Mean` agree
|
/// slice-driven mean's operation order, so streamed and slice `Mean` agree
|
||||||
@@ -190,47 +164,6 @@ mod tests {
|
|||||||
use aura_core::AnyColumn;
|
use aura_core::AnyColumn;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
/// The vocabulary rows are prose renderings of the executable rules —
|
|
||||||
/// pin them against `fold_binds_at` / `fold_output_kind` so the
|
|
||||||
/// introspection surface cannot drift from what the engine enforces.
|
|
||||||
#[test]
|
|
||||||
fn fold_vocabulary_rows_match_the_executable_rules() {
|
|
||||||
let rows = fold_vocabulary();
|
|
||||||
assert_eq!(rows.len(), 7, "one row per FoldKind");
|
|
||||||
for row in rows {
|
|
||||||
let f64_only = fold_binds_at(row.kind, ScalarKind::F64)
|
|
||||||
&& !fold_binds_at(row.kind, ScalarKind::I64);
|
|
||||||
match row.binds {
|
|
||||||
"f64 taps" => assert!(f64_only, "{} claims f64-only but binds wider", row.id),
|
|
||||||
"any tap" => assert!(
|
|
||||||
fold_binds_at(row.kind, ScalarKind::I64)
|
|
||||||
&& fold_binds_at(row.kind, ScalarKind::Bool),
|
|
||||||
"{} claims any-tap but refuses a kind",
|
|
||||||
row.id
|
|
||||||
),
|
|
||||||
other => panic!("unknown binds prose {other:?} on {}", row.id),
|
|
||||||
}
|
|
||||||
match row.out {
|
|
||||||
"i64" => assert_eq!(fold_output_kind(row.kind, ScalarKind::F64), ScalarKind::I64),
|
|
||||||
"f64" => assert_eq!(fold_output_kind(row.kind, ScalarKind::F64), ScalarKind::F64),
|
|
||||||
"tap kind" => {
|
|
||||||
assert_eq!(fold_output_kind(row.kind, ScalarKind::F64), ScalarKind::F64);
|
|
||||||
assert_eq!(fold_output_kind(row.kind, ScalarKind::I64), ScalarKind::I64);
|
|
||||||
}
|
|
||||||
other => panic!("unknown out prose {other:?} on {}", row.id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// C29 entry seam: every fold row ships a gate-clean one-line meaning.
|
|
||||||
#[test]
|
|
||||||
fn fold_vocabulary_docs_pass_the_doc_gate() {
|
|
||||||
for row in fold_vocabulary() {
|
|
||||||
aura_core::doc_gate(row.id, row.doc)
|
|
||||||
.unwrap_or_else(|f| panic!("fold {} doc fails the gate: {f:?}", row.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Drive a fold over an f64 series and return the emitted rows.
|
/// Drive a fold over an f64 series and return the emitted rows.
|
||||||
fn run_f64_fold(fold: FoldKind, values: &[f64]) -> Vec<(Timestamp, Vec<Scalar>)> {
|
fn run_f64_fold(fold: FoldKind, values: &[f64]) -> Vec<(Timestamp, Vec<Scalar>)> {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|||||||
Reference in New Issue
Block a user