Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

glob!: Add three-arg version to specify base_path #347

Merged
merged 1 commit into from Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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,19 +538,41 @@ 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)
}};
}
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