#![allow(dead_code)]
use ndarray::{Array1, Array2};
use serde_json::Value;
use std::fs;
use std::path::Path;
pub fn load_golden_data(filename: &str) -> Vec<Value> {
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("golden_data")
.join(filename);
let contents = fs::read_to_string(&path)
.unwrap_or_else(|e| panic!("Failed to read {}: {}", path.display(), e));
serde_json::from_str(&contents).expect("Failed to parse JSON")
}
pub fn json_to_array1(val: &Value) -> Array1<f64> {
let vec: Vec<f64> = val
.as_array()
.expect("expected JSON array")
.iter()
.map(|v| v.as_f64().expect("expected number"))
.collect();
Array1::from_vec(vec)
}
pub fn json_to_array2(val: &Value) -> Array2<f64> {
let rows: Vec<Vec<f64>> = val
.as_array()
.expect("expected JSON array of arrays")
.iter()
.map(|row| {
row.as_array()
.expect("expected inner array")
.iter()
.map(|v| v.as_f64().expect("expected number"))
.collect()
})
.collect();
let nrows = rows.len();
let ncols = rows[0].len();
let flat: Vec<f64> = rows.into_iter().flatten().collect();
Array2::from_shape_vec((nrows, ncols), flat).expect("shape mismatch")
}
pub fn assert_close(actual: f64, expected: f64, tol: f64, context: &str) {
let diff = (actual - expected).abs();
assert!(
diff < tol,
"{}: expected {}, got {}, diff {} > tol {}",
context,
expected,
actual,
diff,
tol
);
}
pub fn assert_array1_close(actual: &Array1<f64>, expected: &Array1<f64>, tol: f64, context: &str) {
assert_eq!(
actual.len(),
expected.len(),
"{}: length mismatch: {} vs {}",
context,
actual.len(),
expected.len()
);
for (i, (&a, &e)) in actual.iter().zip(expected.iter()).enumerate() {
assert_close(a, e, tol, &format!("{}[{}]", context, i));
}
}
#[allow(dead_code)]
pub fn assert_array2_close(actual: &Array2<f64>, expected: &Array2<f64>, tol: f64, context: &str) {
assert_eq!(
actual.shape(),
expected.shape(),
"{}: shape mismatch",
context
);
for ((r, c), &a) in actual.indexed_iter() {
let e = expected[[r, c]];
assert_close(a, e, tol, &format!("{}[{},{}]", context, r, c));
}
}