From 686de754aa613ccc820541ce1d7f95ab1a0095ee Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Sat, 2 Mar 2024 15:49:04 -0800 Subject: [PATCH] Add `require_full_match` option (#448) May need some refining. Closes https://github.com/mitsuhiko/insta/issues/351, but with an additional option, since `force_update` seems like a bad term for this --- cargo-insta/src/cli.rs | 3 +++ src/env.rs | 14 ++++++++++++++ src/lib.rs | 2 ++ src/runtime.rs | 15 +++++++++++++-- src/snapshot.rs | 12 +++++++++++- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/cargo-insta/src/cli.rs b/cargo-insta/src/cli.rs index 4b5bfae2..ac4d5d9d 100644 --- a/cargo-insta/src/cli.rs +++ b/cargo-insta/src/cli.rs @@ -891,6 +891,9 @@ fn prepare_test_runner<'snapshot_ref>( if cmd.require_full_match { proc.env("INSTA_REQUIRE_FULL_MATCH", "1"); } + if cmd.require_full_match { + proc.env("INSTA_REQUIRE_FULL_MATCH", "1"); + } let glob_filter = cmd.glob_filter .iter() diff --git a/src/env.rs b/src/env.rs index d5440b2f..ea0b0c0c 100644 --- a/src/env.rs +++ b/src/env.rs @@ -98,6 +98,7 @@ impl std::error::Error for Error { pub struct ToolConfig { force_update_snapshots: bool, force_pass: bool, + require_full_match: bool, output: OutputBehavior, snapshot_update: SnapshotUpdate, #[cfg(feature = "glob")] @@ -157,6 +158,14 @@ impl ToolConfig { Ok("1") => true, _ => return Err(Error::Env("INSTA_FORCE_UPDATE")), }, + require_full_match: match env::var("INSTA_REQUIRE_FULL_MATCH").as_deref() { + Err(_) | Ok("") => resolve(&cfg, &["behavior", "require_full_match"]) + .and_then(|x| x.as_bool()) + .unwrap_or(false), + Ok("0") => false, + Ok("1") => true, + _ => return Err(Error::Env("INSTA_REQUIRE_FULL_MATCH")), + }, force_pass: match env::var("INSTA_FORCE_PASS").as_deref() { Err(_) | Ok("") => resolve(&cfg, &["behavior", "force_pass"]) .and_then(|x| x.as_bool()) @@ -255,6 +264,11 @@ impl ToolConfig { self.force_update_snapshots } + /// Should we fail if metadata doesn't match? + pub fn require_full_match(&self) -> bool { + self.require_full_match + } + /// Is insta instructed to fail in tests? pub fn force_pass(&self) -> bool { self.force_pass diff --git a/src/lib.rs b/src/lib.rs index 3aa14d9d..602ab721 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -196,6 +196,8 @@ //! behavior: //! # also set by INSTA_FORCE_UPDATE //! force_update: true/false +//! # also set by INSTA_REQUIRE_FULL_MATCH +//! require_full_match: true/false //! # also set by INSTA_FORCE_PASS //! force_pass: true/false //! # also set by INSTA_OUTPUT diff --git a/src/runtime.rs b/src/runtime.rs index c5b88414..d61c25a0 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -666,8 +666,19 @@ pub fn assert_snapshot( } }); - // pass if the snapshots are missing - if ctx.old_snapshot.as_ref().map(|x| x.contents()) == Some(new_snapshot.contents()) { + let pass = ctx + .old_snapshot + .as_ref() + .map(|x| { + if tool_config.require_full_match() { + x.matches_fully(&new_snapshot) + } else { + x.matches(&new_snapshot) + } + }) + .unwrap_or(false); + + if pass { ctx.cleanup_passing()?; if tool_config.force_update_snapshots() { diff --git a/src/snapshot.rs b/src/snapshot.rs index dead284b..59c7d869 100644 --- a/src/snapshot.rs +++ b/src/snapshot.rs @@ -128,7 +128,7 @@ impl PendingInlineSnapshot { } /// Snapshot metadata information. -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default, Clone, PartialEq)] pub struct MetaData { /// The source file (relative to workspace root). pub(crate) source: Option, @@ -434,6 +434,16 @@ impl Snapshot { &self.snapshot } + /// Snapshot contents match another snapshot's. + pub fn matches(&self, other: &Snapshot) -> bool { + self.contents() == other.contents() + } + + /// Snapshot contents _and_ metadata match another snapshot's. + pub fn matches_fully(&self, other: &Snapshot) -> bool { + self.matches(other) && self.metadata == other.metadata + } + /// The snapshot contents as a &str pub fn contents_str(&self) -> &str { self.snapshot.as_str()