7 releases
0.3.0 | Jan 19, 2023 |
---|---|
0.2.4 | Jan 11, 2023 |
0.2.2 | Dec 31, 2022 |
0.1.0 | Dec 26, 2022 |
#98 in Testing
39 downloads per month
255KB
5.5K
SLoC
xpct
xpct is an assertions library for Rust. It's designed to be ergonomic, batteries-included, and test framework agnostic.
About
xpct is extensible. In addition to allowing you to write custom matchers, it separates the logic of matchers from how they format their output, meaning you can:
- Hook into existing formatters to write custom matchers with pretty output without having to worry about formatting.
- Customize the formatting of existing matchers without having to reimplement their logic.
Want to get started? Check out the tutorial.
How do you pronounce "xpct"?
However you choose to pronounce it is how it's pronounced! I pronounce it like "expect."
Docs
Examples
A simple equality assertion, like assert_eq
:
use xpct::{expect, equal};
expect!("disco").to(equal("Disco"));
[src/main.rs:4:5] = "disco"
Expected:
"disco"
to equal:
"Disco"
Asserting that every element in a vec is Some
and unwrapping it to a
Vec<&str>
:
use xpct::{be_some, every, expect};
let items = vec![Some("foo"), Some("bar"), None];
let output: Vec<&str> = expect!(items)
.to(every(be_some))
.into_inner();
[src/main.rs:6:29] = items
Expected all of these to succeed:
[2] FAILED
Expected this to be Some(_)
Asserting that the given string does not match any of the given matchers:
use xpct::{expect, any, match_regex, contain_substr, equal, have_suffix};
let location = String::from("Revachol West");
expect!(location).to_not(any(|ctx| {
ctx.borrow::<str>()
.to(match_regex(r"\w+ (North|South|East|West)$"))
.to(contain_substr("Revachol"))
.to(equal("Martinaise"))
.to(have_suffix("Jamrock"));
}));
[src/main.rs:6:5] = location
Expected all of these to succeed:
[0] FAILED
Expected:
"Revachol West"
to not match the regex:
"\\w+ (North|South|East|West)$"
[1] FAILED
Expected:
"Revachol West"
to not contain the substring:
"Revachol"
Making assertions about individual fields of a struct:
use std::io;
use xpct::{
all, be_empty, be_gt, be_ok, be_some, be_true, expect, fields, have_prefix, match_fields,
why,
};
struct Person {
name: Option<String>,
age: u32,
id: String,
is_superstar: bool,
}
fn get_person() -> io::Result<Person> {
Ok(Person {
name: Some("".into()),
age: 44,
id: String::from("12-62-05-JAM41"),
is_superstar: true,
})
}
expect!(get_person())
.to(be_ok())
.to(match_fields(fields!(Person {
name: all(|ctx| ctx
.to(be_some())?
.to_not(be_empty())
),
age: be_gt(0),
id: why(have_prefix("REV"), "all IDs must have this prefix"),
is_superstar: be_true(),
})));
[src/main.rs:25:5] = get_person()
Expected all of these fields to succeed:
my_crate::main::Person {
name: FAILED
Expected this to not be empty
age: OK
id: FAILED
🛈 all IDs must have this prefix
Expected:
"12-62-05-JAM41"
to have the prefix:
"REV"
is_superstar: OK
}
MSRV Policy
The last two stable Rust releases are supported. Older releases may or may not be supported as well.
The MSRV will only be increased when necessary to take advantage of new Rust features—not every time there is a new Rust release. An increase in the MSRV will be accompanied by a minor semver bump if >=1.0.0 or a patch semver bump if <1.0.0.
Semver Policy
Prior to version 1.0.0, breaking changes will be accompanied by a minor version bump, and new features and bug fixes will be accompanied by a patch version bump. The semantics of minor vs patch versions <1.0.0 is unspecified in the semver spec.
Dependencies
~125–610KB
~14K SLoC