use std::{fmt, fs, path::Path};
struct DiffError(String);
impl fmt::Debug for DiffError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
impl fmt::Display for DiffError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
impl std::error::Error for DiffError {}
fn read_schemas(case: &Path) -> datatest_stable::Result<(String, String)> {
let schemas = fs::read_to_string(case)?;
let mut schemas = schemas.split("# --- #");
let source = schemas.next().expect("Can't find first schema in test case.");
let target = schemas.next().expect("Can't find second schema in test case.");
Ok((source.to_owned(), target.to_owned()))
}
fn run_test_backwards(case: &Path) -> datatest_stable::Result<()> {
let (source, target) = read_schemas(case)?;
run_test_impl(target, source)
}
fn run_test(case: &Path) -> datatest_stable::Result<()> {
let (source, target) = read_schemas(case)?;
run_test_impl(source, target)
}
fn run_test_impl(source: String, target: String) -> datatest_stable::Result<()> {
if cfg!(windows) {
return Ok(()); }
let diff = graphql_schema_diff::diff(&source, &target).unwrap();
{
let resolved_spans: Vec<_> = graphql_schema_diff::resolve_spans(&source, &target, &diff).collect();
let patched = graphql_schema_diff::patch(&source, &diff, &resolved_spans).unwrap();
if patched.schema().trim() != target.trim() {
return Err(DiffError(
similar::udiff::unified_diff(
similar::Algorithm::default(),
&target,
patched.schema(),
5,
Some(("Original target", "Patched")),
)
.to_string(),
)
.into());
}
}
Ok(())
}
datatest_stable::harness! {
{ test = run_test, root = "./tests/patch", pattern = r"^.*\.graphql$" },
{ test = run_test_backwards, root = "./tests/patch", pattern = r"^.*\.graphql$" },
}