use animsmith_core::diff::{
AMPLITUDE_THRESHOLD_M, DURATION_THRESHOLD_S, MetricDelta, PHASE_THRESHOLD,
ROTATION_RANGE_THRESHOLD_DEG, SEAM_THRESHOLD, SPEED_THRESHOLD_MPS, diff_measurements,
};
use animsmith_core::measure::ClipMeasurements;
use serde_json::json;
use std::collections::BTreeMap;
type MeasurementMap = BTreeMap<String, ClipMeasurements>;
type PublicDiffFn = fn(&MeasurementMap, &MeasurementMap) -> Vec<MetricDelta>;
const PUBLIC_DIFF_MEASUREMENTS: PublicDiffFn = diff_measurements;
fn measurements(duration_s: f64) -> MeasurementMap {
serde_json::from_value(json!({
"walk": {
"duration_s": duration_s,
"frame_count": 31,
"animated_bones": ["hips"],
"bone_rotation_range_deg": { "hips": 10.0 },
"loop_seam_ratio": 0.2,
"gait": {
"phase": 0.25,
"lr_amplitude_m": 0.1
},
"speed_mps": 1.0
}
}))
.expect("valid public measurement map")
}
#[test]
fn public_diff_api_accepts_deserialized_measurements() {
let deltas = PUBLIC_DIFF_MEASUREMENTS(&measurements(1.0), &measurements(1.1));
assert_eq!(deltas.len(), 1, "{deltas:?}");
let delta = &deltas[0];
assert_eq!(delta.clip, "walk");
assert_eq!(delta.metric, "duration_s");
assert_eq!(delta.before, Some(1.0));
assert_eq!(delta.after, Some(1.1));
assert_eq!(delta.note, "moved");
}
#[test]
fn threshold_constants_are_public_and_unchanged() {
assert_eq!(DURATION_THRESHOLD_S, 0.017);
assert_eq!(ROTATION_RANGE_THRESHOLD_DEG, 1.0);
assert_eq!(SEAM_THRESHOLD, 0.05);
assert_eq!(PHASE_THRESHOLD, 0.05);
assert_eq!(AMPLITUDE_THRESHOLD_M, 0.005);
assert_eq!(SPEED_THRESHOLD_MPS, 0.1);
}