Skip to content

Commit

Permalink
Add matches_legacy method to encapsulate legacy normalization (#599)
Browse files Browse the repository at this point in the history
Another PR taking some unambiguous code from #563
  • Loading branch information
max-sixty authored Sep 17, 2024
1 parent a9b46fa commit 0894efd
Showing 1 changed file with 46 additions and 10 deletions.
56 changes: 46 additions & 10 deletions insta/src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ use std::io::{BufRead, BufReader, Write};
use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};

use crate::content::{self, json, yaml, Content};
use crate::{
content::{self, json, yaml, Content},
elog,
utils::style,
};

lazy_static::lazy_static! {
static ref RUN_ID: String = {
Expand Down Expand Up @@ -268,7 +272,7 @@ impl MetaData {
}
}

/// A helper to work with stored snapshots.
/// A helper to work with file snapshots.
#[derive(Debug, Clone)]
pub struct Snapshot {
module_name: String,
Expand Down Expand Up @@ -321,7 +325,7 @@ impl Snapshot {
}
}
}
crate::elog!("A snapshot uses an old snapshot format; please update it to the new format with `cargo insta test --force-update-snapshots --accept`.\n\nSnapshot is at: {}", p.to_string_lossy());
elog!("A snapshot uses an old snapshot format; please update it to the new format with `cargo insta test --force-update-snapshots --accept`.\n\nSnapshot is at: {}", p.to_string_lossy());
rv
};

Expand Down Expand Up @@ -520,7 +524,8 @@ impl SnapshotContents {
SnapshotContents(get_inline_snapshot_value(value))
}

/// Returns the snapshot contents as string with surrounding whitespace removed.
/// Returns the snapshot contents as a normalized string (for example,
/// removing surrounding whitespace)
pub fn as_str(&self) -> &str {
let out = self.0.trim_start_matches(['\r', '\n']).trim_end();
// Old inline snapshots have `---` at the start, so this strips that if
Expand All @@ -532,15 +537,36 @@ impl SnapshotContents {
}
}

/// Returns the snapshot contents as string without any trimming.
/// Returns the snapshot contents as string without any normalization
pub fn as_str_exact(&self) -> &str {
self.0.as_str()
}

/// Matches another snapshot without any normalization
pub fn matches_fully(&self, other: &SnapshotContents) -> bool {
self.as_str_exact() == other.as_str_exact()
}

/// Snapshot matches based on the latest format.
pub fn matches_latest(&self, other: &SnapshotContents) -> bool {
self.as_str() == other.as_str()
}

pub fn matches_legacy(&self, other: &SnapshotContents) -> bool {
fn as_str_legacy(sc: &SnapshotContents) -> &str {
let out = sc.as_str();
// Legacy inline snapshots have `---` at the start, so this strips that if
// it exists.
match out.strip_prefix("---\n") {
Some(old_snapshot) => old_snapshot,
None => out,
}
}
as_str_legacy(self) == as_str_legacy(other)
}

/// Create the literal string to write inline, adding `#` to escape the
/// value, indentation, delimiters
pub fn to_inline(&self, indentation: usize) -> String {
let contents = &self.0;
let mut out = String::new();
Expand Down Expand Up @@ -570,8 +596,9 @@ impl SnapshotContents {
out.extend(
contents
.lines()
// newline needs to be at the start, since we don't want the end
// finishing with a newline - the closing suffix should be on the same line
// Adds an additional newline at the start of multiline
// string (not sure this is the clearest way of representing
// it, but it works...)
.map(|l| {
format!(
"\n{:width$}{l}",
Expand All @@ -580,7 +607,8 @@ impl SnapshotContents {
l = l
)
})
// `lines` removes the final line ending - add back
// `lines` removes the final line ending — add back. Include
// indentation so the closing delimited aligns with the full string.
.chain(Some(format!("\n{:width$}", "", width = indentation))),
);
} else {
Expand Down Expand Up @@ -625,7 +653,15 @@ impl From<SnapshotContents> for String {

impl PartialEq for SnapshotContents {
fn eq(&self, other: &Self) -> bool {
self.as_str() == other.as_str()
// Ideally match on current rules, but otherwise fall back to legacy rules
if self.matches_latest(other) {
true
} else if self.matches_legacy(other) {
elog!("{} {}\n{}",style("Snapshot passes but is a legacy format. Please run `cargo insta test --force-update-snapshots --accept` to update to a newer format.").yellow().bold(),"Snapshot contents:", self.as_str());
true
} else {
false
}
}
}

Expand Down Expand Up @@ -719,7 +755,7 @@ fn get_inline_snapshot_value(frozen_value: &str) -> String {
// (the only call site)

if frozen_value.trim_start().starts_with('⋮') {
crate::elog!("A snapshot uses an old snapshot format; please update it to the new format with `cargo insta test --force-update-snapshots --accept`.\n\nSnapshot is at: {}", frozen_value);
elog!("A snapshot uses an old snapshot format; please update it to the new format with `cargo insta test --force-update-snapshots --accept`.\n\nSnapshot is at: {}", frozen_value);

// legacy format - retain so old snapshots still work
let mut buf = String::new();
Expand Down

0 comments on commit 0894efd

Please sign in to comment.