Skip to content

Commit e693634

Browse files
committed
[meta] add support for include_dir
I wanted to publish a crate to crates.io containing a bunch of files with test vectors that can be reused, and then use it within datatest-stable. To address this use case, add `include_dir` as an optional dependency. See the documentation for more.
1 parent 0036907 commit e693634

File tree

12 files changed

+818
-210
lines changed

12 files changed

+818
-210
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ jobs:
2929
uses: taiki-e/install-action@8484225d9734e230a8bf38421a4ffec1cc249372 # v2
3030
with:
3131
tool: cargo-sync-rdme,just
32+
- name: Install nightly toolchain for cargo-sync-rdme
33+
uses: dtolnay/rust-toolchain@nightly
3234
- name: Generate readmes
3335
run: just generate-readmes
3436
- name: Check for differences
@@ -68,24 +70,29 @@ jobs:
6870
- uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2
6971
with:
7072
key: ${{ matrix.rust-version }}
73+
- name: Install tools
74+
uses: taiki-e/install-action@8484225d9734e230a8bf38421a4ffec1cc249372 # v2
75+
with:
76+
tool: cargo-hack,just,nextest
7177
- name: Build
72-
run: cargo build
73-
- name: Install latest nextest release
74-
uses: taiki-e/install-action@nextest
75-
- name: Build datatest-stable
76-
run: cargo build
78+
run: just powerset build
79+
- name: Build with all targets
80+
run: just powerset build --all-targets
7781
- name: Run tests
78-
run: cargo nextest run
82+
run: just powerset nextest run
7983
- name: Run tests with cargo test
80-
run: cargo test
84+
run: just powerset test
8185

8286
# Remove Cargo.lock to ensure that building with the latest versions works on stable.
8387
- name: Remove Cargo.lock and rebuild on stable
8488
if: matrix.rust-version == 'stable'
8589
run: rm Cargo.lock && cargo build
90+
- name: Build with all targets
91+
if: matrix.rust-version == 'stable'
92+
run: just powerset build --all-targets
8693
- name: Run tests on stable
8794
if: matrix.rust-version == 'stable'
88-
run: cargo nextest run
95+
run: just powerset nextest run
8996
- name: Run tests with cargo test on stable
9097
if: matrix.rust-version == 'stable'
91-
run: cargo test
98+
run: just powerset test

Cargo.lock

Lines changed: 20 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: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,17 @@ crates-io = true
2121
docs-rs = true
2222
rust-version = true
2323

24+
[package.metadata.docs.rs]
25+
all-features = true
26+
rustdoc-args = ["--cfg=doc_cfg"]
27+
28+
[lints.rust]
29+
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(doc_cfg)'] }
30+
2431
[dependencies]
2532
camino = "1.1.9"
2633
fancy-regex = "0.14.0"
34+
include_dir = { version = "0.7.4", optional = true }
2735
libtest-mimic = "0.8.1"
2836
walkdir = "2.5.0"
2937

@@ -38,3 +46,6 @@ harness = false
3846
[[test]]
3947
name = "run_example"
4048
harness = true
49+
50+
[features]
51+
include-dir = ["dep:include_dir"]

Justfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
help:
33
just --list
44

5+
6+
# Run `cargo hack --feature-powerset` with the given arguments.
7+
powerset *args:
8+
cargo hack --feature-powerset {{args}}
9+
510
# Build docs for crates and direct dependencies
611
rustdoc:
712
@cargo tree --depth 1 -e normal --prefix none --workspace \
@@ -11,4 +16,4 @@ rustdoc:
1116

1217
# Generate README.md files using `cargo-sync-rdme`.
1318
generate-readmes:
14-
cargo sync-rdme --toolchain nightly
19+
cargo sync-rdme --toolchain nightly --all-features

