Skip to content

Commit

Permalink
Unify handling of file & inline snapshots
Browse files Browse the repository at this point in the history
This is the code for mitsuhiko#456 (comment), as mentioned in mitsuhiko#466.

There's a very small change in yaml inline snapshots — shown here in the tests. In return, it makes the macros simpler & more maintainable.
  • Loading branch information
max-sixty committed Mar 26, 2024
1 parent 8379841 commit b31e6c6
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 63 deletions.
45 changes: 12 additions & 33 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,59 +223,39 @@ macro_rules! assert_compact_json_snapshot {
#[doc(hidden)]
#[macro_export]
macro_rules! _assert_serialized_snapshot {
// If there are redaction expressions and an inline snapshot, capture
// the redactions expressions and pass to `_assert_snapshot_base`
//
// Note that if we could unify the Inline & File represenations of snapshots
// redactions we could unify some of these branches.

(format=$format:ident, $value:expr, $(match ..)? {$($k:expr => $v:expr),* $(,)?}, @$snapshot:literal) => {{
// If there are redaction expressions, capture the redactions expressions
// and pass to `_assert_snapshot_base`
(format=$format:ident, $value:expr, $(match ..)? {$($k:expr => $v:expr),* $(,)?} $($arg:tt)*) => {{
let transform = |value| {
let (_, value) = $crate::_prepare_snapshot_for_redaction!(value, {$($k => $v),*}, $format, Inline);
let (_, value) = $crate::_prepare_snapshot_for_redaction!(value, {$($k => $v),*}, $format);
value
};
$crate::_assert_snapshot_base!(transform=transform, $value, @$snapshot);
$crate::_assert_snapshot_base!(transform=transform, $value $($arg)*);
}};
// If there are redaction expressions and no name, add a auto-generated name, call self
(format=$format:ident, $value:expr, $(match ..)? {$($k:expr => $v:expr),* $(,)?} $(,)?) => {{
$crate::_assert_serialized_snapshot!(format=$format, $crate::_macro_support::AutoName, $value, {$($k => $v),*});
}};
// If there are redaction expressions, capture and pass to `_assert_snapshot_base`
// If there's a name and redaction expressions, capture and pass to `_assert_snapshot_base`
(format=$format:ident, $name:expr, $value:expr, $(match ..)? {$($k:expr => $v:expr),* $(,)?} $(,)?) => {{
let transform = |value| {
let (_, value) = $crate::_prepare_snapshot_for_redaction!(value, {$($k => $v),*}, $format, File);
let (_, value) = $crate::_prepare_snapshot_for_redaction!(value, {$($k => $v),*}, $format);
value
};
$crate::_assert_snapshot_base!(transform=transform, $name, $value);
}};
// If there's an inline snapshot, capture serialization function and pass to
// `_assert_snapshot_base`, specifying `Inline`
// Capture serialization function and pass to `_assert_snapshot_base`
//
(format=$format:ident, $($arg:expr),*, @$snapshot:literal) => {{
let transform = |value| {$crate::_macro_support::serialize_value(
&value,
$crate::_macro_support::SerializationFormat::$format,
$crate::_macro_support::SnapshotLocation::Inline
)};
$crate::_assert_snapshot_base!(transform = transform, $($arg),*, @$snapshot);
}};
// Capture serialization function and pass to `_assert_snapshot_base`,
// specifying `File`
(format=$format:ident, $($arg:expr),* $(,)?) => {{
(format=$format:ident, $($arg:tt)*) => {{
let transform = |value| {$crate::_macro_support::serialize_value(
&value,
$crate::_macro_support::SerializationFormat::$format,
$crate::_macro_support::SnapshotLocation::File
)};
$crate::_assert_snapshot_base!(transform = transform, $($arg),*);
$crate::_assert_snapshot_base!(transform = transform, $($arg)*);
}};
}

#[cfg(feature = "redactions")]
#[doc(hidden)]
#[macro_export]
macro_rules! _prepare_snapshot_for_redaction {
($value:expr, {$($k:expr => $v:expr),*}, $format:ident, $location:ident) => {
($value:expr, {$($k:expr => $v:expr),*}, $format:ident) => {
{
let vec = vec![
$((
Expand All @@ -287,7 +267,6 @@ macro_rules! _prepare_snapshot_for_redaction {
&$value,
&vec,
$crate::_macro_support::SerializationFormat::$format,
$crate::_macro_support::SnapshotLocation::$location
);
(vec, value)
}
Expand All @@ -298,7 +277,7 @@ macro_rules! _prepare_snapshot_for_redaction {
#[doc(hidden)]
#[macro_export]
macro_rules! _prepare_snapshot_for_redaction {
($value:expr, {$($k:expr => $v:expr),*}, $format:ident, $location:ident) => {
($value:expr, {$($k:expr => $v:expr),*}, $format:ident) => {
compile_error!("insta was compiled without redaction support.");
};
}
Expand Down
28 changes: 5 additions & 23 deletions src/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ pub enum SnapshotLocation {
File,
}

pub fn serialize_content(
mut content: Content,
format: SerializationFormat,
location: SnapshotLocation,
) -> String {
pub fn serialize_content(mut content: Content, format: SerializationFormat) -> String {
content = Settings::with(|settings| {
if settings.sort_maps() {
content.sort_maps();
Expand All @@ -41,13 +37,7 @@ pub fn serialize_content(
});

match format {
SerializationFormat::Yaml => {
let serialized = yaml::to_string(&content);
match location {
SnapshotLocation::Inline => serialized,
SnapshotLocation::File => serialized[4..].to_string(),
}
}
SerializationFormat::Yaml => yaml::to_string(&content)[4..].to_string(),
SerializationFormat::Json => json::to_string_pretty(&content),
SerializationFormat::JsonCompact => json::to_string_compact(&content),
#[cfg(feature = "csv")]
Expand Down Expand Up @@ -98,29 +88,24 @@ pub fn serialize_content(
}
}

pub fn serialize_value<S: Serialize>(
s: &S,
format: SerializationFormat,
location: SnapshotLocation,
) -> String {
pub fn serialize_value<S: Serialize>(s: &S, format: SerializationFormat) -> String {
let serializer = ContentSerializer::<ValueError>::new();
let content = Serialize::serialize(s, serializer).unwrap();
serialize_content(content, format, location)
serialize_content(content, format)
}

#[cfg(feature = "redactions")]
pub fn serialize_value_redacted<S: Serialize>(
s: &S,
redactions: &[(crate::redaction::Selector, crate::redaction::Redaction)],
format: SerializationFormat,
location: SnapshotLocation,
) -> String {
let serializer = ContentSerializer::<ValueError>::new();
let mut content = Serialize::serialize(s, serializer).unwrap();
for (selector, redaction) in redactions {
content = selector.redact(content, redaction);
}
serialize_content(content, format, location)
serialize_content(content, format)
}

#[test]
Expand All @@ -140,7 +125,6 @@ fn test_yaml_serialization() {
),
]),
SerializationFormat::Yaml,
SnapshotLocation::File,
);
crate::assert_snapshot!(&yaml, @r###"
env:
Expand All @@ -166,10 +150,8 @@ fn test_yaml_serialization() {
),
]),
SerializationFormat::Yaml,
SnapshotLocation::Inline,
);
crate::assert_snapshot!(&inline_yaml, @r###"
---
env:
- ENVIRONMENT
- production
Expand Down
2 changes: 0 additions & 2 deletions tests/test_inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ fn test_yaml_inline() {
username: "peter-pan".into(),
email: "peterpan@wonderland.invalid".into()
}, @r###"
---
id: 42
username: peter-pan
email: peterpan@wonderland.invalid
Expand All @@ -207,7 +206,6 @@ fn test_yaml_inline_redacted() {
}, {
".id" => "[user-id]"
}, @r###"
---
id: "[user-id]"
username: peter-pan
email: peterpan@wonderland.invalid
Expand Down
2 changes: 0 additions & 2 deletions tests/test_redaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ fn test_redact_newtype_enum() {
assert_yaml_snapshot!(visitor, {
r#".id"# => "[id]",
}, @r###"
---
Visitor:
id: "[id]"
name: my-name
Expand All @@ -346,7 +345,6 @@ fn test_redact_newtype_enum() {
assert_yaml_snapshot!(admin, {
r#".id"# => "[id]",
}, @r###"
---
Admin:
id: "[id]"
username: john_doe
Expand Down
3 changes: 0 additions & 3 deletions tests/test_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ fn test_simple() {
settings.set_sort_maps(true);
settings.bind(|| {
assert_yaml_snapshot!(&map, @r###"
---
a: first value
b: second value
c: third value
Expand All @@ -40,7 +39,6 @@ fn test_bound_to_scope() {
settings.set_sort_maps(true);
let _guard = settings.bind_to_scope();
assert_yaml_snapshot!(&map, @r###"
---
a: first value
b: second value
c: third value
Expand All @@ -62,7 +60,6 @@ fn test_settings_macro() {

with_settings!({sort_maps => true}, {
insta::assert_yaml_snapshot!(&map, @r###"
---
a: first value
b: second value
c: third value
Expand Down

0 comments on commit b31e6c6

Please sign in to comment.