use std::path::PathBuf;
pub fn load_fixture(category: &str, filename: &str) -> String {
let fixture_path = fixture_path(category, filename);
std::fs::read_to_string(&fixture_path)
.unwrap_or_else(|e| panic!("Failed to load fixture {}: {}", fixture_path.display(), e))
}
pub fn fixture_path(category: &str, filename: &str) -> PathBuf {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("tests");
path.push("fixtures");
path.push(category);
path.push(filename);
path
}
pub fn fixture_exists(category: &str, filename: &str) -> bool {
fixture_path(category, filename).exists()
}
pub fn load_fixture_as<T>(category: &str, filename: &str) -> T
where
T: serde::de::DeserializeOwned,
{
let json = load_fixture(category, filename);
serde_json::from_str(&json)
.unwrap_or_else(|e| panic!("Failed to parse fixture {}/{}: {}", category, filename, e))
}
pub fn assert_roundtrip<T>(value: &T)
where
T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + std::fmt::Debug,
{
let json = serde_json::to_string(value).expect("Failed to serialize");
let deserialized: T = serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(value, &deserialized, "Roundtrip failed");
}
pub fn assert_json_roundtrip<T>(json: &str)
where
T: serde::de::DeserializeOwned + serde::Serialize,
{
let parsed: T = serde_json::from_str(json).expect("Failed to parse JSON");
let reserialized = serde_json::to_value(&parsed).expect("Failed to serialize");
let original: serde_json::Value = serde_json::from_str(json).expect("Failed to parse original");
assert_eq!(
original, reserialized,
"JSON roundtrip produced different output"
);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fixture_path() {
let path = fixture_path("users", "basic_user.json");
let path_str = path.to_string_lossy();
assert!(path_str.contains("tests"));
assert!(path_str.contains("fixtures"));
assert!(path_str.contains("users"));
assert!(path_str.contains("basic_user.json"));
assert!(path_str.ends_with("basic_user.json"));
}
}