README.md

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010
<!-- cargo-sync-rdme ]] -->
1111
<!-- cargo-sync-rdme rustdoc [[ -->
1212
`datatest-stable` is a test harness intended to write *file-driven* or *data-driven* tests,
13-
where individual test cases are specified as files and not as code.
13+
where individual test case fixtures are specified as files and not as code.
1414

1515
Given:
1616

1717
* a test `my_test` that accepts a path, and optionally the contents as input
18-
* a directory to look for files in
18+
* a directory to look for files (test fixtures) in
1919
* a pattern to match files on
2020

21-
`datatest-stable` will call the `my_test` function once per matching file in the directory.
21+
`datatest-stable` will call the `my_test` function once per matching file in
22+
the directory. Directory traversals are recursive.
2223

2324
`datatest-stable` works with [cargo nextest](https://nexte.st/), and is part of the [nextest-rs
2425
organization](https://github.com/nextest-rs/) on GitHub.
@@ -38,6 +39,7 @@ harness = false
3839

3940
* `testfn` - The test function to be executed on each matching input. This function can be one
4041
of:
42+
4143
* `fn(&Path) -> datatest_stable::Result<()>`
4244
* `fn(&Utf8Path) -> datatest_stable::Result<()>` (`Utf8Path` is part of the
4345
[`camino`](https://docs.rs/camino) library, and is re-exported here for convenience.)
@@ -49,14 +51,23 @@ harness = false
4951
in as a `Vec<u8>` (erroring out if that failed).
5052
* `root` - The path to the root directory where the input files (fixtures) live. This path is
5153
relative to the root of the crate (the directory where the crate’s `Cargo.toml` is located).
54+
55+
`root` is an arbitrary expression that implements `Display`, such as `&str`, or a
56+
function call that returns a `Utf8PathBuf`.
57+
5258
* `pattern` - a regex used to match against and select each file to be tested. Extended regexes
5359
with lookaround and backtracking are supported via the
5460
[`fancy_regex`](https://docs.rs/fancy-regex) crate.
61+
62+
`pattern` is an arbitrary expression that implements `Display`, such as
63+
`&str`, or a function call that returns a `String`.
64+
65+
The passed-in `Path` and `Utf8Path` are **absolute** paths to the files to be tested.
5566

5667
The three parameters can be repeated if you have multiple sets of data-driven tests to be run:
5768
`datatest_stable::harness!(testfn1, root1, pattern1, testfn2, root2, pattern2)`.
5869

59-
## Examples
70+
### Examples
6071

6172
This is an example test. Use it with `harness = false`.
6273

@@ -82,6 +93,92 @@ datatest_stable::harness!(
8293
);
8394
````
8495

96+
### Embedding directories at compile time
97+
98+
With the `include-dir` feature enabled, you can use the
99+
[`include_dir`](https://docs.rs/include_dir) crate’s [`include_dir!`](https://docs.rs/include_dir_macros/0.7.4/include_dir_macros/macro.include_dir.html) macro.
100+
This allows you to embed directories into the binary at compile time.
101+
102+
This is generally not recommended for rapidly-changing test data, since each
103+
change will force a rebuild. But it can be useful for relatively-unchanging
104+
data suites distributed separately, e.g. on crates.io.
105+
106+
With the `include-dir` feature enabled, you can use:
107+
108+
````rust
109+
// The `include_dir!` macro is re-exported for convenience.
110+
use datatest_stable::include_dir;
111+
use std::path::Path;
112+
113+
fn my_test(path: &Path, contents: Vec<u8>) -> datatest_stable::Result<()> {
114+
// ... write test here
115+
Ok(())
116+
}
117+
118+
datatest_stable::harness!(
119+
my_test, include_dir!("tests/files"), r"^.*/*",
120+
);
121+
````
122+
123+
You can also use directories published as `static` items in upstream crates:
124+
125+
````rust
126+
use datatest_stable::{include_dir, Utf8Path};
127+
128+
// In the upstream crate:
129+
pub static FIXTURES: include_dir::Dir<'static> = include_dir!("tests/files");
130+
131+
// In your test:
132+
fn my_test(path: &Utf8Path, contents: String) -> datatest_stable::Result<()> {
133+
// ... write test here
134+
Ok(())
135+
}
136+
137+
datatest_stable::harness!(
138+
my_test, &FIXTURES, r"^.*/*",
139+
);
140+
````
141+
142+
In this case, the passed-in `Path` and `Utf8Path` are **relative** to the
143+
root of the included directory.
144+
145+
Because the files don’t exist on disk, the test functions must accept their
146+
contents as either a `String` or a `Vec<u8>`. If the argument is not
147+
provided, the harness will panic at runtime.
148+
149+
### Conditionally embedding directories
150+
151+
It is also possible to conditionally include directories at compile time via
152+
a feature flag. For example, you might have an internal-only `testing`
153+
feature that you turn on locally, but users don’t on crates.io. In that
154+
case, you can use:
155+
156+
````rust
157+
use datatest_stable::Utf8Path;
158+
159+
static FIXTURES: &str = "tests/files";
160+
161+
static FIXTURES: include_dir::Dir<'static> = datatest_stable::include_dir!("tests/files");
162+
163+
fn my_test(path: &Utf8Path, contents: String) -> datatest_stable::Result<()> {
164+
// ... write test here
165+
Ok(())
166+
}
167+
168+
datatest_stable::harness!(
169+
my_test, &FIXTURES, r"^.*/*",
170+
);
171+
````
172+
173+
In this case, note that `path` will be absolute if `FIXTURES` is a string,
174+
and relative if `FIXTURES` is a `Dir`. Your test should be prepared to
175+
handle either case.
176+
177+
## Features
178+
179+
* `include-dir`: Enables the `include_dir!` macro, which allows embedding
180+
directories at compile time. This feature is disabled by default.
181+
85182
## Minimum supported Rust version (MSRV)
86183

87184
The minimum supported Rust version is **Rust 1.72**. MSRV bumps may be accompanied by a minor

0 commit comments

Comments
 (0)