Skip to main content

wowlab_test_support/
float.rs

1use googletest::{
2    matcher::Matcher,
3    matchers::{NearMatcher, near, predicate},
4};
5
6/// Default absolute tolerance for floating-point assertions.
7pub const TOL: f64 = 1e-9;
8
9/// Match one floating-point value within [`TOL`] of `expected`.
10#[must_use]
11pub fn near_tol(expected: f64) -> NearMatcher<f64> {
12    near(expected, TOL)
13}
14
15/// Match a slice element-by-element within [`TOL`] of `expected`.
16#[must_use]
17pub fn slice_near(expected: &[f64]) -> impl for<'a> Matcher<&'a [f64]> {
18    let expected = expected.to_vec();
19
20    predicate(move |actual: &[f64]| {
21        actual.len() == expected.len()
22            && actual
23                .iter()
24                .zip(&expected)
25                .all(|(actual, expected)| (actual - expected).abs() <= TOL)
26    })
27    .with_description(
28        "is element-wise near the expected slice",
29        "is not element-wise near the expected slice",
30    )
31}
32
33#[cfg(test)]
34mod tests {
35    use googletest::prelude::*;
36
37    use super::*;
38
39    #[gtest]
40    fn scalar_matcher_uses_default_tolerance() -> Result<()> {
41        verify_that!(1.0 + TOL / 2.0, near_tol(1.0))
42    }
43
44    #[gtest]
45    fn slice_matcher_checks_every_element() -> Result<()> {
46        verify_that!(&[1.0, 2.0 + TOL / 2.0][..], slice_near(&[1.0, 2.0]))
47    }
48}