Skip to content

Commit 0a9e06b

Browse files
authored
Merge pull request #295 from epage/tryfn
feat(fn)!: Split Harness out into tryfn
2 parents 3e293f6 + a30d3bf commit 0a9e06b

File tree

10 files changed

+125
-78
lines changed

10 files changed

+125
-78
lines changed

Cargo.lock

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

crates/snapbox/Cargo.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ default = ["color-auto", "diff"]
3232

3333
#! Feature Flags
3434

35-
## Simple input/output test harness
36-
harness = ["dep:libtest-mimic", "dep:ignore"]
3735
## Smarter binary file detection
3836
detect-encoding = ["dep:content_inspector"]
3937
## Snapshotting of paths
@@ -71,9 +69,6 @@ name = "snap-fixture" # For `snapbox`s tests only
7169
normalize-line-endings = "0.3.0"
7270
snapbox-macros = { path = "../snapbox-macros", version = "0.3.8" }
7371

74-
libtest-mimic = { version = "0.7.0", optional = true }
75-
ignore = { version = "0.4", optional = true }
76-
7772
content_inspector = { version = "0.2.4", optional = true }
7873

7974
tempfile = { version = "3.0", optional = true }

crates/snapbox/src/assert/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl Assert {
7777
}
7878
}
7979

