Skip to content

Commit

Permalink
Prevent inline snapshots in loops. Fixes #307
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Dec 3, 2022
1 parent 4d5e330 commit 745b45b
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@ All notable changes to insta and cargo-insta are documented here.
- Added support for rendering some invisibles in diffs. This now also
should make sure that ANSI sequences in strings are no longer screwing
up the terminal output. (#308)
- Prevent inline snapshots to be used in loops. (#307)

## 1.21.2

Expand Down
16 changes: 15 additions & 1 deletion src/runtime.rs
@@ -1,5 +1,5 @@
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::collections::{BTreeMap, BTreeSet};
use std::error::Error;
use std::fs;
use std::io::Write;
Expand All @@ -21,6 +21,8 @@ lazy_static::lazy_static! {
Mutex::new(BTreeMap::new());
static ref TEST_NAME_CLASH_DETECTION: Mutex<BTreeMap<String, bool>> =
Mutex::new(BTreeMap::new());
static ref INLINE_DUPLICATES: Mutex<BTreeSet<String>> =
Mutex::new(BTreeSet::new());
}

// This macro is basically eprintln but without being captured and
Expand Down Expand Up @@ -243,6 +245,7 @@ impl<'a> SnapshotAssertionContext<'a> {
snapshot_file = Some(file);
}
ReferenceValue::Inline(contents) => {
prevent_inline_duplicate(function_name, assertion_file, assertion_line);
snapshot_name = detect_snapshot_name(function_name, module_path, true, is_doctest)
.ok()
.map(Cow::Owned);
Expand Down Expand Up @@ -411,6 +414,17 @@ impl<'a> SnapshotAssertionContext<'a> {
}
}

fn prevent_inline_duplicate(function_name: &str, assertion_file: &str, assertion_line: u32) {
let key = format!("{}|{}|{}", function_name, assertion_file, assertion_line);
let mut set = INLINE_DUPLICATES.lock().unwrap();
if set.contains(&key) {
// drop the lock so we don't poison it
drop(set);
panic!("Insta does not allow inline snapshot assertions in loops");
}
set.insert(key);
}

/// This prints the information about the snapshot
fn print_snapshot_info(ctx: &SnapshotAssertionContext, new_snapshot: &Snapshot) {
match get_output_behavior() {
Expand Down
8 changes: 8 additions & 0 deletions tests/test_inline.rs
Expand Up @@ -278,3 +278,11 @@ fn test_compact_json() {
]
"###);
}

#[test]
#[should_panic = "Insta does not allow inline snapshot assertions in loops"]
fn test_inline_test_in_loop() {
for i in 0..10 {
assert_snapshot!(i.to_string(), @"0");
}
}

0 comments on commit 745b45b

Please sign in to comment.