Skip to content

Commit

Permalink
Added new filters feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Jul 23, 2022
1 parent cae792f commit 9d72c22
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,7 @@ All notable changes to insta and cargo-insta are documented here.

- Fixed an issue in `cargo-insta` where sometimes accepting inline snapshots
would crash with an out of bounds panic.
- Added new `filters` feature.

## 1.16.0

Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Expand Up @@ -24,6 +24,9 @@ default = ["colors"]
# snapshots.
redactions = ["pest", "pest_derive"]

# Enables support for running filters on snapshot
filters = ["regex"]

# Glob support
glob = ["walkdir", "globset"]

Expand All @@ -50,6 +53,7 @@ globset = { version = "0.4.6", optional = true }
walkdir = { version = "2.3.1", optional = true }
similar = { version = "2.1.0", features = ["inline"] }
once_cell = "1.9.0"
regex = { version = "1.6.0", default-features = false, optional = true, features = ["std", "unicode"] }

[dev-dependencies]
similar-asserts = "1.2.0"
6 changes: 6 additions & 0 deletions src/lib.rs
Expand Up @@ -140,6 +140,7 @@
//! * `ron`: enables RON support ([`assert_ron_snapshot!`])
//! * `toml`: enables TOML support ([`assert_toml_snapshot!`])
//! * `redactions`: enables support for redactions
//! * `filters`: enables support for filters
//! * `glob`: enables support for globbing ([`glob!`])
//! * `colors`: enables color output (enabled by default)
//!
Expand All @@ -161,6 +162,9 @@ mod utils;
#[cfg(feature = "redactions")]
mod redaction;

#[cfg(feature = "filters")]
mod filters;

#[cfg(feature = "glob")]
mod glob;

Expand All @@ -176,6 +180,8 @@ pub use crate::snapshot::{MetaData, Snapshot};
/// are exposed for documentation primarily.
pub mod internals {
pub use crate::content::Content;
#[cfg(feature = "filters")]
pub use crate::filters::Filters;
pub use crate::runtime::AutoName;
pub use crate::snapshot::{MetaData, SnapshotContents};
#[cfg(feature = "redactions")]
Expand Down
5 changes: 5 additions & 0 deletions src/runtime.rs
Expand Up @@ -472,6 +472,11 @@ pub fn assert_snapshot(
assertion_line,
)?;

// apply filters if they are available
#[cfg(feature = "filters")]
let new_snapshot_value =
Settings::with(|settings| settings.filters().apply_to(new_snapshot_value));

let new_snapshot = ctx.new_snapshot(new_snapshot_value.into(), expr);

// memoize the snapshot file if requested.
Expand Down
58 changes: 57 additions & 1 deletion src/settings.rs
Expand Up @@ -14,6 +14,9 @@ use crate::{
redaction::{dynamic_redaction, sorted_redaction, ContentPath, Redaction, Selector},
};

#[cfg(feature = "filters")]
use crate::filters::Filters;

static DEFAULT_SETTINGS: Lazy<Arc<ActualSettings>> = Lazy::new(|| {
Arc::new(ActualSettings {
sort_maps: false,
Expand All @@ -26,6 +29,8 @@ static DEFAULT_SETTINGS: Lazy<Arc<ActualSettings>> = Lazy::new(|| {
prepend_module_to_snapshot: true,
#[cfg(feature = "redactions")]
redactions: Redactions::default(),
#[cfg(feature = "filters")]
filters: Filters::default(),
#[cfg(feature = "glob")]
allow_empty_glob: false,
})
Expand Down Expand Up @@ -62,6 +67,8 @@ pub struct ActualSettings {
pub prepend_module_to_snapshot: bool,
#[cfg(feature = "redactions")]
pub redactions: Redactions,
#[cfg(feature = "filters")]
pub filters: Filters,
#[cfg(feature = "glob")]
pub allow_empty_glob: bool,
}
Expand Down Expand Up @@ -104,6 +111,11 @@ impl ActualSettings {
self.redactions = r.into();
}

#[cfg(feature = "filters")]
pub fn filters<F: Into<Filters>>(&mut self, f: F) {
self.filters = f.into();
}

#[cfg(feature = "glob")]
pub fn allow_empty_glob(&mut self, value: bool) {
self.allow_empty_glob = value;
Expand Down Expand Up @@ -370,7 +382,7 @@ impl Settings {
/// The default set is empty.
#[cfg(feature = "redactions")]
pub fn set_redactions<R: Into<Redactions>>(&mut self, redactions: R) {
self._private_inner_mut().redactions = redactions.into();
self._private_inner_mut().redactions(redactions);
}

/// Removes all redactions.
Expand All @@ -389,6 +401,50 @@ impl Settings {
.map(|&(ref a, ref b)| (a, &**b))
}

/// Adds a new filter.
///
/// Filters are similar to redactions but are applied as regex onto the final snapshot
/// value. This can be used to perform modifications to the snapshot string that would
/// be impossible to do with redactions because for instance the value is just a string.
///
/// The first argument is the [`regex`] pattern to apply, the second is a replacement
/// string. The replacement string has the same functionality as the second argument
/// to [`Regex::replace`](regex::Regex::replace).
///
/// This is useful to perform some cleanup procedures on the snapshot for unstable values.
///
/// ```rust
/// # use insta::Settings;
/// # async fn foo() {
/// # let mut settings = Settings::new();
/// settings.add_filter(r"\b[[:xdigit:]]{32}\b", "[UID]");
/// # }
/// ```
#[cfg(feature = "filters")]
pub fn add_filter<S: Into<String>>(&mut self, regex: &str, replacement: S) {
self._private_inner_mut().filters.add(regex, replacement);
}

/// Replaces the currently set filters.
///
/// The default set is empty.
#[cfg(feature = "filters")]
pub fn set_filters<F: Into<Filters>>(&mut self, filters: F) {
self._private_inner_mut().filters(filters);
}

/// Removes all filters.
#[cfg(feature = "filters")]
pub fn clear_filters(&mut self) {
self._private_inner_mut().filters.clear();
}

/// Returns the current filters
#[cfg(feature = "filters")]
pub(crate) fn filters(&self) -> &Filters {
&self.inner.filters
}

/// Sets the snapshot path.
///
/// If not absolute it's relative to where the test is in.
Expand Down
10 changes: 10 additions & 0 deletions src/snapshot.rs
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::error::Error;
use std::fs;
use std::io::{BufRead, BufReader, Write};
Expand Down Expand Up @@ -349,6 +350,15 @@ impl SnapshotContents {
}
}

impl<'a> From<Cow<'a, str>> for SnapshotContents {
fn from(value: Cow<'a, str>) -> Self {
match value {
Cow::Borrowed(s) => SnapshotContents::from(s),
Cow::Owned(s) => SnapshotContents::from(s),
}
}
}

impl From<&str> for SnapshotContents {
fn from(value: &str) -> SnapshotContents {
// make sure we have unix newlines consistently
Expand Down

0 comments on commit 9d72c22

Please sign in to comment.