80-
pub(crate) fn try_eq(
80+
pub fn try_eq(
8181
&self,
8282
expected: crate::Data,
8383
actual: crate::Data,
@@ -397,6 +397,12 @@ impl Assert {
397397
}
398398
}
399399

400+
impl Assert {
401+
pub fn selected_action(&self) -> Action {
402+
self.action
403+
}
404+
}
405+
400406
impl Default for Assert {
401407
fn default() -> Self {
402408
Self {

crates/snapbox/src/lib.rs

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
//!
2828
//! Testing Functions:
2929
//! - [`assert_eq`][crate::assert_eq()] for quick and dirty snapshotting
30-
//! - [`harness::Harness`] for discovering test inputs and asserting against snapshot files:
3130
//!
3231
//! Testing Commands:
3332
//! - [`cmd::Command`]: Process spawning for testing of non-interactive commands
@@ -58,38 +57,6 @@
5857
//! .eq(snapbox::file!["help_output_is_clean.txt"], actual);
5958
//! ```
6059
//!
61-
//! [`harness::Harness`]
62-
#![cfg_attr(not(feature = "harness"), doc = " ```rust,ignore")]
63-
#![cfg_attr(feature = "harness", doc = " ```rust,no_run")]
64-
//! snapbox::harness::Harness::new(
65-
//! "tests/fixtures/invalid",
66-
//! setup,
67-
//! test,
68-
//! )
69-
//! .select(["tests/cases/*.in"])
70-
//! .action_env("SNAPSHOTS")
71-
//! .test();
72-
//!
73-
//! fn setup(input_path: std::path::PathBuf) -> snapbox::harness::Case {
74-
//! let name = input_path.file_name().unwrap().to_str().unwrap().to_owned();
75-
//! let expected = snapbox::Data::read_from(&input_path.with_extension("out"), None);
76-
//! snapbox::harness::Case {
77-
//! name,
78-
//! fixture: input_path,
79-
//! expected,
80-
//! }
81-
//! }
82-
//!
83-
//! fn test(input_path: &std::path::Path) -> Result<usize, Box<dyn std::error::Error>> {
84-
//! let raw = std::fs::read_to_string(input_path)?;
85-
//! let num = raw.parse::<usize>()?;
86-
//!
87-
//! let actual = num + 10;
88-
//!
89-
//! Ok(actual)
90-
//! }
91-
//! ```
92-
//!
9360
//! [trycmd]: https://docs.rs/trycmd
9461
9562
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
@@ -104,9 +71,6 @@ pub mod path;
10471
pub mod report;
10572
pub mod utils;
10673

107-
#[cfg(feature = "harness")]
108-
pub mod harness;
109-
11074
pub use assert::Assert;
11175
pub use data::Data;
11276
pub use data::IntoData;

crates/tryfn/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Change Log
2+
All notable changes to this project will be documented in this file.
3+
4+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
5+
and this project adheres to [Semantic Versioning](http://semver.org/).
6+
7+
<!-- next-header -->
8+
## [Unreleased] - ReleaseDate
9+
10+
<!-- next-url -->
11+
[Unreleased]: https://github.com/assert-rs/trycmd/compare/3e293f6f6167270d85f57a7b59fd94590af6fa97...HEAD

crates/tryfn/Cargo.toml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[package]
2+
name = "tryfn"
3+
version = "0.1.0"
4+
description = "File-driven snapshot testing for a function"
5+
authors = ["Ed Page <[email protected]>"]
6+
repository = "https://github.com/assert-rs/trycmd.git"
7+
homepage = "https://github.com/assert-rs/trycmd"
8+
documentation = "http://docs.rs/tryfn/"
9+
readme = "README.md"
10+
categories = ["development-tools::testing"]
11+
keywords = ["test", "assert", "snapsjot"]
12+
license.workspace = true
13+
edition.workspace = true
14+
rust-version.workspace = true
15+
include.workspace = true
16+
17+
[package.metadata.docs.rs]
18+
all-features = true
19+
rustdoc-args = ["--cfg", "docsrs"]
20+
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
21+
22+
[package.metadata.release]
23+
pre-release-replacements = [
24+
{file="CHANGELOG.md", search="Unreleased", replace="{{version}}", min=1},
25+
{file="CHANGELOG.md", search="\\.\\.\\.HEAD", replace="...{{tag_name}}", exactly=1},
26+
{file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", min=1},
27+
{file="CHANGELOG.md", search="<!-- next-header -->", replace="<!-- next-header -->\n## [Unreleased] - ReleaseDate\n", exactly=1},
28+
{file="CHANGELOG.md", search="<!-- next-url -->", replace="<!-- next-url -->\n[Unreleased]: https://github.com/assert-rs/trycmd/compare/{{tag_name}}...HEAD", exactly=1},
29+
]
30+
31+
[features]
32+
default = ["color-auto", "diff"]
33+
diff = ["snapbox/diff"]
34+
color = ["snapbox/color"]
35+
color-auto = ["snapbox/color-auto"]
36+
37+
[dependencies]
38+
snapbox = { path = "../snapbox", version = "0.5.9", default-features = false }
39+
libtest-mimic = "0.7.0"
40+
ignore = "0.4"

crates/tryfn/LICENSE-APACHE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE-APACHE

crates/tryfn/LICENSE-MIT

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE-MIT

crates/tryfn/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# tryfn
2+
3+
> File-driven snapshot testing for a function
4+
5+
[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]
6+
![License](https://img.shields.io/crates/l/tryfn.svg)
7+
[![Crates Status](https://img.shields.io/crates/v/tryfn.svg)][Crates.io]
8+
9+
## License
10+
11+
Licensed under either of
12+
13+
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
14+
* MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
15+
16+
at your option.
17+
18+
### Contribution
19+
20+
Unless you explicitly state otherwise, any contribution intentionally
21+
submitted for inclusion in the work by you, as defined in the Apache-2.0
22+
license, shall be dual licensed as above, without any additional terms or
23+
conditions.
24+
25+
[Crates.io]: https://crates.io/crates/tryfn
26+
[Documentation]: https://docs.rs/tryfn

crates/snapbox/src/harness.rs renamed to crates/tryfn/src/lib.rs

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@
66
//! # Examples
77
//!
88
//! ```rust,no_run
9-
//! snapbox::harness::Harness::new(
9+
//! fn some_func(num: usize) -> usize {
10+
//! // ...
11+
//! # 10
12+
//! }
13+
//!
14+
//! tryfn::Harness::new(
1015
//! "tests/fixtures/invalid",
1116
//! setup,
1217
//! test,
1318
//! )
1419
//! .select(["tests/cases/*.in"])
15-
//! .action_env("SNAPSHOTS")
1620
//! .test();
1721
//!
18-
//! fn setup(input_path: std::path::PathBuf) -> snapbox::harness::Case {
22+
//! fn setup(input_path: std::path::PathBuf) -> tryfn::Case {
1923
//! let name = input_path.file_name().unwrap().to_str().unwrap().to_owned();
20-
//! let expected = snapbox::Data::read_from(&input_path.with_extension("out"), None);
21-
//! snapbox::harness::Case {
24+
//! let expected = tryfn::Data::read_from(&input_path.with_extension("out"), None);
25+
//! tryfn::Case {
2226
//! name,
2327
//! fixture: input_path,
2428
//! expected,
@@ -29,26 +33,24 @@
2933
//! let raw = std::fs::read_to_string(input_path)?;
3034
//! let num = raw.parse::<usize>()?;
3135
//!
32-
//! let actual = num + 10;
36+
//! let actual = some_func(num);
3337
//!
3438
//! Ok(actual)
3539
//! }
3640
//! ```
3741
38-
use crate::assert::Action;
39-
use crate::Data;
40-
4142
use libtest_mimic::Trial;
4243

44+
pub use snapbox::data::DataFormat;
45+
pub use snapbox::Data;
46+
4347
/// [`Harness`] for discovering test inputs and asserting against snapshot files
44-
///
45-
/// See [`harness`][crate::harness] for more details
4648
pub struct Harness<S, T, I, E> {
4749
root: std::path::PathBuf,
4850
overrides: Option<ignore::overrides::Override>,
4951
setup: S,
5052
test: T,
51-
config: crate::Assert,
53+
config: snapbox::Assert,
5254
test_output: std::marker::PhantomData<I>,
5355
test_error: std::marker::PhantomData<E>,
5456
}
@@ -67,29 +69,29 @@ where
6769
/// - `setup`: Given a path, choose the test name and the output location
6870
/// - `test`: Given a path, return the actual output value
6971
///
70-
/// By default [`filters`][crate::filters] are applied, including:
72+
/// By default [`filters`][snapbox::filters] are applied, including:
7173
/// - `...` is a line-wildcard when on a line by itself
7274
/// - `[..]` is a character-wildcard when inside a line
7375
/// - `[EXE]` matches `.exe` on Windows
7476
/// - `\` to `/`
7577
/// - Newlines
7678
///
77-
/// To limit this to newline normalization for text, have [`Setup`] call [`Data::raw`][crate::Data::raw] on `expected`.
79+
/// To limit this to newline normalization for text, have [`Setup`] call [`Data::raw`][snapbox::Data::raw] on `expected`.
7880
pub fn new(input_root: impl Into<std::path::PathBuf>, setup: S, test: T) -> Self {
7981
Self {
8082
root: input_root.into(),
8183
overrides: None,
8284
setup,
8385
test,
84-
config: crate::Assert::new().action_env(crate::assert::DEFAULT_ACTION_ENV),
86+
config: snapbox::Assert::new().action_env(snapbox::assert::DEFAULT_ACTION_ENV),
8587
test_output: Default::default(),
8688
test_error: Default::default(),
8789
}
8890
}
8991

9092
/// Path patterns for selecting input files
9193
///
92-
/// This used gitignore syntax
94+
/// This uses gitignore syntax
9395
pub fn select<'p>(mut self, patterns: impl IntoIterator<Item = &'p str>) -> Self {
9496
let mut overrides = ignore::overrides::OverrideBuilder::new(&self.root);
9597
for line in patterns {
@@ -99,20 +101,12 @@ where
99101
self
100102
}
101103

102-
/// Read the failure action from an environment variable
103-
pub fn action_env(mut self, var_name: &str) -> Self {
104-
self.config = self.config.action_env(var_name);
105-
self
106-
}
107-
108-
/// Override the failure action
109-
pub fn action(mut self, action: Action) -> Self {
110-
self.config = self.config.action(action);
111-
self
112-
}
113-
114104
/// Customize the assertion behavior
115-
pub fn with_assert(mut self, config: crate::Assert) -> Self {
105+
///
106+
/// Includes
107+
/// - Configuring redactions
108+
/// - Override updating environment vaeiable
109+
pub fn with_assert(mut self, config: snapbox::Assert) -> Self {
116110
self.config = config;
117111
self
118112
}
@@ -149,11 +143,13 @@ where
149143
Trial::test(case.name.clone(), move || {
150144
let actual = test.run(&case.fixture)?;
151145
let actual = actual.to_string();
152-
let actual = crate::Data::text(actual);
146+
let actual = snapbox::Data::text(actual);
153147
config.try_eq(case.expected.clone(), actual, Some(&case.name))?;
154148
Ok(())
155149
})
156-
.with_ignored_flag(shared_config.action == Action::Ignore)
150+
.with_ignored_flag(
151+
shared_config.selected_action() == snapbox::assert::Action::Ignore,
152+
)
157153
})
158154
.collect();
159155

@@ -162,6 +158,7 @@ where
162158
}
163159
}
164160

161+
/// Function signature for generating a test [`Case`] from a path fixture
165162
pub trait Setup {
166163
fn setup(&self, fixture: std::path::PathBuf) -> Case;
167164
}
@@ -175,6 +172,7 @@ where
175172
}
176173
}
177174

175+
/// Function signature for running a test [`Case`]
178176
pub trait Test<S, E>
179177
where
180178
S: std::fmt::Display,
@@ -194,9 +192,7 @@ where
194192
}
195193
}
196194

197-
/// A test case enumerated by the [`Harness`] with data from the `setup` function
198-
///
199-
/// See [`harness`][crate::harness] for more details
195+
/// A test case enumerated by the [`Harness`] with data from the [`Setup`] function
200196
pub struct Case {
201197
/// Display name
202198
pub name: String,

0 commit comments

Comments
 (0)