Vendor dependencies

This commit is contained in:
2026-08-01 16:11:49 +03:00
parent 7f139a0241
commit 6b5e7f0f8b
29706 changed files with 9575646 additions and 0 deletions
+455
View File
@@ -0,0 +1,455 @@
use std::path::Path;
pub use unindent::Unindent;
use super::resources;
use mytest::*;
use rstest_test::{assert_in, assert_not_in, Project, Stringable, TestResults};
fn prj(res: &str) -> Project {
let path = Path::new("fixture").join(res);
crate::prj().set_code_file(resources(path))
}
fn run_test(res: &str) -> (std::process::Output, String) {
let prj = prj(res);
(
prj.run_tests().unwrap(),
prj.get_name().to_owned().to_string(),
)
}
mod should {
use rstest_test::{assert_regex, CountMessageOccurrence};
use super::*;
#[test]
fn use_input_fixtures() {
let (output, _) = run_test("simple_injection.rs");
TestResults::new().ok("success").fail("fail").assert(output);
}
#[test]
fn create_a_struct_that_return_the_fixture() {
let (output, _) = run_test("fixture_struct.rs");
TestResults::new()
.ok("resolve_new")
.ok("resolve_default")
.ok("injected_new")
.ok("injected_default")
.assert(output);
}
#[test]
fn be_accessible_from_other_module() {
let (output, _) = run_test("from_other_module.rs");
TestResults::new().ok("struct_access").assert(output);
}
#[test]
fn not_show_any_warning() {
let (output, _) = run_test("no_warning.rs");
assert_not_in!(output.stderr.str(), "warning:");
}
#[test]
fn rename() {
let (output, _) = run_test("rename.rs");
TestResults::new().ok("test").assert(output);
}
mod accept_and_return {
use super::*;
#[test]
fn impl_traits() {
let (output, _) = run_test("impl.rs");
TestResults::new()
.ok("base_impl_return")
.ok("nested_impl_return")
.ok("nested_multiple_impl_return")
.ok("base_impl_input")
.ok("nested_impl_input")
.ok("nested_multiple_impl_input")
.assert(output);
}
#[test]
fn dyn_traits() {
let (output, _) = run_test("dyn.rs");
TestResults::new()
.ok("test_dyn_box")
.ok("test_dyn_ref")
.ok("test_dyn_box_resolve")
.ok("test_dyn_ref_resolve")
.assert(output);
}
}
#[rstest]
#[case::base("async_fixture.rs")]
#[case::use_global("await_complete_fixture.rs")]
#[case::use_selective("await_partial_fixture.rs")]
fn resolve_async_fixture(#[case] code: &str) {
let prj = prj(code);
prj.add_dependency("async-std", r#"{version="*", features=["attributes"]}"#);
let output = prj.run_tests().unwrap();
TestResults::new()
.ok("default_is_async")
.ok("use_async_fixture")
.ok("use_async_impl_output")
.ok("use_async_nest_fixture_default")
.ok("use_async_nest_fixture_injected")
.ok("use_async_nest_fixture_with_default")
.ok("use_two_args_mix_fixture")
.ok("use_two_args_mix_fixture_inject_first")
.ok("use_two_args_mix_fixture_inject_both")
.assert(output);
}
#[test]
fn resolve_fixture_generics_by_fixture_input() {
let (output, _) = run_test("resolve.rs");
TestResults::new()
.ok("test_u32")
.ok("test_i32")
.assert(output);
}
#[test]
fn use_defined_return_type_if_any() {
let (output, _) = run_test("defined_return_type.rs");
TestResults::new()
.ok("resolve")
.ok("resolve_partial")
.ok("resolve_attrs")
.ok("resolve_partial_attrs")
.assert(output);
}
#[test]
fn clean_up_default_from_unused_generics() {
let (output, _) = run_test("clean_up_default_generics.rs");
TestResults::new()
.ok("resolve")
.ok("resolve_partial")
.assert(output);
}
#[test]
fn apply_partial_fixture() {
let (output, _) = run_test("partial.rs");
TestResults::new()
.ok("default")
.ok("t_partial_1")
.ok("t_partial_2")
.ok("t_complete")
.assert(output);
}
#[test]
fn apply_partial_fixture_from_value_attribute() {
let (output, _) = run_test("partial_in_attr.rs");
TestResults::new()
.ok("default")
.ok("t_partial_1")
.ok("t_partial_2")
.ok("t_complete")
.assert(output);
}
#[rstest]
#[case::compact_form("default.rs")]
#[case::attrs_form("default_in_attrs.rs")]
fn use_input_values_if_any(#[case] file: &str) {
let (output, _) = run_test(file);
TestResults::new()
.ok("test_simple")
.ok("test_simple_changed")
.ok("test_double")
.ok("test_double_changed")
.ok("test_mixed")
.assert(output);
}
#[test]
fn convert_literal_string_for_default_values() {
let (output, _) = run_test("default_conversion.rs");
assert_regex!(
"Cannot parse 'error' to get [a-z:_0-9]*MyType",
output.stdout.str()
);
TestResults::new()
.ok("test_base")
.ok("test_byte_array")
.ok("test_convert_custom")
.fail("test_fail_conversion")
.assert(output);
}
#[rstest]
#[case("once.rs")]
#[case::no_return("once_no_return.rs")]
#[case::defined_type("once_defined_type.rs")]
fn accept_once_attribute_and_call_fixture_just_once(#[case] fname: &str) {
let project = prj(fname).with_nocapture();
let output = project.run_tests().unwrap();
// Just to see the errors if fixture doesn't compile
assert_in!(output.stderr.str(), "Exec fixture() just once");
let occurrences = output.stderr.str().count("Exec fixture() just once");
assert_eq!(1, occurrences);
}
mod show_correct_errors {
use super::*;
use std::process::Output;
use rstest::{fixture, rstest};
#[fixture]
#[once]
fn errors_rs() -> (Output, String) {
run_test("errors.rs")
}
#[rstest]
fn when_cannot_resolve_fixture(errors_rs: &(Output, String)) {
let (output, name) = errors_rs.clone();
assert_in!(output.stderr.str(), "error[E0433]: ");
assert_in!(
output.stderr.str(),
format!(
r#"
--> {name}/src/lib.rs:14:33
|
14 | fn error_cannot_resolve_fixture(no_fixture: u32) {{"#
)
.unindent()
);
}
#[rstest]
fn on_mismatched_types_inner(errors_rs: &(Output, String)) {
let (output, name) = errors_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error[E0308]: mismatched types
--> {name}/src/lib.rs:10:18
|
10 | let a: u32 = "";
"#
)
.unindent()
);
}
#[rstest]
fn on_mismatched_types_argument(errors_rs: &(Output, String)) {
let (output, name) = errors_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error[E0308]: mismatched types
--> {name}/src/lib.rs:17:29
"#
)
.unindent()
);
assert_in!(
output.stderr.str(),
r#"
17 | fn error_fixture_wrong_type(fixture: String) {}
| ^^^^^^"#
.unindent()
);
}
#[rstest]
fn on_invalid_fixture(errors_rs: &(Output, String)) {
let (output, name) = errors_rs.clone();
assert_in!(
output.stderr.str(),
format!(
"
error: Missed argument: 'not_a_fixture' should be a test function argument.
--> {name}/src/lib.rs:19:11
|
19 | #[fixture(not_a_fixture(24))]
| ^^^^^^^^^^^^^
"
)
.unindent()
);
}
#[rstest]
fn on_duplicate_fixture_argument(errors_rs: &(Output, String)) {
let (output, name) = errors_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error: Duplicate argument: 'f' is already defined.
--> {name}/src/lib.rs:32:23
|
32 | #[fixture(f("first"), f("second"))]
| ^
"#
)
.unindent()
);
}
#[rstest]
fn on_destruct_implicit_fixture(errors_rs: &(Output, String)) {
let (output, name) = errors_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error: To destruct a fixture you should provide a path to resolve it by '#[from(...)]' attribute.
--> {name}/src/lib.rs:48:35
|
48 | fn error_destruct_without_resolve(T(a): T) {{}}
| ^^^^^^^
"#
)
.unindent()
);
}
#[rstest]
fn on_destruct_explicit_fixture_without_from(errors_rs: &(Output, String)) {
let (output, name) = errors_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error: To destruct a fixture you should provide a path to resolve it by '#[from(...)]' attribute.
--> {name}/src/lib.rs:51:57
|
51 | fn error_destruct_without_resolve_also_with(#[with(21)] T(a): T) {{}}
| ^^^^^^^
"#
)
.unindent()
);
assert_eq!(
1,
output.stderr.str().count("51 | fn error_destruct_without")
)
}
#[fixture]
#[once]
fn errors_once_rs() -> (Output, String) {
run_test("errors_once.rs")
}
#[rstest]
fn once_async(errors_once_rs: &(Output, String)) {
let (output, name) = errors_once_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error: Cannot apply #[once] to async fixture.
--> {}/src/lib.rs:4:1
|
4 | #[once]
"#,
name
)
.unindent()
);
}
#[rstest]
fn once_generic_type(errors_once_rs: &(Output, String)) {
let (output, name) = errors_once_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error: Cannot apply #[once] on generic fixture.
--> {}/src/lib.rs:9:1
|
9 | #[once]
"#,
name
)
.unindent()
);
}
#[rstest]
fn once_generic_impl(errors_once_rs: &(Output, String)) {
let (output, name) = errors_once_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error: Cannot apply #[once] on generic fixture.
--> {}/src/lib.rs:15:1
|
15 | #[once]
"#,
name
)
.unindent()
);
}
#[rstest]
fn once_on_not_sync_type(errors_once_rs: &(Output, String)) {
let (output, name) = errors_once_rs.clone();
assert_in!(
output.stderr.str(),
format!(
r#"
error[E0277]: `Cell<u32>` cannot be shared between threads safely
--> {}/src/lib.rs:20:1
|
20 | #[fixture]
| ^^^^^^^^^^ `Cell<u32>` cannot be shared between threads safely
"#,
name,
)
.unindent(),
);
}
}
}
+35
View File
@@ -0,0 +1,35 @@
use rstest_test::{sanitize_name, testname, Project};
/// Rstest integration tests
mod rstest;
/// Fixture's integration tests
mod fixture;
use lazy_static::lazy_static;
use std::path::{Path, PathBuf};
use temp_testdir::TempDir;
lazy_static! {
static ref ROOT_DIR: TempDir = TempDir::default().permanent();
static ref ROOT_PROJECT: Project = Project::new(ROOT_DIR.as_ref());
}
pub fn base_prj() -> Project {
let prj_name = sanitize_name(testname());
ROOT_PROJECT.subproject(&prj_name)
}
pub fn prj() -> Project {
let prj_name = sanitize_name(testname());
let prj = ROOT_PROJECT.subproject(&prj_name);
prj.add_local_dependency("rstest");
prj
}
pub fn resources<O: AsRef<Path>>(name: O) -> PathBuf {
Path::new("tests").join("resources").join(name)
}
@@ -0,0 +1,73 @@
use std::io::prelude::*;
use rstest::*;
#[fixture]
async fn async_u32() -> u32 {
42
}
#[fixture]
async fn nest_fixture(#[future] async_u32: u32) -> u32 {
async_u32.await
}
#[fixture(fortytwo = async { 42 })]
async fn nest_fixture_with_default(#[future] fortytwo: u32) -> u32 {
fortytwo.await
}
#[rstest]
async fn default_is_async() {
assert_eq!(42, async_u32::default().await);
}
#[rstest]
async fn use_async_nest_fixture_default(#[future] nest_fixture: u32) {
assert_eq!(42, nest_fixture.await);
}
#[rstest(nest_fixture(async { 24 }))]
async fn use_async_nest_fixture_injected(#[future] nest_fixture: u32) {
assert_eq!(24, nest_fixture.await);
}
#[rstest]
async fn use_async_nest_fixture_with_default(#[future] nest_fixture_with_default: u32) {
assert_eq!(42, nest_fixture_with_default.await);
}
#[rstest]
async fn use_async_fixture(#[future] async_u32: u32) {
assert_eq!(42, async_u32.await);
}
#[fixture]
async fn async_impl_output() -> impl Read {
std::io::Cursor::new(vec![1, 2, 3, 4, 5])
}
#[rstest]
async fn use_async_impl_output<T: Read>(#[future] async_impl_output: T) {
let reader = async_impl_output.await;
}
#[fixture(four = async { 4 }, two = 2)]
async fn two_args_mix_fixture(#[future] four: u32, two: u32) -> u32 {
four.await * 10 + two
}
#[rstest]
async fn use_two_args_mix_fixture(#[future] two_args_mix_fixture: u32) {
assert_eq!(42, two_args_mix_fixture.await);
}
#[rstest(two_args_mix_fixture(async { 5 }))]
async fn use_two_args_mix_fixture_inject_first(#[future] two_args_mix_fixture: u32) {
assert_eq!(52, two_args_mix_fixture.await);
}
#[rstest(two_args_mix_fixture(async { 3 }, 1))]
async fn use_two_args_mix_fixture_inject_both(#[future] two_args_mix_fixture: u32) {
assert_eq!(31, two_args_mix_fixture.await);
}
@@ -0,0 +1,105 @@
use std::io::prelude::*;
use rstest::*;
#[fixture]
async fn async_u32() -> u32 {
42
}
#[fixture]
#[awt]
async fn nest_fixture(#[future] async_u32: u32) -> u32 {
async_u32
}
#[fixture]
#[awt]
async fn nest_fixture_with_default(
#[future]
#[default(async { 42 })]
fortytwo: u32,
) -> u32 {
fortytwo
}
#[rstest]
async fn default_is_async() {
assert_eq!(42, async_u32::default().await);
}
#[rstest]
#[awt]
async fn use_async_nest_fixture_default(#[future] nest_fixture: u32) {
assert_eq!(42, nest_fixture);
}
#[rstest]
#[awt]
async fn use_async_nest_fixture_injected(
#[future]
#[with(async { 24 })]
nest_fixture: u32,
) {
assert_eq!(24, nest_fixture);
}
#[rstest]
#[awt]
async fn use_async_nest_fixture_with_default(#[future] nest_fixture_with_default: u32) {
assert_eq!(42, nest_fixture_with_default);
}
#[rstest]
#[awt]
async fn use_async_fixture(#[future] async_u32: u32) {
assert_eq!(42, async_u32);
}
#[fixture]
async fn async_impl_output() -> impl Read {
std::io::Cursor::new(vec![1, 2, 3, 4, 5])
}
#[rstest]
#[awt]
async fn use_async_impl_output<T: Read>(#[future] async_impl_output: T) {
let reader = async_impl_output;
}
#[fixture]
#[awt]
async fn two_args_mix_fixture(
#[future]
#[default(async { 4 })]
four: u32,
#[default(2)] two: u32,
) -> u32 {
four * 10 + two
}
#[rstest]
#[awt]
async fn use_two_args_mix_fixture(#[future] two_args_mix_fixture: u32) {
assert_eq!(42, two_args_mix_fixture);
}
#[rstest]
#[awt]
async fn use_two_args_mix_fixture_inject_first(
#[future]
#[with(async { 5 })]
two_args_mix_fixture: u32,
) {
assert_eq!(52, two_args_mix_fixture);
}
#[rstest]
#[awt]
async fn use_two_args_mix_fixture_inject_both(
#[future]
#[with(async { 3 }, 1)]
two_args_mix_fixture: u32,
) {
assert_eq!(31, two_args_mix_fixture);
}
@@ -0,0 +1,94 @@
use std::io::prelude::*;
use rstest::*;
#[fixture]
async fn async_u32() -> u32 {
42
}
#[fixture]
async fn nest_fixture(#[future(awt)] async_u32: u32) -> u32 {
async_u32
}
#[fixture]
async fn nest_fixture_with_default(
#[future(awt)]
#[default(async { 42 })]
fortytwo: u32,
) -> u32 {
fortytwo
}
#[rstest]
async fn default_is_async() {
assert_eq!(42, async_u32::default().await);
}
#[rstest]
async fn use_async_nest_fixture_default(#[future(awt)] nest_fixture: u32) {
assert_eq!(42, nest_fixture);
}
#[rstest]
async fn use_async_nest_fixture_injected(
#[future(awt)]
#[with(async { 24 })]
nest_fixture: u32,
) {
assert_eq!(24, nest_fixture);
}
#[rstest]
async fn use_async_nest_fixture_with_default(#[future(awt)] nest_fixture_with_default: u32) {
assert_eq!(42, nest_fixture_with_default);
}
#[rstest]
async fn use_async_fixture(#[future(awt)] async_u32: u32) {
assert_eq!(42, async_u32);
}
#[fixture]
async fn async_impl_output() -> impl Read {
std::io::Cursor::new(vec![1, 2, 3, 4, 5])
}
#[rstest]
async fn use_async_impl_output<T: Read>(#[future(awt)] async_impl_output: T) {
let reader = async_impl_output;
}
#[fixture]
async fn two_args_mix_fixture(
#[future(awt)]
#[default(async { 4 })]
four: u32,
#[default(2)] two: u32,
) -> u32 {
four * 10 + two
}
#[rstest]
async fn use_two_args_mix_fixture(#[future(awt)] two_args_mix_fixture: u32) {
assert_eq!(42, two_args_mix_fixture);
}
#[rstest]
async fn use_two_args_mix_fixture_inject_first(
#[future(awt)]
#[with(async { 5 })]
two_args_mix_fixture: u32,
) {
assert_eq!(52, two_args_mix_fixture);
}
#[rstest]
async fn use_two_args_mix_fixture_inject_both(
#[future(awt)]
#[with(async { 3 }, 1)]
two_args_mix_fixture: u32,
) {
assert_eq!(31, two_args_mix_fixture);
}
@@ -0,0 +1,31 @@
use rstest::*;
#[fixture]
fn s() -> &'static str {
"42"
}
#[fixture]
fn fx<S: ToString>(s: S) -> usize {
s.to_string().len()
}
#[fixture]
fn sum() -> usize {
42
}
#[fixture]
fn fx_double<S: ToString>(sum: usize, s: S) -> usize {
s.to_string().len() + sum
}
#[test]
fn resolve() {
assert_eq!(2, fx::default())
}
#[test]
fn resolve_partial() {
assert_eq!(12, fx_double::partial_1(10))
}
@@ -0,0 +1,46 @@
use rstest::{fixture, rstest};
#[fixture(value = 42)]
pub fn simple(value: u32) -> u32 {
value
}
#[fixture(value = 21, mult = 2)]
pub fn double(value: u32, mult: u32) -> u32 {
value * mult
}
#[fixture]
pub fn middle() -> u32 {
2
}
#[fixture(value = 21, mult = 4)]
pub fn mixed(value: u32, middle: u32, mult: u32) -> u32 {
value * mult / middle
}
#[rstest]
fn test_simple(simple: u32) {
assert_eq!(simple, 42)
}
#[rstest(simple(21))]
fn test_simple_changed(simple: u32) {
assert_eq!(simple, 21)
}
#[rstest]
fn test_double(double: u32) {
assert_eq!(double, 42)
}
#[rstest(double(20, 3))]
fn test_double_changed(double: u32) {
assert_eq!(double, 60)
}
#[rstest]
fn test_mixed(mixed: u32) {
assert_eq!(mixed, 42)
}
@@ -0,0 +1,51 @@
use rstest::{fixture, rstest};
use std::net::{Ipv4Addr, SocketAddr};
struct MyType(String);
struct E;
impl core::str::FromStr for MyType {
type Err = E;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"error" => Err(E),
inner => Ok(MyType(inner.to_owned())),
}
}
}
#[fixture]
fn base(#[default("1.2.3.4")] ip: Ipv4Addr, #[default(r#"8080"#)] port: u16) -> SocketAddr {
SocketAddr::new(ip.into(), port)
}
#[fixture]
fn fail(#[default("error")] t: MyType) -> MyType {
t
}
#[fixture]
fn valid(#[default("some")] t: MyType) -> MyType {
t
}
#[rstest]
fn test_base(base: SocketAddr) {
assert_eq!(base, "1.2.3.4:8080".parse().unwrap());
}
#[fixture]
fn byte_array(#[default(b"1234")] some: &[u8]) -> usize {
some.len()
}
#[rstest]
fn test_byte_array(byte_array: usize) {
assert_eq!(4, byte_array);
}
#[rstest]
fn test_convert_custom(valid: MyType) {}
#[rstest]
fn test_fail_conversion(fail: MyType) {}
@@ -0,0 +1,46 @@
use rstest::{fixture, rstest};
#[fixture]
pub fn simple(#[default(42)] value: u32) -> u32 {
value
}
#[fixture]
pub fn double(#[default(20 + 1)] value: u32, #[default(1 + 1)] mult: u32) -> u32 {
value * mult
}
#[fixture]
pub fn middle() -> u32 {
2
}
#[fixture]
pub fn mixed(#[default(21)] value: u32, middle: u32, #[default(2 + 2)] mult: u32) -> u32 {
value * mult / middle
}
#[rstest]
fn test_simple(simple: u32) {
assert_eq!(simple, 42)
}
#[rstest(simple(21))]
fn test_simple_changed(simple: u32) {
assert_eq!(simple, 21)
}
#[rstest]
fn test_double(double: u32) {
assert_eq!(double, 42)
}
#[rstest(double(20, 3))]
fn test_double_changed(double: u32) {
assert_eq!(double, 60)
}
#[rstest]
fn test_mixed(mixed: u32) {
assert_eq!(mixed, 42)
}
@@ -0,0 +1,43 @@
use rstest::*;
#[fixture]
pub fn i() -> u32 {
42
}
#[fixture]
pub fn j() -> i32 {
-42
}
#[fixture(::default<impl Iterator<Item=(u32, i32)>>::partial_1<impl Iterator<Item=(I,i32)>>)]
pub fn fx<I, J>(i: I, j: J) -> impl Iterator<Item=(I, J)> {
std::iter::once((i, j))
}
#[test]
fn resolve() {
assert_eq!((42, -42), fx::default().next().unwrap())
}
#[test]
fn resolve_partial() {
assert_eq!((42.0, -42), fx::partial_1(42.0).next().unwrap())
}
#[fixture]
#[default(impl Iterator<Item=(u32, i32)>)]
#[partial_1(impl Iterator<Item=(I,i32)>)]
pub fn fx_attrs<I, J>(i: I, j: J) -> impl Iterator<Item=(I, J)> {
std::iter::once((i, j))
}
#[test]
fn resolve_attrs() {
assert_eq!((42, -42), fx_attrs::default().next().unwrap())
}
#[test]
fn resolve_partial_attrs() {
assert_eq!((42.0, -42), fx_attrs::partial_1(42.0).next().unwrap())
}
@@ -0,0 +1,41 @@
use rstest::*;
#[fixture]
fn dyn_box() -> Box<dyn Iterator<Item=i32>> {
Box::new(std::iter::once(42))
}
#[fixture]
fn dyn_ref() -> &'static dyn ToString {
&42
}
#[fixture]
fn dyn_box_resolve(mut dyn_box: Box<dyn Iterator<Item=i32>>) -> i32 {
dyn_box.next().unwrap()
}
#[fixture]
fn dyn_ref_resolve(dyn_ref: &dyn ToString) -> String {
dyn_ref.to_string()
}
#[rstest]
fn test_dyn_box(mut dyn_box: Box<dyn Iterator<Item=i32>>) {
assert_eq!(42, dyn_box.next().unwrap())
}
#[rstest]
fn test_dyn_ref(dyn_ref: &dyn ToString) {
assert_eq!("42", dyn_ref.to_string())
}
#[rstest]
fn test_dyn_box_resolve(dyn_box_resolve: i32) {
assert_eq!(42, dyn_box_resolve)
}
#[rstest]
fn test_dyn_ref_resolve(dyn_ref_resolve: String) {
assert_eq!("42", dyn_ref_resolve)
}
@@ -0,0 +1,51 @@
use rstest::*;
#[fixture]
pub fn fixture() -> u32 {
42
}
#[fixture]
fn error_inner(fixture: u32) {
let a: u32 = "";
}
#[fixture]
fn error_cannot_resolve_fixture(no_fixture: u32) {}
#[fixture]
fn error_fixture_wrong_type(fixture: String) {}
#[fixture(not_a_fixture(24))]
fn error_inject_an_invalid_fixture(fixture: String) {}
#[fixture]
fn name() -> &'static str {
"name"
}
#[fixture]
fn f(name: &str) -> String {
name.to_owned()
}
#[fixture(f("first"), f("second"))]
fn error_inject_a_fixture_more_than_once(f: String) {}
struct T(u32);
#[fixture]
fn structed() -> T {
T(42)
}
#[fixture]
fn structed_injectd(fixture: u32) -> T {
T(fixture)
}
#[fixture]
fn error_destruct_without_resolve(T(a): T) {}
#[fixture]
fn error_destruct_without_resolve_also_with(#[with(21)] T(a): T) {}
@@ -0,0 +1,24 @@
use rstest::*;
#[fixture]
#[once]
async fn error_async_once_fixture() {
}
#[fixture]
#[once]
fn error_generics_once_fixture<T: std::fmt::Debug>() -> T {
42
}
#[fixture]
#[once]
fn error_generics_once_fixture() -> impl Iterator<Item = u32> {
std::iter::once(42)
}
#[fixture]
#[once]
fn error_once_fixture_not_sync() -> std::cell::Cell<u32> {
std::cell::Cell::new(42)
}
@@ -0,0 +1,44 @@
use rstest::fixture;
trait Mult {
fn mult(&self, n: u32) -> u32;
}
struct M(u32);
impl Mult for M {
fn mult(&self, n: u32) -> u32 {
n * self.0
}
}
#[fixture]
fn my_fixture() -> u32 { 42 }
#[fixture]
fn multiplier() -> M {
M(2)
}
#[fixture]
fn my_fixture_injected(my_fixture: u32, multiplier: impl Mult) -> u32 { multiplier.mult(my_fixture) }
#[test]
fn resolve_new() {
assert_eq!(42, my_fixture::get());
}
#[test]
fn resolve_default() {
assert_eq!(42, my_fixture::default());
}
#[test]
fn injected_new() {
assert_eq!(63, my_fixture_injected::get(21, M(3)));
}
#[test]
fn injected_default() {
assert_eq!(84, my_fixture_injected::default());
}
@@ -0,0 +1,14 @@
mod my_mod {
use rstest::{fixture};
#[fixture]
pub fn mod_fixture() -> u32 { 42 }
}
use my_mod::mod_fixture;
#[test]
fn struct_access() {
assert_eq!(42, mod_fixture::default());
}
@@ -0,0 +1,57 @@
use rstest::*;
#[fixture]
fn fx_base_impl_return() -> impl Iterator<Item=u32> { std::iter::once(42) }
#[fixture]
fn fx_base_impl_input(mut fx_base_impl_return: impl Iterator<Item=u32>) -> u32 {
fx_base_impl_return.next().unwrap()
}
#[rstest]
fn base_impl_return(mut fx_base_impl_return: impl Iterator<Item=u32>) {
assert_eq!(42, fx_base_impl_return.next().unwrap());
}
#[rstest]
fn base_impl_input(mut fx_base_impl_input: u32) {
assert_eq!(42, fx_base_impl_input);
}
#[fixture]
fn fx_nested_impl_return() -> impl Iterator<Item=impl ToString> { std::iter::once(42) }
#[fixture]
fn fx_nested_impl_input(mut fx_nested_impl_return: impl Iterator<Item=impl ToString>) -> String {
fx_nested_impl_return.next().unwrap().to_string()
}
#[rstest]
fn nested_impl_return(mut fx_nested_impl_return: impl Iterator<Item=impl ToString>) {
assert_eq!("42", fx_nested_impl_return.next().unwrap().to_string());
}
#[rstest]
fn nested_impl_input(mut fx_nested_impl_input: String) {
assert_eq!("42", &fx_nested_impl_input);
}
#[fixture]
fn fx_nested_multiple_impl_return() -> (impl Iterator<Item=impl ToString>, impl ToString) {
(std::iter::once(42), 42i32)
}
#[fixture]
fn fx_nested_multiple_impl_input(mut fx_nested_multiple_impl_return: (impl Iterator<Item=impl ToString>, impl ToString)) -> bool {
fx_nested_multiple_impl_return.0.next().unwrap().to_string() == fx_nested_multiple_impl_return.1.to_string()
}
#[rstest]
fn nested_multiple_impl_return(mut fx_nested_multiple_impl_return: (impl Iterator<Item=impl ToString>, impl ToString)) {
assert_eq!(fx_nested_multiple_impl_return.0.next().unwrap().to_string(), fx_nested_multiple_impl_return.1.to_string());
}
#[rstest]
fn nested_multiple_impl_input(fx_nested_multiple_impl_input: bool) {
assert!(fx_nested_multiple_impl_input);
}
@@ -0,0 +1,17 @@
use rstest::*;
#[fixture]
fn val() -> i32 {
21
}
#[fixture]
fn fortytwo(mut val: i32) -> i32 {
val *= 2;
val
}
#[rstest]
fn the_test(fortytwo: i32) {
assert_eq!(fortytwo, 42);
}
@@ -0,0 +1,21 @@
use rstest::{fixture, rstest};
#[fixture]
#[once]
fn once_fixture() -> u32 {
eprintln!("Exec fixture() just once");
42
}
#[rstest]
fn base(once_fixture: &u32) {
assert_eq!(&42, once_fixture);
}
#[rstest]
#[case(2)]
#[case(3)]
#[case(7)]
fn cases(once_fixture: &u32, #[case] divisor: u32) {
assert_eq!(0, *once_fixture % divisor);
}
@@ -0,0 +1,33 @@
use rstest::{fixture, rstest};
#[fixture]
#[default(u32)]
#[partial_1(u32)]
#[once]
fn once_fixture(#[default(())] a: (), #[default(())] b: ()) -> u32 {
eprintln!("Exec fixture() just once");
42
}
#[rstest]
fn base(once_fixture: &u32) {
assert_eq!(&42, once_fixture);
}
#[rstest]
fn base_partial(#[with(())] once_fixture: &u32) {
assert_eq!(&42, once_fixture);
}
#[rstest]
fn base_complete(#[with((), ())] once_fixture: &u32) {
assert_eq!(&42, once_fixture);
}
#[rstest]
#[case(2)]
#[case(3)]
#[case(7)]
fn cases(once_fixture: &u32, #[case] divisor: u32) {
assert_eq!(0, *once_fixture % divisor);
}
@@ -0,0 +1,20 @@
use rstest::*;
#[fixture]
#[once]
fn once_fixture() {
eprintln!("Exec fixture() just once");
}
#[rstest]
fn base(_once_fixture: ()) {
assert!(true);
}
#[rstest]
#[case()]
#[case()]
#[case()]
fn cases(_once_fixture: ()) {
assert!(true);
}
@@ -0,0 +1,40 @@
use rstest::*;
#[fixture]
fn f1() -> u32 { 0 }
#[fixture]
fn f2() -> u32 { 0 }
#[fixture]
fn f3() -> u32 { 0 }
#[fixture]
fn fixture(f1: u32, f2: u32, f3: u32) -> u32 { f1 + 10 * f2 + 100 * f3 }
#[fixture(fixture(7))]
fn partial_1(fixture: u32) -> u32 { fixture }
#[fixture(fixture(2, 4))]
fn partial_2(fixture: u32) -> u32 { fixture }
#[fixture(fixture(2, 4, 5))]
fn complete(fixture: u32) -> u32 { fixture }
#[rstest]
fn default(fixture: u32) {
assert_eq!(fixture, 0);
}
#[rstest]
fn t_partial_1(partial_1: u32) {
assert_eq!(partial_1, 7);
}
#[rstest]
fn t_partial_2(partial_2: u32) {
assert_eq!(partial_2, 42);
}
#[rstest]
fn t_complete(complete: u32) {
assert_eq!(complete, 542);
}
@@ -0,0 +1,54 @@
use rstest::*;
#[fixture]
fn f1() -> u32 {
0
}
#[fixture]
fn f2() -> u32 {
0
}
#[fixture]
fn f3() -> u32 {
0
}
#[fixture]
fn fixture(f1: u32, f2: u32, f3: u32) -> u32 {
f1 + 10 * f2 + 100 * f3
}
#[fixture]
fn partial_1(#[with(7)] fixture: u32) -> u32 {
fixture
}
#[fixture]
fn partial_2(#[with(2, 4)] fixture: u32) -> u32 {
fixture
}
#[fixture]
fn complete(#[with(2, 4, 5)] fixture: u32) -> u32 {
fixture
}
#[rstest]
fn default(fixture: u32) {
assert_eq!(fixture, 0);
}
#[rstest]
fn t_partial_1(partial_1: u32) {
assert_eq!(partial_1, 7);
}
#[rstest]
fn t_partial_2(partial_2: u32) {
assert_eq!(partial_2, 42);
}
#[rstest]
fn t_complete(complete: u32) {
assert_eq!(complete, 542);
}
@@ -0,0 +1,64 @@
use rstest::*;
#[fixture]
fn very_long_and_boring_name(#[default(42)] inject: u32) -> u32 {
inject
}
mod sub_module {
use super::*;
#[fixture]
pub fn mod_fixture() -> u32 {
42
}
}
#[fixture(very_long_and_boring_name as foo)]
fn compact(foo: u32) -> u32 {
foo
}
#[fixture(very_long_and_boring_name(21) as foo)]
fn compact_injected(foo: u32) -> u32 {
foo
}
#[fixture(sub_module::mod_fixture as foo)]
fn compact_from_mod(foo: u32) -> u32 {
foo
}
#[fixture]
fn attribute(#[from(very_long_and_boring_name)] foo: u32) -> u32 {
foo
}
#[fixture]
fn attribute_mod(#[from(sub_module::mod_fixture)] foo: u32) -> u32 {
foo
}
#[fixture]
fn attribute_injected(
#[from(very_long_and_boring_name)]
#[with(21)]
foo: u32,
) -> u32 {
foo
}
#[rstest]
fn test(
compact: u32,
attribute: u32,
attribute_mod: u32,
compact_from_mod: u32,
compact_injected: u32,
attribute_injected: u32,
) {
assert_eq!(compact, attribute);
assert_eq!(attribute, attribute_mod);
assert_eq!(attribute_mod, compact_from_mod);
assert_eq!(compact_injected, attribute_injected);
}
@@ -0,0 +1,42 @@
use rstest::{rstest, fixture};
pub trait Tr {
fn get() -> Self;
}
impl Tr for i32 {
fn get() -> Self {
42
}
}
impl Tr for u32 {
fn get() -> Self {
42
}
}
#[fixture]
pub fn f<T: Tr>() -> T {
T::get()
}
#[fixture]
pub fn fu32(f: u32) -> u32 {
f
}
#[fixture]
pub fn fi32(f: i32) -> i32 {
f
}
#[rstest]
fn test_u32(fu32: u32) {
assert_eq!(fu32, 42)
}
#[rstest]
fn test_i32(fi32: i32) {
assert_eq!(fi32, 42)
}
@@ -0,0 +1,17 @@
use rstest::{rstest, fixture};
#[fixture]
fn root() -> u32 { 21 }
#[fixture]
fn injection(root: u32) -> u32 { 2 * root }
#[rstest]
fn success(injection: u32) {
assert_eq!(42, injection);
}
#[rstest]
fn fail(injection: u32) {
assert_eq!(41, injection);
}
@@ -0,0 +1,38 @@
use rstest::*;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
#[rstest]
fn start_with_name(
#[files("files/**/*.txt")]
#[by_ref]
path: &PathBuf,
) {
let name = path.file_name().unwrap();
let mut f = File::open(&path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
assert!(contents.starts_with(name.to_str().unwrap()))
}
#[fixture]
fn f() -> u32 {
42
}
#[rstest]
#[case(42)]
fn test(
#[by_ref] f: &u32,
#[case]
#[by_ref]
c: &u32,
#[values(42, 142)]
#[by_ref]
v: &u32,
) {
assert_eq!(f, c);
assert_eq!(*c, *v % 100);
}
@@ -0,0 +1,4 @@
use rstest::rstest;
#[rstest(one, two, three)]
fn should_show_error_for_no_case(one: u32, two: u32, three: u32) {}
@@ -0,0 +1,18 @@
use rstest::*;
#[rstest]
#[case::pass(42, async { 42 })]
#[case::fail(42, async { 41 })]
#[should_panic]
#[case::pass_panic(42, async { 41 })]
#[should_panic]
#[case::fail_panic(42, async { 42 })]
async fn my_async_test(#[case] expected: u32, #[case] #[future] value: u32) {
assert_eq!(expected, value.await);
}
#[rstest]
#[case::pass(42, async { 42 })]
async fn my_async_test_revert(#[case] expected: u32, #[future] #[case] value: u32) {
assert_eq!(expected, value.await);
}
@@ -0,0 +1,28 @@
use rstest::*;
#[rstest]
#[case::pass(42, async { 42 })]
#[case::fail(42, async { 41 })]
#[should_panic]
#[case::pass_panic(42, async { 41 })]
#[should_panic]
#[case::fail_panic(42, async { 42 })]
async fn my_async_test(
#[case] expected: u32,
#[case]
#[future(awt)]
value: u32,
) {
assert_eq!(expected, value);
}
#[rstest]
#[case::pass(42, async { 42 })]
async fn my_async_test_revert(
#[case] expected: u32,
#[future(awt)]
#[case]
value: u32,
) {
assert_eq!(expected, value);
}
@@ -0,0 +1,30 @@
use rstest::*;
#[rstest]
#[case::pass(42, async { 42 })]
#[case::fail(42, async { 41 })]
#[should_panic]
#[case::pass_panic(42, async { 41 })]
#[should_panic]
#[case::fail_panic(42, async { 42 })]
#[awt]
async fn my_async_test(
#[case] expected: u32,
#[case]
#[future]
value: u32,
) {
assert_eq!(expected, value);
}
#[rstest]
#[case::pass(42, async { 42 })]
#[awt]
async fn my_async_test_revert(
#[case] expected: u32,
#[future]
#[case]
value: u32,
) {
assert_eq!(expected, value);
}
@@ -0,0 +1,24 @@
use rstest::*;
#[rstest]
#[case::pass(async { 3 })]
#[awt]
async fn my_mut_test_global_awt(
#[future]
#[case]
mut a: i32,
) {
a = 4;
assert_eq!(a, 4);
}
#[rstest]
#[case::pass(async { 3 })]
async fn my_mut_test_local_awt(
#[future(awt)]
#[case]
mut a: i32,
) {
a = 4;
assert_eq!(a, 4);
}
@@ -0,0 +1,24 @@
use rstest::rstest;
#[rstest(
val,
case::no_panic(0),
#[should_panic]
case::panic(2),
#[should_panic(expected="expected")]
case::panic_with_message(3),
case::no_panic_but_fail(1),
#[should_panic]
case::panic_but_fail(0),
#[should_panic(expected="other")]
case::panic_with_wrong_message(3),
)]
fn attribute_per_case(val: i32) {
match val {
0 => assert!(true),
1 => assert!(false),
2 => panic!("No catch"),
3 => panic!("expected"),
_ => panic!("Not defined"),
}
}
@@ -0,0 +1,10 @@
use rstest::rstest;
#[cfg(test)]
#[rstest(a, b, case(42), case(1, 2), case(43))]
fn error_less_arguments(a: u32, b: u32) {}
#[cfg(test)]
#[rstest(a, case(42, 43), case(12), case(24, 34))]
fn error_too_much_arguments(a: u32) {}
@@ -0,0 +1,11 @@
use rstest::rstest;
#[rstest(
expected,
case::user_test_description(true),
case(true),
case::user_test_description_fail(false)
)]
fn description(expected: bool) {
assert!(expected);
}
@@ -0,0 +1,10 @@
use rstest::*;
#[rstest]
#[case::first_no_dump("Please don't trace me")]
#[trace]
#[case::dump_me("Trace it!")]
#[case::last_no_dump("Please don't trace me")]
fn cases(#[case] s: &str) {
assert!(false);
}
@@ -0,0 +1,21 @@
use rstest::*;
use actix_rt;
use std::future::Future;
#[rstest(expected, value,
case::pass(42, 42),
#[should_panic]
case::panic(41, 42),
case::fail(1, 42)
)]
#[test]
fn sync(expected: u32, value: u32) { assert_eq!(expected, value); }
#[rstest(expected, value,
case::pass(42, async { 42 }),
#[should_panic]
case::panic(41, async { 42 }),
case::fail(1, async { 42 })
)]
#[actix_rt::test]
async fn fn_async(expected: u32, value: impl Future<Output=u32>) { assert_eq!(expected, value.await); }
@@ -0,0 +1,5 @@
use rstest::rstest;
#[cfg(test)]
#[rstest(f, case(42), case(24))]
fn error_param_not_exist() {}
@@ -0,0 +1,5 @@
use rstest::rstest;
#[cfg(test)]
#[rstest(a,b,c, case(1,2,3), case(3,2,1))]
fn error_param_not_exist(b: u32) {}
@@ -0,0 +1,54 @@
use rstest::*;
#[fixture]
fn f1() -> u32 {
0
}
#[fixture]
fn f2() -> u32 {
0
}
#[fixture]
fn f3() -> u32 {
0
}
#[fixture]
fn fixture(f1: u32, f2: u32, f3: u32) -> u32 {
f1 + 10 * f2 + 100 * f3
}
#[rstest(expected, case(0), case(1000))]
fn default(fixture: u32, expected: u32) {
assert_eq!(fixture, expected);
}
#[rstest(fixture(7), expected, case(7), case(1000))]
fn partial_1(fixture: u32, expected: u32) {
assert_eq!(fixture, expected);
}
#[rstest(expected, case(7), case(1000))]
fn partial_attr_1(#[with(7)] fixture: u32, expected: u32) {
assert_eq!(fixture, expected);
}
#[rstest(fixture(2, 4), expected, case(42), case(1000))]
fn partial_2(fixture: u32, expected: u32) {
assert_eq!(fixture, expected);
}
#[rstest(expected, case(42), case(1000))]
fn partial_attr_2(#[with(2, 4)] fixture: u32, expected: u32) {
assert_eq!(fixture, expected);
}
#[rstest(fixture(2, 4, 5), expected, case(542), case(1000))]
fn complete(fixture: u32, expected: u32) {
assert_eq!(fixture, expected);
}
#[rstest(expected, case(542), case(1000))]
fn complete_attr(#[with(2, 4, 5)] fixture: u32, expected: u32) {
assert_eq!(fixture, expected);
}
@@ -0,0 +1,10 @@
use rstest::rstest;
#[rstest(
expected, input,
case(4, "ciao"),
case(3, "Foo")
)]
fn strlen_test(expected: usize, input: &str) {
assert_eq!(expected, input.len());
}
@@ -0,0 +1,37 @@
use rstest::rstest;
#[rstest]
#[case::ciao(4, "ciao")]
#[should_panic]
#[case::panic(42, "Foo")]
#[case::foo(3, "Foo")]
fn all(#[case] expected: usize, #[case] input: &str) {
assert_eq!(expected, input.len());
}
#[rstest(expected, input)]
#[case::ciao(4, "ciao")]
#[case::foo(3, "Foo")]
#[should_panic]
#[case::panic(42, "Foo")]
fn just_cases(expected: usize, input: &str) {
assert_eq!(expected, input.len());
}
#[rstest(
case::ciao(4, "ciao"),
case::foo(3, "Foo"),
#[should_panic]
case::panic(42, "Foo"),
)]
fn just_args(#[case] expected: usize, #[case] input: &str) {
assert_eq!(expected, input.len());
}
#[rstest]
#[case(0, "ciao")]
#[case(0, "Foo")]
#[should_panic]
fn all_panic(#[case] expected: usize, #[case] input: &str) {
assert_eq!(expected, input.len());
}
@@ -0,0 +1,33 @@
use rstest::*;
#[rstest]
#[case::description(42)]
fn with_case(#[context] ctx: Context, #[case] _c: u32) {
assert_eq!("with_case", ctx.name);
assert_eq!(Some("description"), ctx.description);
assert_eq!(Some(0), ctx.case);
}
#[rstest]
fn without_case(#[context] ctx: Context) {
assert_eq!("without_case", ctx.name);
assert_eq!(None, ctx.description);
assert_eq!(None, ctx.case);
}
mod first {
mod inner {
use rstest::*;
#[rstest]
fn test(#[context] ctx: Context) {
assert!(ctx.module.ends_with("first::inner"));
}
}
}
#[rstest]
fn measure_time(#[context] ctx: Context) {
std::thread::sleep(std::time::Duration::from_millis(100));
assert!(ctx.start.elapsed() >= std::time::Duration::from_millis(100));
}
@@ -0,0 +1,75 @@
use rstest::*;
use std::net::SocketAddr;
#[rstest]
#[case(true, "1.2.3.4:42")]
#[case(true, r#"4.3.2.1:24"#)]
#[case(false, "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443")]
#[case(false, r#"[2aa1:db8:85a3:8af:1319:8a2e:375:4873]:344"#)]
#[case(false, "this.is.not.a.socket.address")]
#[case(false, r#"this.is.not.a.socket.address"#)]
fn cases(#[case] expected: bool, #[case] addr: SocketAddr) {
assert_eq!(expected, addr.is_ipv4());
}
#[rstest]
fn values(
#[values(
"1.2.3.4:42",
r#"4.3.2.1:24"#,
"this.is.not.a.socket.address",
r#"this.is.not.a.socket.address"#
)]
addr: SocketAddr,
) {
assert!(addr.is_ipv4())
}
#[rstest]
#[case(b"12345")]
fn not_convert_byte_array(#[case] cases: &[u8], #[values(b"abc")] values: &[u8]) {
assert_eq!(5, cases.len());
assert_eq!(3, values.len());
}
trait MyTrait {
fn my_trait(&self) -> u32 {
42
}
}
impl MyTrait for &str {}
#[rstest]
#[case("impl", "nothing")]
fn not_convert_impl(#[case] that_impl: impl MyTrait, #[case] s: &str) {
assert_eq!(42, that_impl.my_trait());
assert_eq!(42, s.my_trait());
}
#[rstest]
#[case("1.2.3.4", "1.2.3.4:42")]
#[case("1.2.3.4".to_owned(), "1.2.3.4:42")]
fn not_convert_generics<S: AsRef<str>>(#[case] ip: S, #[case] addr: SocketAddr) {
assert_eq!(addr.ip().to_string(), ip.as_ref());
}
struct MyType(String);
struct E;
impl core::str::FromStr for MyType {
type Err = E;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"error" => Err(E),
inner => Ok(MyType(inner.to_owned())),
}
}
}
#[rstest]
#[case("hello", "hello")]
#[case("doesn't mater", "error")]
fn convert_without_debug(#[case] expected: &str, #[case] converted: MyType) {
assert_eq!(expected, converted.0);
}
@@ -0,0 +1,75 @@
use other_name::*;
use std::net::SocketAddr;
#[rstest]
#[case(true, "1.2.3.4:42")]
#[case(true, r#"4.3.2.1:24"#)]
#[case(false, "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443")]
#[case(false, r#"[2aa1:db8:85a3:8af:1319:8a2e:375:4873]:344"#)]
#[case(false, "this.is.not.a.socket.address")]
#[case(false, r#"this.is.not.a.socket.address"#)]
fn cases(#[case] expected: bool, #[case] addr: SocketAddr) {
assert_eq!(expected, addr.is_ipv4());
}
#[rstest]
fn values(
#[values(
"1.2.3.4:42",
r#"4.3.2.1:24"#,
"this.is.not.a.socket.address",
r#"this.is.not.a.socket.address"#
)]
addr: SocketAddr,
) {
assert!(addr.is_ipv4())
}
#[rstest]
#[case(b"12345")]
fn not_convert_byte_array(#[case] cases: &[u8], #[values(b"abc")] values: &[u8]) {
assert_eq!(5, cases.len());
assert_eq!(3, values.len());
}
trait MyTrait {
fn my_trait(&self) -> u32 {
42
}
}
impl MyTrait for &str {}
#[rstest]
#[case("impl", "nothing")]
fn not_convert_impl(#[case] that_impl: impl MyTrait, #[case] s: &str) {
assert_eq!(42, that_impl.my_trait());
assert_eq!(42, s.my_trait());
}
#[rstest]
#[case("1.2.3.4", "1.2.3.4:42")]
#[case("1.2.3.4".to_owned(), "1.2.3.4:42")]
fn not_convert_generics<S: AsRef<str>>(#[case] ip: S, #[case] addr: SocketAddr) {
assert_eq!(addr.ip().to_string(), ip.as_ref());
}
struct MyType(String);
struct E;
impl core::str::FromStr for MyType {
type Err = E;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"error" => Err(E),
inner => Ok(MyType(inner.to_owned())),
}
}
}
#[rstest]
#[case("hello", "hello")]
#[case("doesn't mater", "error")]
fn convert_without_debug(#[case] expected: &str, #[case] converted: MyType) {
assert_eq!(expected, converted.0);
}
@@ -0,0 +1,79 @@
use rstest::*;
struct T {
a: u32,
b: u32,
}
impl T {
fn new(a: u32, b: u32) -> Self {
Self { a, b }
}
}
struct S(u32, u32);
#[fixture]
fn fix() -> T {
T::new(1, 42)
}
#[fixture]
fn named() -> S {
S(1, 42)
}
#[fixture]
fn tuple() -> (u32, u32) {
(1, 42)
}
#[fixture]
fn swap(#[from(fix)] T { a, b }: T) -> T {
T::new(b, a)
}
#[rstest]
fn swapped(#[from(swap)] T { a, b }: T) {
assert_eq!(a, 42);
assert_eq!(b, 1);
}
#[rstest]
#[case::two_times_twenty_one(T::new(2, 21))]
#[case::six_times_seven(T{ a: 6, b: 7 })]
fn cases_destruct(
#[from(fix)] T { a, b }: T,
#[case] T { a: c, b: d }: T,
#[values(T::new(42, 1), T{ a: 3, b: 14})] T { a: e, b: f }: T,
) {
assert_eq!(a * b, 42);
assert_eq!(c * d, 42);
assert_eq!(e * f, 42);
}
#[rstest]
#[case::two_times_twenty_one(S(2, 21))]
#[case::six_times_seven(S(6, 7))]
fn cases_destruct_named_tuple(
#[from(named)] S(a, b): S,
#[case] S(c, d): S,
#[values(S(42, 1), S(3, 14))] S(e, f): S,
) {
assert_eq!(a * b, 42);
assert_eq!(c * d, 42);
assert_eq!(e * f, 42);
}
#[rstest]
#[case::two_times_twenty_one((2, 21))]
#[case::six_times_seven((6, 7))]
fn cases_destruct_tuple(
#[from(tuple)] (a, b): (u32, u32),
#[case] (c, d): (u32, u32),
#[values((42, 1), (3, 14))] (e, f): (u32, u32),
) {
assert_eq!(a * b, 42);
assert_eq!(c * d, 42);
assert_eq!(e * f, 42);
}
@@ -0,0 +1,62 @@
use rstest::*;
#[derive(Debug)]
struct A {}
#[fixture]
fn fu32() -> u32 {
42
}
#[fixture]
fn fstring() -> String {
"A String".to_string()
}
#[fixture]
fn ftuple() -> (A, String, i32) {
(A {}, "A String".to_string(), -12)
}
#[rstest]
#[trace]
fn single_fail(fu32: u32, fstring: String, ftuple: (A, String, i32)) {
assert!(false);
}
#[rstest]
fn no_trace_single_fail(fu32: u32, fstring: String, ftuple: (A, String, i32)) {
assert!(false);
}
#[rstest]
#[case(42, "str", ("ss", -12))]
#[case(24, "trs", ("tt", -24))]
#[trace]
fn cases_fail(#[case] u: u32, #[case] s: &str, #[case] t: (&str, i32)) {
assert!(false);
}
#[rstest]
#[case(42, "str", ("ss", -12))]
#[case(24, "trs", ("tt", -24))]
fn no_trace_cases_fail(#[case] u: u32, #[case] s: &str, #[case] t: (&str, i32)) {
assert!(false);
}
#[rstest]
#[trace]
fn matrix_fail(
#[values(1, 3)] u: u32,
#[values("rst", "srt")] s: &str,
#[values(("SS", -12), ("TT", -24))] t: (&str, i32),
) {
assert!(false);
}
#[rstest]
fn no_trace_matrix_fail(
#[values(1, 3)] u: u32,
#[values("rst", "srt")] s: &str,
#[values(("SS", -12), ("TT", -24))] t: (&str, i32),
) {
assert!(false);
}
@@ -0,0 +1,63 @@
use rstest::*;
#[derive(Debug)]
struct A {}
#[fixture]
fn fu32() -> u32 {
42
}
#[fixture]
fn fstring() -> String {
"A String".to_string()
}
#[fixture]
fn ftuple() -> (A, String, i32) {
(A {}, "A String".to_string(), -12)
}
#[rstest(::trace)]
fn single_fail(fu32: u32, fstring: String, ftuple: (A, String, i32)) {
assert!(false);
}
#[rstest]
fn no_trace_single_fail(fu32: u32, fstring: String, ftuple: (A, String, i32)) {
assert!(false);
}
#[rstest(u, s, t,
case(42, "str", ("ss", -12)),
case(24, "trs", ("tt", -24))
::trace
)]
fn cases_fail(u: u32, s: &str, t: (&str, i32)) {
assert!(false);
}
#[rstest(u, s, t,
case(42, "str", ("ss", -12)),
case(24, "trs", ("tt", -24))
)]
fn no_trace_cases_fail(u: u32, s: &str, t: (&str, i32)) {
assert!(false);
}
#[rstest(
u => [1, 2],
s => ["rst", "srt"],
t => [("SS", -12), ("TT", -24)]
::trace
)]
fn matrix_fail(u: u32, s: &str, t: (&str, i32)) {
assert!(false);
}
#[rstest(
u => [1, 2],
s => ["rst", "srt"],
t => [("SS", -12), ("TT", -24)]
)]
fn no_trace_matrix_fail(u: u32, s: &str, t: (&str, i32)) {
assert!(false);
}
@@ -0,0 +1,51 @@
use rstest::*;
struct A;
struct B;
#[derive(Debug)]
struct D;
#[fixture]
fn fu32() -> u32 {
42
}
#[fixture]
fn fb() -> B {
B {}
}
#[fixture]
fn fd() -> D {
D {}
}
#[fixture]
fn fa() -> A {
A {}
}
#[rstest]
#[trace]
fn simple(fu32: u32, #[notrace] fa: A, #[notrace] fb: B, fd: D) {
assert!(false);
}
#[rstest]
#[trace]
#[case(A{}, B{}, D{})]
fn cases(fu32: u32, #[case] #[notrace] a: A, #[case] #[notrace] b: B, #[case] d: D) {
assert!(false);
}
#[rstest]
#[trace]
fn matrix(
fu32: u32,
#[notrace]
#[values(A{})]
a: A,
#[notrace]
#[values(B{})]
b: B,
#[values(D{}) ] dd: D,
) {
assert!(false);
}
@@ -0,0 +1,41 @@
use rstest::*;
struct A;
struct B;
#[derive(Debug)]
struct D;
#[fixture]
fn fu32() -> u32 { 42 }
#[fixture]
fn fb() -> B { B {} }
#[fixture]
fn fd() -> D { D {} }
#[fixture]
fn fa() -> A { A {} }
#[rstest(
::trace::notrace(fa,fb))
]
fn simple(fu32: u32, fa: A, fb: B, fd: D) {
assert!(false);
}
#[rstest(a,b,d,
case(A{}, B{}, D{})
::trace::notrace(a,b))
]
fn cases(fu32: u32, a: A, b: B, d: D) {
assert!(false);
}
#[rstest(
a => [A{}],
b => [B{}],
dd => [D{}],
::trace::notrace(a,b))
]
fn matrix(fu32: u32, a: A, b: B, dd: D) {
assert!(false);
}
@@ -0,0 +1,21 @@
struct S;
#[rustfmt::skip] mod _skip_format {
use rstest::*; use super::*;
#[fixture]
fn fixture() -> S { S {} }
#[rstest]
#[trace]
fn single(fixture: S) {}
#[rstest(s)]
#[trace]
#[case(S{})]
fn cases(s: S) {}
#[rstest(
s => [S{}])]
#[trace]
fn matrix(s: S) {}
}
@@ -0,0 +1,21 @@
struct S;
#[rustfmt::skip] mod _skip_format {
use rstest::*; use super::*;
#[fixture]
fn fixture() -> S { S {} }
#[rstest(
::trace)]
fn single(fixture: S) {}
#[rstest(s,
case(S{})
::trace)]
fn cases(s: S) {}
#[rstest(
s => [S{}]
::trace)]
fn matrix(s: S) {}
}
@@ -0,0 +1,126 @@
use rstest::*;
#[fixture]
pub fn fixture() -> u32 {
42
}
#[rstest(f, case(42))]
fn error_inner(f: i32) {
let a: u32 = "";
}
#[rstest(f, case(42))]
fn error_cannot_resolve_fixture(no_fixture: u32, f: u32) {}
#[rstest(f, case(42))]
fn error_fixture_wrong_type(fixture: String, f: u32) {}
#[rstest(f, case(42))]
fn error_case_wrong_type(f: &str) {}
#[rstest(condition,
case(vec![1,2,3].contains(2)))
]
fn error_in_arbitrary_rust_code_cases(condition: bool) {
assert!(condition)
}
#[rstest(f, case(42), not_a_fixture(24))]
fn error_inject_an_invalid_fixture(f: u32) {}
#[fixture]
fn n() -> u32 {
24
}
#[fixture]
fn f(n: u32) -> u32 {
2 * n
}
#[rstest(f, f(42), case(12))]
fn error_inject_a_fixture_that_is_already_a_case(f: u32) {}
#[rstest(f(42), f, case(12))]
fn error_define_case_that_is_already_an_injected_fixture(f: u32) {}
#[rstest(v, f(42), f(42), case(12))]
fn error_inject_a_fixture_more_than_once(v: u32, f: u32) {}
#[rstest(f => [42])]
fn error_matrix_wrong_type(f: &str) {}
#[rstest(condition => [vec![1,2,3].contains(2)] )]
fn error_arbitrary_rust_code_matrix(condition: bool) {
assert!(condition)
}
#[rstest(empty => [])]
fn error_empty_list(empty: &str) {}
#[rstest(not_exist_1 => [42],
not_exist_2 => [42])]
fn error_no_match_args() {}
#[rstest(f => [41, 42], f(42))]
fn error_inject_a_fixture_that_is_already_a_value_list(f: u32) {}
#[rstest(f(42), f => [41, 42])]
fn error_define_a_value_list_that_is_already_an_injected_fixture(f: u32) {}
#[rstest(a, case(42), a => [42])]
fn error_define_a_value_list_that_is_already_a_case_arg(a: u32) {}
#[rstest(a => [42], a, case(42))]
fn error_define_a_case_arg_that_is_already_a_value_list(a: u32) {}
#[rstest(a => [42, 24], a => [24, 42])]
fn error_define_a_value_list_that_is_already_a_value_list(f: u32) {}
#[rstest(a, a, case(42))]
fn error_define_a_case_arg_that_is_already_a_case_arg(a: u32) {}
struct S;
#[rstest]
#[case("donald duck")]
fn error_convert_to_type_that_not_implement_from_str(#[case] s: S) {}
#[rstest]
#[case(async { "hello" } )]
async fn error_future_on_impl_type(
#[case]
#[future]
s: impl AsRef<str>,
) {
}
#[rstest]
#[case(async { 42 } )]
async fn error_future_more_than_once(
#[case]
#[future]
#[future]
a: i32,
) {
}
#[rstest]
#[timeout]
fn error_timeout_without_arg() {}
#[rstest]
#[timeout(some -> strange -> invalid -> expression)]
fn error_timeout_without_expression_arg() {}
#[rstest]
#[timeout(42)]
fn error_timeout_without_duration() {}
#[rstest]
fn error_absolute_path_files(#[files("/tmp/tmp.Q81idVZYAV/*.txt")] path: std::path::PathBuf) {}
struct T(u32, u32);
#[rstest]
#[case(T(3, 4))]
fn wrong_destruct_fixture(T(a, b): T, #[with(42)] T(c, d): T) {}
@@ -0,0 +1,142 @@
use rstest::*;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
#[rstest]
fn start_with_name(
#[files("files/**/*.txt")]
#[exclude("exclude")]
#[files("../files_test_sub_folder/**/*.txt")]
path: PathBuf,
) {
let name = path.file_name().unwrap();
let mut f = File::open(&path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
assert!(contents.starts_with(name.to_str().unwrap()))
}
#[rstest]
fn start_with_name_file_mode(
#[files("files/**/*.txt")]
#[exclude("exclude")]
#[files("../files_test_sub_folder/**/*.txt")]
#[mode = path]
path: PathBuf,
) {
let name = path.file_name().unwrap();
let mut f = File::open(&path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
assert!(contents.starts_with(name.to_str().unwrap()))
}
#[rstest]
fn start_with_name_with_include(
#[files("files/**/*.txt")]
#[exclude("exclude")]
#[include_dot_files]
path: PathBuf,
) {
let name = path.file_name().unwrap();
let mut f = File::open(&path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
assert!(contents.starts_with(name.to_str().unwrap()))
}
#[rstest]
fn ignore_missing_env_vars(
#[ignore_missing_env_vars]
#[files("files/**/${__SHOULD_NOT_BE_DECLARED__}*.txt")]
#[exclude("exclude")]
path: PathBuf,
) {
let name = path.file_name().unwrap();
let mut f = File::open(&path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
assert!(contents.starts_with(name.to_str().unwrap()))
}
#[rstest]
fn env_vars(
#[files("${FILES_ENV_VAR}/**/*.txt")]
#[exclude("exclude")]
path: PathBuf,
) {
let name = path.file_name().unwrap();
let mut f = File::open(&path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
assert!(contents.starts_with(name.to_str().unwrap()))
}
#[rstest]
fn env_vars_unknown(
#[files("${__UNKNOWN__:-files}/**/*.txt")]
#[exclude("exclude")]
path: PathBuf,
) {
let name = path.file_name().unwrap();
let mut f = File::open(&path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
assert!(contents.starts_with(name.to_str().unwrap()))
}
#[rstest]
fn env_vars_base_dir(
#[files("**/*.txt")]
#[base_dir = "files"]
#[exclude("exclude")]
path: PathBuf,
) {
let name = path.file_name().unwrap();
let mut f = File::open(&path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
assert!(contents.starts_with(name.to_str().unwrap()))
}
#[rstest]
fn include_str(
#[files("files/**/*.txt")]
#[exclude("exclude")]
#[files("../files_test_sub_folder/**/*.txt")]
#[mode = str]
contents: &str,
) {
assert!(contents.len() != 0)
}
#[rstest]
fn include_bytes(
#[files("files/**/*.txt")]
#[exclude("exclude")]
#[files("../files_test_sub_folder/**/*.txt")]
#[mode = bytes]
contents: &[u8],
) {
assert!(contents.len() != 0)
}
mod module {
#[rstest::rstest]
fn pathbuf_need_not_be_in_scope(
#[files("files/**/*.txt")]
#[exclude("exclude")]
#[include_dot_files]
path: std::path::PathBuf,
) {
let _ = path;
}
}
@@ -0,0 +1,18 @@
use rstest::*;
#[fixture]
fn fixture() -> String { "str".to_owned() }
#[rstest]
fn simple<S: AsRef<str>>(fixture: S) {
assert_eq!(3, fixture.as_ref().len());
}
#[rstest(
expected, input,
case(4, String::from("ciao")),
case(3, "Foo")
)]
fn strlen_test<S: AsRef<str>>(expected: usize, input: S) {
assert_eq!(expected, input.as_ref().len());
}
@@ -0,0 +1,35 @@
use rstest::*;
#[fixture]
fn inject() -> u32 {
0
}
#[fixture]
fn ex() -> u32 {
42
}
#[fixture]
fn fix(inject: u32, ex: u32) -> bool {
(inject * 2) == ex
}
#[rstest(
fix(21),
a,
case(21, 2),
expected => [4, 2*3-2],
)]
#[case::second(14, 3)]
fn happy(
fix: bool,
a: u32,
#[case] b: u32,
expected: usize,
#[values("ciao", "buzz")] input: &str,
) {
assert!(fix);
assert_eq!(a * b, 42);
assert_eq!(expected, input.len());
}
@@ -0,0 +1,6 @@
use rstest::*;
#[rstest]
#[case(42, 2)]
#[case(43, 3)]
fn test(#[case] _ignore1: u32, #[case] _ignore2: u32, #[values(1, 2, 3, 4)] _ignore3: u32) {}
@@ -0,0 +1,16 @@
use rstest::*;
use sqlx::SqlitePool;
struct FixtureStruct {}
#[fixture]
fn my_fixture() -> FixtureStruct {
FixtureStruct {}
}
#[rstest]
#[sqlx::test]
async fn test_db(my_fixture: FixtureStruct, #[ignore] pool: SqlitePool) {
assert!(true);
}
@@ -0,0 +1,18 @@
use rstest::*;
#[fixture]
fn fixture() -> String { "str".to_owned() }
#[rstest]
fn simple(fixture: impl AsRef<str>) {
assert_eq!(3, fixture.as_ref().len());
}
#[rstest(
expected, input,
case(4, String::from("ciao")),
case(3, "Foo")
)]
fn strlen_test(expected: usize, input: impl AsRef<str>) {
assert_eq!(expected, input.as_ref().len());
}
@@ -0,0 +1,21 @@
use rstest::*;
enum E<'a> {
A(bool),
B(&'a std::cell::Cell<E<'a>>),
}
#[rstest]
#[case(E::A(true))]
fn case<'a>(#[case] e: E<'a>) {}
#[rstest]
fn values<'a>(#[values(E::A(true))] e: E<'a>) {}
#[fixture]
fn e<'a>() -> E<'a> {
E::A(true)
}
#[rstest]
fn fixture<'a>(e: E<'a>) {}
@@ -0,0 +1,28 @@
use std::cell::Cell;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum E<'a> {
A(bool),
B(&'a Cell<E<'a>>),
}
fn make_e_from_bool<'a>(_bump: &'a (), b: bool) -> E<'a> {
E::A(b)
}
#[cfg(test)]
mod tests {
use rstest::*;
use super::*;
#[fixture]
fn bump() -> () {}
#[rstest]
#[case(true, E::A(true))]
fn it_works<'a>(#[by_ref] bump: &'a (), #[case] b: bool, #[case] expected: E<'a>) {
let actual = make_e_from_bool(&bump, b);
assert_eq!(actual, expected);
}
}
@@ -0,0 +1,12 @@
use rstest::*;
#[rstest]
async fn my_async_test(
#[future]
#[values(async { 1 }, async { 2 })]
first: u32,
#[values(42, 21)]
second: u32
) {
assert_eq!(42, first.await * second);
}
@@ -0,0 +1,12 @@
use rstest::*;
#[rstest]
async fn my_async_test(
#[future(awt)]
#[values(async { 1 }, async { 2 })]
first: u32,
#[values(42, 21)]
second: u32
) {
assert_eq!(42, first * second);
}
@@ -0,0 +1,13 @@
use rstest::*;
#[rstest]
#[awt]
async fn my_async_test(
#[future]
#[values(async { 1 }, async { 2 })]
first: u32,
#[values(42, 21)]
second: u32
) {
assert_eq!(42, first * second);
}
@@ -0,0 +1,17 @@
use rstest::*;
use actix_rt;
use std::future::Future;
#[rstest(
first => [1, 2],
second => [2, 1],
)]
#[test]
fn sync(first: u32, second: u32) { assert_eq!(2, first * second); }
#[rstest(
first => [async { 1 }, async { 2 }],
second => [2, 1],
)]
#[actix_rt::test]
async fn fn_async(first: impl Future<Output=u32>, second: u32) { assert_eq!(2, first.await * second); }
@@ -0,0 +1,54 @@
use rstest::*;
#[fixture]
fn f1() -> u32 {
0
}
#[fixture]
fn f2() -> u32 {
0
}
#[fixture]
fn f3() -> u32 {
0
}
#[fixture]
fn fixture(f1: u32, f2: u32, f3: u32) -> u32 {
f1 + f2 + 2 * f3
}
#[rstest(a => [0, 1], b => [0, 2])]
fn default(fixture: u32, a: u32, b: u32) {
assert_eq!(fixture, a * b);
}
#[rstest(a => [0, 1], b => [0, 2], fixture(1))]
fn partial_1(fixture: u32, a: u32, b: u32) {
assert_eq!(fixture, a * b);
}
#[rstest(a => [0, 1], b => [0, 2])]
fn partial_attr_1(#[with(1)] fixture: u32, a: u32, b: u32) {
assert_eq!(fixture, a * b);
}
#[rstest(a => [0, 1], b => [0, 2], fixture(0, 2))]
fn partial_2(fixture: u32, a: u32, b: u32) {
assert_eq!(fixture, a * b);
}
#[rstest(a => [0, 1], b => [0, 2])]
fn partial_attr_2(#[with(0, 2)] fixture: u32, a: u32, b: u32) {
assert_eq!(fixture, a * b);
}
#[rstest(a => [0, 1], b => [0, 2], fixture(0, 0, 1))]
fn complete(fixture: u32, a: u32, b: u32) {
assert_eq!(fixture, a * b);
}
#[rstest(a => [0, 1], b => [0, 2])]
fn complete_attr(#[with(0, 0, 1)] fixture: u32, a: u32, b: u32) {
assert_eq!(fixture, a * b);
}
@@ -0,0 +1,9 @@
use rstest::rstest;
#[rstest(
expected => [4, 2*3-2],
input => ["ciao", "buzz"],
)]
fn strlen_test(expected: usize, input: &str) {
assert_eq!(expected, input.len());
}
@@ -0,0 +1,20 @@
use rstest::rstest;
#[rstest]
fn both(#[values(4, 2*3-2)] expected: usize, #[values("ciao", "buzz")] input: &str) {
assert_eq!(expected, input.len());
}
#[rstest(
input => ["ciao", "buzz"]
)]
fn first(#[values(4, 2*3-2)] expected: usize, input: &str) {
assert_eq!(expected, input.len());
}
#[rstest(
expected => [4, 2*3-2]
)]
fn second(expected: usize, #[values("ciao", "buzz")] input: &str) {
assert_eq!(expected, input.len());
}
@@ -0,0 +1,29 @@
use rstest::*;
#[fixture]
pub fn fixture() -> u32 { 42 }
#[rstest]
fn should_success(mut fixture: u32) {
fixture += 1;
assert_eq!(fixture, 43);
}
#[rstest]
fn should_fail(mut fixture: u32) {
fixture += 1;
assert_ne!(fixture, 43);
}
#[rstest(
expected, val,
case(45, 1),
case(46, 2),
case(47, 2)
)]
fn add_test(mut fixture: u32, expected: u32, mut val: u32) {
fixture += 1;
val += fixture + 1;
assert_eq!(expected, val);
}
@@ -0,0 +1,33 @@
#![no_std]
use rstest::{fixture, rstest};
#[fixture]
#[once]
fn once_fixture() -> u64 {
42
}
#[fixture]
#[once]
fn empty_once_fixture() {}
#[fixture]
async fn async_fixture() -> u64 {
42
}
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
#[rstest]
#[case("2", "2", "4")]
fn it_works(#[case] left: u64, #[case] right: u64, #[case] expected: u64) {
assert_eq!(add(left, right), expected);
}
#[rstest]
async fn async_works(#[future] async_fixture: u64) {
assert_eq!(42, async_fixture.await);
}
@@ -0,0 +1,27 @@
use rstest::*;
#[fixture]
pub fn fixture() -> u32 { 42 }
#[rstest]
#[should_panic]
fn should_success(fixture: u32) {
assert_ne!(fixture, 42);
}
#[rstest]
#[should_panic]
fn should_fail(fixture: u32) {
assert_eq!(fixture, 42);
}
#[rstest(
expected, input,
case(4, 5),
case(3, 2),
case(3, 3)
)]
#[should_panic]
fn fail(expected: i32, input: i32) {
assert_eq!(expected, input);
}
@@ -0,0 +1,11 @@
use rstest::rstest;
#[rstest]
struct Foo;
#[rstest]
impl Foo {}
#[rstest]
mod mod_baz {}
@@ -0,0 +1,9 @@
use rstest::*;
#[fixture]
fn can_be_ignored() {}
#[rstest]
fn ignore_input(_can_be_ignored: ()) {
assert!(true);
}
@@ -0,0 +1,49 @@
use rstest::*;
#[fixture]
fn very_long_and_boring_name(#[default(42)] inject: u32) -> u32 {
inject
}
mod sub_module {
use super::*;
#[fixture]
pub fn mod_fixture() -> u32 {
42
}
}
#[rstest(very_long_and_boring_name as foo)]
fn compact(foo: u32) {
assert!(42 == foo);
}
#[rstest(sub_module::mod_fixture as foo)]
fn compact_mod(foo: u32) {
assert!(42 == foo);
}
#[rstest(very_long_and_boring_name(21) as foo)]
fn compact_injected(foo: u32) {
assert!(21 == foo);
}
#[rstest]
fn attribute(#[from(very_long_and_boring_name)] foo: u32) {
assert!(42 == foo);
}
#[rstest]
fn attribute_mod(#[from(sub_module::mod_fixture)] foo: u32) {
assert!(42 == foo);
}
#[rstest]
fn attribute_injected(
#[from(very_long_and_boring_name)]
#[with(21)]
foo: u32,
) {
assert!(21 == foo);
}
@@ -0,0 +1,19 @@
use rstest::rstest;
#[rstest]
fn should_success() -> Result<(), &'static str> {
Ok(())
}
#[rstest]
fn should_fail() -> Result<(), &'static str> {
Err("Return Error")
}
#[rstest(ret,
case::should_success(Ok(())),
case::should_fail(Err("Return Error"))
)]
fn return_type(ret: Result<(), &'static str>) -> Result<(), &'static str> {
ret
}
@@ -0,0 +1,26 @@
use rstest::*;
#[fixture]
async fn fixture() -> u32 { 42 }
#[rstest]
async fn should_pass(#[future] fixture: u32) {
assert_eq!(fixture.await, 42);
}
#[rstest]
async fn should_fail(#[future] fixture: u32) {
assert_ne!(fixture.await, 42);
}
#[rstest]
#[should_panic]
async fn should_panic_pass(#[future] fixture: u32) {
panic!(format!("My panic -> fixture = {}", fixture.await));
}
#[rstest]
#[should_panic]
async fn should_panic_fail(#[future] fixture: u32) {
assert_eq!(fixture.await, 42);
}
@@ -0,0 +1,28 @@
use rstest::*;
#[fixture]
async fn fixture() -> u32 {
42
}
#[rstest]
async fn should_pass(#[future(awt)] fixture: u32) {
assert_eq!(fixture, 42);
}
#[rstest]
async fn should_fail(#[future(awt)] fixture: u32) {
assert_ne!(fixture, 42);
}
#[rstest]
#[should_panic]
async fn should_panic_pass(#[future(awt)] fixture: u32) {
panic!(format!("My panic -> fixture = {}", fixture));
}
#[rstest]
#[should_panic]
async fn should_panic_fail(#[future(awt)] fixture: u32) {
assert_eq!(fixture, 42);
}
@@ -0,0 +1,32 @@
use rstest::*;
#[fixture]
async fn fixture() -> u32 {
42
}
#[rstest]
#[awt]
async fn should_pass(#[future] fixture: u32) {
assert_eq!(fixture, 42);
}
#[rstest]
#[awt]
async fn should_fail(#[future] fixture: u32) {
assert_ne!(fixture, 42);
}
#[rstest]
#[awt]
#[should_panic]
async fn should_panic_pass(#[future] fixture: u32) {
panic!(format!("My panic -> fixture = {}", fixture));
}
#[rstest]
#[awt]
#[should_panic]
async fn should_panic_fail(#[future] fixture: u32) {
assert_eq!(fixture, 42);
}
@@ -0,0 +1,16 @@
use rstest::*;
#[derive(Debug)]
struct A {}
#[fixture]
fn fu32() -> u32 { 42 }
#[fixture]
fn fstring() -> String { "A String".to_string() }
#[fixture]
fn ftuple() -> (A, String, i32) { (A{}, "A String".to_string(), -12) }
#[rstest(::trace)]
fn should_fail(fu32: u32, fstring: String, ftuple: (A, String, i32)) {
assert!(false);
}
@@ -0,0 +1,41 @@
use rstest::*;
use actix_rt;
#[fixture]
fn a() -> u32 {
42
}
#[rstest]
#[test]
fn sync_case(a: u32) {}
#[rstest]
#[test]
#[should_panic]
fn sync_case_panic(a: u32) { panic!("panic") }
#[rstest]
#[test]
fn sync_case_fail(a: u32) { assert_eq!(2, a); }
#[rstest]
#[test]
fn sync_case_panic_fail(a: u32) { panic!("panic") }
#[rstest]
#[actix_rt::test]
async fn async_case(a: u32) {}
#[rstest]
#[actix_rt::test]
async fn async_case_fail(a: u32) { assert_eq!(2, a); }
#[rstest]
#[actix_rt::test]
#[should_panic]
async fn async_case_panic(a: u32) { panic!("panic") }
#[rstest]
#[actix_rt::test]
async fn async_case_panic_fail(a: u32) { panic!("panic") }
@@ -0,0 +1,54 @@
use rstest::*;
#[fixture]
fn f1() -> u32 {
0
}
#[fixture]
fn f2() -> u32 {
0
}
#[fixture]
fn f3() -> u32 {
0
}
#[fixture]
fn fixture(f1: u32, f2: u32, f3: u32) -> u32 {
f1 + 10 * f2 + 100 * f3
}
#[rstest]
fn default(fixture: u32) {
assert_eq!(fixture, 0);
}
#[rstest(fixture(7))]
fn partial_1(fixture: u32) {
assert_eq!(fixture, 7);
}
#[rstest]
fn partial_attr_1(#[with(7)] fixture: u32) {
assert_eq!(fixture, 7);
}
#[rstest(fixture(2, 4))]
fn partial_2(fixture: u32) {
assert_eq!(fixture, 42);
}
#[rstest]
fn partial_attr_2(#[with(2, 4)] fixture: u32) {
assert_eq!(fixture, 42);
}
#[rstest(fixture(2, 4, 5))]
fn complete(fixture: u32) {
assert_eq!(fixture, 542);
}
#[rstest]
fn complete_attr(#[with(2, 4, 5)] fixture: u32) {
assert_eq!(fixture, 542);
}
@@ -0,0 +1,32 @@
use rstest::*;
pub trait Tr {
fn get() -> Self;
}
impl Tr for i32 {
fn get() -> Self {
42
}
}
impl Tr for u32 {
fn get() -> Self {
42
}
}
#[fixture]
pub fn fgen<T: Tr>() -> T {
T::get()
}
#[rstest]
fn generics_u32(fgen: u32) {
assert_eq!(fgen, 42u32);
}
#[rstest]
fn generics_i32(fgen: i32) {
assert_eq!(fgen, 42i32);
}
@@ -0,0 +1,14 @@
use rstest::*;
#[fixture]
pub fn fixture() -> u32 { 42 }
#[rstest]
fn should_success(fixture: u32) {
assert_eq!(fixture, 42);
}
#[rstest]
fn should_fail(fixture: u32) {
assert_ne!(fixture, 42);
}
@@ -0,0 +1,232 @@
use rstest::*;
use std::time::Duration;
fn ms(ms: u32) -> Duration {
Duration::from_millis(ms.into())
}
mod thread {
use super::*;
fn delayed_sum(a: u32, b: u32, delay: Duration) -> u32 {
std::thread::sleep(delay);
a + b
}
#[rstest]
#[timeout(ms(80))]
fn single_pass() {
assert_eq!(4, delayed_sum(2, 2, ms(10)));
}
#[rstest]
#[timeout(ms(100))]
fn single_fail_value() {
assert_eq!(5, delayed_sum(2, 2, ms(1)));
}
#[rstest]
#[timeout(ms(1000))]
#[should_panic = "user message"]
fn fail_with_user_message() {
panic!("user message");
}
#[rstest]
#[timeout(ms(10))]
fn single_fail_timeout() {
assert_eq!(4, delayed_sum(2, 2, ms(80)));
}
#[rstest]
#[timeout(ms(80))]
#[case(ms(10))]
fn one_pass(#[case] delay: Duration) {
assert_eq!(4, delayed_sum(2, 2, delay));
}
#[rstest]
#[timeout(ms(10))]
#[case(ms(80))]
fn one_fail_timeout(#[case] delay: Duration) {
assert_eq!(4, delayed_sum(2, 2, delay));
}
#[rstest]
#[timeout(ms(100))]
#[case(ms(1))]
fn one_fail_value(#[case] delay: Duration) {
assert_eq!(5, delayed_sum(2, 2, delay));
}
#[rstest]
#[case::pass(ms(1), 4)]
#[case::fail_timeout(ms(80), 4)]
#[case::fail_value(ms(1), 5)]
#[timeout(ms(40))]
fn group_same_timeout(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay));
}
#[rstest]
#[timeout(ms(100))]
#[case::pass(ms(1), 4)]
#[timeout(ms(30))]
#[case::fail_timeout(ms(70), 4)]
#[timeout(ms(100))]
#[case::fail_value(ms(1), 5)]
fn group_single_timeout(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay));
}
#[rstest]
#[case::pass(ms(1), 4)]
#[timeout(ms(10))]
#[case::fail_timeout(ms(60), 4)]
#[case::fail_value(ms(1), 5)]
#[timeout(ms(100))]
fn group_one_timeout_override(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay));
}
struct S {}
#[rstest]
#[case(S{})]
fn compile_with_no_copy_arg(#[case] _s: S) {
assert!(true);
}
#[fixture]
fn no_copy() -> S {
S {}
}
#[rstest]
fn compile_with_no_copy_fixture(no_copy: S) {
assert!(true);
}
#[rstest]
fn default_timeout_failure() {
assert_eq!(4, delayed_sum(2, 2, ms(1100)));
}
}
mod async_std_cases {
use super::*;
async fn delayed_sum(a: u32, b: u32, delay: Duration) -> u32 {
async_std::task::sleep(delay).await;
a + b
}
#[rstest]
#[timeout(ms(80))]
async fn single_pass() {
assert_eq!(4, delayed_sum(2, 2, ms(10)).await);
}
#[rstest]
#[timeout(ms(10))]
async fn single_fail_timeout() {
assert_eq!(4, delayed_sum(2, 2, ms(80)).await);
}
#[rstest]
#[timeout(ms(100))]
async fn single_fail_value() {
assert_eq!(5, delayed_sum(2, 2, ms(1)).await);
}
#[rstest]
#[timeout(ms(1000))]
#[should_panic = "user message"]
async fn fail_with_user_message() {
panic! {"user message"};
}
#[rstest]
#[timeout(ms(80))]
#[case(ms(10))]
async fn one_pass(#[case] delay: Duration) {
assert_eq!(4, delayed_sum(2, 2, delay).await);
}
#[rstest]
#[timeout(ms(10))]
#[case(ms(80))]
async fn one_fail_timeout(#[case] delay: Duration) {
assert_eq!(4, delayed_sum(2, 2, delay).await);
}
#[rstest]
#[timeout(ms(100))]
#[case(ms(1))]
async fn one_fail_value(#[case] delay: Duration) {
assert_eq!(5, delayed_sum(2, 2, delay).await);
}
#[rstest]
#[case::pass(ms(1), 4)]
#[case::fail_timeout(ms(80), 4)]
#[case::fail_value(ms(1), 5)]
#[timeout(ms(40))]
async fn group_same_timeout(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay).await);
}
#[rstest]
#[timeout(ms(100))]
#[case::pass(ms(1), 4)]
#[timeout(ms(30))]
#[case::fail_timeout(ms(70), 4)]
#[timeout(ms(100))]
#[case::fail_value(ms(1), 5)]
async fn group_single_timeout(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay).await);
}
#[rstest]
#[case::pass(ms(1), 4)]
#[timeout(ms(10))]
#[case::fail_timeout(ms(60), 4)]
#[case::fail_value(ms(1), 5)]
#[timeout(ms(100))]
async fn group_one_timeout_override(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay).await);
}
struct S {}
#[rstest]
#[case(S{})]
async fn compile_with_no_copy_arg(#[case] _s: S) {
assert!(true);
}
#[fixture]
fn no_copy() -> S {
S {}
}
#[rstest]
fn compile_with_no_copy_fixture(_no_copy: S) {
assert!(true);
}
#[fixture]
async fn a_fix() -> S {
S {}
}
#[rstest]
fn compile_with_async_fixture(#[future] a_fix: S) {
assert!(true);
}
#[rstest]
async fn compile_with_async_awt_fixture(#[future(awt)] a_fix: S) {
assert!(true);
}
}
@@ -0,0 +1,17 @@
use rstest::*;
use std::time::Duration;
fn ms(ms: u32) -> Duration {
Duration::from_millis(ms.into())
}
async fn delayed_sum(a: u32, b: u32,delay: Duration) -> u32 {
async_std::task::sleep(delay).await;
a + b
}
#[rstest]
#[timeout(ms(80))]
async fn single_pass() {
assert_eq!(4, delayed_sum(2, 2, ms(10)).await);
}
@@ -0,0 +1,114 @@
use other_name::*;
use std::time::Duration;
fn ms(ms: u32) -> Duration {
Duration::from_millis(ms.into())
}
mod thread {
use super::*;
fn delayed_sum(a: u32, b: u32, delay: Duration) -> u32 {
std::thread::sleep(delay);
a + b
}
#[rstest]
#[timeout(ms(80))]
fn single_pass() {
assert_eq!(4, delayed_sum(2, 2, ms(10)));
}
#[rstest]
#[timeout(ms(100))]
fn single_fail_value() {
assert_eq!(5, delayed_sum(2, 2, ms(1)));
}
#[rstest]
#[timeout(ms(1000))]
#[should_panic = "user message"]
fn fail_with_user_message() {
panic!("user message");
}
#[rstest]
#[timeout(ms(10))]
fn single_fail_timeout() {
assert_eq!(4, delayed_sum(2, 2, ms(80)));
}
#[rstest]
#[timeout(ms(80))]
#[case(ms(10))]
fn one_pass(#[case] delay: Duration) {
assert_eq!(4, delayed_sum(2, 2, delay));
}
#[rstest]
#[timeout(ms(10))]
#[case(ms(80))]
fn one_fail_timeout(#[case] delay: Duration) {
assert_eq!(4, delayed_sum(2, 2, delay));
}
#[rstest]
#[timeout(ms(100))]
#[case(ms(1))]
fn one_fail_value(#[case] delay: Duration) {
assert_eq!(5, delayed_sum(2, 2, delay));
}
#[rstest]
#[case::pass(ms(1), 4)]
#[case::fail_timeout(ms(80), 4)]
#[case::fail_value(ms(1), 5)]
#[timeout(ms(40))]
fn group_same_timeout(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay));
}
#[rstest]
#[timeout(ms(100))]
#[case::pass(ms(1), 4)]
#[timeout(ms(30))]
#[case::fail_timeout(ms(70), 4)]
#[timeout(ms(100))]
#[case::fail_value(ms(1), 5)]
fn group_single_timeout(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay));
}
#[rstest]
#[case::pass(ms(1), 4)]
#[timeout(ms(10))]
#[case::fail_timeout(ms(60), 4)]
#[case::fail_value(ms(1), 5)]
#[timeout(ms(100))]
fn group_one_timeout_override(#[case] delay: Duration, #[case] expected: u32) {
assert_eq!(expected, delayed_sum(2, 2, delay));
}
struct S {}
#[rstest]
#[case(S{})]
fn compile_with_no_copy_arg(#[case] _s: S) {
assert!(true);
}
#[fixture]
fn no_copy() -> S {
S {}
}
#[rstest]
fn compile_with_no_copy_fixture(no_copy: S) {
assert!(true);
}
#[rstest]
fn default_timeout_failure() {
assert_eq!(4, delayed_sum(2, 2, ms(1100)));
}
}
@@ -0,0 +1,25 @@
use rstest::*;
#[fixture]
fn f() -> String {
"f".to_owned()
}
fn append(s: &mut String, a: &str) -> String {
s.push_str("-");
s.push_str(a);
s.clone()
}
#[rstest]
#[case(append(&mut f, "a"), "f-a", "f-a-b")]
fn use_mutate_fixture(
mut f: String,
#[case] a: String,
#[values(append(&mut f, "b"))] b: String,
#[case] expected_a: &str,
#[case] expected_b: &str,
) {
assert_eq!(expected_a, a);
assert_eq!(expected_b, b);
}
@@ -0,0 +1,21 @@
use rstest::*;
enum Application {
Python,
Node,
Go,
}
enum Method {
GET,
POST,
PUT,
HEAD,
}
#[rstest]
fn name_values(
#[values(Application::Python, Application::Node, Application::Go)] _val: Application,
#[values(Method::GET, Method::POST, Method::PUT, Method::HEAD)] _method: Method,
) {
}
File diff suppressed because it is too large Load Diff