use crate::patch::device::DeviceExt;
use anyhow::{anyhow, Context, Result};
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use svd_rs::Device;
use yaml_rust::{yaml::Hash, Yaml, YamlLoader};
pub fn res_dir() -> PathBuf {
std::env::current_dir().unwrap().join(Path::new("res"))
}
pub fn get_patcher(test_subdir: &Path) -> Result<(Device, Hash)> {
let test_subdir = res_dir().join(test_subdir);
let yaml_file = test_subdir.join("patch.yaml");
let f = File::open(&yaml_file)?;
let mut contents = String::new();
(&f).read_to_string(&mut contents)?;
let docs = YamlLoader::load_from_str(&contents)?;
let yaml = docs[0].as_hash().unwrap();
let svdpath = abspath(
&yaml_file,
Path::new(
yaml.get(&Yaml::String("_svd".into()))
.unwrap()
.as_str()
.ok_or_else(|| anyhow!("You must have an svd key in the root YAML file"))?,
),
);
let f = File::open(svdpath)?;
let mut contents = String::new();
(&f).read_to_string(&mut contents)?;
let device = svd_parser::parse(&contents)?;
Ok((device, yaml.clone()))
}
pub fn test_expected(test_subdir: &Path) -> Result<()> {
let (mut device, yaml) = get_patcher(test_subdir)?;
device
.process(&yaml, &Default::default())
.context("processing patch.yaml")?;
let expected_file = res_dir().join(test_subdir.join("expected.svd"));
let f = File::open(&expected_file)
.with_context(|| format!("opening {}", expected_file.display()))?;
let mut contents = String::new();
(&f).read_to_string(&mut contents)?;
let expected = svd_parser::parse(&contents)
.with_context(|| format!("parsing {}", expected_file.display()))?;
if device != expected {
let config = svd_encoder::Config::default();
let dev_text = svd_encoder::encode_with_config(&device, &config)?;
let expected_text = svd_encoder::encode_with_config(&expected, &config)?;
let diff = similar::TextDiff::from_lines(&expected_text, &dev_text);
Err(anyhow!(
"patch did not produce expected results:\n{}",
diff.unified_diff()
))
} else {
Ok(())
}
}
fn abspath(frompath: &Path, relpath: &Path) -> PathBuf {
normpath::BasePath::new(frompath)
.unwrap()
.parent()
.unwrap()
.unwrap()
.join(relpath)
.canonicalize()
.unwrap()
.as_path()
.into()
}