Repository: mitsuhiko/insta
Pull request #569 (2024-08-17 20:14:38)

Enable inline snapshots to be force-updated
We previously excluded these. But it's somewhat required for #563, and I don't think there's a big downside -- we only generate pending files when a snapshot doesn't match of `--force-update-snapshots` is passed.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd01721..abc9f8a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,8 @@ All notable changes to insta and cargo-insta are documented here.
   themselves contain `###`. If there are no existing `#` characters in the
   snapshot value, a single `#` will be used.  #540
 
+- Inline snapshots can now be updated with `--force-update-snapshots`.  #569
+
 - `cargo insta test` accepts multiple `--exclude` flags.  #520
 
 - `test` `runner` in insta's yaml config works.  #544
diff --git a/insta/src/runtime.rs b/insta/src/runtime.rs
index 245157e..90c9639 100644
--- a/insta/src/runtime.rs
+++ b/insta/src/runtime.rs
@@ -397,6 +397,7 @@ impl<'a> SnapshotAssertionContext<'a> {
             }
             SnapshotUpdateBehavior::NewFile => {
                 if let Some(ref snapshot_file) = self.snapshot_file {
+                    // File snapshot
                     if let Some(new_path) = new_snapshot.save_new(snapshot_file)? {
                         if should_print {
                             elog!(
@@ -415,19 +416,7 @@ impl<'a> SnapshotAssertionContext<'a> {
                                 .bold(),
                         );
                     }
-
-                // special case for pending inline snapshots.  Here we really only want
-                // to write the contents if the snapshot contents changed as the metadata
-                // is not retained for inline snapshots.  This used to have different
-                // behavior in the past where we did indeed want to rewrite the snapshots
-                // entirely since we used to change the canonical snapshot format, but now
-                // this is significantly less likely to happen and seeing hundreds of unchanged
-                // inline snapshots in the review screen is not a lot of fun.
-                } else if self
-                    .old_snapshot
-                    .as_ref()
-                    .map_or(true, |x| x.contents() != new_snapshot.contents())
-                {
+                } else {
                     PendingInlineSnapshot::new(
                         Some(new_snapshot),
                         self.old_snapshot.clone(),


Test patch:
diff --git a/cargo-insta/tests/main.rs b/cargo-insta/tests/main.rs
index 249cac1..064a36c 100644
--- a/cargo-insta/tests/main.rs
+++ b/cargo-insta/tests/main.rs
@@ -71,6 +71,7 @@ fn assert_success(output: &std::process::Output) {
     // we would otherwise lose any output from the command such as `dbg!`
     // statements.
     eprint!("{}", String::from_utf8_lossy(&output.stderr));
+    eprint!("{}", String::from_utf8_lossy(&output.stdout));
     assert!(
         output.status.success(),
         "Tests failed: {}\n{}",
@@ -716,6 +717,62 @@ fn test_virtual_manifest_single_crate() {
     "###     );
 }
 
+#[test]
+fn test_force_update_inline_snapshot() {
+    let test_project = TestFiles::new()
+        .add_file(
+            "Cargo.toml",
+            r#"
+[package]
+name = "force-update-inline"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+insta = { path = '$PROJECT_PATH' }
+"#
+            .to_string(),
+        )
+        .add_file(
+            "src/lib.rs",
+            r#####"
+#[test]
+fn test_excessive_hashes() {
+    insta::assert_snapshot!("foo", @r####"foo"####);
+}
+"#####
+                .to_string(),
+        )
+        .create_project();
+
+    // Run the test with --force-update-snapshots and --accept
+    let output = test_project
+        .cmd()
+        .args([
+            "test",
+            "--force-update-snapshots",
+            "--accept",
+            "--",
+            "--nocapture",
+        ])
+        .output()
+        .unwrap();
+
+    assert_success(&output);
+
+    assert_snapshot!(test_project.diff("src/lib.rs"), @r#####"
+    --- Original: src/lib.rs
+    +++ Updated: src/lib.rs
+    @@ -1,5 +1,5 @@
+     
+     #[test]
+     fn test_excessive_hashes() {
+    -    insta::assert_snapshot!("foo", @r####"foo"####);
+    +    insta::assert_snapshot!("foo", @"foo");
+     }
+    "#####);
+}
+
 #[test]
 fn test_hashtag_escape_in_inline_snapshot() {
     let test_project = TestFiles::new()