Skip to content

Commit

Permalink
Merge pull request #266 from epage/auto
Browse files Browse the repository at this point in the history
fix(snap): Provide more stable snapshots
  • Loading branch information
epage authored Mar 1, 2024
2 parents dbb1aca + d1ea406 commit e79db96
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 15 deletions.
27 changes: 18 additions & 9 deletions crates/snapbox/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,12 @@ impl<D: std::fmt::Debug> ToDebug for D {
#[macro_export]
macro_rules! file {
[_] => {{
let stem = ::std::path::Path::new(::std::file!()).file_stem().unwrap();
let rel_path = ::std::format!("snapshots/{}-{}.txt", stem.to_str().unwrap(), line!());
let mut path = $crate::current_dir!();
path.push(rel_path);
let path = $crate::data::generate_snapshot_path($crate::fn_path!(), None);
$crate::Data::read_from(&path, None)
}};
[_ : $type:ident] => {{
let stem = ::std::path::Path::new(::std::file!()).file_stem().unwrap();
let ext = $crate::data::DataFormat:: $type.ext();
let rel_path = ::std::format!("snapshots/{}-{}.{ext}", stem.to_str().unwrap(), line!());
let mut path = $crate::current_dir!();
path.push(rel_path);
let format = $crate::data::DataFormat:: $type;
let path = $crate::data::generate_snapshot_path($crate::fn_path!(), Some(format));
$crate::Data::read_from(&path, Some($crate::data::DataFormat:: $type))
}};
[$path:literal] => {{
Expand Down Expand Up @@ -568,3 +562,18 @@ fn is_binary(data: &[u8]) -> bool {
fn is_binary(_data: &[u8]) -> bool {
false
}

#[doc(hidden)]
pub fn generate_snapshot_path(fn_path: &str, format: Option<DataFormat>) -> std::path::PathBuf {
use std::fmt::Write as _;

let fn_path_normalized = fn_path.replace("::", "__");
let mut path = format!("tests/snapshots/{fn_path_normalized}");
let count = runtime::get().count(&path);
if 0 < count {
write!(&mut path, "@{count}").unwrap();
}
path.push('.');
path.push_str(format.unwrap_or(DataFormat::Text).ext());
path.into()
}
57 changes: 51 additions & 6 deletions crates/snapbox/src/data/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,30 @@ pub(crate) fn get() -> std::sync::MutexGuard<'static, Runtime> {

#[derive(Default)]
pub(crate) struct Runtime {
per_file: Vec<FileRuntime>,
per_file: Vec<SourceFileRuntime>,
path_count: Vec<PathRuntime>,
}

impl Runtime {
const fn new() -> Self {
Self {
per_file: Vec::new(),
path_count: Vec::new(),
}
}

pub(crate) fn count(&mut self, path_prefix: &str) -> usize {
if let Some(entry) = self
.path_count
.iter_mut()
.find(|entry| entry.is(path_prefix))
{
entry.next()
} else {
let entry = PathRuntime::new(path_prefix);
let next = entry.count();
self.path_count.push(entry);
next
}
}

Expand All @@ -28,7 +45,7 @@ impl Runtime {
{
entry.update(&actual, inline)?;
} else {
let mut entry = FileRuntime::new(inline)?;
let mut entry = SourceFileRuntime::new(inline)?;
entry.update(&actual, inline)?;
self.per_file.push(entry);
}
Expand All @@ -37,18 +54,18 @@ impl Runtime {
}
}

struct FileRuntime {
struct SourceFileRuntime {
path: std::path::PathBuf,
original_text: String,
patchwork: Patchwork,
}

impl FileRuntime {
fn new(inline: &Inline) -> std::io::Result<FileRuntime> {
impl SourceFileRuntime {
fn new(inline: &Inline) -> std::io::Result<SourceFileRuntime> {
let path = inline.position.file.clone();
let original_text = std::fs::read_to_string(&path)?;
let patchwork = Patchwork::new(original_text.clone());
Ok(FileRuntime {
Ok(SourceFileRuntime {
path,
original_text,
patchwork,
Expand Down Expand Up @@ -324,6 +341,34 @@ impl StrLitKind {
}
}

#[derive(Clone)]
struct PathRuntime {
path_prefix: String,
count: usize,
}

impl PathRuntime {
fn new(path_prefix: &str) -> Self {
Self {
path_prefix: path_prefix.to_owned(),
count: 0,
}
}

fn is(&self, path_prefix: &str) -> bool {
self.path_prefix == path_prefix
}

fn next(&mut self) -> usize {
self.count += 1;
self.count
}

fn count(&self) -> usize {
self.count
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
43 changes: 43 additions & 0 deletions crates/snapbox/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,46 @@ macro_rules! cargo_rustc_current_dir {
}
}};
}

/// Path to the current function
///
/// Closures are ignored
#[doc(hidden)]
#[macro_export]
macro_rules! fn_path {
() => {{
fn f() {}
fn type_name_of_val<T>(_: T) -> &'static str {
std::any::type_name::<T>()
}
let mut name = type_name_of_val(f).strip_suffix("::f").unwrap_or("");
while let Some(rest) = name.strip_suffix("::{{closure}}") {
name = rest;
}
name
}};
}

#[cfg(test)]
mod test {
#[test]
fn direct_fn_path() {
assert_eq!(fn_path!(), "snapbox::macros::test::direct_fn_path");
}

#[test]
#[allow(clippy::redundant_closure_call)]
fn closure_fn_path() {
(|| {
assert_eq!(fn_path!(), "snapbox::macros::test::closure_fn_path");
})()
}

#[test]
fn nested_fn_path() {
fn nested() {
assert_eq!(fn_path!(), "snapbox::macros::test::nested_fn_path::nested");
}
nested()
}
}

0 comments on commit e79db96

Please sign in to comment.