Skip to content

Commit

Permalink
Deprecate assert_display_snapshot, refactor macros
Browse files Browse the repository at this point in the history
This PR:
- Deprecates `assert_display_snapshot` in favor of `assert_snapshot`, as discussed in mitsuhiko#379
- Makes a sizable change in how macros are constructed:
  - It makes macros consistent — previously `debug` & `display` had different forms than the others, not taking a `debug_expr`.
  - The non-redaction macros are a simple wrapper of `_assert_snapshot_base`, which takes a closure `transform` of how to transform the input to a string.
  - The redaction macros are a simple wrapper of `_assert_serialized_snapshot`, which takes an arg `format` (similar to before), and uses that to construct a transform.
  - As a result, the boilerplate for each macros is removed.

It's not quite complete, but wanted to post before spending more time on it.

Still todo:
- We get a couple of test failures; I need to look into this; we seem to be generating an additional `---` in some yaml snapshots. (possibly something is being converted to string twice?)
- Update docs; previously the debug_expr wasn't documented, and now that the source is more opaque this is more important
  • Loading branch information
max-sixty committed Jun 18, 2023
1 parent e65d78e commit ba4db8b
Showing 1 changed file with 97 additions and 202 deletions.
299 changes: 97 additions & 202 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,9 @@ macro_rules! _function_name {
#[cfg_attr(docsrs, doc(cfg(feature = "csv")))]
#[macro_export]
macro_rules! assert_csv_snapshot {
($value:expr, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, Csv, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, {$($k => $v),*}, Csv, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, {$($k => $v),*}, Csv);
}};
($name:expr, $value:expr) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, Csv);
}};
($name:expr, $value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, {$($k => $v),*}, Csv);
}};
($value:expr) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, Csv);
}};
($($arg:tt)*) => {
$crate::_assert_serialized_snapshot!(format=Csv, $($arg)*);
};
}

/// Asserts a `Serialize` snapshot in TOML format.
Expand All @@ -82,24 +67,9 @@ macro_rules! assert_csv_snapshot {
#[cfg_attr(docsrs, doc(cfg(feature = "toml")))]
#[macro_export]
macro_rules! assert_toml_snapshot {
($value:expr, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, Toml, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, {$($k => $v),*}, Toml, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, {$($k => $v),*}, Toml);
}};
($name:expr, $value:expr) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, Toml);
}};
($name:expr, $value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, {$($k => $v),*}, Toml);
}};
($value:expr) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, Toml);
}};
($($arg:tt)*) => {
$crate::_assert_serialized_snapshot!(format=Toml, $($arg)*);
};
}

/// Asserts a `Serialize` snapshot in YAML format.
Expand Down Expand Up @@ -150,24 +120,9 @@ macro_rules! assert_toml_snapshot {
#[cfg_attr(docsrs, doc(cfg(feature = "yaml")))]
#[macro_export]
macro_rules! assert_yaml_snapshot {
($value:expr, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, Yaml, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, {$($k => $v),*}, Yaml, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, {$($k => $v),*}, Yaml);
}};
($name:expr, $value:expr) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, Yaml);
}};
($name:expr, $value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, {$($k => $v),*}, Yaml);
}};
($value:expr) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, Yaml);
}};
($($arg:tt)*) => {
$crate::_assert_serialized_snapshot!(format=Yaml, $($arg)*);
};
}

/// Asserts a `Serialize` snapshot in RON format.
Expand All @@ -194,24 +149,9 @@ macro_rules! assert_yaml_snapshot {
#[cfg_attr(docsrs, doc(cfg(feature = "ron")))]
#[macro_export]
macro_rules! assert_ron_snapshot {
($value:expr, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, Ron, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, {$($k => $v),*}, Ron, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, {$($k => $v),*}, Ron);
}};
($name:expr, $value:expr) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, Ron);
}};
($name:expr, $value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, {$($k => $v),*}, Ron);
}};
($value:expr) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, Ron);
}};
($($arg:tt)*) => {
$crate::_assert_serialized_snapshot!(format=Ron, $($arg)*);
};
}

/// Asserts a `Serialize` snapshot in JSON format.
Expand All @@ -238,24 +178,9 @@ macro_rules! assert_ron_snapshot {
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
#[macro_export]
macro_rules! assert_json_snapshot {
($value:expr, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, Json, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, {$($k => $v),*}, Json, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, {$($k => $v),*}, Json);
}};
($name:expr, $value:expr) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, Json);
}};
($name:expr, $value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, {$($k => $v),*}, Json);
}};
($value:expr) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, Json);
}};
($($arg:tt)*) => {
$crate::_assert_serialized_snapshot!(format=Json, $($arg)*);
};
}

