rstest_test-0.11.0/.cargo_vcs_info.json0000644000000001510000000000100134730ustar { "git": { "sha1": "7ac624c3a54de3d7a1506441863562371c5a2359" }, "path_in_vcs": "rstest_test" }rstest_test-0.11.0/Cargo.toml0000644000000021650000000000100115000ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "rstest_test" version = "0.11.0" authors = ["Michele d'Amico "] description = """ Provides some utilities used by to write rstest crate's tests. """ homepage = "https://github.com/la10736/rstest" readme = "README.md" keywords = ["test"] categories = ["development-tools::testing"] license = "MIT/Apache-2.0" repository = "https://github.com/la10736/rstest" [dependencies.regex] version = "1.5.6" [dependencies.toml_edit] version = "0.19.0" [dev-dependencies.lazy_static] version = "1.4.0" [dev-dependencies.rstest] version = "0.16.0" default-features = false [dev-dependencies.temp_testdir] version = "0.2.3" rstest_test-0.11.0/Cargo.toml.orig000064400000000000000000000011171046102023000151550ustar 00000000000000[package] authors = ["Michele d'Amico "] categories = ["development-tools::testing"] description = """ Provides some utilities used by to write rstest crate's tests. """ edition = "2018" homepage = "https://github.com/la10736/rstest" keywords = ["test"] license = "MIT/Apache-2.0" name = "rstest_test" readme = "README.md" repository = "https://github.com/la10736/rstest" version = "0.11.0" [dependencies] regex = "1.5.6" toml_edit = "0.19.0" [dev-dependencies] lazy_static = "1.4.0" rstest = {version = "0.16.0", default-features = false} temp_testdir = "0.2.3" rstest_test-0.11.0/README.md000064400000000000000000000026231046102023000135500ustar 00000000000000[![Crate][crate-image]][crate-link] [![Status][test-action-image]][test-action-link] [![Apache 2.0 Licensed][license-apache-image]][license-apache-link] [![MIT Licensed][license-mit-image]][license-mit-link] # Helper crate for testing `rstest` crate This crate proivides a little framework for wrinting end to end test. You can crete rust project, add workspace modules and code file. Run `build` and `test` actions and write assertions based on passed and failed tests. Moreover give some utilities on assertions, strings manipulations and test name. This crate isn't designed for general pourpuse use but just as `rstest` develop helper crate. ## License Licensed under either of * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or [license-apache-link]) * MIT license [LICENSE-MIT](LICENSE-MIT) or [license-MIT-link] at your option. [//]: # (links) [crate-image]: https://img.shields.io/crates/v/rstest_test.svg [crate-link]: https://crates.io/crates/rstest_test [test-action-image]: https://github.com/la10736/rstest/workflows/Test/badge.svg [test-action-link]: https://github.com/la10736/rstest/actions?query=workflow:Test [license-apache-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg [license-mit-image]: https://img.shields.io/badge/license-MIT-blue.svg [license-apache-link]: http://www.apache.org/licenses/LICENSE-2.0 [license-MIT-link]: http://opensource.org/licenses/MIT rstest_test-0.11.0/checkoutlist.md000064400000000000000000000011441046102023000153110ustar 00000000000000# TODO list - [ ] Update rustup - [ ] Update dependency `cargo upgrade` - [ ] Run all test - [ ] Stable: `RSTEST_TEST_CHANNEL=stable; cargo +${RSTEST_TEST_CHANNEL} test` - [ ] Beta: `RSTEST_TEST_CHANNEL=beta; cargo +${RSTEST_TEST_CHANNEL} test` - [ ] Nightly: `RSTEST_TEST_CHANNEL=nightly; cargo +${RSTEST_TEST_CHANNEL} test` - [ ] Change next version - [ ] `Cargo.toml` - [ ] `README.md`) - [ ] Change dev-dependency version on `rstest_test` - [ ] `rstest` - [ ] `rstest_macro` - [ ] `rstest_reuse` - [ ] Check README - [ ] prepare deploy `cargo publish --dry-run` - [ ] deploy `cargo publish` rstest_test-0.11.0/src/lib.rs000064400000000000000000000001251046102023000141670ustar 00000000000000pub use regex; pub mod prj; pub mod utils; pub use prj::Project; pub use utils::*; rstest_test-0.11.0/src/prj.rs000064400000000000000000000153751046102023000142310ustar 00000000000000use std::{ self, ffi::{OsStr, OsString}, io::Write, path::{Path, PathBuf}, process::{Command, Stdio}, }; use std::borrow::Cow; use std::fs::{read_to_string, File}; use std::io::Read; use std::sync::Arc; use toml_edit::{Array, Document, Item, Table}; #[derive(Clone)] pub enum Channel { Stable, Beta, Nightly, Custom(String), } pub static CHANNEL_DEFAULT: Channel = Channel::Stable; pub static ENV_CHANNEL: &str = "RSTEST_TEST_CHANNEL"; impl From for Channel { fn from(value: String) -> Self { match value.to_lowercase().as_str() { "stable" => Channel::Stable, "beta" => Channel::Beta, "nightly" => Channel::Nightly, _ => Channel::Custom(value), } } } impl Default for Channel { fn default() -> Self { std::env::var(ENV_CHANNEL) .ok() .map(Channel::from) .unwrap_or_else(|| CHANNEL_DEFAULT.clone()) } } pub struct Project { pub name: OsString, root: PathBuf, channel: Channel, nocapture: bool, ws: Arc>, } impl Project { const GLOBAL_TEST_ATTR: &'static str = "#![cfg(test)]"; pub fn new>(root: P) -> Self { Self { root: root.as_ref().to_owned(), name: "project".into(), channel: Default::default(), nocapture: false, ws: Arc::new(std::sync::RwLock::new(())), } .create() } pub fn get_name(&self) -> Cow { self.name.to_string_lossy() } pub fn with_nocapture(mut self) -> Self { self.nocapture = true; self } pub fn subproject>(&self, name: O) -> Self { let _guard = self.ws.write().expect("Cannot lock workspace resource"); self.workspace_add(name.as_ref().to_str().unwrap()); Self { root: self.path(), name: name.as_ref().to_owned(), channel: self.channel.clone(), nocapture: self.nocapture, ws: self.ws.clone(), } .create() } pub fn name>(mut self, name: O) -> Self { self.name = name.as_ref().to_owned(); self } pub fn path(&self) -> PathBuf { self.root.join(&self.name) } pub fn run_tests(&self) -> Result { let _guard = self.ws.read().expect("Cannot lock workspace resource"); if !self.has_test_global_attribute(self.code_path()) { self.add_test_global_attribute(self.code_path()) } let mut cmd = Command::new("cargo"); cmd.current_dir(&self.path()) .arg(&self.cargo_channel_arg()) .arg("test"); if self.nocapture { cmd.args(["--", "--nocapture"]); } cmd.output() } pub fn compile(&self) -> Result { let _guard = self.ws.read().expect("Cannot lock workspace resource"); Command::new("cargo") .current_dir(&self.path()) .arg("build") .output() } fn create(self) -> Self { match Command::new("cargo") .current_dir(&self.root) .arg("init") .args(vec!["--edition", "2018"]) .arg(&self.name) .stdout(Stdio::null()) .stderr(Stdio::null()) .spawn() .unwrap() .wait() .unwrap() .code() .unwrap() { 0 => { std::fs::File::create(self.code_path()).unwrap(); self } code => panic!("cargo init return an error code: {}", code), } } fn has_test_global_attribute(&self, path: impl AsRef) -> bool { read_to_string(&path) .unwrap() .starts_with(Self::GLOBAL_TEST_ATTR) } fn add_test_global_attribute(&self, path: impl AsRef) { let body = read_to_string(&path).unwrap(); let mut out = std::fs::File::create(&path).unwrap(); write!(out, "{}", Self::GLOBAL_TEST_ATTR).unwrap(); write!(out, "{body}").unwrap(); } pub fn set_code_file>(self, src: P) -> Self { std::fs::copy(src, self.code_path()).unwrap(); self } pub fn append_code>(&self, code: S) { std::fs::OpenOptions::new() .append(true) .open(self.code_path()) .unwrap() .write_all(code.as_ref().as_ref()) .unwrap() } pub fn add_dependency(&self, crate_name: &str, attrs: &str) { let mut doc = self.read_cargo_toml(); doc["dependencies"].or_insert(Item::Table(Table::new()))[crate_name] .or_insert(Item::Value(attrs.parse().unwrap())); self.save_cargo_toml(&doc); } pub fn add_path_dependency(&self, name: &str, path: &str) { self.add_dependency(name, format!(r#"{{path="{path}"}}"#).as_str()); } pub fn add_local_dependency(&self, name: &str) { self.add_path_dependency(name, &self.exec_dir_str()); } pub fn exec_dir_str(&self) -> String { std::env::current_dir() .unwrap() .as_os_str() .to_str() .unwrap() .to_owned() } fn workspace_add(&self, prj: &str) { let mut doc = self.read_cargo_toml(); let members: Array = Array::default(); if let Some(members) = doc["workspace"].or_insert(Item::Table(Table::new()))["members"] .or_insert(Item::Value(members.into())) .as_array_mut() { members.push(prj) } self.save_cargo_toml(&doc); } fn code_path(&self) -> PathBuf { self.path().join("src").join("lib.rs") } fn cargo_toml_path(&self) -> PathBuf { let mut path = self.path(); path.push("Cargo.toml"); path } fn read_cargo_toml(&self) -> Document { let mut orig = String::new(); File::open(self.cargo_toml_path()) .expect("cannot open Cargo.toml") .read_to_string(&mut orig) .expect("cannot read Cargo.toml"); orig.parse::().expect("invalid Cargo.toml") } fn save_cargo_toml(&self, doc: &Document) { File::create(self.cargo_toml_path()) .expect("cannot update Cargo.toml") .write_all(doc.to_string().as_bytes()) .expect("cannot write Cargo.toml"); } fn cargo_channel_arg(&self) -> String { match &self.channel { Channel::Stable => "+stable".into(), Channel::Beta => "+beta".into(), Channel::Nightly => "+nightly".into(), Channel::Custom(name) => format!("+{name}"), } } } rstest_test-0.11.0/src/utils.rs000064400000000000000000000244211046102023000145660ustar 00000000000000use std::borrow::Cow; use std::thread; #[macro_export] macro_rules! assert_in { ($text:expr, $message:expr) => ({ match (&$text, &$message) { (text_val, message_val) => { if !text_val.contains(message_val) { panic!(r#"assertion failed: `text don't contain message` text: `{}`, message: `{}`"#, text_val, message_val) } } } }); ($text:expr, $message:expr, ) => ( assert_in!($text, $message) ); ($text:expr, $message:expr, $($arg:tt)+) => ({ match (&$text, &$message) { (text_val, message_val) => { if !text_val.contains(message_val) { panic!(r#"assertion failed: `text don't contain message` text: `{}`, message: `{}`: {}"#, text_val, message_val, format_args!($($arg)+)) } } } }); } #[macro_export] macro_rules! assert_all_in { ($text:expr, $expected:expr) => ( assert_in!($text, $expected) ); ($text:expr, $expected:expr, ) => ( assert_in!($text, $message) ); ($text:expr, $expected:expr, $( $others:expr ) ,+) => ( { assert_in!($text, $expected); assert_all_in!($text $(, $others)*); } ); } #[macro_export] macro_rules! assert_not_in { ($text:expr, $message:expr) => ({ match (&$text, &$message) { (text_val, message_val) => { if text_val.contains(message_val) { panic!(r#"assertion failed: `text contains message` text: `{}`, message: `{}`"#, text_val, message_val) } } } }); ($message:expr, $expected:expr, ) => ( assert_not_in!($message, $expected) ); ($text:expr, $message:expr, $($arg:tt)+) => ({ match (&$text, &$message) { (text_val, message_val) => { if text_val.contains(message_val) { panic!(r#"assertion failed: `text contains message` text: `{}`, message: `{}`: {}"#, text_val, message_val, format_args!($($arg)+)) } } } }); } #[macro_export] macro_rules! assert_regex { ($regex:expr, $text:expr) => ({ match (&$text, &$regex) { (text_val, regex_val) => { use $crate::regex::Regex; if !Regex::new(regex_val).unwrap().is_match(text_val) { panic!(r#"assertion failed: `text don't satisfy regex` regex: `{}`, text: `{}`"#, regex_val, text_val) } } } }); ($regex:expr, $message:expr, ) => ( assert_regex_in!($regex, $message) ); ($regex:expr, $text:expr, $($arg:tt)+) => ({ match (&$text, &$regex) { (text_val, regex_val) => { use $crate::regex::Regex; if !!Regex::new(regex_val).unwrap().is_match(text_val) { panic!(r#"assertion failed: `text don't satisfy regex` regex: `{}`, text: `{}`: {}"#, regex_val, text_val, format_args!($($arg)+)) } } } }); } #[derive(Clone)] pub(crate) struct TestInfo { exactly: bool, times: usize, } impl Default for TestInfo { fn default() -> Self { Self { exactly: true, times: 1, } } } #[derive(Clone)] pub(crate) enum TestResult> { Ok(S, TestInfo), Fail(S, TestInfo), } impl> TestResult { fn assert(&self, output: impl AsRef) { let regex = if self.exactly() { format!("test {}( - should panic)? ... {}", self.name(), self.msg()) } else { format!( "test .*{}.*( - should panic)? ... {}", self.name(), self.msg() ) }; match self.times() { 0 => {} 1 => { assert_regex!(regex, output.as_ref()); } n => { assert_regex!(regex, output.as_ref()); assert_eq!( n, output.count_regex(regex), "test {} is present but wrong count", self.name() ); } } } fn ok(name: S, exactly: bool, occurence: usize) -> Self { Self::Ok( name, TestInfo { exactly, times: occurence, }, ) } fn fail(name: S, exactly: bool, occurence: usize) -> Self { Self::Fail( name, TestInfo { exactly, times: occurence, }, ) } pub fn is_fail(&self) -> bool { use TestResult::*; matches!(*self, Fail(_, _)) } #[allow(dead_code)] pub fn is_ok(&self) -> bool { use self::TestResult::*; matches!(*self, Ok(_, _)) } pub fn name(&self) -> String { use self::TestResult::*; match *self { Ok(ref s, _) => s.as_ref().to_owned(), Fail(ref s, _) => s.as_ref().to_owned(), } } pub fn msg(&self) -> &'static str { use self::TestResult::*; match *self { Ok(_, _) => "ok", Fail(_, _) => "FAILED", } } fn info(&self) -> &TestInfo { match self { TestResult::Ok(_, o) => o, TestResult::Fail(_, o) => o, } } fn exactly(&self) -> bool { self.info().exactly } fn times(&self) -> usize { self.info().times } } #[derive(Default, Clone)] pub struct TestResults where S: AsRef + Clone, { results: Vec>, contains: bool, } impl TestResults where S: AsRef + Clone, { pub fn new() -> Self { TestResults { results: vec![], contains: false, } } pub fn with_contains(self, contains: bool) -> Self { Self { results: self.results, contains, } } pub fn ok_with(self, name: S, exactly: bool, occurence: usize) -> Self { self.append(TestResult::ok(name, exactly, occurence)) } pub fn fail_with(self, name: S, exactly: bool, occurence: usize) -> Self { self.append(TestResult::fail(name, exactly, occurence)) } pub fn ok(self, name: S) -> Self { let contains = self.contains; self.ok_with(name, !contains, 1) } pub fn fail(self, name: S) -> Self { let contains = self.contains; self.fail_with(name, !contains, 1) } pub fn ok_in(self, name: S) -> Self { self.ok_with(name, false, 1) } pub fn fail_in(self, name: S) -> Self { self.fail_with(name, false, 1) } pub fn ok_times(self, name: S, occurence: usize) -> Self { let contains = self.contains; self.ok_with(name, !contains, occurence) } pub fn fail_times(self, name: S, occurence: usize) -> Self { let contains = self.contains; self.fail_with(name, !contains, occurence) } pub(crate) fn append(mut self, test: TestResult) -> Self { self.results.push(test); self } pub fn assert(&self, output: ::std::process::Output) { let (expected_code, msg) = if !self.should_fail() { (0, "Unexpected fails!") } else { (101, "Some test should fail!") }; assert_eq!( Some(expected_code), output.status.code(), "{}\n Console: \nOUT:\n{}\nERR:\n{}\n", msg, output.stdout.str(), output.stderr.str() ); let stderr = output.stderr.str(); let output = output.stdout.str(); if output.is_empty() { eprintln!("Stderr: {stderr}"); panic!("Empty stdout!"); } assert_in!(output, format!("running {} test", self.count_tests())); self.for_each(|t| t.assert(output.as_ref())); if self.should_fail() { assert_in!(output, "failures:".to_string()); } self.for_each_failed(|t| assert_in!(output, format!(" {}", t.name()))); } fn should_fail(&self) -> bool { self.results.iter().any(|r| r.is_fail()) } fn for_each)>(&self, action: F) { self.results.iter().for_each(action) } fn for_each_failed)>(&self, action: F) { self.results.iter().filter(|r| r.is_fail()).for_each(action) } fn count_tests(&self) -> usize { self.results.iter().map(|t| t.times()).sum() } } pub trait Stringable { fn str(&self) -> Cow; } impl> Stringable for B { fn str(&self) -> Cow { String::from_utf8_lossy(self.as_ref()) } } pub fn testname() -> String { thread::current().name().unwrap().to_string() } pub trait CountMessageOccurrence { fn count>(&self, message: S) -> usize; fn count_regex>(&self, message: S) -> usize; } impl CountMessageOccurrence for ST where ST: AsRef, { fn count>(&self, message: S) -> usize { self.as_ref() .lines() .filter(|line| line.contains(message.as_ref())) .count() } fn count_regex>(&self, regex: S) -> usize { let regex = regex::Regex::new(regex.as_ref()).unwrap(); self.as_ref() .lines() .filter(|line| regex.is_match(line)) .count() } } #[cfg(test)] mod test { use super::*; #[test] fn should_count_message_occurence() { let foo_occurences = " foobaz bar foobazfoo baz foo " .count("foo"); assert_eq!(3, foo_occurences); } #[test] fn should_count_regex_occurence() { let message = " 123 aa2bb abc 2aa foo " .count_regex(r"\d+"); assert_eq!(3, message); } #[test] fn should_get_test_path() { use super::*; assert_eq!("utils::test::should_get_test_path", testname()); } } pub fn sanitize_name>(s: S) -> String { s.as_ref().replace(':', "_").replace("__", "_") } rstest_test-0.11.0/tests/framework.rs000064400000000000000000000143541046102023000160020ustar 00000000000000use lazy_static::lazy_static; use temp_testdir::TempDir; use rstest::rstest; use rstest_test::*; lazy_static! { static ref ROOT_DIR: TempDir = TempDir::default().permanent(); static ref ROOT_PROJECT: Project = Project::new(ROOT_DIR.as_ref()); } fn prj() -> Project { let prj_name = sanitize_name(utils::testname()); ROOT_PROJECT.subproject(&prj_name) } #[rstest] #[case::default_conf(TestResults::new())] #[case::contains(TestResults::new().with_contains(true))] fn one_success(#[case] results: TestResults<&str>) { let project = prj(); project.append_code( r#" #[test] fn success() { assert!(true); } "#, ); let output = project.run_tests().unwrap(); results.ok("success").assert(output); } #[rstest] #[case::default_conf(TestResults::new())] #[case::contains(TestResults::new().with_contains(true))] fn one_fail(#[case] results: TestResults<&str>) { let project = prj(); project.append_code( r#" #[test] fn fail() { assert!(false); } "#, ); let output = project.run_tests().unwrap(); results.fail("fail").assert(output); } #[rstest] #[case::default_conf(TestResults::new())] #[case::contains(TestResults::new().with_contains(true))] fn more_tests(#[case] results: TestResults<&str>) { let project = prj(); project.append_code( r#" #[test] fn success() { assert!(true); } #[test] fn fail() { assert!(false); } #[test] fn eq() { assert_eq!(1, 1); } #[test] fn no_eq() { assert_eq!(1, 2); } "#, ); let output = project.run_tests().unwrap(); results .ok("success") .ok("eq") .fail("fail") .fail("no_eq") .assert(output); } #[rstest] #[case::default_conf(TestResults::new())] #[case::contains(TestResults::new().with_contains(true))] fn tests_with_should_panic(#[case] results: TestResults<&str>) { let project = prj(); project.append_code( r#" #[test] #[should_panic] fn success() { assert!(false); } #[test] #[should_panic] fn fail() { assert!(true); } "#, ); let output = project.run_tests().unwrap(); results.ok("success").fail("fail").assert(output); } #[test] fn should_check_just_contains_conf() { let project = prj(); project.append_code( r#" #[test] fn success() { assert!(true); } #[test] fn fail() { assert!(false); } #[test] fn eq() { assert_eq!(1, 1); } #[test] fn two_eq() { assert_eq!(2, 2); } #[test] fn enq() { assert_eq!(1, 2); } #[test] fn two_enq() { assert_eq!(1, 3); } "#, ); let output = project.run_tests().unwrap(); let results = TestResults::new().with_contains(true); results .ok("suc") .ok_times("eq", 2) .fail("fai") .fail_times("enq", 2) .assert(output); } #[test] fn should_check_just_contains_on_some_test() { let project = prj(); project.append_code( r#" #[test] fn success() { assert!(true); } #[test] fn fail() { assert!(false); } #[test] fn eq() { assert_eq!(1, 1); } #[test] fn two_eq() { assert_eq!(2, 2); } #[test] fn enq() { assert_eq!(1, 2); } #[test] fn two_enq() { assert_eq!(1, 3); } "#, ); let output = project.run_tests().unwrap(); let results = TestResults::new(); results .ok("success") .ok_with("eq", false, 2) .fail("fail") .fail("enq") .fail("two_enq") .assert(output); } #[test] fn should_check_some_tests_as_contains() { let project = prj(); project.append_code( r#" #[test] fn case_1() { assert!(true); } #[test] fn case_2_aa() { assert!(true); } #[test] fn case_3_b() { assert!(false); } "#, ); let output = project.run_tests().unwrap(); let results = TestResults::new(); results .ok("case_1") .ok_in("case_2") .fail_in("case_3") .assert(output); } #[test] #[should_panic] fn should_dont_wrongly_check_contains() { let project = prj(); project.append_code( r#" #[test] fn case_1_aa() { assert!(true); } "#, ); let output = project.run_tests().unwrap(); let results = TestResults::new(); results.ok("case_1").assert(output); } #[test] #[should_panic(expected = "but wrong count")] fn should_detect_wrong_contains() { let project = prj(); project.append_code( r#" #[test] fn case_1() { assert!(true); } #[test] fn case_2() { assert!(true); } #[test] fn case_3() { assert!(true); } "#, ); let output = project.run_tests().unwrap(); let results = TestResults::new(); results .ok("case_3") .ok_with("case", false, 2) .assert(output); } #[test] fn nocapture_in_tests() { let project = prj().with_nocapture(); project.append_code( r#" #[test] fn success() { println!("Some output"); } "#, ); let output = project.run_tests().unwrap(); assert_in!(output.stdout.str(), "Some output") } #[test] fn add_local_dependency() { let project = prj(); project.add_local_dependency("rstest_test"); project.append_code( r#" use rstest_test::assert_in; #[test] fn success() { assert_in!("foo bar baz", "bar"); } "#, ); let output = project.run_tests().unwrap(); TestResults::new().ok("success").assert(output); } rstest_test-0.11.0/tests/macros.rs000064400000000000000000000051011046102023000152570ustar 00000000000000use rstest_test::{assert_all_in, assert_in, assert_not_in, assert_regex}; #[test] fn assert_in_should_find_string() { assert_in!( "messege that firtspart continue. some other", "part cont" ); } #[test] #[should_panic] fn assert_in_should_panic_if_no_string_in_message() { assert_in!( "messege that firtspart continue. some other", "something else" ); } #[test] #[should_panic] fn assert_in_should_panic_if_empty() { assert_in!("", "a"); } #[test] #[should_panic(expected = "supercalifragili")] fn assert_in_should_yield_text_if_fail() { assert_in!("supercalifragili", "x"); } #[test] #[should_panic(expected = "xxx")] fn assert_in_should_yield_message_if_fail() { assert_in!("supercalifragili", "xxx"); } #[test] fn assert_all_in_should_check_all_clause() { assert_all_in!("supercalifragili", "ercal", "alifrag", "percal"); } #[test] #[should_panic(expected = "xxx")] fn assert_all_in_should_check_all_clause_and_fail() { assert_all_in!("supercalifragili", "ercal", "alifrag", "xxx"); } #[test] #[should_panic(expected = "xxx")] fn assert_all_in_should_raise_the_first_that_didnt_match() { assert_all_in!("supercalifragili", "ercal", "xxx", "yyy", "lifragi"); } #[test] #[should_panic] fn assert_not_in_should_find_string() { assert_not_in!( "messege that firtspart continue. some other", "part cont" ); } #[test] fn assert_not_in_pass_if_no_string_in_message() { assert_not_in!( "messege that firtspart continue. some other", "something else" ); } #[test] fn assert_not_in_should_pass_if_empty() { assert_not_in!("", "a"); } #[test] #[should_panic(expected = "supercalifragili")] fn assert_not_in_should_yield_text_if_fail() { assert_not_in!("supercalifragili", "rcal"); } #[test] #[should_panic(expected = "rcal")] fn assert_not_in_should_yield_message_if_fail() { assert_not_in!("supercalifragili", "rcal"); } #[test] fn assert_regex_should_find_string() { assert_regex!( "ege .+ firts", "messege that firtspart continue. some other" ); } #[test] #[should_panic] fn assert_regex_should_panic_if_message_dont_match() { assert_regex!("ege .*", "something else"); } #[test] #[should_panic(expected = "supercalifragili")] fn assert_regex_should_yield_text_if_fail() { assert_regex!("x", "supercalifragili"); } #[test] #[should_panic(expected = "xxx")] fn assert_regex_should_yield_regex_if_fail() { assert_regex!("xxx", "supercalifragili"); } rstest_test-0.11.0/todo.md000064400000000000000000000000141046102023000135500ustar 00000000000000# TODO list