use std::collections::BTreeMap;
use std::path::Path;
use serde::Deserialize;
use warble::ContextLoader;
use warble_mdl_context::{infer_additivity, MdlContext};
use wren_core_base::mdl::manifest::Manifest;
fn golden(rel: &str) -> String {
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../golden/bootstrap-context")
.join(rel);
std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("read {}: {e}", path.display()))
}
fn example(rel: &str) -> String {
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../examples/bootstrap-agent")
.join(rel);
std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("read {}: {e}", path.display()))
}
#[derive(Debug, Deserialize)]
struct Column {
name: String,
#[serde(rename = "type")]
col_type: String,
}
#[derive(Debug, Deserialize)]
struct Model {
name: String,
columns: Vec<Column>,
}
#[derive(Debug, Deserialize)]
struct Mdl {
models: Vec<Model>,
}
#[derive(Debug, Deserialize)]
struct SchemaFidelityGroundTruth {
expected: Mdl,
cases: Vec<SchemaFidelityCase>,
}
#[derive(Debug, Deserialize)]
struct SchemaFidelityCase {
id: String,
produced: Mdl,
expected_correct: usize,
expected_total: usize,
}
fn columns_of(mdl: &Mdl) -> BTreeMap<String, String> {
let mut map = BTreeMap::new();
for model in &mdl.models {
for col in &model.columns {
map.insert(
format!("{}.{}", model.name, col.name),
col.col_type.to_uppercase(),
);
}
}
map
}
fn schema_fidelity(expected: &Mdl, produced: &Mdl) -> (usize, usize) {
let exp = columns_of(expected);
let prod = columns_of(produced);
let total = exp.len();
let correct = exp
.iter()
.filter(|(key, ty)| prod.get(*key).map(|p| p == *ty).unwrap_or(false))
.count();
(correct, total)
}
#[test]
fn schema_fidelity_scorer_reproduces_every_labelled_case() {
let gt: SchemaFidelityGroundTruth =
serde_yaml::from_str(&golden("schema_fidelity_ground_truth.yaml"))
.expect("schema_fidelity ground truth parses");
assert!(
gt.cases.len() >= 4,
"want faithful + missing-column + wrong-type + missing-table"
);
let mut reproduced = 0usize;
for case in >.cases {
let (correct, total) = schema_fidelity(>.expected, &case.produced);
assert_eq!(
(correct, total),
(case.expected_correct, case.expected_total),
"case '{}': scorer gave ({correct}/{total}) but ground truth expects ({}/{})",
case.id,
case.expected_correct,
case.expected_total
);
reproduced += 1;
}
assert_eq!(reproduced, gt.cases.len());
let faithful = gt.cases.iter().find(|c| c.id == "faithful").unwrap();
let (correct, total) = schema_fidelity(>.expected, &faithful.produced);
assert_eq!(
correct, total,
"a faithful bootstrap must score fidelity 1.0"
);
}
#[test]
fn expected_mdl_fixture_matches_ground_truth() {
let gt: SchemaFidelityGroundTruth =
serde_yaml::from_str(&golden("schema_fidelity_ground_truth.yaml")).unwrap();
let manifest: Manifest =
serde_json::from_str(&example("expected-mdl/manifest.json")).expect("expected MDL parses");
let gt_cols = columns_of(>.expected);
let manifest_cols: BTreeMap<String, String> = manifest
.models
.iter()
.flat_map(|m| {
m.columns
.iter()
.map(move |c| (format!("{}.{}", m.name, c.name), c.r#type.to_uppercase()))
})
.collect();
assert_eq!(
gt_cols, manifest_cols,
"the schema_fidelity ground truth must mirror examples/bootstrap-agent/expected-mdl/manifest.json"
);
}
#[derive(Debug, Deserialize)]
struct MetricSoundnessGroundTruth {
cases: Vec<MetricSoundnessCase>,
}
#[derive(Debug, Deserialize)]
struct MetricSoundnessCase {
id: String,
expression: String,
expected_additivity: String,
}
fn additivity_str(a: warble::Additivity) -> &'static str {
match a {
warble::Additivity::Additive => "additive",
warble::Additivity::SemiAdditive => "semi_additive",
warble::Additivity::NonAdditive => "non_additive",
}
}
#[test]
fn metric_soundness_matches_the_production_additivity_oracle() {
let gt: MetricSoundnessGroundTruth =
serde_yaml::from_str(&golden("metric_soundness_ground_truth.yaml"))
.expect("metric_soundness ground truth parses");
assert!(
gt.cases.len() >= 5,
"want additive + non-additive (distinct/ratio/avg) all represented"
);
let mut sound = 0usize;
for case in >.cases {
let inferred = additivity_str(infer_additivity(&case.expression));
let matches = inferred == case.expected_additivity;
assert!(
matches,
"case '{}': oracle inferred '{inferred}' for `{}` but ground truth expects '{}'",
case.id, case.expression, case.expected_additivity
);
if matches {
sound += 1;
}
}
let metric_soundness = sound as f64 / gt.cases.len() as f64;
assert_eq!(
metric_soundness, 1.0,
"the production additivity oracle must reproduce every labelled soundness verdict"
);
}
#[test]
fn bootstrapped_context_satisfies_downstream_consumer_preconditions() {
let manifest: Manifest =
serde_json::from_str(&example("expected-mdl/manifest.json")).expect("expected MDL parses");
let ctx = MdlContext::from_manifest(&manifest);
assert!(ctx.is_parseable(), "bootstrapped MDL must parse");
assert!(
!ctx.metrics().is_empty(),
"has_metric: bootstrapped MDL exposes queryable metrics (answer_query needs this)"
);
assert!(
!ctx.time_dimensions().is_empty(),
"has_time_dimension: bootstrapped MDL exposes a time dimension (explain_change/dashboards need this)"
);
assert!(
ctx.can_answer("metric_additive"),
"the bootstrapped cube declares a measure, so metric_additive is answerable"
);
let total_revenue = ctx
.metrics()
.iter()
.find(|m| m.name == "total_revenue")
.expect("the revenue cube's total_revenue measure is bootstrapped");
assert!(
total_revenue.declared,
"total_revenue is a declared measure"
);
assert_eq!(
total_revenue.additivity,
Some(warble::Additivity::Additive),
"SUM(amount) is additive — decomposition-safe for downstream consumers"
);
}