use camino::Utf8Path;
use datatest_stable::Result;
use std::{fs::File, io::Read, path::Path};
fn test_artifact(path: &Path) -> Result<()> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(())
}
fn test_artifact_utf8(path: &Utf8Path) -> Result<()> {
test_artifact(path.as_ref())
}
fn test_artifact_utf8_abs(path: &Utf8Path) -> Result<()> {
assert!(path.is_absolute(), "path must be absolute: {:?}", path);
#[cfg(windows)]
{
assert!(
!path.as_str().contains('/'),
"path must not contain forward slashes: {:?}",
path
);
}
test_artifact(path.as_ref())
}
#[cfg(feature = "include-dir")]
#[macro_use]
mod with_contents {
use super::*;
macro_rules! maybe_include_dir {
() => {
include_dir::include_dir!("$CARGO_MANIFEST_DIR/tests/files")
};
}
pub(crate) static MAYBE_INCLUDE_STATIC: include_dir::Dir =
include_dir::include_dir!("$CARGO_MANIFEST_DIR/tests/files");
pub(crate) fn test_artifact_string(path: &Path, contents: String) -> Result<()> {
compare_contents(path, contents.as_bytes())
}
pub(crate) fn test_artifact_utf8_string(path: &Utf8Path, contents: String) -> Result<()> {
compare_contents(path.as_std_path(), contents.as_bytes())
}
pub(crate) fn test_artifact_bytes(path: &Path, contents: Vec<u8>) -> Result<()> {
compare_contents(path, &contents)
}
pub(crate) fn test_artifact_utf8_bytes(path: &Utf8Path, contents: Vec<u8>) -> Result<()> {
compare_contents(path.as_std_path(), &contents)
}
fn compare_contents(path: &Path, expected: &[u8]) -> Result<()> {
assert!(
!path.to_string_lossy().starts_with("tests/files"),
"path must not start with 'tests/files': {:?}",
path
);
let path = format!("tests/files/{}", path.to_str().unwrap());
compare(path.as_ref(), expected)
}
}
#[cfg(not(feature = "include-dir"))]
#[macro_use]
mod with_contents {
use super::*;
macro_rules! maybe_include_dir {
() => {
"tests/files"
};
}
pub(crate) static MAYBE_INCLUDE_STATIC: &str = "tests/files";
pub(crate) fn test_artifact_string(path: &Path, contents: String) -> Result<()> {
compare_contents(path, contents.as_bytes())
}
pub(crate) fn test_artifact_utf8_string(path: &Utf8Path, contents: String) -> Result<()> {
compare_contents(path.as_std_path(), contents.as_bytes())
}
pub(crate) fn test_artifact_bytes(path: &Path, contents: Vec<u8>) -> Result<()> {
compare_contents(path, &contents)
}
pub(crate) fn test_artifact_utf8_bytes(path: &Utf8Path, contents: Vec<u8>) -> Result<()> {
compare_contents(path.as_std_path(), &contents)
}
fn compare_contents(path: &Path, expected: &[u8]) -> Result<()> {
assert!(
path.to_string_lossy().starts_with("tests/files"),
"path must start with 'tests/files': {:?}",
path
);
compare(&path, expected)
}
}
fn compare(path: &Path, expected: &[u8]) -> Result<()> {
assert!(path.is_relative(), "path must be relative: {:?}", path);
assert!(
!path.to_string_lossy().contains('\\'),
"path must not contain backslashes: {:?}",
path
);
let actual =
std::fs::read(path).map_err(|error| format!("failed to read file: {:?}: {error}", path))?;
assert_eq!(expected, &actual, "file contents match for {:?}", path);
Ok(())
}
#[cfg(windows)]
static TESTS_FILES_MAIN_SEP: &str = "tests\\files";
#[cfg(not(windows))]
static TESTS_FILES_MAIN_SEP: &str = "tests/files";
fn tests_files_abs() -> String {
std::env::current_dir()
.expect("current dir obtained")
.join("tests/files")
.to_string_lossy()
.into_owned()
}
datatest_stable::harness! {
{
test = test_artifact,
root = "tests/files",
pattern = r"^.*(?<!\.skip)\.txt$",
},
{
test = test_artifact_utf8,
root = TESTS_FILES_MAIN_SEP,
pattern = r"^.*\.txt$",
},
{
test = test_artifact_utf8_abs,
root = tests_files_abs(),
pattern = r"^(dir/a|b|c\.skip)\.txt$",
},
{
test = with_contents::test_artifact_string,
root = maybe_include_dir!(),
pattern = r"^(dir/a|b|c\.skip)\.txt$",
},
{
test = with_contents::test_artifact_utf8_string,
root = &with_contents::MAYBE_INCLUDE_STATIC,
pattern = r"^.*\.txt$",
},
{
test = with_contents::test_artifact_bytes,
root = &with_contents::MAYBE_INCLUDE_STATIC,
},
{
test = with_contents::test_artifact_utf8_bytes,
root = maybe_include_dir!(),
pattern = r"^.*\.txt$",
},
}