Skip to content

Commit

Permalink
glob!: Add three-arg version to specify base_path (#347)
Browse files Browse the repository at this point in the history
  • Loading branch information
the-kenny committed Feb 15, 2023
1 parent 64ba457 commit 9d70fac
Show file tree
Hide file tree
Showing 16 changed files with 166 additions and 5 deletions.
10 changes: 9 additions & 1 deletion src/glob.rs
Expand Up @@ -39,6 +39,15 @@ lazy_static::lazy_static! {
}

pub fn glob_exec<F: FnMut(&Path)>(manifest_dir: &str, base: &Path, pattern: &str, mut f: F) {
// If settings.allow_empty_glob() == true and `base` doesn't exist, skip
// everything. This is necessary as `base` is user-controlled via `glob!/3`
// and may not exist.
let mut settings = Settings::clone_current();

if settings.allow_empty_glob() && !base.exists() {
return;
}

let glob = GlobBuilder::new(pattern)
.case_insensitive(true)
.literal_separator(true)
Expand All @@ -48,7 +57,6 @@ pub fn glob_exec<F: FnMut(&Path)>(manifest_dir: &str, base: &Path, pattern: &str

let walker = WalkDir::new(base).follow_links(true);
let mut glob_found_matches = false;
let mut settings = Settings::clone_current();

GLOB_STACK.lock().unwrap().push(GlobCollector {
failed: 0,
Expand Down
30 changes: 26 additions & 4 deletions src/macros.rs
Expand Up @@ -538,21 +538,43 @@ macro_rules! with_settings {
/// are deferred until the end of of it. In other words this means that each snapshot
/// assertion within the `glob!` block are reported. It can be disabled by setting
/// `INSTA_GLOB_FAIL_FAST` environment variable to `1`.
///
/// A three-argument version of this macro allows specifying a base directory
/// for the glob to start in. This allows globbing in arbitrary directories,
/// including parent directories:
///
/// ```
/// # use insta::{assert_snapshot, glob, Settings};
/// # let mut settings = Settings::clone_current();
/// # settings.set_allow_empty_glob(true);
/// # let _dropguard = settings.bind_to_scope();
/// use std::fs;
///
/// glob!("../test_data", "inputs/*.txt", |path| {
/// let input = fs::read_to_string(path).unwrap();
/// assert_snapshot!(input.to_uppercase());
/// });
/// ```
#[cfg(feature = "glob")]
#[cfg_attr(docsrs, doc(cfg(feature = "glob")))]
#[macro_export]
macro_rules! glob {
($glob:expr, $closure:expr) => {{
($base_path:expr, $glob:expr, $closure:expr) => {{
use std::path::Path;
let base = $crate::_macro_support::get_cargo_workspace(env!("CARGO_MANIFEST_DIR"))
.join(file!())
.parent()
.unwrap()
.join(Path::new(file!()).parent().unwrap())
.join($base_path)
.to_path_buf();

// we try to canonicalize but on some platforms (eg: wasm) that might not work, so
// we instead silently fall back.
let base = base.canonicalize().unwrap_or_else(|_| base);
$crate::_macro_support::glob_exec(env!("CARGO_MANIFEST_DIR"), &base, $glob, $closure);
}};

($glob:expr, $closure:expr) => {{
insta::glob!(".", $glob, $closure)
}};
}

/// Utility macro to permit a multi-snapshot run where all snapshots match.
Expand Down
53 changes: 53 additions & 0 deletions tests/glob_submodule/mod.rs
@@ -0,0 +1,53 @@
#![cfg(feature = "glob")]

#[test]
fn test_basic_globbing_parent_dir() {
insta::glob!("../inputs", "*.txt", |path| {
let contents = std::fs::read_to_string(path).unwrap();
insta::assert_json_snapshot!(&contents);
});
}

#[test]
fn test_basic_globbing_nested_parent_dir_base_path() {
insta::glob!("../inputs-nested", "*/*.txt", |path| {
let contents = std::fs::read_to_string(path).unwrap();
insta::assert_snapshot!(&contents);
});
}

#[test]
fn test_basic_globbing_nested_parent_glob() {
insta::glob!("..", "inputs-nested/*/*.txt", |path| {
let contents = std::fs::read_to_string(path).unwrap();
insta::assert_snapshot!(&contents);
});
}

#[test]
fn test_globs_follow_links_parent_dir_base_path() {
insta::glob!("../link-to-inputs", "*.txt", |path| {
let contents = std::fs::read_to_string(path).unwrap();
insta::assert_json_snapshot!(&contents);
});
}

#[test]
fn test_globs_follow_links_parent_dir_glob() {
insta::glob!("..", "link-to-inputs/*.txt", |path| {
let contents = std::fs::read_to_string(path).unwrap();
insta::assert_json_snapshot!(&contents);
});
}

#[test]
fn test_basic_globbing_absolute_dir() {
insta::glob!(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/inputs"),
"*.txt",
|path| {
let contents = std::fs::read_to_string(path).unwrap();
insta::assert_json_snapshot!(&contents);
}
);
}
@@ -0,0 +1,6 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs/goodbye.txt
---
"Contents of goodbye"
@@ -0,0 +1,6 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs/hello.txt
---
"Contents of hello"
@@ -0,0 +1,7 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs-nested/a/file.txt
---
Hello A

@@ -0,0 +1,7 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs-nested/b/file.txt
---
Hello B

@@ -0,0 +1,7 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs-nested/a/file.txt
---
Hello A

@@ -0,0 +1,7 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs-nested/b/file.txt
---
Hello B

@@ -0,0 +1,6 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs/goodbye.txt
---
"Contents of goodbye"
@@ -0,0 +1,6 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs/hello.txt
---
"Contents of hello"
@@ -0,0 +1,6 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs/goodbye.txt
---
"Contents of goodbye"
@@ -0,0 +1,6 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs/hello.txt
---
"Contents of hello"
@@ -0,0 +1,6 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs/goodbye.txt
---
"Contents of goodbye"
@@ -0,0 +1,6 @@
---
source: tests/glob_submodule/mod.rs
expression: "&contents"
input_file: tests/inputs/hello.txt
---
"Contents of hello"
2 changes: 2 additions & 0 deletions tests/test_glob.rs
@@ -1,5 +1,7 @@
#![cfg(feature = "glob")]

mod glob_submodule;

#[test]
fn test_basic_globbing() {
insta::glob!("inputs/*.txt", |path| {
Expand Down

0 comments on commit 9d70fac

Please sign in to comment.