/// Asserts a `Serialize` snapshot in compact JSON format.
Expand Down Expand Up @@ -283,61 +208,39 @@ macro_rules! assert_json_snapshot {
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
#[macro_export]
macro_rules! assert_compact_json_snapshot {
($value:expr, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, JsonCompact, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}, @$snapshot:literal) => {{
$crate::_assert_serialized_snapshot!($value, {$($k => $v),*}, JsonCompact, @$snapshot);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, {$($k => $v),*}, JsonCompact);
}};
($name:expr, $value:expr) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, JsonCompact);
}};
($name:expr, $value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!(Some($name), $value, {$($k => $v),*}, JsonCompact);
}};
($value:expr) => {{
$crate::_assert_serialized_snapshot!($crate::_macro_support::AutoName, $value, JsonCompact);
}};
($($arg:tt)*) => {
$crate::_assert_serialized_snapshot!(format=JsonCompact, $($arg)*);
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! _assert_serialized_snapshot {
($value:expr, $format:ident, @$snapshot:literal) => {{
let value = $crate::_macro_support::serialize_value(
&$value,
(format=$format:ident, $value:expr, {$($k:expr => $v:expr),*$(,)?}, @$snapshot:literal) => {{
let transform = |value| {
let (_, value) = $crate::_prepare_snapshot_for_redaction!(value, {$($k => $v),*}, $format, Inline);
value
};
$crate::_assert_snapshot_base!(transform=transform, $value, stringify!($value), @$snapshot);
}};
(format=$format:ident, $value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
$crate::_assert_serialized_snapshot!(format=$format, $crate::_macro_support::AutoName, $value, {$($k => $v),*});
}};
(format=$format:ident, $name:expr, $value:expr, {$($k:expr => $v:expr),*$(,)?}) => {{
let transform = |value| {
let (_, value) = $crate::_prepare_snapshot_for_redaction!(value, {$($k => $v),*}, $format, File);
value
};
$crate::_assert_snapshot_base!(transform=transform, $name, $value, stringify!($value));
}};
(format=$format:ident, $($arg:tt)*) => {{
let transform = |value| {$crate::_macro_support::serialize_value(
&value,
$crate::_macro_support::SerializationFormat::$format,
$crate::_macro_support::SnapshotLocation::Inline
);
$crate::assert_snapshot!(
value,
stringify!($value),
@$snapshot
);
}};
($value:expr, {$($k:expr => $v:expr),*$(,)?}, $format:ident, @$snapshot:literal) => {{
let (vec, value) = $crate::_prepare_snapshot_for_redaction!($value, {$($k => $v),*}, $format, Inline);
$crate::assert_snapshot!(value, stringify!($value), @$snapshot);
}};
($name:expr, $value:expr, $format:ident) => {{
let value = $crate::_macro_support::serialize_value(
&$value,
$crate::_macro_support::SerializationFormat::$format,
$crate::_macro_support::SnapshotLocation::File
);
$crate::assert_snapshot!(
$name,
value,
stringify!($value)
);
)};
$crate::_assert_snapshot_base!(transform = transform, $($arg)*);
}};
($name:expr, $value:expr, {$($k:expr => $v:expr),*$(,)?}, $format:ident) => {{
let (vec, value) = $crate::_prepare_snapshot_for_redaction!($value, {$($k => $v),*}, $format, File);
$crate::assert_snapshot!($name, value, stringify!($value));
}}
}

#[cfg(feature = "redactions")]
Expand Down Expand Up @@ -375,89 +278,45 @@ macro_rules! _prepare_snapshot_for_redaction {
/// Asserts a `Debug` snapshot.
///
/// The value needs to implement the `fmt::Debug` trait. This is useful for
/// simple values that do not implement the `Serialize` trait but does not
/// simple values that do not implement the `Serialize` trait, but does not
/// permit redactions.
///
/// Debug is called with `"{:#?}"`, which means this uses pretty-print.
///
/// The snapshot name is optional.
#[macro_export]
macro_rules! assert_debug_snapshot {
($value:expr, @$snapshot:literal) => {{
let value = format!("{:#?}", $value);
$crate::assert_snapshot!(value, stringify!($value), @$snapshot);
}};
($name:expr, $value:expr) => {{
let value = format!("{:#?}", $value);
$crate::assert_snapshot!(Some($name), value, stringify!($value));
}};
($value:expr) => {{
let value = format!("{:#?}", $value);
$crate::assert_snapshot!($crate::_macro_support::AutoName, value, stringify!($value));
}};
}

/// Asserts a `Display` snapshot.
///
/// The value needs to implement the `fmt::Display` trait.
///
/// The snapshot name is optional.
#[macro_export]
macro_rules! assert_display_snapshot {
($value:expr, @$snapshot:literal) => {{
let value = format!("{}", $value);
$crate::assert_snapshot!(value, stringify!($value), @$snapshot);
}};
($name:expr, $value:expr) => {{
let value = format!("{}", $value);
$crate::assert_snapshot!(Some($name), value, stringify!($value));
}};
($value:expr) => {{
let value = format!("{}", $value);
$crate::assert_snapshot!($crate::_macro_support::AutoName, value, stringify!($value));
}};
($($arg:tt)*) => {
$crate::_assert_snapshot_base!(transform=|v| format!("{:#?}", v), $($arg)*)
};
}

/// Asserts a string snapshot.
///
/// This is the most simplistic of all assertion methods. It just accepts
/// a string to store as snapshot an does not apply any other transformations
/// on it. This is useful to build ones own primitives.
///
/// ```no_run
/// # use insta::*;
/// assert_snapshot!("reference value to snapshot");
/// ```
///
/// Optionally a third argument can be given as expression which will be
/// stringified as debug expression. For more information on this look at the
/// source of this macro and other assertion macros.
///
/// The snapshot name is optional.
// A helper macro which takes a closure as `transform`, and runs the closure on
// the value. This allows us to implement other macros with a small wrapper.
#[doc(hidden)]
#[macro_export]
macro_rules! assert_snapshot {
($value:expr, @$snapshot:literal) => {
$crate::assert_snapshot!(
macro_rules! _assert_snapshot_base {
(transform=$transform:expr, $value:expr, @$snapshot:literal) => {
$crate::_assert_snapshot_base!(
transform = $transform,
$crate::_macro_support::ReferenceValue::Inline($snapshot),
$value,
stringify!($value)
)
};
($value:expr, $debug_expr:expr, @$snapshot:literal) => {
$crate::assert_snapshot!(
(transform=$transform:expr, $value:expr, $debug_expr:expr, @$snapshot:literal) => {
$crate::_assert_snapshot_base!(
transform = $transform,
$crate::_macro_support::ReferenceValue::Inline($snapshot),
$value,
$debug_expr
)
};
($name:expr, $value:expr) => {
$crate::assert_snapshot!($name, $value, stringify!($value))
(transform=$transform:expr, $name:expr, $value:expr) => {
$crate::_assert_snapshot_base!(transform = $transform, $name, $value, stringify!($value))
};
($name:expr, $value:expr, $debug_expr:expr) => {{
(transform=$transform:expr, $name:expr, $value:expr, $debug_expr:expr) => {
$crate::_macro_support::assert_snapshot(
// Creates a ReferenceValue::Named variant
$name.into(),
&$value,
&$transform($value),
env!("CARGO_MANIFEST_DIR"),
$crate::_function_name!(),
module_path!(),
Expand All @@ -466,9 +325,45 @@ macro_rules! assert_snapshot {
$debug_expr,
)
.unwrap()
}};
($value:expr) => {
$crate::assert_snapshot!($crate::_macro_support::AutoName, $value, stringify!($value))
};
(transform=$transform:expr, $value:expr) => {
$crate::_assert_snapshot_base!(
transform = $transform,
$crate::_macro_support::AutoName,
$value,
stringify!($value)
)
};
}

/// Asserts a `Display` snapshot.
///
/// This is now deprecated, replaced by the more generic `assert_snapshot!()`
#[macro_export]
#[deprecated = "use assert_snapshot!() instead"]
macro_rules! assert_display_snapshot {
($($arg:tt)*) => {
$crate::assert_snapshot!($($arg)*)
};
}

/// Asserts a string snapshot.
///
/// This is the simplest of all assertion methods. It accepts any value
/// that implements `fmt::Display`.
///
/// ```no_run
/// # use insta::*;
/// assert_snapshot!("reference value to snapshot");
/// ```
///
/// Optionally a third argument can be given as expression which will be
/// stringified as debug expression. For more information on this, check out
/// https://insta.rs/docs/snapshot-types/.
#[macro_export]
macro_rules! assert_snapshot {
($($arg:tt)*) => {
$crate::_assert_snapshot_base!(transform=|v| format!("{}", v), $($arg)*)
};
}

Expand Down

0 comments on commit ba4db8b

Please sign in to comment.