Skip to content

Commit

Permalink
Merge pull request #321 from epage/macro
Browse files Browse the repository at this point in the history
feat(assert): Add assert_data_eq!
  • Loading branch information
epage authored May 17, 2024
2 parents 490dc89 + 1f5c4dd commit 3ac846d
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 42 deletions.
6 changes: 3 additions & 3 deletions crates/snapbox/src/assert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ impl Assert {
}

let checks: Vec<_> =
crate::path::PathDiff::subset_eq_iter_inner(expected_root, actual_root).collect();
crate::dir::PathDiff::subset_eq_iter_inner(expected_root, actual_root).collect();
self.verify(checks);
}

Expand Down Expand Up @@ -319,7 +319,7 @@ impl Assert {
Action::Ignore | Action::Verify | Action::Overwrite => {}
}

let checks: Vec<_> = crate::path::PathDiff::subset_matches_iter_inner(
let checks: Vec<_> = crate::dir::PathDiff::subset_matches_iter_inner(
expected_root,
actual_root,
&self.substitutions,
Expand All @@ -332,7 +332,7 @@ impl Assert {
#[track_caller]
fn verify(
&self,
mut checks: Vec<Result<(std::path::PathBuf, std::path::PathBuf), crate::path::PathDiff>>,
mut checks: Vec<Result<(std::path::PathBuf, std::path::PathBuf), crate::dir::PathDiff>>,
) {
if checks.iter().all(Result::is_ok) {
for check in checks {
Expand Down
4 changes: 2 additions & 2 deletions crates/snapbox/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use filters::FilterSet;
///
/// let actual = some_function();
/// let expected = snapbox::str![["5"]];
/// snapbox::assert_eq(actual.to_debug(), expected);
/// snapbox::assert_data_eq!(actual.to_debug(), expected);
/// ```
pub trait ToDebug {
fn to_debug(&self) -> Data;
Expand All @@ -64,7 +64,7 @@ impl<D: std::fmt::Debug> ToDebug for D {
///
/// let actual = some_function();
/// let expected = snapbox::str![["5"]];
/// snapbox::assert_eq(actual.into_json(), expected);
/// snapbox::assert_data_eq!(actual.into_json(), expected);
/// ```
#[cfg(feature = "json")]
pub trait IntoJson {
Expand Down
20 changes: 10 additions & 10 deletions crates/snapbox/src/data/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,41 +372,41 @@ impl PathRuntime {
#[cfg(test)]
mod tests {
use super::*;
use crate::assert_eq;
use crate::assert_data_eq;
use crate::prelude::*;
use crate::str;

#[test]
fn test_format_patch() {
let patch = format_patch(None, "hello\nworld\n");

assert_eq(
assert_data_eq!(
patch,
str![[r##"
[r#"
hello
world
"#]"##]],
patch,
);

let patch = format_patch(None, r"hello\tworld");
assert_eq(str![[r##"[r#"hello\tworld"#]"##]], patch);
assert_data_eq!(patch, str![[r##"[r#"hello\tworld"#]"##]].raw());

let patch = format_patch(None, "{\"foo\": 42}");
assert_eq(str![[r##"[r#"{"foo": 42}"#]"##]], patch);
assert_data_eq!(patch, str![[r##"[r#"{"foo": 42}"#]"##]]);

let patch = format_patch(Some(0), "hello\nworld\n");
assert_eq(
assert_data_eq!(
patch,
str![[r##"
[r#"
hello
world
"#]"##]],
patch,
);

let patch = format_patch(Some(4), "single line");
assert_eq(str![[r#""single line""#]], patch);
assert_data_eq!(patch, str![[r#""single line""#]]);
}

#[test]
Expand All @@ -415,7 +415,8 @@ mod tests {
patchwork.patch(4..7, "zwei");
patchwork.patch(0..3, "один");
patchwork.patch(8..13, "3");
assert_eq(
assert_data_eq!(
patchwork.to_debug(),
str![[r#"
Patchwork {
text: "один zwei 3",
Expand All @@ -435,7 +436,6 @@ mod tests {
],
}
"#]],
patchwork.to_debug(),
);
}

Expand Down
24 changes: 12 additions & 12 deletions crates/snapbox/src/filter/redactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ impl Redactions {
}

pub(crate) fn with_exe() -> Self {
let mut substitutions = Self::new();
substitutions
let mut redactions = Self::new();
redactions
.insert("[EXE]", std::env::consts::EXE_SUFFIX)
.unwrap();
substitutions
redactions
}

/// Insert an additional match pattern
Expand Down Expand Up @@ -172,7 +172,7 @@ fn validate_placeholder(placeholder: &'static str) -> crate::assert::Result<&'st
Ok(placeholder)
}

fn normalize(input: &str, pattern: &str, substitutions: &Redactions) -> String {
fn normalize(input: &str, pattern: &str, redactions: &Redactions) -> String {
if input == pattern {
return input.to_owned();
}
Expand All @@ -191,7 +191,7 @@ fn normalize(input: &str, pattern: &str, substitutions: &Redactions) -> String {
input_lines[input_index..]
.iter()
.copied()
.map(|s| substitutions.substitute(s)),
.map(|s| redactions.substitute(s)),
);
break 'outer;
};
Expand All @@ -204,7 +204,7 @@ fn normalize(input: &str, pattern: &str, substitutions: &Redactions) -> String {
};
let next_input_index = input_index + 1;

if line_matches(input_line, pattern_line, substitutions) {
if line_matches(input_line, pattern_line, redactions) {
pattern_index = next_pattern_index;
input_index = next_input_index;
normalized.push(Cow::Borrowed(pattern_line));
Expand Down Expand Up @@ -232,7 +232,7 @@ fn normalize(input: &str, pattern: &str, substitutions: &Redactions) -> String {
input_lines[input_index..]
.iter()
.copied()
.map(|s| substitutions.substitute(s)),
.map(|s| redactions.substitute(s)),
);
break 'outer;
}
Expand All @@ -250,7 +250,7 @@ fn normalize(input: &str, pattern: &str, substitutions: &Redactions) -> String {
input_lines[input_index..future_input_index]
.iter()
.copied()
.map(|s| substitutions.substitute(s)),
.map(|s| redactions.substitute(s)),
);
pattern_index = future_pattern_index;
input_index = future_input_index;
Expand All @@ -262,7 +262,7 @@ fn normalize(input: &str, pattern: &str, substitutions: &Redactions) -> String {
input_lines[input_index..]
.iter()
.copied()
.map(|s| substitutions.substitute(s)),
.map(|s| redactions.substitute(s)),
);
break 'outer;
}
Expand All @@ -275,15 +275,15 @@ fn is_line_elide(line: &str) -> bool {
line == "...\n" || line == "..."
}

fn line_matches(line: &str, pattern: &str, substitutions: &Redactions) -> bool {
fn line_matches(line: &str, pattern: &str, redactions: &Redactions) -> bool {
if line == pattern {
return true;
}

let subbed = substitutions.substitute(line);
let subbed = redactions.substitute(line);
let mut line = subbed.as_ref();

let pattern = substitutions.clear(pattern);
let pattern = redactions.clear(pattern);

let mut sections = pattern.split("[..]").peekable();
while let Some(section) = sections.next() {
Expand Down
14 changes: 10 additions & 4 deletions crates/snapbox/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! ## Which tool is right
//!
//! - [cram](https://bitheap.org/cram/): End-to-end CLI snapshotting agnostic of any programming language
//! - See also [scrut](https://github.com/facebookincubator/scrut)
//! - [trycmd](https://crates.io/crates/trycmd): For running a lot of blunt tests (limited test predicates)
//! - Particular attention is given to allow the test data to be pulled into documentation, like
//! with [mdbook](https://rust-lang.github.io/mdBook/)
Expand All @@ -25,7 +26,7 @@
//! ## Getting Started
//!
//! Testing Functions:
//! - [`assert_eq`][crate::assert_eq()] and [`assert_matches`] for reusing diffing / pattern matching for non-snapshot testing
//! - [`assert_data_eq!`] for quick and dirty snapshotting
//! - [`harness::Harness`] for discovering test inputs and asserting against snapshot files:
//!
//! Testing Commands:
Expand All @@ -44,17 +45,17 @@
//!
//! # Examples
//!
//! [`assert_matches`]
//! [`assert_data_eq!`]
//! ```rust
//! snapbox::assert_matches("Hello [..] people!", "Hello many people!");
//! snapbox::assert_data_eq!("Hello many people!", "Hello [..] people!");
//! ```
//!
//! [`Assert`]
//! ```rust,no_run
//! let actual = "...";
//! snapbox::Assert::new()
//! .action_env("SNAPSHOTS")
//! .matches(snapbox::file!["help_output_is_clean.txt"], actual);
//! .eq_(actual, snapbox::file!["help_output_is_clean.txt"]);
//! ```
//!
//! [`harness::Harness`]
Expand Down Expand Up @@ -160,6 +161,10 @@ pub mod prelude {
/// assert_eq(file!["output.txt"], actual);
/// ```
#[track_caller]
#[deprecated(
since = "0.5.11",
note = "Replaced with `assert_data_eq!(actual, expected.raw())`"
)]
pub fn assert_eq(expected: impl Into<crate::Data>, actual: impl Into<crate::Data>) {
Assert::new()
.action_env(assert::DEFAULT_ACTION_ENV)
Expand Down Expand Up @@ -192,6 +197,7 @@ pub fn assert_eq(expected: impl Into<crate::Data>, actual: impl Into<crate::Data
/// assert_matches(file!["output.txt"], actual);
/// ```
#[track_caller]
#[deprecated(since = "0.5.11", note = "Replaced with `assert_data_eq!(actual)`")]
pub fn assert_matches(pattern: impl Into<crate::Data>, actual: impl Into<crate::Data>) {
Assert::new()
.action_env(assert::DEFAULT_ACTION_ENV)
Expand Down
47 changes: 47 additions & 0 deletions crates/snapbox/src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
/// Check if a value is the same as an expected value
///
/// By default [`filters`][crate::filter] are applied, including:
/// - `...` is a line-wildcard when on a line by itself
/// - `[..]` is a character-wildcard when inside a line
/// - `[EXE]` matches `.exe` on Windows
/// - `\` to `/`
/// - Newlines
///
/// To limit this to newline normalization for text, call [`Data::raw`][crate::Data] on `expected`.
///
/// # Effective signature
///
/// ```rust
/// # use snapbox::IntoData;
/// fn assert_data_eq(actual: impl IntoData, expected: impl IntoData) {
/// // ...
/// }
/// ```
///
/// # Examples
///
/// ```rust
/// # use snapbox::assert_data_eq;
/// let output = "something";
/// let expected = "so[..]g";
/// assert_data_eq!(output, expected);
/// ```
///
/// Can combine this with [`file!`]
/// ```rust,no_run
/// # use snapbox::assert_data_eq;
/// # use snapbox::file;
/// let actual = "something";
/// assert_data_eq!(actual, file!["output.txt"]);
/// ```
#[macro_export]
macro_rules! assert_data_eq {
($actual: expr, $expected: expr $(,)?) => {{
let actual = $crate::IntoData::into_data($actual);
let expected = $crate::IntoData::into_data($expected);
$crate::Assert::new()
.action_env($crate::assert::DEFAULT_ACTION_ENV)
.eq_(actual, expected);
}};
}

/// Find the directory for your source file
#[doc(hidden)] // forced to be visible in intended location
#[macro_export]
Expand Down
22 changes: 11 additions & 11 deletions crates/snapbox/tests/testsuite/assert.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
use snapbox::assert_eq;
use snapbox::assert_data_eq;
use snapbox::file;
use snapbox::str;

#[test]
fn test_trivial_assert() {
assert_eq(str!["5"], "5");
assert_data_eq!("5", str!["5"]);
}

#[test]
fn smoke_test_indent() {
assert_eq(
assert_data_eq!(
"\
line1
line2
",
str![[r#"
line1
line2
"#]]
.indent(true),
);

assert_data_eq!(
"\
line1
line2
",
);

assert_eq(
str![[r#"
line1
line2
"#]]
.indent(false),
"\
line1
line2
",
);
}

#[test]
fn test_expect_file() {
assert_eq(file!["../../README.md"], include_str!("../../README.md"))
assert_data_eq!(include_str!("../../README.md"), file!["../../README.md"]);
}

0 comments on commit 3ac846d

Please sign in to comment.