extern crate ntest_test_cases;
extern crate ntest_timeout;
#[doc(inline)]
pub use ntest_test_cases::test_case;
#[doc(inline)]
pub use ntest_timeout::timeout;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
mod traits;
#[doc(inline)]
pub use crate::traits::MaxDifference;
#[doc(hidden)]
pub fn execute_with_timeout<T: Send>(
code: &'static (dyn Fn() -> T + Sync + 'static),
timeout_ms: u64,
) -> Option<T> {
let (sender, receiver) = mpsc::channel();
thread::spawn(move || if let Ok(()) = sender.send(code()) {});
match receiver.recv_timeout(Duration::from_millis(timeout_ms)) {
Ok(t) => Some(t),
Err(_) => None,
}
}
#[doc(hidden)]
pub fn about_eq<T: MaxDifference>(a: T, b: T, eps: f64) -> bool {
a.max_diff(b) < eps
}
#[macro_export]
macro_rules! assert_about_eq {
($a:expr, $b:expr, $eps:expr) => {
let eps = $eps;
assert!(
$crate::about_eq($a, $b, eps),
"assertion failed: `(left !== right)` \
(left: `{:?}`, right: `{:?}`, epsilon: `{:?}`)",
$a,
$b,
eps
);
};
($a:expr, $b:expr,$eps:expr,) => {
assert_about_eq!($a, $b, $eps);
};
($a:expr, $b:expr) => {
assert_about_eq!($a, $b, 1.0e-6);
};
($a:expr, $b:expr,) => {
assert_about_eq!($a, $b, 1.0e-6);
};
}
#[macro_export]
macro_rules! assert_true {
($x:expr) => {
if !$x {
panic!("assertion failed: Expected 'true', but was 'false'");
}
};
($x:expr,) => {
assert_true!($x);
};
}
#[macro_export]
macro_rules! assert_false {
($x:expr) => {{
if $x {
panic!("assertion failed: Expected 'false', but was 'true'");
}
}};
($x:expr,) => {{
assert_false!($x);
}};
}
#[macro_export]
macro_rules! assert_panics {
($x:block) => {{
let result = std::panic::catch_unwind(|| $x);
if !result.is_err() {
panic!("assertion failed: code in block did not panic");
}
}};
($x:block,) => {{
assert_panics!($x);
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn assert_true() {
assert_true!(true);
}
#[test]
#[should_panic]
fn assert_true_fails() {
assert_true!(false);
}
#[test]
fn assert_true_trailing_comma() {
assert_true!(true,);
}
#[test]
fn assert_false() {
assert_false!(false);
}
#[test]
#[should_panic]
fn assert_false_fails() {
assert_false!(true);
}
#[test]
fn assert_false_trailing_comma() {
assert_false!(false,);
}
#[test]
fn assert_panics() {
assert_panics!({ panic!("I am panicing!") },);
}
#[test]
#[should_panic]
fn assert_panics_fails() {
assert_panics!({ println!("I am not panicing!") },);
}
#[test]
fn assert_panics_trailing_comma() {
assert_panics!({ panic!("I am panicing!") },);
}
#[test]
fn vector() {
assert_about_eq!(vec![1.1, 2.1], vec![1.1, 2.1]);
}
#[test]
#[should_panic]
fn vector_fails() {
assert_about_eq!(vec![1.2, 2.1], vec![1.1, 2.1]);
}
#[test]
fn vector_trailing_comma() {
assert_about_eq!(vec![1.2, 2.1], vec![1.2, 2.1],);
}
#[test]
fn vector_trailing_comma_with_epsilon() {
assert_about_eq!(vec![1.100000001, 2.1], vec![1.1, 2.1], 0.001f64,);
}
#[test]
fn it_should_not_panic_if_values_are_approx_equal() {
assert_about_eq!(64f32.sqrt(), 8f32);
}
#[test]
fn about_equal_f32() {
assert_about_eq!(3f32, 3f32, 1f64);
}
#[test]
fn about_equal_f64() {
assert_about_eq!(3f64, 3f64);
}
#[test]
fn compare_with_epsilon() {
assert_about_eq!(42f64, 43f64, 2f64);
}
#[test]
#[should_panic]
fn fail_with_epsilon() {
assert_about_eq!(3f64, 4f64, 1e-8f64);
}
}