Skip to content

Commit

Permalink
fix(assert)!: Merge _eq and _matches with Data::raw
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Apr 22, 2024
1 parent a40159f commit 1762764
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 163 deletions.
47 changes: 10 additions & 37 deletions crates/snapbox/src/assert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::Action;
/// # use snapbox::Assert;
/// # use snapbox::file;
/// let actual = "something";
/// Assert::new().matches(file!["output.txt"], actual);
/// Assert::new().eq(file!["output.txt"], actual);
/// ```
#[derive(Clone, Debug)]
pub struct Assert {
Expand All @@ -37,61 +37,34 @@ impl Assert {

/// Check if a value is the same as an expected value
///
/// When the content is text, newlines are normalized.
///
/// ```rust
/// # use snapbox::Assert;
/// let actual = "something";
/// let expected = "something";
/// Assert::new().eq(expected, actual);
/// ```
///
/// Can combine this with [`file!`][crate::file]
/// ```rust,no_run
/// # use snapbox::Assert;
/// # use snapbox::file;
/// let actual = "something";
/// Assert::new().eq(file!["output.txt"], actual);
/// ```
#[track_caller]
pub fn eq(&self, expected: impl Into<crate::Data>, actual: impl Into<crate::Data>) {
let expected = expected.into();
let actual = actual.into();
if let Err(err) = self.try_eq(expected.raw(), actual, Some(&"In-memory")) {
err.panic();
}
}

/// Check if a value matches a pattern
///
/// Pattern syntax:
/// By default [`filters`][crate::filters] 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
///
/// Normalization:
/// - Newlines
/// - `\` to `/`
/// - Newlines
///
/// To limit this to newline normalization for text, call [`Data::raw`][crate::Data::raw] on `expected`.
///
/// ```rust
/// # use snapbox::Assert;
/// let actual = "something";
/// let expected = "so[..]g";
/// Assert::new().matches(expected, actual);
/// Assert::new().eq(expected, actual);
/// ```
///
/// Can combine this with [`file!`][crate::file]
/// ```rust,no_run
/// # use snapbox::Assert;
/// # use snapbox::file;
/// let actual = "something";
/// Assert::new().matches(file!["output.txt"], actual);
/// Assert::new().eq(file!["output.txt"], actual);
/// ```
#[track_caller]
pub fn matches(&self, pattern: impl Into<crate::Data>, actual: impl Into<crate::Data>) {
let pattern = pattern.into();
pub fn eq(&self, expected: impl Into<crate::Data>, actual: impl Into<crate::Data>) {
let expected = expected.into();
let actual = actual.into();
if let Err(err) = self.try_eq(pattern, actual, Some(&"In-memory")) {
if let Err(err) = self.try_eq(expected, actual, Some(&"In-memory")) {
err.panic();
}
}
Expand Down
104 changes: 20 additions & 84 deletions crates/snapbox/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,15 @@ impl OutputAssert {

/// Ensure the command wrote the expected data to `stdout`.
///
/// By default [`filters`][crate::filters] 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::raw] on `expected`.
///
/// ```rust,no_run
/// use snapbox::cmd::Command;
/// use snapbox::cmd::cargo_bin;
Expand All @@ -596,7 +605,7 @@ impl OutputAssert {
/// .env("stdout", "hello")
/// .env("stderr", "world")
/// .assert()
/// .stdout_eq("hello");
/// .stdout_eq("he[..]o");
/// ```
///
/// Can combine this with [`file!`][crate::file]
Expand All @@ -619,47 +628,6 @@ impl OutputAssert {

#[track_caller]
fn stdout_eq_inner(self, expected: crate::Data) -> Self {
let actual = crate::Data::from(self.output.stdout.as_slice());
if let Err(err) = self.config.try_eq(expected.raw(), actual, Some(&"stdout")) {
err.panic();
}

self
}

/// Ensure the command wrote the expected data to `stdout`.
///
/// ```rust,no_run
/// use snapbox::cmd::Command;
/// use snapbox::cmd::cargo_bin;
///
/// let assert = Command::new(cargo_bin("snap-fixture"))
/// .env("stdout", "hello")
/// .env("stderr", "world")
/// .assert()
/// .stdout_matches("he[..]o");
/// ```
///
/// Can combine this with [`file!`][crate::file]
/// ```rust,no_run
/// use snapbox::cmd::Command;
/// use snapbox::cmd::cargo_bin;
/// use snapbox::file;
///
/// let assert = Command::new(cargo_bin("snap-fixture"))
/// .env("stdout", "hello")
/// .env("stderr", "world")
/// .assert()
/// .stdout_matches(file!["stdout.log"]);
/// ```
#[track_caller]
pub fn stdout_matches(self, expected: impl Into<crate::Data>) -> Self {
let expected = expected.into();
self.stdout_matches_inner(expected)
}

#[track_caller]
fn stdout_matches_inner(self, expected: crate::Data) -> Self {
let actual = crate::Data::from(self.output.stdout.as_slice());
if let Err(err) = self.config.try_eq(expected, actual, Some(&"stdout")) {
err.panic();
Expand All @@ -670,6 +638,15 @@ impl OutputAssert {

/// Ensure the command wrote the expected data to `stderr`.
///
/// By default [`filters`][crate::filters] 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::raw] on `expected`.
///
/// ```rust,no_run
/// use snapbox::cmd::Command;
/// use snapbox::cmd::cargo_bin;
Expand All @@ -678,7 +655,7 @@ impl OutputAssert {
/// .env("stdout", "hello")
/// .env("stderr", "world")
/// .assert()
/// .stderr_eq("world");
/// .stderr_eq("wo[..]d");
/// ```
///
/// Can combine this with [`file!`][crate::file]
Expand All @@ -701,47 +678,6 @@ impl OutputAssert {

#[track_caller]
fn stderr_eq_inner(self, expected: crate::Data) -> Self {
let actual = crate::Data::from(self.output.stderr.as_slice());
if let Err(err) = self.config.try_eq(expected.raw(), actual, Some(&"stderr")) {
err.panic();
}

self
}

/// Ensure the command wrote the expected data to `stderr`.
///
/// ```rust,no_run
/// use snapbox::cmd::Command;
/// use snapbox::cmd::cargo_bin;
///
/// let assert = Command::new(cargo_bin("snap-fixture"))
/// .env("stdout", "hello")
/// .env("stderr", "world")
/// .assert()
/// .stderr_matches("wo[..]d");
/// ```
///
/// Can combine this with [`file!`][crate::file]
/// ```rust,no_run
/// use snapbox::cmd::Command;
/// use snapbox::cmd::cargo_bin;
/// use snapbox::file;
///
/// let assert = Command::new(cargo_bin("snap-fixture"))
/// .env("stdout", "hello")
/// .env("stderr", "world")
/// .assert()
/// .stderr_matches(file!["stderr.log"]);
/// ```
#[track_caller]
pub fn stderr_matches(self, expected: impl Into<crate::Data>) -> Self {
let expected = expected.into();
self.stderr_matches_inner(expected)
}

#[track_caller]
fn stderr_matches_inner(self, expected: crate::Data) -> Self {
let actual = crate::Data::from(self.output.stderr.as_slice());
if let Err(err) = self.config.try_eq(expected, actual, Some(&"stderr")) {
err.panic();
Expand Down
2 changes: 1 addition & 1 deletion crates/snapbox/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl Data {
}

/// Remove default [`filters`][crate::filters] from this `expected` result
pub(crate) fn raw(mut self) -> Self {
pub fn raw(mut self) -> Self {
self.filters = FilterSet::empty().newlines();
self
}
Expand Down
7 changes: 4 additions & 3 deletions crates/snapbox/src/data/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,10 @@ world
);

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

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

#[test]
Expand Down Expand Up @@ -400,7 +400,8 @@ Patchwork {
],
}
"#]],
"#]]
.raw(),
patchwork.to_debug(),
);
}
Expand Down
7 changes: 7 additions & 0 deletions crates/snapbox/src/data/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ impl Inline {
data.is(format)
}

/// Remove default [`filters`][crate::filters] from this `expected` result
pub fn raw(self) -> super::Data {
let mut data: super::Data = self.into();
data.filters = super::FilterSet::empty().newlines();
data
}

fn trimmed(&self) -> String {
let mut data = self.data;
if data.contains('\n') {
Expand Down
51 changes: 13 additions & 38 deletions crates/snapbox/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
//! ## Getting Started
//!
//! Testing Functions:
//! - [`assert_eq`][crate::assert_eq()] and [`assert_matches`] for reusing diffing / pattern matching for non-snapshot testing
//! - [`assert_eq`][crate::assert_eq()] for quick and dirty snapshotting
//! - [`harness::Harness`] for discovering test inputs and asserting against snapshot files:
//!
//! Testing Commands:
Expand All @@ -44,17 +44,17 @@
//!
//! # Examples
//!
//! [`assert_matches`]
//! [`assert_eq`][crate::assert_eq()]
//! ```rust
//! snapbox::assert_matches("Hello [..] people!", "Hello many people!");
//! snapbox::assert_eq("Hello [..] people!", "Hello many people!");
//! ```
//!
//! [`Assert`]
//! ```rust,no_run
//! let actual = "...";
//! snapbox::Assert::new()
//! .action_env("SNAPSHOTS")
//! .matches(snapbox::file!["help_output_is_clean.txt"], actual);
//! .eq(snapbox::file!["help_output_is_clean.txt"], actual);
//! ```
//!
//! [`harness::Harness`]
Expand Down Expand Up @@ -121,12 +121,19 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;

/// Check if a value is the same as an expected value
///
/// When the content is text, newlines are normalized.
/// By default [`filters`] 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`] on `expected`.
///
/// ```rust
/// # use snapbox::assert_eq;
/// let output = "something";
/// let expected = "something";
/// let expected = "so[..]g";
/// assert_eq(expected, output);
/// ```
///
Expand All @@ -144,38 +151,6 @@ pub fn assert_eq(expected: impl Into<crate::Data>, actual: impl Into<crate::Data
.eq(expected, actual);
}

/// Check if a value matches a pattern
///
/// Pattern syntax:
/// - `...` is a line-wildcard when on a line by itself
/// - `[..]` is a character-wildcard when inside a line
/// - `[EXE]` matches `.exe` on Windows
///
/// Normalization:
/// - Newlines
/// - `\` to `/`
///
/// ```rust
/// # use snapbox::assert_matches;
/// let output = "something";
/// let expected = "so[..]g";
/// assert_matches(expected, output);
/// ```
///
/// Can combine this with [`file!`]
/// ```rust,no_run
/// # use snapbox::assert_matches;
/// # use snapbox::file;
/// let actual = "something";
/// assert_matches(file!["output.txt"], actual);
/// ```
#[track_caller]
pub fn assert_matches(pattern: impl Into<crate::Data>, actual: impl Into<crate::Data>) {
Assert::new()
.action_env(DEFAULT_ACTION_ENV)
.matches(pattern, actual);
}

/// Check if a path matches the content of another path, recursively
///
/// When the content is text, newlines are normalized.
Expand Down

0 comments on commit 1762764

Please sign in to comment.