Skip to content

Commit 11623ea

Browse files
committed
switch to camino
1 parent 3fee2f2 commit 11623ea

File tree

8 files changed

+62
-44
lines changed

8 files changed

+62
-44
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ categories = ["development-tools::testing"]
1111
keywords = ["datatest", "data-driven-tests", "test-harness"]
1212

1313
[dependencies]
14+
camino = "1.1.6"
1415
libtest-mimic = "0.6.1"
1516
regex = "1.5.4"
1617
walkdir = "2.3.2"

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ harness = false
3030
2. Call the `datatest_stable::harness!(testfn, root, pattern)` macro with the following
3131
parameters:
3232
* `testfn` - The test function to be executed on each matching input. This function must have
33-
the type `fn(&Path) -> datatest_stable::Result<()>`
33+
the type `fn(&Utf8Path) -> datatest_stable::Result<()>`. (`Utf8Path` is part of the
34+
[`camino`](https://docs.rs/camino) library.)
3435
* `root` - The path to the root directory where the input files (fixtures) live. This path is
3536
relative to the root of the crate.
3637
* `pattern` - the regex used to match against and select each file to be tested.
@@ -43,9 +44,9 @@ The three parameters can be repeated if you have multiple sets of data-driven te
4344
This is an example test. Use it with `harness = false`.
4445

4546
```rust
46-
use std::path::Path;
47+
use datatest_stable::Utf8Path;
4748

48-
fn my_test(path: &Path) -> datatest_stable::Result<()> {
49+
fn my_test(path: &Utf8Path) -> datatest_stable::Result<()> {
4950
// ... write test here
5051

5152
Ok(())
@@ -61,8 +62,8 @@ version update; at any time, at least the last 3 stable versions of Rust will be
6162

6263
## See also
6364

64-
* [`datatest`](https://crates.io/crates/datatest): the original inspiration for this crate,
65-
with a better UI and more features but targeting nightly Rust
65+
* [`datatest`](https://crates.io/crates/datatest): the original inspiration for this crate, with
66+
a better UI and more features but targeting nightly Rust
6667
* [Data-driven testing](https://en.wikipedia.org/wiki/Data-driven_testing)
6768

6869
## License

src/lib.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
//! 2. Call the `datatest_stable::harness!(testfn, root, pattern)` macro with the following
2828
//! parameters:
2929
//! * `testfn` - The test function to be executed on each matching input. This function must have
30-
//! the type `fn(&Path) -> datatest_stable::Result<()>`
30+
//! the type `fn(&Utf8Path) -> datatest_stable::Result<()>`. (`Utf8Path` is part of the
31+
//! [`camino`](https://docs.rs/camino) library.)
3132
//! * `root` - The path to the root directory where the input files (fixtures) live. This path is
3233
//! relative to the root of the crate.
3334
//! * `pattern` - the regex used to match against and select each file to be tested.
@@ -40,9 +41,9 @@
4041
//! This is an example test. Use it with `harness = false`.
4142
//!
4243
//! ```rust
43-
//! use std::path::Path;
44+
//! use datatest_stable::Utf8Path;
4445
//!
45-
//! fn my_test(path: &Path) -> datatest_stable::Result<()> {
46+
//! fn my_test(path: &Utf8Path) -> datatest_stable::Result<()> {
4647
//! // ... write test here
4748
//!
4849
//! Ok(())
@@ -58,8 +59,8 @@
5859
//!
5960
//! # See also
6061
//!
61-
//! * [`datatest`](https://crates.io/crates/datatest): the original inspiration for this crate,
62-
//! with a better UI and more features but targeting nightly Rust
62+
//! * [`datatest`](https://crates.io/crates/datatest): the original inspiration for this crate, with
63+
//! a better UI and more features but targeting nightly Rust
6364
//! * [Data-driven testing](https://en.wikipedia.org/wiki/Data-driven_testing)
6465
6566
#![warn(missing_docs)]
@@ -71,4 +72,10 @@ mod utils;
7172
/// The result type for `datatest-stable` tests.
7273
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
7374

75+
/// A re-export of this type from the `camino` crate, since it forms part of function signatures.
76+
#[doc(no_inline)]
77+
pub use camino::Utf8Path;
78+
79+
/// Not part of the public API, just used for macros.
80+
#[doc(hidden)]
7481
pub use self::runner::{runner, Requirements};

src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ macro_rules! harness {
1616
$crate::Requirements::new(
1717
$name,
1818
stringify!($name).to_string(),
19-
$root.to_string(),
19+
$root.to_string().into(),
2020
$pattern.to_string()
2121
)
2222
);

src/runner.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#![allow(clippy::integer_arithmetic)]
55

66
use crate::{utils, Result};
7+
use camino::{Utf8Path, Utf8PathBuf};
78
use libtest_mimic::{Arguments, Trial};
8-
use std::path::Path;
99

1010
#[doc(hidden)]
1111
pub fn runner(requirements: &[Requirements]) {
@@ -19,18 +19,18 @@ pub fn runner(requirements: &[Requirements]) {
1919

2020
#[doc(hidden)]
2121
pub struct Requirements {
22-
test: fn(&Path) -> Result<()>,
22+
test: fn(&Utf8Path) -> Result<()>,
2323
test_name: String,
24-
root: String,
24+
root: Utf8PathBuf,
2525
pattern: String,
2626
}
2727

2828
impl Requirements {
2929
#[doc(hidden)]
3030
pub fn new(
31-
test: fn(&Path) -> Result<()>,
31+
test: fn(&Utf8Path) -> Result<()>,
3232
test_name: String,
33-
root: String,
33+
root: Utf8PathBuf,
3434
pattern: String,
3535
) -> Self {
3636
Self {
@@ -44,17 +44,15 @@ impl Requirements {
4444
/// Scans all files in a given directory, finds matching ones and generates a test descriptor
4545
/// for each of them.
4646
fn expand(&self) -> Vec<Trial> {
47-
let root = Path::new(&self.root).to_path_buf();
48-
4947
let re = regex::Regex::new(&self.pattern)
5048
.unwrap_or_else(|_| panic!("invalid regular expression: '{}'", self.pattern));
5149

52-
let tests: Vec<_> = utils::iterate_directory(&root)
53-
.filter_map(|path| {
54-
let input_path = path.to_string_lossy();
55-
if re.is_match(&input_path) {
50+
let tests: Vec<_> = utils::iterate_directory(&self.root)
51+
.filter_map(|path_res| {
52+
let path = path_res.expect("error while iterating directory");
53+
if re.is_match(path.as_str()) {
5654
let testfn = self.test;
57-
let name = utils::derive_test_name(&root, &path, &self.test_name);
55+
let name = utils::derive_test_name(&self.root, &path, &self.test_name);
5856
Some(Trial::test(name, move || {
5957
(testfn)(&path).map_err(|err| format!("{:?}", err).into())
6058
}))

src/utils.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
11
// Copyright (c) The Diem Core Contributors
22
// SPDX-License-Identifier: MIT OR Apache-2.0
33

4-
use std::path::{Path, PathBuf};
4+
use camino::{Utf8Path, Utf8PathBuf};
55

66
/// Helper function to iterate through all the files in the given directory, skipping hidden files,
77
/// and return an iterator of their paths.
8-
pub fn iterate_directory(path: &Path) -> impl Iterator<Item = PathBuf> {
8+
pub fn iterate_directory(path: &Utf8Path) -> impl Iterator<Item = std::io::Result<Utf8PathBuf>> {
99
walkdir::WalkDir::new(path)
1010
.into_iter()
11-
.map(::std::result::Result::unwrap)
12-
.filter(|entry| {
13-
entry.file_type().is_file()
14-
&& entry
15-
.file_name()
16-
.to_str()
17-
.map_or(false, |s| !s.starts_with('.')) // Skip hidden files
11+
.filter(|res| {
12+
// Continue to bubble up all errors to the parent.
13+
res.as_ref().map_or(true, |entry| {
14+
entry.file_type().is_file()
15+
&& entry
16+
.file_name()
17+
.to_str()
18+
.map_or(false, |s| !s.starts_with('.')) // Skip hidden files
19+
})
20+
})
21+
.map(|res| match res {
22+
Ok(entry) => {
23+
Utf8PathBuf::try_from(entry.into_path()).map_err(|error| error.into_io_error())
24+
}
25+
Err(error) => Err(error.into()),
1826
})
19-
.map(|entry| entry.path().to_path_buf())
2027
}
2128

22-
pub fn derive_test_name(root: &Path, path: &Path, test_name: &str) -> String {
23-
let relative = path.strip_prefix(root).unwrap_or_else(|_| {
24-
panic!(
25-
"failed to strip prefix '{}' from path '{}'",
26-
root.display(),
27-
path.display()
28-
)
29-
});
29+
pub fn derive_test_name(root: &Utf8Path, path: &Utf8Path, test_name: &str) -> String {
30+
let relative = path
31+
.strip_prefix(root)
32+
.unwrap_or_else(|_| panic!("failed to strip prefix '{}' from path '{}'", root, path));
3033

31-
format!("{}::{}", test_name, relative.display())
34+
format!("{}::{}", test_name, relative)
3235
}

tests/example.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// Copyright (c) The Diem Core Contributors
22
// SPDX-License-Identifier: MIT OR Apache-2.0
33

4+
use camino::Utf8Path;
45
use datatest_stable::Result;
5-
use std::{fs::File, io::Read, path::Path};
6+
use std::{fs::File, io::Read};
67

7-
fn test_artifact(path: &Path) -> Result<()> {
8+
fn test_artifact(path: &Utf8Path) -> Result<()> {
89
let mut file = File::open(path)?;
910
let mut contents = String::new();
1011
file.read_to_string(&mut contents)?;

0 commit comments

Comments
 (0)