This is an automated email from the ASF dual-hosted git repository.
tisonkun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datasketches-rust.git
The following commit(s) were added to refs/heads/main by this push:
new f876679 test: standardize assertions with googletest matchers (#213)
f876679 is described below
commit f876679307ff11a6a431c88e678ba0aaacb11218
Author: tison <[email protected]>
AuthorDate: Tue Aug 25 09:55:18 2026 +0800
test: standardize assertions with googletest matchers (#213)
---
Cargo.lock | 10 --
Cargo.toml | 1 -
datasketches/Cargo.toml | 1 -
datasketches/src/hll/array4.rs | 33 +++---
datasketches/src/hll/array6.rs | 22 ++--
datasketches/src/hll/array8.rs | 22 ++--
datasketches/src/hll/composite_interpolation.rs | 14 +--
datasketches/src/hll/estimator.rs | 16 +--
datasketches/src/hll/harmonic_numbers.rs | 25 +++--
datasketches/src/req/compactor.rs | 9 +-
datasketches/src/req/sorted_view.rs | 39 ++++---
.../src/thetafamily/common/binomial_bounds.rs | 39 ++++---
datasketches/src/thetafamily/theta/sketch.rs | 10 +-
datasketches/tests/bloom_test/sketch.rs | 18 ++--
datasketches/tests/frequencies_test/update.rs | 43 ++++----
datasketches/tests/hll_test/union.rs | 114 +++++++-------------
datasketches/tests/hll_test/update.rs | 117 ++++++---------------
datasketches/tests/req_test/accuracy.rs | 10 +-
datasketches/tests/req_test/bounds.rs | 36 +++----
datasketches/tests/req_test/core.rs | 106 ++++++++++++-------
datasketches/tests/req_test/merge.rs | 24 +++--
datasketches/tests/req_test/query.rs | 63 +++++------
datasketches/tests/req_test/sorted_view_api.rs | 48 +++++----
datasketches/tests/req_test/structure.rs | 30 ++++--
datasketches/tests/req_test/union.rs | 19 +++-
datasketches/tests/serde_tests/bloom.rs | 9 +-
datasketches/tests/serde_tests/frequencies.rs | 18 ++--
datasketches/tests/serde_tests/hll.rs | 29 +++--
datasketches/tests/serde_tests/req.rs | 75 +++++--------
datasketches/tests/serde_tests/tdigest.rs | 9 +-
datasketches/tests/serde_tests/tuple.rs | 5 +-
datasketches/tests/tdigest_test/sketch.rs | 6 +-
datasketches/tests/theta_test/a_not_b.rs | 21 ++--
datasketches/tests/theta_test/intersection.rs | 28 +++--
.../tests/theta_test/jaccard_similarity.rs | 23 ++--
datasketches/tests/theta_test/sketch.rs | 57 +++++-----
datasketches/tests/theta_test/union.rs | 35 +++---
datasketches/tests/tuple_test/a_not_b.rs | 9 +-
datasketches/tests/tuple_test/intersection.rs | 9 +-
.../tests/tuple_test/jaccard_similarity.rs | 23 ++--
datasketches/tests/tuple_test/sketch.rs | 12 ++-
datasketches/tests/tuple_test/union.rs | 9 +-
42 files changed, 627 insertions(+), 619 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index a29494c..8ad1542 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -67,15 +67,6 @@ dependencies = [
"windows-sys 0.61.2",
]
-[[package]]
-name = "approx"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
-dependencies = [
- "num-traits",
-]
-
[[package]]
name = "autocfg"
version = "1.5.1"
@@ -237,7 +228,6 @@ dependencies = [
name = "datasketches"
version = "0.4.0"
dependencies = [
- "approx",
"divan",
"googletest",
"insta",
diff --git a/Cargo.toml b/Cargo.toml
index 7d8c74f..42c554d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,7 +32,6 @@ rust-version = "1.86.0"
datasketches = { path = "datasketches" }
# Crates.io dependencies
-approx = { version = "0.5" }
clap = { version = "4.6.5", features = ["derive"] }
divan = { version = "0.1.21" }
googletest = { version = "0.14.3" }
diff --git a/datasketches/Cargo.toml b/datasketches/Cargo.toml
index 7afa4bd..6f7f4d7 100644
--- a/datasketches/Cargo.toml
+++ b/datasketches/Cargo.toml
@@ -104,7 +104,6 @@ rand = { workspace = true, optional = true }
[dev-dependencies]
divan = { workspace = true }
-approx = { workspace = true }
googletest = { workspace = true }
insta = { workspace = true }
proptest = { workspace = true }
diff --git a/datasketches/src/hll/array4.rs b/datasketches/src/hll/array4.rs
index 2ed8888..7438175 100644
--- a/datasketches/src/hll/array4.rs
+++ b/datasketches/src/hll/array4.rs
@@ -439,6 +439,12 @@ impl Array4 {
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::gt;
+ use googletest::prelude::is_finite;
+ use googletest::prelude::lt;
+ use googletest::prelude::none;
+
use super::*;
use crate::hll::Coupon;
@@ -480,20 +486,14 @@ mod tests {
// (not exact, but should be non-zero and not NaN/Inf)
let estimate = arr.estimate();
- assert!(estimate > 0.0, "Estimate should be positive");
- assert!(estimate.is_finite(), "Estimate should be finite");
- assert!(estimate < 100_000.0, "Estimate should be reasonable");
+ assert_that!(estimate, gt(0.0));
+ assert_that!(estimate, is_finite());
+ assert_that!(estimate, lt(100_000.0));
// Rough sanity check: with 100 updates to different slots,
// estimate should be in a reasonable range (very loose bounds)
- assert!(
- estimate > 1_000.0,
- "Estimate seems too low for 10_000 updates"
- );
- assert!(
- estimate < 100_000.0,
- "Estimate seems too high for 10_000 updates"
- );
+ assert_that!(estimate, gt(1_000.0));
+ assert_that!(estimate, lt(100_000.0));
}
#[test]
@@ -507,14 +507,11 @@ mod tests {
// Verify registers were updated (not exact values, just check they
changed)
// kxq0 should have decreased (we removed a 0 and added a 10)
// Initial kxq0 = 256 (all zeros = 1.0 each)
- assert!(arr.estimator.kxq0() < 256.0, "kxq0 should have decreased");
+ assert_that!(arr.estimator.kxq0(), lt(256.0));
// kxq1 should have a small positive value (from 1/2^40)
- assert!(arr.estimator.kxq1() > 0.0, "kxq1 should be positive");
- assert!(
- arr.estimator.kxq1() < 0.001,
- "kxq1 should be small (1/2^40 is tiny)"
- );
+ assert_that!(arr.estimator.kxq1(), gt(0.0));
+ assert_that!(arr.estimator.kxq1(), lt(0.001));
}
#[test]
@@ -535,7 +532,7 @@ mod tests {
assert_eq!(arr.num_at_cur_min, num_slots - 1);
assert_eq!(arr.get_raw(0), 14);
assert_eq!(arr.get(0), 15);
- assert!(arr.aux_map.is_none());
+ assert_that!(arr.aux_map, none());
for slot in 1..num_slots {
assert_eq!(arr.get(slot), 1);
diff --git a/datasketches/src/hll/array6.rs b/datasketches/src/hll/array6.rs
index 2fc756c..24ef2cb 100644
--- a/datasketches/src/hll/array6.rs
+++ b/datasketches/src/hll/array6.rs
@@ -288,6 +288,11 @@ fn num_bytes_for_k(k: u32) -> usize {
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::gt;
+ use googletest::prelude::is_finite;
+ use googletest::prelude::lt;
+
use super::*;
use crate::hll::Coupon;
@@ -367,12 +372,12 @@ mod tests {
let estimate = arr.estimate();
// Sanity checks
- assert!(estimate > 0.0, "Estimate should be positive");
- assert!(estimate.is_finite(), "Estimate should be finite");
+ assert_that!(estimate, gt(0.0));
+ assert_that!(estimate, is_finite());
// Rough bounds for 10K unique items (very loose)
- assert!(estimate > 1_000.0, "Estimate seems too low");
- assert!(estimate < 100_000.0, "Estimate seems too high");
+ assert_that!(estimate, gt(1_000.0));
+ assert_that!(estimate, lt(100_000.0));
}
#[test]
@@ -398,13 +403,10 @@ mod tests {
arr.update(Coupon::pack(1, 40)); // value >= 32, goes to kxq1
// Initial kxq0 = 256 (all zeros = 1.0 each)
- assert!(arr.estimator.kxq0() < 256.0, "kxq0 should have decreased");
+ assert_that!(arr.estimator.kxq0(), lt(256.0));
// kxq1 should have a small positive value (from 1/2^40)
- assert!(arr.estimator.kxq1() > 0.0, "kxq1 should be positive");
- assert!(
- arr.estimator.kxq1() < 0.001,
- "kxq1 should be small (1/2^40 is tiny)"
- );
+ assert_that!(arr.estimator.kxq1(), gt(0.0));
+ assert_that!(arr.estimator.kxq1(), lt(0.001));
}
}
diff --git a/datasketches/src/hll/array8.rs b/datasketches/src/hll/array8.rs
index b06e5ed..45df645 100644
--- a/datasketches/src/hll/array8.rs
+++ b/datasketches/src/hll/array8.rs
@@ -353,6 +353,11 @@ impl Array8 {
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::gt;
+ use googletest::prelude::is_finite;
+ use googletest::prelude::lt;
+
use super::*;
use crate::hll::Coupon;
@@ -426,12 +431,12 @@ mod tests {
let estimate = arr.estimate();
// Sanity checks
- assert!(estimate > 0.0, "Estimate should be positive");
- assert!(estimate.is_finite(), "Estimate should be finite");
+ assert_that!(estimate, gt(0.0));
+ assert_that!(estimate, is_finite());
// Rough bounds for 10K unique items (very loose)
- assert!(estimate > 1_000.0, "Estimate seems too low");
- assert!(estimate < 100_000.0, "Estimate seems too high");
+ assert_that!(estimate, gt(1_000.0));
+ assert_that!(estimate, lt(100_000.0));
}
#[test]
@@ -477,14 +482,11 @@ mod tests {
arr.update(Coupon::pack(1, 50)); // value >= 32, goes to kxq1
// Initial kxq0 = 256 (all zeros = 1.0 each)
- assert!(arr.estimator.kxq0() < 256.0, "kxq0 should have decreased");
+ assert_that!(arr.estimator.kxq0(), lt(256.0));
// kxq1 should have a positive value (from 1/2^50)
- assert!(arr.estimator.kxq1() > 0.0, "kxq1 should be positive");
- assert!(
- arr.estimator.kxq1() < 1e-10,
- "kxq1 should be very small (1/2^50 ≈ 8.9e-16)"
- );
+ assert_that!(arr.estimator.kxq1(), gt(0.0));
+ assert_that!(arr.estimator.kxq1(), lt(1e-10));
}
#[test]
diff --git a/datasketches/src/hll/composite_interpolation.rs
b/datasketches/src/hll/composite_interpolation.rs
index 8bf1e79..9f2083e 100644
--- a/datasketches/src/hll/composite_interpolation.rs
+++ b/datasketches/src/hll/composite_interpolation.rs
@@ -4748,6 +4748,10 @@ static ARRAYS: [[f64; NUM_X_VALUES]; 18] = [
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::gt;
+ use googletest::prelude::near;
+
use super::*;
#[test]
@@ -4787,8 +4791,8 @@ mod tests {
assert_eq!(x_arr.len(), 257);
// Check first few values match the C++ data
- assert!((x_arr[0] - 10.767999803534).abs() < 1e-6);
- assert!((x_arr[1] - 11.237701481774).abs() < 1e-6);
+ assert_that!(x_arr[0], near(10.767999803534, 1e-6));
+ assert_that!(x_arr[1], near(11.237701481774, 1e-6));
}
#[test]
@@ -4796,11 +4800,7 @@ mod tests {
// X array should be strictly increasing
let x_arr = get_x_arr(8);
for i in 1..x_arr.len() {
- assert!(
- x_arr[i] > x_arr[i - 1],
- "X array should be monotonically increasing at index {}",
- i
- );
+ assert_that!(x_arr[i], gt(x_arr[i - 1]), "index: {i}");
}
}
}
diff --git a/datasketches/src/hll/estimator.rs
b/datasketches/src/hll/estimator.rs
index f5b4652..e81a859 100644
--- a/datasketches/src/hll/estimator.rs
+++ b/datasketches/src/hll/estimator.rs
@@ -492,6 +492,10 @@ static NON_HIP_UB: [f64; 27] = [
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::gt;
+ use googletest::prelude::lt;
+
use super::*;
#[test]
@@ -512,10 +516,10 @@ mod tests {
est.update(8, 0, 10);
// HIP should have increased
- assert!(est.hip_accum() > 0.0);
+ assert_that!(est.hip_accum(), gt(0.0));
// kxq0 should have changed (10 < 32)
- assert!(est.kxq0() < 256.0);
+ assert_that!(est.kxq0(), lt(256.0));
assert_eq!(est.kxq1(), 0.0); // kxq1 unchanged
}
@@ -528,7 +532,7 @@ mod tests {
let kxq0_after_10 = est.kxq0();
let kxq1_after_10 = est.kxq1();
- assert!(kxq0_after_10 < 256.0);
+ assert_that!(kxq0_after_10, lt(256.0));
assert_eq!(kxq1_after_10, 0.0);
// Update from 10 to 50 (crosses the 32 boundary)
@@ -536,8 +540,8 @@ mod tests {
let kxq0_after_50 = est.kxq0();
let kxq1_after_50 = est.kxq1();
- assert!(kxq0_after_50 < kxq0_after_10); // Removed 1/2^10 from kxq0
(decreases kxq0)
- assert!(kxq1_after_50 > 0.0); // Added 1/2^50 to kxq1
+ assert_that!(kxq0_after_50, lt(kxq0_after_10)); // Removed 1/2^10 from
kxq0 (decreases kxq0)
+ assert_that!(kxq1_after_50, gt(0.0)); // Added 1/2^50 to kxq1
}
#[test]
@@ -547,7 +551,7 @@ mod tests {
// Normal update
est.update(8, 0, 5);
let hip_normal = est.hip_accum();
- assert!(hip_normal > 0.0);
+ assert_that!(hip_normal, gt(0.0));
// Set out-of-order
est.set_out_of_order(true);
diff --git a/datasketches/src/hll/harmonic_numbers.rs
b/datasketches/src/hll/harmonic_numbers.rs
index dea7141..649ab22 100644
--- a/datasketches/src/hll/harmonic_numbers.rs
+++ b/datasketches/src/hll/harmonic_numbers.rs
@@ -104,18 +104,23 @@ pub fn bitmap_estimate(bit_vector_length: u32,
num_bits_set: u32) -> f64 {
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::gt;
+ use googletest::prelude::lt;
+ use googletest::prelude::near;
+
use super::*;
#[test]
fn test_exact_harmonic_numbers() {
// H(1) = 1
- assert!((harmonic_number(1) - 1.0).abs() < 1e-10);
+ assert_that!(harmonic_number(1), near(1.0, 1e-10));
// H(2) = 1 + 1/2 = 1.5
- assert!((harmonic_number(2) - 1.5).abs() < 1e-10);
+ assert_that!(harmonic_number(2), near(1.5, 1e-10));
// H(3) = 1 + 1/2 + 1/3 = 11/6
- assert!((harmonic_number(3) - 11.0 / 6.0).abs() < 1e-10);
+ assert_that!(harmonic_number(3), near(11.0 / 6.0, 1e-10));
// H(10) should be exact from table
let expected = 1.0
@@ -128,7 +133,7 @@ mod tests {
+ 1.0 / 8.0
+ 1.0 / 9.0
+ 1.0 / 10.0;
- assert!((harmonic_number(10) - expected).abs() < 1e-10);
+ assert_that!(harmonic_number(10), near(expected, 1e-10));
}
#[test]
@@ -139,14 +144,14 @@ mod tests {
let approx = (n as f64).ln() + EULER_MASCHERONI + 1.0 / (2.0 * n as
f64);
// Should be close (within 0.1%)
- assert!((h_n - approx).abs() / h_n < 0.001);
+ assert_that!(h_n, near(approx, h_n * 0.001));
}
#[test]
fn test_bitmap_estimate_empty() {
// No bits set = estimate should be near 0
let est = bitmap_estimate(1024, 0);
- assert!(est.abs() < 1e-6);
+ assert_that!(est, near(0.0, 1e-6));
}
#[test]
@@ -156,11 +161,11 @@ mod tests {
let est = bitmap_estimate(k, k);
// With all slots hit, estimate should be >> k
- assert!(est > k as f64);
+ assert_that!(est, gt(k as f64));
// H(k) - H(0) = H(k), so estimate = k * H(k)
let expected = k as f64 * harmonic_number(k as usize);
- assert!((est - expected).abs() < 1e-6);
+ assert_that!(est, near(expected, 1e-6));
}
#[test]
@@ -170,7 +175,7 @@ mod tests {
let est = bitmap_estimate(k, k / 2);
// Should be between 0 and k * H(k)
- assert!(est > 0.0);
- assert!(est < k as f64 * harmonic_number(k as usize));
+ assert_that!(est, gt(0.0));
+ assert_that!(est, lt(k as f64 * harmonic_number(k as usize)));
}
}
diff --git a/datasketches/src/req/compactor.rs
b/datasketches/src/req/compactor.rs
index 81d9d7a..746e614 100644
--- a/datasketches/src/req/compactor.rs
+++ b/datasketches/src/req/compactor.rs
@@ -486,6 +486,9 @@ where
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::ge;
+
use super::*;
#[test]
@@ -596,10 +599,6 @@ mod tests {
a.merge(&b);
- assert!(
- a.num_sections >= 12,
- "merge must loop ensure_enough_sections; got num_sections={}
(single-call would yield 6)",
- a.num_sections
- );
+ assert_that!(a.num_sections, ge(12));
}
}
diff --git a/datasketches/src/req/sorted_view.rs
b/datasketches/src/req/sorted_view.rs
index 337f0c6..312adf8 100644
--- a/datasketches/src/req/sorted_view.rs
+++ b/datasketches/src/req/sorted_view.rs
@@ -273,6 +273,14 @@ where
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::all;
+ use googletest::prelude::anything;
+ use googletest::prelude::err;
+ use googletest::prelude::ge;
+ use googletest::prelude::le;
+ use googletest::prelude::near;
+
use super::*;
fn create_test_view() -> SortedView<i32> {
@@ -293,16 +301,16 @@ mod tests {
let view = create_test_view();
// Test exact matches
- assert!((view.rank(&1, SearchCriteria::Inclusive)? - 0.2).abs() <
1e-10);
- assert!((view.rank(&1, SearchCriteria::Exclusive)? - 0.0).abs() <
1e-10);
+ assert_that!(view.rank(&1, SearchCriteria::Inclusive)?, near(0.2,
1e-10));
+ assert_that!(view.rank(&1, SearchCriteria::Exclusive)?, near(0.0,
1e-10));
// Test values between items
- assert!((view.rank(&2, SearchCriteria::Inclusive)? - 0.2).abs() <
1e-10);
- assert!((view.rank(&6, SearchCriteria::Inclusive)? - 0.6).abs() <
1e-10);
+ assert_that!(view.rank(&2, SearchCriteria::Inclusive)?, near(0.2,
1e-10));
+ assert_that!(view.rank(&6, SearchCriteria::Inclusive)?, near(0.6,
1e-10));
// Test edge cases
- assert!((view.rank(&0, SearchCriteria::Inclusive)? - 0.0).abs() <
1e-10);
- assert!((view.rank(&10, SearchCriteria::Inclusive)? - 1.0).abs() <
1e-10);
+ assert_that!(view.rank(&0, SearchCriteria::Inclusive)?, near(0.0,
1e-10));
+ assert_that!(view.rank(&10, SearchCriteria::Inclusive)?, near(1.0,
1e-10));
Ok(())
}
@@ -316,13 +324,13 @@ mod tests {
// Test middle values
let median = view.quantile(0.5, SearchCriteria::Inclusive)?;
- assert!((3..=7).contains(&median)); // Should be around the middle
(values are 1,3,5,7,9)
+ assert_that!(median, all!(ge(3), le(7))); // Should be around the
middle (values are 1,3,5,7,9)
// Test various ranks
let q25 = view.quantile(0.25, SearchCriteria::Inclusive)?;
let q75 = view.quantile(0.75, SearchCriteria::Inclusive)?;
- assert!(q25 <= median);
- assert!(median <= q75);
+ assert_that!(q25, le(median));
+ assert_that!(median, le(q75));
Ok(())
}
@@ -336,7 +344,7 @@ mod tests {
// Sum should be approximately 1.0
let sum: f64 = pmf.iter().sum();
- assert!((sum - 1.0).abs() < 1e-10);
+ assert_that!(sum, near(1.0, 1e-10));
Ok(())
}
@@ -350,11 +358,11 @@ mod tests {
// CDF should be monotonically increasing
for i in 1..cdf.len() {
- assert!(cdf[i] >= cdf[i - 1]);
+ assert_that!(cdf[i], ge(cdf[i - 1]));
}
// Last value should be 1.0
- assert!((cdf[cdf.len() - 1] - 1.0).abs() < 1e-10);
+ assert_that!(cdf[cdf.len() - 1], near(1.0, 1e-10));
Ok(())
}
@@ -366,7 +374,10 @@ mod tests {
assert_eq!(view.total_weight(), 0);
// Operations on empty view should return errors
- assert!(view.rank(&5, SearchCriteria::Inclusive).is_err());
- assert!(view.quantile(0.5, SearchCriteria::Inclusive).is_err());
+ assert_that!(view.rank(&5, SearchCriteria::Inclusive),
err(anything()));
+ assert_that!(
+ view.quantile(0.5, SearchCriteria::Inclusive),
+ err(anything())
+ );
}
}
diff --git a/datasketches/src/thetafamily/common/binomial_bounds.rs
b/datasketches/src/thetafamily/common/binomial_bounds.rs
index 9ca251c..86b74fc 100644
--- a/datasketches/src/thetafamily/common/binomial_bounds.rs
+++ b/datasketches/src/thetafamily/common/binomial_bounds.rs
@@ -672,6 +672,12 @@ fn compute_approx_binomial_upper_bound(
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::anything;
+ use googletest::prelude::err;
+ use googletest::prelude::gt;
+ use googletest::prelude::near;
+
use super::*;
fn run_test_aux(max_num_samples: u64, ci: NumStdDev, min_p: f64) -> [f64;
5] {
@@ -788,10 +794,7 @@ mod tests {
fn assert_approx_equal(ci: NumStdDev, j: usize, expected: f64, actual:
f64) {
let ratio = actual / expected;
- assert!(
- (ratio - 1.0).abs() < TOL,
- "ci={ci:?}, j={j}: expected {expected}, got {actual},
ratio={ratio}",
- );
+ assert_that!(ratio, near(1.0, TOL), "ci={ci:?}, j={j}",);
}
for ci in [NumStdDev::One, NumStdDev::Two, NumStdDev::Three] {
@@ -822,13 +825,19 @@ mod tests {
#[test]
fn check_check_args() {
// Invalid theta values
- assert!(lower_bound(10, 0.0, NumStdDev::One).is_err());
- assert!(lower_bound(10, 1.01, NumStdDev::One).is_err());
- assert!(lower_bound(10, -0.1, NumStdDev::One).is_err());
+ assert_that!(lower_bound(10, 0.0, NumStdDev::One), err(anything()));
+ assert_that!(lower_bound(10, 1.01, NumStdDev::One), err(anything()));
+ assert_that!(lower_bound(10, -0.1, NumStdDev::One), err(anything()));
- assert!(upper_bound(10, 0.0, NumStdDev::One, false).is_err());
- assert!(upper_bound(10, 1.01, NumStdDev::One, false).is_err());
- assert!(upper_bound(10, -0.1, NumStdDev::One, false).is_err());
+ assert_that!(upper_bound(10, 0.0, NumStdDev::One, false),
err(anything()));
+ assert_that!(
+ upper_bound(10, 1.01, NumStdDev::One, false),
+ err(anything())
+ );
+ assert_that!(
+ upper_bound(10, -0.1, NumStdDev::One, false),
+ err(anything())
+ );
}
#[test]
@@ -856,13 +865,13 @@ mod tests {
// When no_data_seen is false with zero samples and theta < 1.0,
// upper bound should be calculated normally and be greater than 0
let result = upper_bound(0, 0.5, NumStdDev::One, false).unwrap();
- assert!(result > 0.0); // Upper bound should exist
+ assert_that!(result, gt(0.0)); // Upper bound should exist
}
#[test]
fn rejects_invalid_proportion_counts() {
- assert!(approximate_lower_bound_on_p(1, 2, 2.0).is_err());
- assert!(approximate_upper_bound_on_p(1, 2, 2.0).is_err());
+ assert_that!(approximate_lower_bound_on_p(1, 2, 2.0), err(anything()));
+ assert_that!(approximate_upper_bound_on_p(1, 2, 2.0), err(anything()));
}
#[test]
@@ -895,8 +904,8 @@ mod tests {
for k in 0..=5 {
let lower = approximate_lower_bound_on_p(5, k, 2.0).unwrap();
let upper = approximate_upper_bound_on_p(5, k, 2.0).unwrap();
- assert!((lower - LOWER[k as usize]).abs() < 1e-14);
- assert!((upper - UPPER[k as usize]).abs() < 1e-14);
+ assert_that!(lower, near(LOWER[k as usize], 1e-14));
+ assert_that!(upper, near(UPPER[k as usize], 1e-14));
}
}
}
diff --git a/datasketches/src/thetafamily/theta/sketch.rs
b/datasketches/src/thetafamily/theta/sketch.rs
index ed91d97..d1870cb 100644
--- a/datasketches/src/thetafamily/theta/sketch.rs
+++ b/datasketches/src/thetafamily/theta/sketch.rs
@@ -1102,6 +1102,10 @@ impl ThetaSketchBuilder {
#[cfg(test)]
mod tests {
+ use googletest::assert_that;
+ use googletest::prelude::gt;
+ use googletest::prelude::near;
+
use super::*;
fn sorted_theta_entries(sketch: &ThetaSketch) -> Vec<u64> {
@@ -1130,7 +1134,7 @@ mod tests {
assert_eq!(theta.num_retained(), compact.num_retained());
assert_eq!(theta.theta64(), compact.theta64());
assert_eq!(sorted_theta_entries(theta),
sorted_compact_entries(compact));
- assert!((theta.estimate() - compact.estimate()).abs() <= 1e-12);
+ assert_that!(theta.estimate(), near(compact.estimate(), 1e-12));
}
fn assert_compact_equivalent(a: &CompactThetaSketch, b:
&CompactThetaSketch) {
@@ -1141,7 +1145,7 @@ mod tests {
assert_eq!(a.theta64(), b.theta64());
assert_eq!(a.seed_hash(), b.seed_hash());
assert_eq!(sorted_compact_entries(a), sorted_compact_entries(b));
- assert!((a.estimate() - b.estimate()).abs() <= 1e-12);
+ assert_that!(a.estimate(), near(b.estimate(), 1e-12));
}
fn assert_compressed_round_trip(theta: &ThetaSketch, compact:
&CompactThetaSketch) {
@@ -1212,7 +1216,7 @@ mod tests {
}
let compact = theta.compact(true);
- assert!(compact.num_retained() > 255);
+ assert_that!(compact.num_retained(), gt(255));
assert!(!compact.is_estimation_mode());
assert!(compact.is_ordered());
diff --git a/datasketches/tests/bloom_test/sketch.rs
b/datasketches/tests/bloom_test/sketch.rs
index 7267607..e164140 100644
--- a/datasketches/tests/bloom_test/sketch.rs
+++ b/datasketches/tests/bloom_test/sketch.rs
@@ -16,6 +16,10 @@
// under the License.
use datasketches::bloom::BloomFilterBuilder;
+use googletest::assert_that;
+use googletest::prelude::ge;
+use googletest::prelude::gt;
+use googletest::prelude::le;
const NUM_BITS: u64 = 65_536;
const NUM_HASHES: u16 = 5;
@@ -38,9 +42,9 @@ fn test_membership_statistics_and_reset() {
assert!(!filter.contains_and_insert(&"apple"));
assert!(filter.contains_and_insert(&"apple"));
- assert!(filter.bits_used() > 0);
- assert!(filter.load_factor() > 0.0);
- assert!(filter.estimated_fpp() > 0.0);
+ assert_that!(filter.bits_used(), gt(0));
+ assert_that!(filter.load_factor(), gt(0.0));
+ assert_that!(filter.estimated_fpp(), gt(0.0));
filter.reset();
assert!(filter.is_empty());
@@ -65,16 +69,16 @@ fn test_union_and_intersection() {
intersection.intersect(&right);
assert!(intersection.contains(&"shared"));
let intersection_bits = intersection.bits_used();
- assert!(intersection_bits <= left_bits);
- assert!(intersection_bits <= right_bits);
+ assert_that!(intersection_bits, le(left_bits));
+ assert_that!(intersection_bits, le(right_bits));
let mut union = left;
union.union(&right);
assert!(union.contains(&"shared"));
assert!(union.contains(&"left"));
assert!(union.contains(&"right"));
- assert!(union.bits_used() >= left_bits);
- assert!(union.bits_used() >= right_bits);
+ assert_that!(union.bits_used(), ge(left_bits));
+ assert_that!(union.bits_used(), ge(right_bits));
}
#[test]
diff --git a/datasketches/tests/frequencies_test/update.rs
b/datasketches/tests/frequencies_test/update.rs
index 7f0d6f6..13d115c 100644
--- a/datasketches/tests/frequencies_test/update.rs
+++ b/datasketches/tests/frequencies_test/update.rs
@@ -17,6 +17,11 @@
use datasketches::frequencies::ErrorType;
use datasketches::frequencies::FrequentItemsSketch;
+use googletest::assert_that;
+use googletest::prelude::ge;
+use googletest::prelude::gt;
+use googletest::prelude::le;
+use googletest::prelude::near;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct TestItem(i32);
@@ -68,13 +73,13 @@ fn test_capacity_and_epsilon_helpers() {
let epsilon = FrequentItemsSketch::<i64>::epsilon_for_lg(10);
let expected = 3.5 / 1024.0;
- assert!((epsilon - expected).abs() < 1e-12);
+ assert_that!(epsilon, near(expected, 1e-12));
let apriori = FrequentItemsSketch::<i64>::apriori_error(10, 10_000);
- assert!((apriori - expected * 10_000.0).abs() < 1e-9);
+ assert_that!(apriori, near(expected * 10_000.0, 1e-9));
let items: FrequentItemsSketch<i32> = FrequentItemsSketch::new(1024);
- assert!((items.epsilon() - expected).abs() < 1e-12);
+ assert_that!(items.epsilon(), near(expected, 1e-12));
assert_eq!(items.current_map_capacity(), 6);
assert_eq!(items.maximum_map_capacity(), 768);
assert_eq!(items.lg_max_map_size(), 10);
@@ -262,7 +267,7 @@ fn test_longs_estimation_mode() {
assert!(!sketch.is_empty());
assert_eq!(sketch.total_weight(), 35);
- assert!(sketch.maximum_error() > 0);
+ assert_that!(sketch.maximum_error(), gt(0));
let items = sketch.frequent_items(ErrorType::NoFalsePositives);
assert_eq!(items.len(), 2);
@@ -272,8 +277,8 @@ fn test_longs_estimation_mode() {
assert_eq!(items[1].estimate(), 10);
let items = sketch.frequent_items(ErrorType::NoFalseNegatives);
- assert!(items.len() >= 2);
- assert!(items.len() <= 12);
+ assert_that!(items.len(), ge(2));
+ assert_that!(items.len(), le(12));
}
#[test]
@@ -290,7 +295,7 @@ fn test_items_estimation_mode() {
assert!(!sketch.is_empty());
assert_eq!(sketch.total_weight(), 35);
- assert!(sketch.maximum_error() > 0);
+ assert_that!(sketch.maximum_error(), gt(0));
let items = sketch.frequent_items(ErrorType::NoFalsePositives);
assert_eq!(items.len(), 2);
@@ -300,8 +305,8 @@ fn test_items_estimation_mode() {
assert_eq!(items[1].estimate(), 10);
let items = sketch.frequent_items(ErrorType::NoFalseNegatives);
- assert!(items.len() >= 2);
- assert!(items.len() <= 12);
+ assert_that!(items.len(), ge(2));
+ assert_that!(items.len(), le(12));
}
#[test]
@@ -369,26 +374,26 @@ fn test_longs_merge_estimation_mode() {
for item in 2..=14 {
sketch1.update(item);
}
- assert!(sketch1.maximum_error() > 0);
+ assert_that!(sketch1.maximum_error(), gt(0));
let mut sketch2: FrequentItemsSketch<i64> = FrequentItemsSketch::new(16);
for item in 8..=20 {
sketch2.update(item);
}
sketch2.update_with_count(21, 11);
- assert!(sketch2.maximum_error() > 0);
+ assert_that!(sketch2.maximum_error(), gt(0));
sketch1.merge(&sketch2);
assert!(!sketch1.is_empty());
assert_eq!(sketch1.total_weight(), 46);
- assert!(sketch1.num_active_items() >= 2);
+ assert_that!(sketch1.num_active_items(), ge(2));
let items =
sketch1.frequent_items_with_threshold(ErrorType::NoFalsePositives, 2);
assert_eq!(items.len(), 2);
assert_eq!(items[0].item(), &21);
- assert!(items[0].estimate() >= 11);
+ assert_that!(items[0].estimate(), ge(11));
assert_eq!(items[1].item(), &1);
- assert!(items[1].estimate() >= 9);
+ assert_that!(items[1].estimate(), ge(9));
}
#[test]
@@ -398,26 +403,26 @@ fn test_items_merge_estimation_mode() {
for item in 2..=14 {
sketch1.update(item);
}
- assert!(sketch1.maximum_error() > 0);
+ assert_that!(sketch1.maximum_error(), gt(0));
let mut sketch2: FrequentItemsSketch<i32> = FrequentItemsSketch::new(16);
for item in 8..=20 {
sketch2.update(item);
}
sketch2.update_with_count(21, 11);
- assert!(sketch2.maximum_error() > 0);
+ assert_that!(sketch2.maximum_error(), gt(0));
sketch1.merge(&sketch2);
assert!(!sketch1.is_empty());
assert_eq!(sketch1.total_weight(), 46);
- assert!(sketch1.num_active_items() >= 2);
+ assert_that!(sketch1.num_active_items(), ge(2));
let items =
sketch1.frequent_items_with_threshold(ErrorType::NoFalsePositives, 2);
assert_eq!(items.len(), 2);
assert_eq!(items[0].item(), &21);
- assert!(items[0].estimate() >= 11);
+ assert_that!(items[0].estimate(), ge(11));
assert_eq!(items[1].item(), &1);
- assert!(items[1].estimate() >= 9);
+ assert_that!(items[1].estimate(), ge(9));
}
#[test]
diff --git a/datasketches/tests/hll_test/union.rs
b/datasketches/tests/hll_test/union.rs
index 529ffc0..ccde9e7 100644
--- a/datasketches/tests/hll_test/union.rs
+++ b/datasketches/tests/hll_test/union.rs
@@ -31,6 +31,13 @@ use datasketches::common::NumStdDev;
use datasketches::hll::HllSketch;
use datasketches::hll::HllType;
use datasketches::hll::HllUnion;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::ge;
+use googletest::prelude::gt;
+use googletest::prelude::le;
+use googletest::prelude::lt;
+use googletest::prelude::near;
const HLL_TYPES: [HllType; 3] = [HllType::Hll4, HllType::Hll6, HllType::Hll8];
@@ -44,13 +51,10 @@ fn make_hll_sketch(hll_type: HllType, lg_config_k: u8,
start: u64, end: u64) ->
fn assert_estimate_within(estimate: f64, expected: f64, relative_error: f64) {
let actual_relative_error = (estimate - expected).abs() / expected;
- assert!(
- actual_relative_error <= relative_error,
- "Expected estimate within {:.1}% of {}, got {} ({:.1}% error)",
- relative_error * 100.0,
- expected,
- estimate,
- actual_relative_error * 100.0,
+ assert_that!(
+ actual_relative_error,
+ le(relative_error),
+ "expected={expected}, estimate={estimate}"
);
}
@@ -102,11 +106,7 @@ fn test_union_basic_operations() {
// Should estimate ~900 unique values (0-899)
let estimate = union.estimate();
- assert!(
- estimate > 800.0 && estimate < 1000.0,
- "Expected estimate around 900, got {}",
- estimate
- );
+ assert_that!(estimate, all!(gt(800.0), lt(1000.0)));
assert!(!union.is_empty());
// Adding empty sketch should not affect estimate
@@ -118,7 +118,7 @@ fn test_union_basic_operations() {
union.update_value("hello");
union.update_value(42i32);
union.update_value(vec![1, 2, 3]);
- assert!(union.estimate() > estimate_before);
+ assert_that!(union.estimate(), gt(estimate_before));
// Test duplicate handling - same sketch added multiple times
let mut dup_union = HllUnion::new(12);
@@ -130,11 +130,7 @@ fn test_union_basic_operations() {
dup_union.update(&sketch);
}
let dup_estimate = dup_union.estimate();
- assert!(
- (dup_estimate - 100.0).abs() < 20.0,
- "Duplicates should not inflate estimate, got {}",
- dup_estimate
- );
+ assert_that!(dup_estimate, near(100.0, 20.0));
}
#[test]
@@ -156,11 +152,7 @@ fn test_union_mode_transitions() {
union.update(&sketch2);
let estimate = union.estimate();
- assert!(
- (estimate - 15.0).abs() < 5.0,
- "List mode: expected estimate around 15, got {}",
- estimate
- );
+ assert_that!(estimate, near(15.0, 5.0));
// Trigger Set mode promotion
let mut sketch3 = HllSketch::new(12, HllType::Hll8);
@@ -170,11 +162,7 @@ fn test_union_mode_transitions() {
union.update(&sketch3);
let estimate = union.estimate();
- assert!(
- (estimate - 600.0).abs() < 100.0,
- "Set mode: estimate should be close to 600, got {}",
- estimate
- );
+ assert_that!(estimate, near(600.0, 100.0));
// Trigger HLL mode promotion
let mut sketch4 = HllSketch::new(12, HllType::Hll8);
@@ -184,11 +172,7 @@ fn test_union_mode_transitions() {
union.update(&sketch4);
let estimate = union.estimate();
- assert!(
- estimate > 9_000.0 && estimate < 11_000.0,
- "HLL mode: expected estimate around 10000, got {}",
- estimate
- );
+ assert_that!(estimate, all!(gt(9_000.0), lt(11_000.0)));
}
#[test]
@@ -214,11 +198,7 @@ fn test_union_mixed_modes() {
let estimate = result.estimate();
// Should estimate ~10,003 unique values
- assert!(
- estimate > 9_500.0 && estimate < 10_500.0,
- "Expected estimate around 10000, got {}",
- estimate
- );
+ assert_that!(estimate, all!(gt(9_500.0), lt(10_500.0)));
}
#[test]
@@ -260,11 +240,10 @@ fn test_union_mixed_hll_types() {
(result6.estimate(), "Hll6"),
(result8.estimate(), "Hll8"),
] {
- assert!(
- result > 6_000.0 && result < 8_000.0,
- "{}: expected estimate around 7000, got {}",
- type_name,
- result
+ assert_that!(
+ result,
+ all!(gt(6_000.0), lt(8_000.0)),
+ "hll_type: {type_name}"
);
}
}
@@ -303,11 +282,7 @@ fn test_union_lg_k_handling() {
// Should estimate ~10,000 unique values (0-9,999)
// Lower precision means higher error tolerance
- assert!(
- estimate > 8_000.0 && estimate < 12_000.0,
- "Expected estimate around 10000, got {}",
- estimate
- );
+ assert_that!(estimate, all!(gt(8_000.0), lt(12_000.0)));
// Test downsampling: union at lower precision than sketch
let mut union2 = HllUnion::new(10);
@@ -321,11 +296,7 @@ fn test_union_lg_k_handling() {
assert_eq!(result2.lg_config_k(), 10, "Result should be at lg_k=10");
let estimate2 = result2.estimate();
- assert!(
- estimate2 > 4_000.0 && estimate2 < 6_000.0,
- "Downsampling should still estimate ~5000, got {}",
- estimate2
- );
+ assert_that!(estimate2, all!(gt(4_000.0), lt(6_000.0)));
}
// Regression coverage for https://github.com/apache/datasketches-cpp/pull/512.
@@ -410,9 +381,9 @@ fn test_union_bounds() {
assert_eq!(union.estimate(), 0.0);
let empty_lower = union.lower_bound(NumStdDev::Two);
let empty_upper = union.upper_bound(NumStdDev::Two);
- assert!(empty_lower >= 0.0, "Lower bound should be non-negative");
- assert!(empty_upper >= 0.0, "Upper bound should be non-negative");
- assert!(empty_lower <= empty_upper);
+ assert_that!(empty_lower, ge(0.0));
+ assert_that!(empty_upper, ge(0.0));
+ assert_that!(empty_lower, le(empty_upper));
// Add sketches
let mut sketch1 = HllSketch::new(12, HllType::Hll8);
@@ -437,18 +408,18 @@ fn test_union_bounds() {
let lower3 = union.lower_bound(NumStdDev::Three);
// Basic sanity checks
- assert!(lower1 <= estimate);
- assert!(estimate <= upper1);
+ assert_that!(estimate, ge(lower1));
+ assert_that!(estimate, le(upper1));
// Bounds should widen with more standard deviations
- assert!(lower2 <= lower1);
- assert!(upper1 <= upper2);
- assert!(lower3 <= lower2);
- assert!(upper2 <= upper3);
+ assert_that!(lower2, le(lower1));
+ assert_that!(upper1, le(upper2));
+ assert_that!(lower3, le(lower2));
+ assert_that!(upper2, le(upper3));
// Bounds should be reasonable
- assert!(lower3 > estimate * 0.5);
- assert!(upper3 < estimate * 1.5);
+ assert_that!(lower3, gt(estimate * 0.5));
+ assert_that!(upper3, lt(estimate * 1.5));
// Test that smaller lg_k has wider bounds (higher RSE)
let mut union_small = HllUnion::new(8);
@@ -475,12 +446,7 @@ fn test_union_bounds() {
- union_large.lower_bound(NumStdDev::Two))
/ est_large;
- assert!(
- width_small > width_large,
- "Smaller union should have wider confidence interval: {} vs {}",
- width_small,
- width_large
- );
+ assert_that!(width_small, gt(width_large));
}
#[test]
@@ -494,7 +460,7 @@ fn test_union_reset() {
union.update(&sketch);
assert!(!union.is_empty());
- assert!(union.estimate() > 900.0);
+ assert_that!(union.estimate(), gt(900.0));
// Reset should clear all state
union.reset();
@@ -689,11 +655,7 @@ fn test_union_large_cardinality() {
let relative_error = (estimate - 200_000.0).abs() / 200_000.0;
// For lg_k=14, relative error should be ~1.04%
- assert!(
- relative_error < 0.05,
- "Relative error should be < 5%, got {:.2}%",
- relative_error * 100.0
- );
+ assert_that!(relative_error, lt(0.05));
}
#[test]
diff --git a/datasketches/tests/hll_test/update.rs
b/datasketches/tests/hll_test/update.rs
index e72c6fc..61e1263 100644
--- a/datasketches/tests/hll_test/update.rs
+++ b/datasketches/tests/hll_test/update.rs
@@ -18,6 +18,13 @@
use datasketches::common::NumStdDev;
use datasketches::hll::HllSketch;
use datasketches::hll::HllType;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::ge;
+use googletest::prelude::gt;
+use googletest::prelude::le;
+use googletest::prelude::lt;
+use googletest::prelude::near;
#[test]
fn test_basic_update() {
@@ -32,12 +39,8 @@ fn test_basic_update() {
}
let estimate = sketch.estimate();
- assert!(estimate > 0.0, "Estimate should be positive after updates");
- assert!(
- (estimate - 100.0).abs() < 20.0,
- "Estimate should be reasonably close to 100, got {}",
- estimate
- );
+ assert_that!(estimate, gt(0.0));
+ assert_that!(estimate, near(100.0, 20.0));
}
#[test]
@@ -51,11 +54,7 @@ fn test_list_to_set_promotion() {
}
let estimate = sketch.estimate();
- assert!(
- (estimate - 600.0).abs() < 100.0,
- "Estimate should be close to 600 after promotion, got {}",
- estimate
- );
+ assert_that!(estimate, near(600.0, 100.0));
}
#[test]
@@ -69,11 +68,7 @@ fn test_set_to_hll_promotion() {
}
let estimate = sketch.estimate();
- assert!(
- (estimate - 1000.0).abs() < 150.0,
- "Estimate should be close to 1000 after full promotion, got {}",
- estimate
- );
+ assert_that!(estimate, near(1000.0, 150.0));
}
#[test]
@@ -89,11 +84,7 @@ fn test_duplicate_handling() {
// Estimate should reflect ~100 unique values, not 1000
let estimate = sketch.estimate();
- assert!(
- (estimate - 100.0).abs() < 20.0,
- "Duplicates should not inflate estimate, got {}",
- estimate
- );
+ assert_that!(estimate, near(100.0, 20.0));
}
#[test]
@@ -108,7 +99,7 @@ fn test_different_types() {
sketch.update(vec![1, 2, 3]);
let estimate = sketch.estimate();
- assert!(estimate >= 5.0, "Should have at least 5 distinct values");
+ assert_that!(estimate, ge(5.0));
}
#[test]
@@ -120,11 +111,7 @@ fn test_hll4_type() {
}
let estimate = sketch.estimate();
- assert!(
- (estimate - 1000.0).abs() < 200.0,
- "HLL4 estimate should be reasonable, got {}",
- estimate
- );
+ assert_that!(estimate, near(1000.0, 200.0));
}
#[test]
@@ -136,11 +123,7 @@ fn test_hll6_type() {
}
let estimate = sketch.estimate();
- assert!(
- (estimate - 1000.0).abs() < 200.0,
- "HLL6 estimate should be reasonable, got {}",
- estimate
- );
+ assert_that!(estimate, near(1000.0, 200.0));
}
#[test]
@@ -162,12 +145,10 @@ fn test_serialization_roundtrip_after_updates() {
// Estimates should match after round-trip (allow some numerical error)
let relative_error = (estimate1 - estimate2).abs() / estimate1;
- assert!(
- relative_error < 0.05,
- "Estimates should match after serialization (< 5% error), got {} vs {}
({:.2}% error)",
- estimate1,
- estimate2,
- relative_error * 100.0
+ assert_that!(
+ relative_error,
+ lt(0.05),
+ "estimate1={estimate1}, estimate2={estimate2}"
);
}
@@ -184,11 +165,7 @@ fn test_large_cardinality() {
let relative_error = (estimate - 100_000.0).abs() / 100_000.0;
// For lg_k=14, relative error should be ~1.04%
- assert!(
- relative_error < 0.05,
- "Relative error should be < 5% for large cardinality, got {:.2}%",
- relative_error * 100.0
- );
+ assert_that!(relative_error, lt(0.05));
}
#[test]
@@ -245,28 +222,18 @@ fn test_bounds_basic() {
let lower3 = sketch.lower_bound(NumStdDev::Three);
// Basic sanity checks
- assert!(lower1 <= estimate, "Lower bound should be <= estimate");
- assert!(estimate <= upper1, "Estimate should be <= upper bound");
+ assert_that!(estimate, ge(lower1));
+ assert_that!(estimate, le(upper1));
// Bounds should widen with more standard deviations
- assert!(lower2 <= lower1, "2-sigma lower should be <= 1-sigma lower");
- assert!(upper1 <= upper2, "1-sigma upper should be <= 2-sigma upper");
- assert!(lower3 <= lower2, "3-sigma lower should be <= 2-sigma lower");
- assert!(upper2 <= upper3, "2-sigma upper should be <= 3-sigma upper");
+ assert_that!(lower2, le(lower1));
+ assert_that!(upper1, le(upper2));
+ assert_that!(lower3, le(lower2));
+ assert_that!(upper2, le(upper3));
// Bounds should be reasonable (within 50% for 3-sigma)
- assert!(
- lower3 > estimate * 0.5,
- "3-sigma lower bound seems too low: {} vs estimate {}",
- lower3,
- estimate
- );
- assert!(
- upper3 < estimate * 1.5,
- "3-sigma upper bound seems too high: {} vs estimate {}",
- upper3,
- estimate
- );
+ assert_that!(lower3, gt(estimate * 0.5));
+ assert_that!(upper3, lt(estimate * 1.5));
}
#[test]
@@ -279,10 +246,7 @@ fn test_bounds_all_modes() {
let estimate = sketch.estimate();
let upper = sketch.upper_bound(NumStdDev::Two);
let lower = sketch.lower_bound(NumStdDev::Two);
- assert!(
- lower <= estimate && estimate <= upper,
- "Bounds don't contain estimate in LIST mode"
- );
+ assert_that!(estimate, all!(ge(lower), le(upper)), "mode: LIST");
// Test Set mode (medium cardinality)
for i in 10..100 {
@@ -291,10 +255,7 @@ fn test_bounds_all_modes() {
let estimate = sketch.estimate();
let upper = sketch.upper_bound(NumStdDev::Two);
let lower = sketch.lower_bound(NumStdDev::Two);
- assert!(
- lower <= estimate && estimate <= upper,
- "Bounds don't contain estimate in SET mode"
- );
+ assert_that!(estimate, all!(ge(lower), le(upper)), "mode: SET");
// Test HLL mode (large cardinality)
for i in 100..5000 {
@@ -303,10 +264,7 @@ fn test_bounds_all_modes() {
let estimate = sketch.estimate();
let upper = sketch.upper_bound(NumStdDev::Two);
let lower = sketch.lower_bound(NumStdDev::Two);
- assert!(
- lower <= estimate && estimate <= upper,
- "Bounds don't contain estimate in HLL mode"
- );
+ assert_that!(estimate, all!(ge(lower), le(upper)), "mode: HLL");
}
#[test]
@@ -333,12 +291,7 @@ fn test_bounds_different_lg_k() {
let width_large = (upper_large - lower_large) / est_large;
// Smaller sketch should have wider relative confidence interval
- assert!(
- width_small > width_large,
- "Smaller sketch should have wider confidence interval: {} vs {}",
- width_small,
- width_large
- );
+ assert_that!(width_small, gt(width_large));
}
#[test]
@@ -350,7 +303,7 @@ fn test_bounds_empty_sketch() {
let lower = sketch.lower_bound(NumStdDev::Two);
assert_eq!(estimate, 0.0, "Empty sketch should have 0 estimate");
- assert!(lower >= 0.0, "Lower bound should be non-negative");
- assert!(upper >= 0.0, "Upper bound should be non-negative");
- assert!(lower <= upper, "Lower bound should be <= upper bound");
+ assert_that!(lower, ge(0.0));
+ assert_that!(upper, ge(0.0));
+ assert_that!(lower, le(upper));
}
diff --git a/datasketches/tests/req_test/accuracy.rs
b/datasketches/tests/req_test/accuracy.rs
index 3d9e8e7..71112ae 100644
--- a/datasketches/tests/req_test/accuracy.rs
+++ b/datasketches/tests/req_test/accuracy.rs
@@ -22,6 +22,8 @@
use datasketches::error::Error;
use datasketches::req::ReqSketch;
use datasketches::req::SearchCriteria;
+use googletest::assert_that;
+use googletest::prelude::le;
#[test]
fn rank_space_error_is_bounded() -> Result<(), Error> {
@@ -40,13 +42,7 @@ fn rank_space_error_is_bounded() -> Result<(), Error> {
let abs_rank_error = (estimated_rank - rank).abs();
let max_abs_rank_error = if rank >= 0.9 { 0.01 } else { 0.02 };
- assert!(
- abs_rank_error <= max_abs_rank_error,
- "rank {} abs error {:.4} > {:.4}",
- rank,
- abs_rank_error,
- max_abs_rank_error
- );
+ assert_that!(abs_rank_error, le(max_abs_rank_error), "rank: {rank}");
}
assert!(!sketch.is_empty());
diff --git a/datasketches/tests/req_test/bounds.rs
b/datasketches/tests/req_test/bounds.rs
index 7fc1469..ad01d95 100644
--- a/datasketches/tests/req_test/bounds.rs
+++ b/datasketches/tests/req_test/bounds.rs
@@ -23,6 +23,11 @@ use datasketches::error::Error;
use datasketches::req::RankAccuracy;
use datasketches::req::ReqSketch;
use datasketches::req::SearchCriteria;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::ge;
+use googletest::prelude::le;
+use googletest::prelude::lt;
#[test]
fn bounds_are_nested_and_in_unit_interval() {
@@ -48,13 +53,15 @@ fn bounds_are_nested_and_in_unit_interval() {
.collect();
for (lower, upper) in &bounds {
- assert!(lower <= upper);
- assert!((0.0..=1.0).contains(lower));
- assert!((0.0..=1.0).contains(upper));
+ assert_that!(*lower, le(*upper));
+ assert_that!(*lower, all!(ge(0.0), le(1.0)));
+ assert_that!(*upper, all!(ge(0.0), le(1.0)));
}
- assert!(bounds[1].0 <= bounds[0].0 && bounds[0].1 <= bounds[1].1);
- assert!(bounds[2].0 <= bounds[1].0 && bounds[1].1 <= bounds[2].1);
+ assert_that!(bounds[1].0, le(bounds[0].0));
+ assert_that!(bounds[0].1, le(bounds[1].1));
+ assert_that!(bounds[2].0, le(bounds[1].0));
+ assert_that!(bounds[1].1, le(bounds[2].1));
}
}
@@ -75,14 +82,7 @@ fn theoretical_error_bounds_cover_uniform_quantiles() ->
Result<(), Error> {
let estimated_rank = sketch.rank(&true_quantile,
SearchCriteria::Inclusive)?;
let lower = sketch.rank_lower_bound(rank, 3);
let upper = sketch.rank_upper_bound(rank, 3);
- assert!(
- estimated_rank >= lower && estimated_rank <= upper,
- "rank {} estimate {:.6} outside [{:.6}, {:.6}]",
- rank,
- estimated_rank,
- lower,
- upper
- );
+ assert_that!(estimated_rank, all!(ge(lower), le(upper)), "rank:
{rank}");
}
Ok(())
@@ -109,9 +109,9 @@ fn hra_and_lra_bounds_are_tighter_at_their_target_end() ->
Result<(), Error> {
(rank - lra.rank_lower_bound(rank,
2)).max(lra.rank_upper_bound(rank, 2) - rank);
if rank >= 0.75 {
- assert!(hra_error <= lra_error);
+ assert_that!(hra_error, le(lra_error));
} else if rank <= 0.25 {
- assert!(lra_error <= hra_error);
+ assert_that!(lra_error, le(hra_error));
}
}
@@ -131,7 +131,7 @@ fn exact_mode_bounds_are_tight() {
for rank in [0.1, 0.25, 0.5, 0.75, 0.9] {
let lower = sketch.rank_lower_bound(rank, 2);
let upper = sketch.rank_upper_bound(rank, 2);
- assert!((upper - lower) / 2.0 < 0.05);
+ assert_that!((upper - lower) / 2.0, lt(0.05));
}
}
@@ -160,12 +160,12 @@ fn high_rank_accuracy_matches_tight_thresholds() {
0.02
};
- assert!(abs_error <= max_abs_error);
+ assert_that!(abs_error, le(max_abs_error));
}
for rank in [0.9, 0.99, 0.999] {
let lower = sketch.rank_lower_bound(rank, 3);
let upper = sketch.rank_upper_bound(rank, 3);
- assert!(rank >= lower && rank <= upper);
+ assert_that!(rank, all!(ge(lower), le(upper)));
}
}
diff --git a/datasketches/tests/req_test/core.rs
b/datasketches/tests/req_test/core.rs
index ee36320..a8b5ed2 100644
--- a/datasketches/tests/req_test/core.rs
+++ b/datasketches/tests/req_test/core.rs
@@ -19,11 +19,21 @@
//! Core ReqSketch construction and update behavior.
-use approx::assert_relative_eq;
use datasketches::error::Error;
use datasketches::req::RankAccuracy;
use datasketches::req::ReqSketch;
use datasketches::req::SearchCriteria;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::anything;
+use googletest::prelude::approx_eq;
+use googletest::prelude::err;
+use googletest::prelude::ge;
+use googletest::prelude::le;
+use googletest::prelude::lt;
+use googletest::prelude::near;
+use googletest::prelude::none;
+use googletest::prelude::ok;
#[test]
fn empty_sketch_has_default_state_and_rejects_queries() {
@@ -34,13 +44,25 @@ fn empty_sketch_has_default_state_and_rejects_queries() {
assert!(!sketch.is_estimation_mode());
assert_eq!(sketch.n(), 0);
assert_eq!(sketch.num_retained(), 0);
- assert!(sketch.min_item().is_none());
- assert!(sketch.max_item().is_none());
+ assert_that!(sketch.min_item(), none());
+ assert_that!(sketch.max_item(), none());
- assert!(sketch.rank(&0.0, SearchCriteria::Inclusive).is_err());
- assert!(sketch.quantile(0.5, SearchCriteria::Inclusive).is_err());
- assert!(sketch.pmf(&[0.0], SearchCriteria::Inclusive).is_err());
- assert!(sketch.cdf(&[0.0], SearchCriteria::Inclusive).is_err());
+ assert_that!(
+ sketch.rank(&0.0, SearchCriteria::Inclusive),
+ err(anything())
+ );
+ assert_that!(
+ sketch.quantile(0.5, SearchCriteria::Inclusive),
+ err(anything())
+ );
+ assert_that!(
+ sketch.pmf(&[0.0], SearchCriteria::Inclusive),
+ err(anything())
+ );
+ assert_that!(
+ sketch.cdf(&[0.0], SearchCriteria::Inclusive),
+ err(anything())
+ );
}
#[test]
@@ -55,37 +77,37 @@ fn single_value_hra_answers_exactly() {
assert_eq!(sketch.min_item(), Some(&1.0));
assert_eq!(sketch.max_item(), Some(&1.0));
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&1.0, SearchCriteria::Exclusive)
.expect("rank should succeed"),
- 0.0
+ approx_eq(0.0)
);
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&1.0, SearchCriteria::Inclusive)
.expect("rank should succeed"),
- 1.0
+ approx_eq(1.0)
);
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&1.1, SearchCriteria::Exclusive)
.expect("rank should succeed"),
- 1.0
+ approx_eq(1.0)
);
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&f32::INFINITY, SearchCriteria::Inclusive)
.expect("rank should succeed"),
- 1.0
+ approx_eq(1.0)
);
for rank in [0.0, 0.5, 1.0] {
- assert_relative_eq!(
+ assert_that!(
sketch
.quantile(rank, SearchCriteria::Exclusive)
.expect("quantile should succeed"),
- 1.0
+ approx_eq(1.0)
);
}
}
@@ -119,29 +141,29 @@ fn repeated_values_respect_search_criteria() {
assert_eq!(sketch.n(), 6);
assert_eq!(sketch.num_retained(), 6);
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&1.0, SearchCriteria::Exclusive)
.expect("rank should succeed"),
- 0.0
+ approx_eq(0.0)
);
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&1.0, SearchCriteria::Inclusive)
.expect("rank should succeed"),
- 0.5
+ approx_eq(0.5)
);
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&2.0, SearchCriteria::Exclusive)
.expect("rank should succeed"),
- 0.5
+ approx_eq(0.5)
);
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&2.0, SearchCriteria::Inclusive)
.expect("rank should succeed"),
- 1.0
+ approx_eq(1.0)
);
}
@@ -157,7 +179,7 @@ fn estimation_mode_compresses_and_keeps_min_max() {
assert!(!sketch.is_empty());
assert!(sketch.is_estimation_mode());
assert_eq!(sketch.n(), n);
- assert!(sketch.num_retained() < n as u32);
+ assert_that!(sketch.num_retained(), lt(n as u32));
assert_eq!(sketch.min_item(), Some(&0.0));
assert_eq!(sketch.max_item(), Some(&((n - 1) as f32)));
@@ -171,9 +193,9 @@ fn estimation_mode_compresses_and_keeps_min_max() {
.rank(&(n as f32), SearchCriteria::Exclusive)
.expect("rank should succeed");
- assert!((r0 - 0.0).abs() <= 1e-3);
- assert!((rmid - 0.5).abs() <= 0.01);
- assert!((rmax - 1.0).abs() <= 1e-3);
+ assert_that!(r0, near(0.0, 1e-3));
+ assert_that!(rmid, near(0.5, 0.01));
+ assert_that!(rmax, near(1.0, 1e-3));
}
#[test]
@@ -220,7 +242,7 @@ fn small_edge_cases_answer_reasonably() -> Result<(),
Error> {
two_values.update(1.0);
two_values.update(100.0);
let median = two_values.quantile(0.5, SearchCriteria::Inclusive)?;
- assert!((1.0..=100.0).contains(&median));
+ assert_that!(median, all!(ge(1.0), le(100.0)));
let mut duplicates = ReqSketch::new();
for _ in 0..100 {
@@ -234,10 +256,22 @@ fn small_edge_cases_answer_reasonably() -> Result<(),
Error> {
#[test]
fn constructors_validate_k() {
// k must be even and within the supported range; both constructors
enforce it.
- assert!(ReqSketch::<f64>::try_new(0, RankAccuracy::HighRank).is_err());
- assert!(ReqSketch::<f64>::try_new(3, RankAccuracy::HighRank).is_err()); //
odd
- assert!(ReqSketch::<f64>::try_new(4096, RankAccuracy::HighRank).is_err());
// too large
- assert!(ReqSketch::<f64>::try_new(12, RankAccuracy::HighRank).is_ok());
- assert!(ReqSketch::<f64>::builder().k(5).is_err()); // odd via builder
- assert!(ReqSketch::<f64>::builder().k(12).is_ok());
+ assert_that!(
+ ReqSketch::<f64>::try_new(0, RankAccuracy::HighRank),
+ err(anything())
+ );
+ assert_that!(
+ ReqSketch::<f64>::try_new(3, RankAccuracy::HighRank),
+ err(anything())
+ ); // odd
+ assert_that!(
+ ReqSketch::<f64>::try_new(4096, RankAccuracy::HighRank),
+ err(anything())
+ ); // too large
+ assert_that!(
+ ReqSketch::<f64>::try_new(12, RankAccuracy::HighRank),
+ ok(anything())
+ );
+ assert_that!(ReqSketch::<f64>::builder().k(5), err(anything())); // odd
via builder
+ assert_that!(ReqSketch::<f64>::builder().k(12), ok(anything()));
}
diff --git a/datasketches/tests/req_test/merge.rs
b/datasketches/tests/req_test/merge.rs
index 4837625..1d7d559 100644
--- a/datasketches/tests/req_test/merge.rs
+++ b/datasketches/tests/req_test/merge.rs
@@ -22,6 +22,10 @@
use datasketches::req::RankAccuracy;
use datasketches::req::ReqSketch;
use datasketches::req::SearchCriteria;
+use googletest::assert_that;
+use googletest::prelude::anything;
+use googletest::prelude::err;
+use googletest::prelude::near;
#[test]
fn merge_into_empty_preserves_source_distribution() {
@@ -57,10 +61,10 @@ fn merge_into_empty_preserves_source_distribution() {
.rank(&500.0, SearchCriteria::Inclusive)
.expect("rank should succeed");
- assert!((q25 - 250.0).abs() / 250.0 <= 0.01);
- assert!((q50 - 500.0).abs() / 500.0 <= 0.01);
- assert!((q75 - 750.0).abs() / 750.0 <= 0.01);
- assert!((r50 - 0.5).abs() / 0.5 <= 0.01);
+ assert_that!(q25, near(250.0, 250.0 * 0.01));
+ assert_that!(q50, near(500.0, 500.0 * 0.01));
+ assert_that!(q75, near(750.0, 750.0 * 0.01));
+ assert_that!(r50, near(0.5, 0.5 * 0.01));
}
#[test]
@@ -100,10 +104,10 @@ fn merge_two_ranges_preserves_distribution() {
.rank(&1000.0, SearchCriteria::Inclusive)
.expect("rank should succeed");
- assert!((q25 - 500.0).abs() / 500.0 <= 0.02);
- assert!((q50 - 1000.0).abs() / 1000.0 <= 0.01);
- assert!((q75 - 1500.0).abs() / 1500.0 <= 0.01);
- assert!((r50 - 0.5).abs() / 0.5 <= 0.01);
+ assert_that!(q25, near(500.0, 500.0 * 0.02));
+ assert_that!(q50, near(1000.0, 1000.0 * 0.01));
+ assert_that!(q75, near(1500.0, 1500.0 * 0.01));
+ assert_that!(r50, near(0.5, 0.5 * 0.01));
}
#[test]
@@ -115,7 +119,7 @@ fn merge_rejects_incompatible_accuracy_modes() {
.expect("build should succeed");
high_rank.update(1.0);
- assert!(high_rank.merge(&low_rank).is_err());
+ assert_that!(high_rank.merge(&low_rank), err(anything()));
}
#[test]
@@ -137,5 +141,5 @@ fn many_small_merges_preserve_count_bounds_and_median() {
let median = sketch
.quantile(0.5, SearchCriteria::Inclusive)
.expect("quantile should succeed");
- assert!((median - 4999.5).abs() < 500.0);
+ assert_that!(median, near(4999.5, 500.0));
}
diff --git a/datasketches/tests/req_test/query.rs
b/datasketches/tests/req_test/query.rs
index 94fe2b1..afa9a4c 100644
--- a/datasketches/tests/req_test/query.rs
+++ b/datasketches/tests/req_test/query.rs
@@ -19,10 +19,15 @@
//! Rank, quantile, PMF, and CDF behavior for ReqSketch.
-use approx::assert_relative_eq;
use datasketches::error::Error;
use datasketches::req::ReqSketch;
use datasketches::req::SearchCriteria;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::ge;
+use googletest::prelude::le;
+use googletest::prelude::lt;
+use googletest::prelude::near;
#[test]
fn exact_mode_rank_quantile_pmf_and_cdf_match_reference() {
@@ -36,42 +41,38 @@ fn exact_mode_rank_quantile_pmf_and_cdf_match_reference() {
assert_eq!(sketch.num_retained(), 10);
for (value, expected) in [(1.0, 0.0), (2.0, 0.1), (6.0, 0.5), (9.0, 0.8),
(10.0, 0.9)] {
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&value, SearchCriteria::Exclusive)
.expect("rank should succeed"),
- expected,
- epsilon = 1e-6
+ near(expected, 1e-6)
);
}
for (value, expected) in [(1.0, 0.1), (2.0, 0.2), (5.0, 0.5), (9.0, 0.9),
(10.0, 1.0)] {
- assert_relative_eq!(
+ assert_that!(
sketch
.rank(&value, SearchCriteria::Inclusive)
.expect("rank should succeed"),
- expected,
- epsilon = 1e-6
+ near(expected, 1e-6)
);
}
for (rank, expected) in [(0.0, 1.0), (0.1, 2.0), (0.5, 6.0), (0.9, 10.0),
(1.0, 10.0)] {
- assert_relative_eq!(
+ assert_that!(
sketch
.quantile(rank, SearchCriteria::Exclusive)
.expect("quantile should succeed"),
- expected,
- epsilon = 1e-6
+ near(expected, 1e-6)
);
}
for (rank, expected) in [(0.0, 1.0), (0.1, 1.0), (0.5, 5.0), (0.9, 9.0),
(1.0, 10.0)] {
- assert_relative_eq!(
+ assert_that!(
sketch
.quantile(rank, SearchCriteria::Inclusive)
.expect("quantile should succeed"),
- expected,
- epsilon = 1e-6
+ near(expected, 1e-6)
);
}
@@ -79,18 +80,18 @@ fn exact_mode_rank_quantile_pmf_and_cdf_match_reference() {
let cdf = sketch
.cdf(&splits, SearchCriteria::Exclusive)
.expect("cdf should succeed");
- assert_relative_eq!(cdf[0], 0.1, epsilon = 1e-6);
- assert_relative_eq!(cdf[1], 0.5, epsilon = 1e-6);
- assert_relative_eq!(cdf[2], 0.8, epsilon = 1e-6);
- assert_relative_eq!(cdf[3], 1.0, epsilon = 1e-6);
+ assert_that!(cdf[0], near(0.1, 1e-6));
+ assert_that!(cdf[1], near(0.5, 1e-6));
+ assert_that!(cdf[2], near(0.8, 1e-6));
+ assert_that!(cdf[3], near(1.0, 1e-6));
let pmf = sketch
.pmf(&splits, SearchCriteria::Exclusive)
.expect("pmf should succeed");
- assert_relative_eq!(pmf[0], 0.1, epsilon = 1e-6);
- assert_relative_eq!(pmf[1], 0.4, epsilon = 1e-6);
- assert_relative_eq!(pmf[2], 0.3, epsilon = 1e-6);
- assert_relative_eq!(pmf[3], 0.2, epsilon = 1e-6);
+ assert_that!(pmf[0], near(0.1, 1e-6));
+ assert_that!(pmf[1], near(0.4, 1e-6));
+ assert_that!(pmf[2], near(0.3, 1e-6));
+ assert_that!(pmf[3], near(0.2, 1e-6));
}
#[test]
@@ -108,14 +109,14 @@ fn pmf_and_cdf_are_consistent() {
.cdf(&split_points, SearchCriteria::Inclusive)
.expect("cdf should succeed");
- assert_relative_eq!(pmf.iter().sum::<f64>(), 1.0, epsilon = 1e-10);
+ assert_that!(pmf.iter().sum::<f64>(), near(1.0, 1e-10));
let mut cumulative = 0.0;
for i in 0..pmf.len() {
cumulative += pmf[i];
- assert_relative_eq!(cdf[i], cumulative, epsilon = 1e-10);
+ assert_that!(cdf[i], near(cumulative, 1e-10));
}
- assert_relative_eq!(cdf[cdf.len() - 1], 1.0, epsilon = 1e-10);
+ assert_that!(cdf[cdf.len() - 1], near(1.0, 1e-10));
}
#[test]
@@ -132,8 +133,8 @@ fn rank_is_monotonic_and_bounded() {
let rank = sketch
.rank(&value, SearchCriteria::Inclusive)
.expect("rank should succeed");
- assert!(rank >= last_rank, "ranks should be monotonic");
- assert!((0.0..=1.0).contains(&rank), "rank should be in [0,1]");
+ assert_that!(rank, ge(last_rank));
+ assert_that!(rank, all!(ge(0.0), le(1.0)));
last_rank = rank;
}
}
@@ -150,7 +151,7 @@ fn quantiles_are_monotonic() -> Result<(), Error> {
for rank in ranks {
let quantile = sketch.quantile(rank, SearchCriteria::Inclusive)?;
- assert!(quantile >= previous);
+ assert_that!(quantile, ge(previous));
previous = quantile;
}
@@ -168,7 +169,7 @@ fn rank_quantile_round_trip_is_consistent() -> Result<(),
Error> {
let quantile = sketch.quantile(target_rank,
SearchCriteria::Inclusive)?;
let recovered_rank = sketch.rank(&quantile,
SearchCriteria::Inclusive)?;
let error = (recovered_rank - target_rank).abs() / target_rank;
- assert!(error < 0.2);
+ assert_that!(error, lt(0.2));
}
Ok(())
@@ -185,9 +186,9 @@ fn search_criteria_rank_consistency() -> Result<(), Error> {
let inclusive_rank = sketch.rank(&value, SearchCriteria::Inclusive)?;
let exclusive_rank = sketch.rank(&value, SearchCriteria::Exclusive)?;
- assert!(exclusive_rank <= inclusive_rank);
- assert!((0.0..=1.0).contains(&inclusive_rank));
- assert!((0.0..=1.0).contains(&exclusive_rank));
+ assert_that!(exclusive_rank, le(inclusive_rank));
+ assert_that!(inclusive_rank, all!(ge(0.0), le(1.0)));
+ assert_that!(exclusive_rank, all!(ge(0.0), le(1.0)));
}
Ok(())
diff --git a/datasketches/tests/req_test/sorted_view_api.rs
b/datasketches/tests/req_test/sorted_view_api.rs
index b8803a2..fa0338c 100644
--- a/datasketches/tests/req_test/sorted_view_api.rs
+++ b/datasketches/tests/req_test/sorted_view_api.rs
@@ -25,6 +25,14 @@ use datasketches::error::ErrorKind;
use datasketches::req::ReqSketch;
use datasketches::req::SearchCriteria;
use datasketches::req::SortedView;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::anything;
+use googletest::prelude::contains_substring;
+use googletest::prelude::err;
+use googletest::prelude::ge;
+use googletest::prelude::lt;
+use googletest::prelude::near;
fn populated_sketch(n: u64) -> ReqSketch<f64> {
let mut sketch = ReqSketch::new();
@@ -85,14 +93,23 @@ fn sorted_view_on_empty_sketch_is_an_empty_view() {
assert_eq!(view.len(), 0);
assert_eq!(view.total_weight(), 0);
// Queries on the empty view still report an error.
- assert!(view.quantile(0.5, SearchCriteria::Inclusive).is_err());
+ assert_that!(
+ view.quantile(0.5, SearchCriteria::Inclusive),
+ err(anything())
+ );
}
#[test]
fn empty_sketch_pmf_cdf_report_error() {
let sketch: ReqSketch<f64> = ReqSketch::new();
- assert!(sketch.pmf(&[1.0], SearchCriteria::Inclusive).is_err());
- assert!(sketch.cdf(&[1.0], SearchCriteria::Inclusive).is_err());
+ assert_that!(
+ sketch.pmf(&[1.0], SearchCriteria::Inclusive),
+ err(anything())
+ );
+ assert_that!(
+ sketch.cdf(&[1.0], SearchCriteria::Inclusive),
+ err(anything())
+ );
}
#[test]
@@ -100,19 +117,22 @@ fn view_rank_is_primary_query_name() {
let sketch = populated_sketch(10);
let view = sketch.sorted_view();
let r = view.rank(&5.0, SearchCriteria::Inclusive).expect("rank");
- assert!((r - 0.6).abs() < 1e-10, "rank of 5.0 in 0..10, got {r}");
+ assert_that!(r, near(0.6, 1e-10));
}
#[test]
fn nan_query_items_are_rejected() {
let sketch = populated_sketch(100);
- let err = sketch
+ let error = sketch
.rank(&f64::NAN, SearchCriteria::Inclusive)
.unwrap_err();
- assert_eq!(err.kind(), ErrorKind::InvalidArgument);
+ assert_eq!(error.kind(), ErrorKind::InvalidArgument);
let view = sketch.sorted_view();
- assert!(view.rank(&f64::NAN, SearchCriteria::Inclusive).is_err());
+ assert_that!(
+ view.rank(&f64::NAN, SearchCriteria::Inclusive),
+ err(anything())
+ );
}
#[test]
@@ -120,21 +140,13 @@ fn error_precedence_empty_before_invalid_rank() {
// On an empty sketch the emptiness is reported before the out-of-range
rank.
let empty: ReqSketch<f64> = ReqSketch::new();
let empty_err = empty.quantile(2.0,
SearchCriteria::Inclusive).unwrap_err();
- assert!(
- empty_err.message().contains("empty"),
- "expected emptiness error, got: {}",
- empty_err.message()
- );
+ assert_that!(empty_err.message(), contains_substring("empty"));
// On a populated sketch the out-of-range rank is reported.
let sketch = populated_sketch(10);
let range_err = sketch.quantile(2.0,
SearchCriteria::Inclusive).unwrap_err();
assert_eq!(range_err.kind(), ErrorKind::InvalidArgument);
- assert!(
- range_err.message().contains("must be in"),
- "expected range error, got: {}",
- range_err.message()
- );
+ assert_that!(range_err.message(), contains_substring("must be in"));
}
#[test]
@@ -160,6 +172,6 @@ fn concurrent_readers_share_the_sketch() {
.collect();
for handle in handles {
let q = handle.join().expect("thread");
- assert!((0.0..1_000.0).contains(&q));
+ assert_that!(q, all!(ge(0.0), lt(1_000.0)));
}
}
diff --git a/datasketches/tests/req_test/structure.rs
b/datasketches/tests/req_test/structure.rs
index aa30cc3..c8f46a2 100644
--- a/datasketches/tests/req_test/structure.rs
+++ b/datasketches/tests/req_test/structure.rs
@@ -20,6 +20,13 @@
//! Public iterator behavior for ReqSketch.
use datasketches::req::ReqSketch;
+use googletest::assert_that;
+use googletest::prelude::each;
+use googletest::prelude::eq;
+use googletest::prelude::ge;
+use googletest::prelude::gt;
+use googletest::prelude::le;
+use googletest::prelude::predicate;
#[test]
fn iterator_weights_sum_to_n_and_items_are_in_range() {
@@ -32,9 +39,9 @@ fn iterator_weights_sum_to_n_and_items_are_in_range() {
assert_eq!(total_weight, sketch.n());
for (item, weight) in sketch.iter() {
- assert!(weight >= 1);
- assert!(item >= *sketch.min_item().expect("non-empty sketch"));
- assert!(item <= *sketch.max_item().expect("non-empty sketch"));
+ assert_that!(weight, ge(1));
+ assert_that!(item, ge(*sketch.min_item().expect("non-empty sketch")));
+ assert_that!(item, le(*sketch.max_item().expect("non-empty sketch")));
}
}
@@ -48,7 +55,8 @@ fn small_sketch_iterator_reports_unit_weights() {
let items: Vec<(f64, u64)> = sketch.iter().collect();
assert_eq!(items.len(), 10);
- assert!(items.iter().all(|&(_, weight)| weight == 1));
+ let weights: Vec<_> = items.iter().map(|&(_, weight)| weight).collect();
+ assert_that!(weights, each(eq(&1)));
}
#[test]
@@ -67,11 +75,15 @@ fn compaction_promotes_surviving_items_to_higher_weights() {
}
let max_weight = sketch.iter().map(|(_, weight)| weight).max().unwrap();
- assert!(
- max_weight > 1,
- "expected promoted items, got max weight {max_weight}"
- );
+ assert_that!(max_weight, gt(1));
// Every weight is a power of two (2^level).
- assert!(sketch.iter().all(|(_, weight)| weight.is_power_of_two()));
+ let weights: Vec<_> = sketch.iter().map(|(_, weight)| weight).collect();
+ assert_that!(
+ weights,
+ each(
+ predicate(|weight: &u64| weight.is_power_of_two())
+ .with_description("is a power of two", "is not a power of two")
+ )
+ );
}
diff --git a/datasketches/tests/req_test/union.rs
b/datasketches/tests/req_test/union.rs
index b069f7a..cb04e15 100644
--- a/datasketches/tests/req_test/union.rs
+++ b/datasketches/tests/req_test/union.rs
@@ -23,6 +23,11 @@ use datasketches::req::RankAccuracy;
use datasketches::req::ReqSketch;
use datasketches::req::ReqUnion;
use datasketches::req::SearchCriteria;
+use googletest::assert_that;
+use googletest::prelude::anything;
+use googletest::prelude::err;
+use googletest::prelude::near;
+use googletest::prelude::ok;
#[test]
fn union_equivalent_to_chained_merge() {
@@ -61,8 +66,8 @@ fn union_equivalent_to_chained_merge() {
.quantile(0.5, SearchCriteria::Inclusive)
.expect("quantile should succeed");
- assert!((q_union - true_median).abs() <= tolerance);
- assert!((q_merge - true_median).abs() <= tolerance);
+ assert_that!(q_union, near(true_median, tolerance));
+ assert_that!(q_merge, near(true_median, tolerance));
}
#[test]
@@ -88,8 +93,14 @@ fn reset_clears_union_state() {
#[test]
fn try_new_validates_k() {
- assert!(ReqUnion::<f64>::try_new(3, RankAccuracy::HighRank).is_err());
- assert!(ReqUnion::<f64>::try_new(12, RankAccuracy::HighRank).is_ok());
+ assert_that!(
+ ReqUnion::<f64>::try_new(3, RankAccuracy::HighRank),
+ err(anything())
+ );
+ assert_that!(
+ ReqUnion::<f64>::try_new(12, RankAccuracy::HighRank),
+ ok(anything())
+ );
}
#[test]
diff --git a/datasketches/tests/serde_tests/bloom.rs
b/datasketches/tests/serde_tests/bloom.rs
index ac5df83..b8f6b38 100644
--- a/datasketches/tests/serde_tests/bloom.rs
+++ b/datasketches/tests/serde_tests/bloom.rs
@@ -21,6 +21,8 @@ use std::path::PathBuf;
use datasketches::bloom::BloomFilter;
use datasketches::bloom::BloomFilterBuilder;
use datasketches::error::ErrorKind;
+use googletest::assert_that;
+use googletest::prelude::gt;
use crate::serialization_test_data;
@@ -50,10 +52,7 @@ fn test_bloom_filter_file(path: PathBuf, expected_num_items:
u64, expected_num_h
"Filter should not be empty for n={}",
expected_num_items
);
- assert!(
- filter1.bits_used() > 0,
- "Non-empty filter should have bits set"
- );
+ assert_that!(filter1.bits_used(), gt(0));
}
// Verify the items that were inserted (integers 0 to n/10-1)
@@ -186,7 +185,7 @@ fn test_inconsistent_num_bits_set_is_rejected() {
filter.insert("apple");
filter.insert("banana");
let actual_bits_set = filter.bits_used();
- assert!(actual_bits_set > 1);
+ assert_that!(actual_bits_set, gt(1));
for serialized_count in [0, actual_bits_set - 1, actual_bits_set + 1] {
let mut bytes = filter.serialize();
diff --git a/datasketches/tests/serde_tests/frequencies.rs
b/datasketches/tests/serde_tests/frequencies.rs
index a81405f..0e4fbdc 100644
--- a/datasketches/tests/serde_tests/frequencies.rs
+++ b/datasketches/tests/serde_tests/frequencies.rs
@@ -23,6 +23,9 @@ use datasketches::error::Error;
use datasketches::error::ErrorKind;
use datasketches::frequencies::FrequentItemValue;
use datasketches::frequencies::FrequentItemsSketch;
+use googletest::assert_that;
+use googletest::prelude::contains_substring;
+use googletest::prelude::gt;
use crate::serialization_test_data;
@@ -176,7 +179,7 @@ fn test_java_frequent_longs_compatibility() {
let sketch = FrequentItemsSketch::<i64>::deserialize(&bytes).unwrap();
assert_eq!(sketch.is_empty(), n == 0);
if n > 10 {
- assert!(sketch.maximum_error() > 0);
+ assert_that!(sketch.maximum_error(), gt(0));
} else {
assert_eq!(sketch.maximum_error(), 0);
}
@@ -238,17 +241,14 @@ fn test_cpp_frequent_longs_compatibility() {
if cfg!(windows) {
if let Err(err) = sketch {
assert_eq!(err.kind(), ErrorKind::InvalidData);
- assert!(
- err.message().contains("insufficient data"),
- "expected insufficient data error, got: {err}"
- );
+ assert_that!(err.message(), contains_substring("insufficient
data"));
continue;
}
}
let sketch = sketch.unwrap();
assert_eq!(sketch.is_empty(), n == 0);
if n > 10 {
- assert!(sketch.maximum_error() > 0);
+ assert_that!(sketch.maximum_error(), gt(0));
} else {
assert_eq!(sketch.maximum_error(), 0);
}
@@ -266,7 +266,7 @@ fn test_cpp_frequent_strings_compatibility() {
let sketch =
FrequentItemsSketch::<String>::deserialize(&bytes).unwrap();
assert_eq!(sketch.is_empty(), n == 0);
if n > 10 {
- assert!(sketch.maximum_error() > 0);
+ assert_that!(sketch.maximum_error(), gt(0));
} else {
assert_eq!(sketch.maximum_error(), 0);
}
@@ -327,7 +327,7 @@ fn test_go_frequent_longs_compatibility() {
let sketch = FrequentItemsSketch::<i64>::deserialize(&bytes).unwrap();
assert_eq!(sketch.is_empty(), n == 0);
if n > 10 {
- assert!(sketch.maximum_error() > 0);
+ assert_that!(sketch.maximum_error(), gt(0));
} else {
assert_eq!(sketch.maximum_error(), 0);
}
@@ -345,7 +345,7 @@ fn test_go_frequent_strings_compatibility() {
let sketch =
FrequentItemsSketch::<String>::deserialize(&bytes).unwrap();
assert_eq!(sketch.is_empty(), n == 0);
if n > 10 {
- assert!(sketch.maximum_error() > 0);
+ assert_that!(sketch.maximum_error(), gt(0));
} else {
assert_eq!(sketch.maximum_error(), 0);
}
diff --git a/datasketches/tests/serde_tests/hll.rs
b/datasketches/tests/serde_tests/hll.rs
index 4501b1f..f491489 100644
--- a/datasketches/tests/serde_tests/hll.rs
+++ b/datasketches/tests/serde_tests/hll.rs
@@ -21,6 +21,12 @@ use std::path::PathBuf;
use datasketches::hash::value::natural_extend;
use datasketches::hll::HllSketch;
use datasketches::hll::HllType;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::ge;
+use googletest::prelude::le;
+use googletest::prelude::lt;
+use googletest::prelude::near;
use crate::serialization_test_data;
@@ -48,23 +54,15 @@ fn test_sketch_file(path: PathBuf, expected_cardinality:
usize, expected_lg_k: u
let lower_bound = expected * (1.0 - error_margin);
let upper_bound = expected * (1.0 + error_margin);
- assert!(
- estimate1 >= lower_bound && estimate1 <= upper_bound,
- "Estimate {} outside bounds [{}, {}] for expected {} in {}",
+ assert_that!(
estimate1,
- lower_bound,
- upper_bound,
- expected,
+ all!(ge(lower_bound), le(upper_bound)),
+ "path: {}",
path.display()
);
} else {
// For n=0, estimate should be very close to 0
- assert!(
- estimate1 < 1.0,
- "Expected near-zero estimate for empty sketch, got {} in {}",
- estimate1,
- path.display()
- );
+ assert_that!(estimate1, lt(1.0), "path: {}", path.display());
}
// Serialize and deserialize again to test round-trip
@@ -123,10 +121,7 @@ fn test_update_after_deserialize_list_mode() {
sketch.update(2u64);
let est = sketch.estimate();
- assert!(
- (est - 2.0).abs() < 0.1,
- "{hll_type:?}: expected estimate close to 2.0 after update
post-deserialize, got {est}"
- );
+ assert_that!(est, near(2.0, 0.1), "hll_type: {hll_type:?}");
}
}
@@ -309,6 +304,6 @@ fn test_estimate_accuracy() {
println!("{:<12} {:<12.0} {:<10.3}", expected, estimate, error_pct,);
// All estimates should be within 2% error
- assert!(error_pct < 2., "Error too high: {:.3}%", error_pct);
+ assert_that!(error_pct, lt(2.));
}
}
diff --git a/datasketches/tests/serde_tests/req.rs
b/datasketches/tests/serde_tests/req.rs
index 277b3f1..8a68fa3 100644
--- a/datasketches/tests/serde_tests/req.rs
+++ b/datasketches/tests/serde_tests/req.rs
@@ -24,6 +24,10 @@ use datasketches::req::RankAccuracy;
use datasketches::req::ReqSketch;
use datasketches::req::ReqValue;
use datasketches::req::SearchCriteria;
+use googletest::assert_that;
+use googletest::prelude::anything;
+use googletest::prelude::err;
+use googletest::prelude::ok;
use crate::serialization_test_data;
@@ -85,11 +89,7 @@ fn deserialize_truncated_preamble() {
for n in 0..8usize {
let bytes = vec![0u8; n];
let result = ReqSketch::<f32>::deserialize(&bytes);
- assert!(
- result.is_err(),
- "deserialize succeeded with {} bytes (expected error)",
- n
- );
+ assert_that!(result, err(anything()), "preamble length: {n}");
}
}
@@ -107,7 +107,7 @@ fn deserialize_wrong_family_id() {
0u8, // num_raw_items
];
let result = ReqSketch::<f32>::deserialize(&bytes);
- assert!(result.is_err(), "deserialize accepted wrong family id");
+ assert_that!(result, err(anything()));
let err = result.unwrap_err();
assert_eq!(
err.kind(),
@@ -126,7 +126,7 @@ fn deserialize_wrong_serial_version() {
12u8, 0u8, 0u8, 0u8,
];
let result = ReqSketch::<f32>::deserialize(&bytes);
- assert!(result.is_err(), "deserialize accepted wrong serial version");
+ assert_that!(result, err(anything()));
}
#[test]
@@ -134,10 +134,7 @@ fn deserialize_invalid_preamble_ints() {
// preamble_ints must be 2 (exact) or 4 (estimation). Try 3.
let bytes = [3u8, 1, 17, 4, 12, 0, 0, 0];
let result = ReqSketch::<f32>::deserialize(&bytes);
- assert!(
- result.is_err(),
- "deserialize accepted invalid preamble_ints=3"
- );
+ assert_that!(result, err(anything()));
}
#[test]
@@ -152,10 +149,7 @@ fn deserialize_rejects_non_empty_zero_levels() {
0u8,
];
let result = ReqSketch::<f32>::deserialize(&bytes);
- assert!(
- result.is_err(),
- "deserialize accepted non-empty sketch with zero levels"
- );
+ assert_that!(result, err(anything()));
}
#[test]
@@ -166,9 +160,9 @@ fn deserialize_rejects_inconsistent_raw_items_header() {
12, 0, 1u8, // num_levels
0u8, // invalid raw item count
];
- assert!(
- ReqSketch::<f32>::deserialize(&raw_with_no_items).is_err(),
- "deserialize accepted raw-items sketch with no raw items"
+ assert_that!(
+ ReqSketch::<f32>::deserialize(&raw_with_no_items),
+ err(anything())
);
let raw_with_two_levels = [
@@ -176,9 +170,9 @@ fn deserialize_rejects_inconsistent_raw_items_header() {
12, 0, 2u8, // invalid for raw-items sketches
1u8,
];
- assert!(
- ReqSketch::<f32>::deserialize(&raw_with_two_levels).is_err(),
- "deserialize accepted raw-items sketch with multiple levels"
+ assert_that!(
+ ReqSketch::<f32>::deserialize(&raw_with_two_levels),
+ err(anything())
);
}
@@ -191,24 +185,18 @@ fn deserialize_odd_k() {
0u8, 0u8,
];
let result = ReqSketch::<f32>::deserialize(&bytes);
- assert!(result.is_err(), "deserialize accepted odd k=11");
+ assert_that!(result, err(anything()));
}
#[test]
fn deserialize_k_out_of_range() {
// k must be in [4, 1024]. Try k=2 (too small).
let bytes_small = [2u8, 1, 17, 4, 2, 0, 0, 0];
- assert!(
- ReqSketch::<f32>::deserialize(&bytes_small).is_err(),
- "accepted k=2"
- );
+ assert_that!(ReqSketch::<f32>::deserialize(&bytes_small), err(anything()));
// k=2048 (too large): little-endian 2048 = [0x00, 0x08]
let bytes_big = [2u8, 1, 17, 4, 0, 8, 0, 0];
- assert!(
- ReqSketch::<f32>::deserialize(&bytes_big).is_err(),
- "accepted k=2048"
- );
+ assert_that!(ReqSketch::<f32>::deserialize(&bytes_big), err(anything()));
}
#[test]
@@ -226,10 +214,7 @@ fn deserialize_truncated_estimation_mode() {
* no payload — truncated */
];
let result = ReqSketch::<f32>::deserialize(&bytes);
- assert!(
- result.is_err(),
- "deserialize accepted truncated estimation-mode bytes"
- );
+ assert_that!(result, err(anything()));
}
#[test]
@@ -243,7 +228,7 @@ fn deserialize_truncated_raw_items() {
0u8, 0, 0x80, 0x3f, // 1.0_f32 (only 1 of the 3 promised items)
];
let result = ReqSketch::<f32>::deserialize(&bytes);
- assert!(result.is_err(), "deserialize accepted truncated raw_items");
+ assert_that!(result, err(anything()));
}
// ---------- Deserialize hardening: malformed compactor fields ----------
@@ -286,30 +271,21 @@ fn single_level_image_is_valid_baseline() {
// Control: the builder with well-formed fields round-trips, so the
malformed
// variants below isolate exactly one bad field.
let bytes = single_level_image(12.0, 0, 3, 1, &[1.0]);
- assert!(
- ReqSketch::<f32>::deserialize(&bytes).is_ok(),
- "baseline single-level image should deserialize"
- );
+ assert_that!(ReqSketch::<f32>::deserialize(&bytes), ok(anything()));
}
#[test]
fn deserialize_rejects_out_of_range_section_size() {
// A garbage section_size_raw drives the `nominal_capacity` arithmetic to
overflow.
let bytes = single_level_image(1e30, 0, 3, 1, &[1.0]);
- assert!(
- ReqSketch::<f32>::deserialize(&bytes).is_err(),
- "deserialize accepted out-of-range section_size_raw"
- );
+ assert_that!(ReqSketch::<f32>::deserialize(&bytes), err(anything()));
}
#[test]
fn deserialize_rejects_oversized_lg_weight() {
// lg_weight >= 64 makes the per-item weight `1u64 << lg_weight` overflow.
let bytes = single_level_image(12.0, 64, 3, 1, &[1.0]);
- assert!(
- ReqSketch::<f32>::deserialize(&bytes).is_err(),
- "deserialize accepted lg_weight = 64"
- );
+ assert_that!(ReqSketch::<f32>::deserialize(&bytes), err(anything()));
}
#[test]
@@ -317,10 +293,7 @@ fn deserialize_rejects_oversized_compactor_num_items() {
// num_items claims billions of items while only one is supplied:
deserialize
// must fail gracefully without attempting a multi-gigabyte allocation.
let bytes = single_level_image(12.0, 0, 3, u32::MAX, &[1.0]);
- assert!(
- ReqSketch::<f32>::deserialize(&bytes).is_err(),
- "deserialize accepted oversized num_items"
- );
+ assert_that!(ReqSketch::<f32>::deserialize(&bytes), err(anything()));
}
// ---------- Cross-language compatibility ----------
diff --git a/datasketches/tests/serde_tests/tdigest.rs
b/datasketches/tests/serde_tests/tdigest.rs
index 34463fc..9702827 100644
--- a/datasketches/tests/serde_tests/tdigest.rs
+++ b/datasketches/tests/serde_tests/tdigest.rs
@@ -20,7 +20,11 @@ use std::path::PathBuf;
use datasketches::tdigest::TDigestMut;
use googletest::assert_that;
+use googletest::prelude::all;
use googletest::prelude::eq;
+use googletest::prelude::ge;
+use googletest::prelude::is_finite;
+use googletest::prelude::le;
use googletest::prelude::near;
use crate::serialization_test_data;
@@ -341,8 +345,5 @@ fn test_large_weights_produce_finite_extreme_quantile() {
let mut tdigest = TDigestMut::deserialize(&bytes, false).unwrap();
let quantile = tdigest.quantile(0.25).unwrap();
- assert!(
- quantile.is_finite() && (lower..=f64::MAX).contains(&quantile),
- "quantile must remain within its finite interpolation bounds, got
{quantile}"
- );
+ assert_that!(quantile, all!(is_finite(), ge(lower), le(f64::MAX)));
}
diff --git a/datasketches/tests/serde_tests/tuple.rs
b/datasketches/tests/serde_tests/tuple.rs
index 3dadf98..b5c36f9 100644
--- a/datasketches/tests/serde_tests/tuple.rs
+++ b/datasketches/tests/serde_tests/tuple.rs
@@ -23,6 +23,8 @@ use datasketches::tuple::CompactTupleSketch;
use datasketches::tuple::DefaultUpdatePolicy;
use datasketches::tuple::TupleSketchBuilder;
use googletest::assert_that;
+use googletest::prelude::each;
+use googletest::prelude::eq;
use googletest::prelude::near;
use crate::serialization_test_data;
@@ -117,7 +119,8 @@ fn round_trip_preserves_summaries() {
CompactTupleSketch::<u64>::deserialize(&sketch.compact(true).serialize()).unwrap();
assert_eq!(restored.num_retained(), 50);
- assert!(restored.iter().all(|(_, &summary)| summary == 3));
+ let summaries: Vec<_> = restored.iter().map(|(_, &summary)|
summary).collect();
+ assert_that!(summaries, each(eq(&3)));
}
#[test]
diff --git a/datasketches/tests/tdigest_test/sketch.rs
b/datasketches/tests/tdigest_test/sketch.rs
index 56be846..162b6d5 100644
--- a/datasketches/tests/tdigest_test/sketch.rs
+++ b/datasketches/tests/tdigest_test/sketch.rs
@@ -20,6 +20,7 @@ use std::mem::size_of;
use datasketches::tdigest::TDigestMut;
use googletest::assert_that;
use googletest::prelude::eq;
+use googletest::prelude::is_finite;
use googletest::prelude::near;
#[test]
@@ -308,10 +309,7 @@ fn test_extreme_values_produce_finite_quantiles() {
assert_eq!(tdigest.max_value(), Some(f64::MAX));
for rank in [0.25, 0.5, 0.75] {
let quantile = tdigest.quantile(rank).unwrap();
- assert!(
- quantile.is_finite(),
- "quantile at rank {rank} must be finite, got {quantile}"
- );
+ assert_that!(quantile, is_finite(), "quantile at rank {rank}");
}
}
diff --git a/datasketches/tests/theta_test/a_not_b.rs
b/datasketches/tests/theta_test/a_not_b.rs
index bcb4388..bc98820 100644
--- a/datasketches/tests/theta_test/a_not_b.rs
+++ b/datasketches/tests/theta_test/a_not_b.rs
@@ -25,7 +25,10 @@ use datasketches::theta::ThetaANotB;
use datasketches::theta::ThetaSketch;
use datasketches::theta::ThetaSketchBuilder;
use googletest::assert_that;
+use googletest::prelude::anything;
+use googletest::prelude::err;
use googletest::prelude::lt;
+use googletest::prelude::near;
fn sketch_with_range(start: u64, count: u64) -> ThetaSketch {
let mut sketch = ThetaSketchBuilder::default().build();
@@ -73,8 +76,14 @@ fn test_seed_mismatch_returns_error() {
let good = sketch_with_range(0, 10);
let a_not_b = ThetaANotB::with_seed(1);
- assert!(a_not_b.compute(&one_other_seed, &good, true).is_err());
- assert!(a_not_b.compute(&good, &one_other_seed, true).is_err());
+ assert_that!(
+ a_not_b.compute(&one_other_seed, &good, true),
+ err(anything())
+ );
+ assert_that!(
+ a_not_b.compute(&good, &one_other_seed, true),
+ err(anything())
+ );
}
#[test]
@@ -201,7 +210,7 @@ fn test_estimation_lower_theta_b_unordered() {
assert!(!r.is_empty());
assert!(r.is_estimation_mode());
assert_eq!(r.theta64(), b.theta64());
- assert!((r.estimate() - 5000.0).abs() <= 5000.0 * 0.03);
+ assert_that!(r.estimate(), near(5000.0, 5000.0 * 0.03));
}
#[test]
@@ -218,7 +227,7 @@ fn test_estimation_lower_theta_b_ordered() {
assert!(!r.is_empty());
assert!(r.is_estimation_mode());
assert_eq!(r.theta64(), b.theta64());
- assert!((r.estimate() - 5000.0).abs() <= 5000.0 * 0.03);
+ assert_that!(r.estimate(), near(5000.0, 5000.0 * 0.03));
}
#[test]
@@ -233,7 +242,7 @@ fn test_estimation_partial_overlap_deserialized_compact() {
assert!(!r.is_empty());
assert!(r.is_estimation_mode());
- assert!((r.estimate() - 5000.0).abs() <= 5000.0 * 0.02);
+ assert_that!(r.estimate(), near(5000.0, 5000.0 * 0.02));
}
#[test]
@@ -246,5 +255,5 @@ fn test_estimation_disjoint_returns_a() {
assert!(!r.is_empty());
assert!(r.is_estimation_mode());
- assert!((r.estimate() - 10000.0).abs() <= 10000.0 * 0.02);
+ assert_that!(r.estimate(), near(10000.0, 10000.0 * 0.02));
}
diff --git a/datasketches/tests/theta_test/intersection.rs
b/datasketches/tests/theta_test/intersection.rs
index 6e9a103..49c7593 100644
--- a/datasketches/tests/theta_test/intersection.rs
+++ b/datasketches/tests/theta_test/intersection.rs
@@ -19,6 +19,12 @@ use datasketches::theta::CompactThetaSketch;
use datasketches::theta::ThetaIntersection;
use datasketches::theta::ThetaSketch;
use datasketches::theta::ThetaSketchBuilder;
+use googletest::assert_that;
+use googletest::prelude::anything;
+use googletest::prelude::err;
+use googletest::prelude::ge;
+use googletest::prelude::near;
+use googletest::prelude::none;
fn sketch_with_range(start: u64, count: u64) -> ThetaSketch {
let mut sketch = ThetaSketchBuilder::default().build();
@@ -37,13 +43,13 @@ fn test_has_result_state_machine() {
assert!(!i.has_result());
i.update(&a).unwrap();
assert!(i.has_result());
- assert!(i.to_sketch(true).unwrap().estimate() >= 1.0);
+ assert_that!(i.to_sketch(true).unwrap().estimate(), ge(1.0));
}
#[test]
fn test_result_before_first_update_returns_none() {
let i = ThetaIntersection::with_seed(123);
- assert!(i.to_sketch(true).is_none());
+ assert_that!(i.to_sketch(true), none());
}
#[test]
@@ -61,7 +67,7 @@ fn test_update_accepts_compact_sketch() {
i.update(&b).unwrap();
let r = i.to_sketch(true).unwrap();
- assert!(r.estimate() == 1.0);
+ assert_eq!(r.estimate(), 1.0);
assert!(r.is_ordered());
let mut c = ThetaSketchBuilder::default().build();
@@ -72,7 +78,7 @@ fn test_update_accepts_compact_sketch() {
i.update(&c.compact(false)).unwrap();
let r = i.to_sketch(false).unwrap();
- assert!(r.estimate() == 0.0);
+ assert_eq!(r.estimate(), 0.0);
assert!(!r.is_ordered());
}
@@ -93,7 +99,7 @@ fn test_seed_mismatch_behaviour() {
one_other_seed.update("value");
let mut i = ThetaIntersection::with_seed(1);
- assert!(i.update(&one_other_seed).is_err());
+ assert_that!(i.update(&one_other_seed), err(anything()));
}
#[test]
@@ -157,7 +163,7 @@ fn test_non_empty_no_retained_keys() {
assert_eq!(r1.num_retained(), 0);
assert!(!r1.is_empty());
assert!(r1.is_estimation_mode());
- assert!((r1.theta() - 0.001).abs() < 1e-10);
+ assert_that!(r1.theta(), near(0.001, 1e-10));
assert_eq!(r1.estimate(), 0.0);
i.update(&s).unwrap();
@@ -165,7 +171,7 @@ fn test_non_empty_no_retained_keys() {
assert_eq!(r2.num_retained(), 0);
assert!(!r2.is_empty());
assert!(r2.is_estimation_mode());
- assert!((r2.theta() - 0.001).abs() < 1e-10);
+ assert_that!(r2.theta(), near(0.001, 1e-10));
assert_eq!(r2.estimate(), 0.0);
}
@@ -241,7 +247,7 @@ fn test_estimation_half_overlap_unordered() {
assert!(!r.is_empty());
assert!(r.is_estimation_mode());
- assert!((r.estimate() - 5000.0).abs() <= 5000.0 * 0.02);
+ assert_that!(r.estimate(), near(5000.0, 5000.0 * 0.02));
}
#[test]
@@ -256,7 +262,7 @@ fn test_estimation_half_overlap_ordered() {
assert!(!r.is_empty());
assert!(r.is_estimation_mode());
- assert!((r.estimate() - 5000.0).abs() <= 5000.0 * 0.02);
+ assert_that!(r.estimate(), near(5000.0, 5000.0 * 0.02));
}
#[test]
@@ -273,7 +279,7 @@ fn
test_estimation_half_overlap_ordered_deserialized_compact() {
assert!(!r.is_empty());
assert!(r.is_estimation_mode());
- assert!((r.estimate() - 5000.0).abs() <= 5000.0 * 0.02);
+ assert_that!(r.estimate(), near(5000.0, 5000.0 * 0.02));
}
#[test]
@@ -312,7 +318,7 @@ fn test_seed_mismatch_non_empty_returns_error() {
s.update(1u64);
let mut i = ThetaIntersection::with_seed(123);
- assert!(i.update(&s).is_err());
+ assert_that!(i.update(&s), err(anything()));
}
#[test]
diff --git a/datasketches/tests/theta_test/jaccard_similarity.rs
b/datasketches/tests/theta_test/jaccard_similarity.rs
index acdee30..104dd51 100644
--- a/datasketches/tests/theta_test/jaccard_similarity.rs
+++ b/datasketches/tests/theta_test/jaccard_similarity.rs
@@ -19,6 +19,10 @@ use datasketches::theta::ThetaJaccardSimilarity;
use datasketches::theta::ThetaSketch;
use datasketches::theta::ThetaSketchBuilder;
use datasketches::thetacommon::JaccardSimilarity;
+use googletest::assert_that;
+use googletest::prelude::anything;
+use googletest::prelude::err;
+use googletest::prelude::near;
fn assert_jaccard_exact(actual: JaccardSimilarity, expected: f64) {
assert_eq!(actual.lower_bound(), expected);
@@ -27,10 +31,7 @@ fn assert_jaccard_exact(actual: JaccardSimilarity, expected:
f64) {
}
fn assert_close(actual: f64, expected: f64, margin: f64) {
- assert!(
- (actual - expected).abs() <= margin,
- "actual={actual}, expected={expected}, margin={margin}"
- );
+ assert_that!(actual, near(expected, margin));
}
fn assert_jaccard_estimate(actual: JaccardSimilarity, expected: f64) {
@@ -167,15 +168,13 @@ fn test_seed_mismatch() {
let mut sketch_b = ThetaSketchBuilder::default().seed(123).build();
sketch_b.update(1u64);
- assert!(
- ThetaJaccardSimilarity::default()
- .compute(&sketch_a, &sketch_b)
- .is_err()
+ assert_that!(
+ ThetaJaccardSimilarity::default().compute(&sketch_a, &sketch_b),
+ err(anything())
);
- assert!(
- ThetaJaccardSimilarity::default()
- .exactly_equal(&sketch_a, &sketch_b)
- .is_err()
+ assert_that!(
+ ThetaJaccardSimilarity::default().exactly_equal(&sketch_a, &sketch_b),
+ err(anything())
);
assert!(
!ThetaJaccardSimilarity::default()
diff --git a/datasketches/tests/theta_test/sketch.rs
b/datasketches/tests/theta_test/sketch.rs
index 2ed07db..f4d976f 100644
--- a/datasketches/tests/theta_test/sketch.rs
+++ b/datasketches/tests/theta_test/sketch.rs
@@ -18,6 +18,12 @@
use datasketches::common::NumStdDev;
use datasketches::hash::value::canonical_float;
use datasketches::theta::ThetaSketchBuilder;
+use googletest::assert_that;
+use googletest::prelude::ge;
+use googletest::prelude::gt;
+use googletest::prelude::le;
+use googletest::prelude::lt;
+use googletest::prelude::near;
#[test]
fn test_basic_update() {
@@ -88,7 +94,7 @@ fn test_theta_reduction() {
}
assert!(sketch.is_estimation_mode()); // Should be in estimation mode
- assert!(sketch.theta() < 1.0);
+ assert_that!(sketch.theta(), lt(1.0));
}
#[test]
@@ -110,7 +116,7 @@ fn test_trim() {
let mut retained_hashes: Vec<_> = sketch.iter().map(|entry|
entry.hash()).collect();
retained_hashes.sort_unstable();
- assert!(sketch.num_retained() <= before_trim);
+ assert_that!(sketch.num_retained(), le(before_trim));
assert_eq!(sketch.num_retained(), 32);
assert_eq!(retained_hashes, expected_hashes[..32]);
assert_eq!(sketch.theta64(), expected_hashes[32]);
@@ -126,8 +132,8 @@ fn test_reset() {
}
assert!(!sketch.is_empty());
assert!(sketch.is_estimation_mode());
- assert!(sketch.num_retained() > 32);
- assert!(sketch.theta() < 1.0);
+ assert_that!(sketch.num_retained(), gt(32));
+ assert_that!(sketch.theta(), lt(1.0));
sketch.reset();
assert!(sketch.is_empty());
@@ -189,7 +195,7 @@ fn test_bounds_estimation_mode() {
}
assert!(!sketch.is_empty());
assert!(sketch.is_estimation_mode());
- assert!(sketch.theta() < 1.0);
+ assert_that!(sketch.theta(), lt(1.0));
let estimate = sketch.estimate();
let lower_bound_1 = sketch.lower_bound(NumStdDev::One);
@@ -200,26 +206,21 @@ fn test_bounds_estimation_mode() {
let upper_bound_3 = sketch.upper_bound(NumStdDev::Three);
// Check estimate is within reasonable margin (2% to be safe)
- assert!(
- (estimate - n as f64).abs() < n as f64 * 0.02,
- "estimate {} is not within 2% of {}",
- estimate,
- n
- );
+ assert_that!(estimate, near(n as f64, n as f64 * 0.02));
// Check bounds are in correct order
- assert!(lower_bound_1 < estimate);
- assert!(estimate < upper_bound_1);
- assert!(lower_bound_2 < estimate);
- assert!(estimate < upper_bound_2);
- assert!(lower_bound_3 < estimate);
- assert!(estimate < upper_bound_3);
+ assert_that!(estimate, gt(lower_bound_1));
+ assert_that!(estimate, lt(upper_bound_1));
+ assert_that!(estimate, gt(lower_bound_2));
+ assert_that!(estimate, lt(upper_bound_2));
+ assert_that!(estimate, gt(lower_bound_3));
+ assert_that!(estimate, lt(upper_bound_3));
// Check that wider confidence intervals are indeed wider
- assert!(lower_bound_3 < lower_bound_2);
- assert!(lower_bound_2 < lower_bound_1);
- assert!(upper_bound_1 < upper_bound_2);
- assert!(upper_bound_2 < upper_bound_3);
+ assert_that!(lower_bound_3, lt(lower_bound_2));
+ assert_that!(lower_bound_2, lt(lower_bound_1));
+ assert_that!(upper_bound_1, lt(upper_bound_2));
+ assert_that!(upper_bound_2, lt(upper_bound_3));
}
#[test]
@@ -235,14 +236,14 @@ fn test_bounds_with_sampling() {
assert!(!sketch.is_empty());
assert!(sketch.is_estimation_mode());
- assert!(sketch.theta() < 1.0);
+ assert_that!(sketch.theta(), lt(1.0));
let estimate = sketch.estimate();
let lower_bound = sketch.lower_bound(NumStdDev::Two);
let upper_bound = sketch.upper_bound(NumStdDev::Two);
- assert!(lower_bound <= estimate);
- assert!(estimate <= upper_bound);
+ assert_that!(estimate, ge(lower_bound));
+ assert_that!(estimate, le(upper_bound));
}
#[test]
@@ -262,10 +263,10 @@ fn test_bounds_all_num_std_devs() {
let ub3 = sketch.upper_bound(NumStdDev::Three);
// Verify the bounds are properly ordered
- assert!(lb3 <= lb2);
- assert!(lb2 <= lb1);
- assert!(ub1 <= ub2);
- assert!(ub2 <= ub3);
+ assert_that!(lb3, le(lb2));
+ assert_that!(lb2, le(lb1));
+ assert_that!(ub1, le(ub2));
+ assert_that!(ub2, le(ub3));
}
#[test]
diff --git a/datasketches/tests/theta_test/union.rs
b/datasketches/tests/theta_test/union.rs
index 2a6f1cc..c19eb9d 100644
--- a/datasketches/tests/theta_test/union.rs
+++ b/datasketches/tests/theta_test/union.rs
@@ -19,6 +19,11 @@ use datasketches::theta::CompactThetaSketch;
use datasketches::theta::ThetaSketch;
use datasketches::theta::ThetaSketchBuilder;
use datasketches::theta::ThetaUnionBuilder;
+use googletest::assert_that;
+use googletest::prelude::anything;
+use googletest::prelude::err;
+use googletest::prelude::le;
+use googletest::prelude::near;
fn sketch_with_range(lg_k: u8, start: i64, count: i64) -> ThetaSketch {
let mut sketch = ThetaSketchBuilder::default().lg_k(lg_k).build();
@@ -29,12 +34,10 @@ fn sketch_with_range(lg_k: u8, start: i64, count: i64) ->
ThetaSketch {
}
fn assert_estimate_close(sketch: &CompactThetaSketch, expected: f64,
tolerance: f64) {
- assert!(
- (sketch.estimate() - expected).abs() <= tolerance,
- "estimate={}, expected={}, tolerance={}, theta={}, retained={}",
+ assert_that!(
sketch.estimate(),
- expected,
- tolerance,
+ near(expected, tolerance),
+ "theta={}, retained={}",
sketch.theta(),
sketch.num_retained()
);
@@ -69,7 +72,7 @@ fn test_non_empty_no_retained_keys() {
assert_eq!(result.num_retained(), 0);
assert!(!result.is_empty());
assert!(result.is_estimation_mode());
- assert!((result.theta() - 0.001).abs() < 1e-10);
+ assert_that!(result.theta(), near(0.001, 1e-10));
}
#[test]
@@ -140,10 +143,10 @@ fn test_estimation_mode_half_overlap() {
let result = union.to_sketch(true);
assert!(!result.is_empty());
assert!(result.is_estimation_mode());
- assert!(
- (result.estimate() - 15000.0).abs() <= 15000.0 * 0.01,
- "estimate={}, theta={}, retained={}",
+ assert_that!(
result.estimate(),
+ near(15000.0, 15000.0 * 0.01),
+ "theta={}, retained={}",
result.theta(),
result.num_retained()
);
@@ -155,7 +158,7 @@ fn test_seed_mismatch() {
sketch.update(1u64);
let mut union = ThetaUnionBuilder::default().seed(123).build();
- assert!(union.update(&sketch).is_err());
+ assert_that!(union.update(&sketch), err(anything()));
}
#[test]
@@ -381,7 +384,7 @@ fn test_union_cutback_to_k() {
let result = union.to_sketch(true);
assert_estimate_close(&result, (6 * k) as f64, (6 * k) as f64 * 0.06);
- assert!(result.num_retained() <= k as usize);
+ assert_that!(result.num_retained(), le(k as usize));
}
#[test]
@@ -659,10 +662,10 @@ fn test_corner_case_union_states() {
union.update(&sketch_b).unwrap();
let result = union.to_sketch(true);
- assert!(
- (result.theta() - expected_theta).abs() < 1e-6,
- "state_a={state_a:?}, state_b={state_b:?}, theta={}",
- result.theta()
+ assert_that!(
+ result.theta(),
+ near(expected_theta, 1e-6),
+ "state_a={state_a:?}, state_b={state_b:?}"
);
assert_eq!(
result.num_retained(),
@@ -682,7 +685,7 @@ fn test_corner_case_union_states() {
union.update(&compact_b).unwrap();
let compact_result = union.to_sketch(true);
- assert!((compact_result.theta() - expected_theta).abs() < 1e-6);
+ assert_that!(compact_result.theta(), near(expected_theta, 1e-6));
assert_eq!(compact_result.num_retained(), expected_count);
assert_eq!(compact_result.is_empty(), expected_empty);
}
diff --git a/datasketches/tests/tuple_test/a_not_b.rs
b/datasketches/tests/tuple_test/a_not_b.rs
index d0162be..18806dd 100644
--- a/datasketches/tests/tuple_test/a_not_b.rs
+++ b/datasketches/tests/tuple_test/a_not_b.rs
@@ -19,6 +19,10 @@ use datasketches::common::NumStdDev;
use datasketches::error::ErrorKind;
use datasketches::tuple::CompactTupleSketch;
use datasketches::tuple::TupleANotB;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::ge;
+use googletest::prelude::le;
use super::default_tuple_sketch_builder;
use super::tuple_sketch_with_range;
@@ -177,8 +181,5 @@ fn estimation_bounds_cover_the_true_difference() {
let upper = result.upper_bound(NumStdDev::Three);
assert!(result.is_estimation_mode());
- assert!(
- lower <= 25_000.0 && 25_000.0 <= upper,
- "expected 25000 in [{lower}, {upper}]"
- );
+ assert_that!(25_000.0, all!(ge(lower), le(upper)));
}
diff --git a/datasketches/tests/tuple_test/intersection.rs
b/datasketches/tests/tuple_test/intersection.rs
index 9dd181f..6338b43 100644
--- a/datasketches/tests/tuple_test/intersection.rs
+++ b/datasketches/tests/tuple_test/intersection.rs
@@ -20,6 +20,10 @@ use datasketches::error::ErrorKind;
use datasketches::tuple::SummaryCombinePolicy;
use datasketches::tuple::SummaryPolicy;
use datasketches::tuple::TupleIntersection;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::ge;
+use googletest::prelude::le;
use super::default_tuple_sketch_builder;
use super::tuple_sketch_with_range;
@@ -173,10 +177,7 @@ fn estimation_bounds_cover_the_true_intersection() {
let upper = result.upper_bound(NumStdDev::Three);
assert!(result.is_estimation_mode());
- assert!(
- lower <= 25_000.0 && 25_000.0 <= upper,
- "expected 25000 in [{lower}, {upper}]"
- );
+ assert_that!(25_000.0, all!(ge(lower), le(upper)));
}
#[test]
diff --git a/datasketches/tests/tuple_test/jaccard_similarity.rs
b/datasketches/tests/tuple_test/jaccard_similarity.rs
index af9342a..7bb6c2a 100644
--- a/datasketches/tests/tuple_test/jaccard_similarity.rs
+++ b/datasketches/tests/tuple_test/jaccard_similarity.rs
@@ -19,6 +19,10 @@ use datasketches::thetacommon::JaccardSimilarity;
use datasketches::tuple::DefaultUpdatePolicy;
use datasketches::tuple::TupleJaccardSimilarity;
use datasketches::tuple::TupleSketchBuilder;
+use googletest::assert_that;
+use googletest::prelude::anything;
+use googletest::prelude::err;
+use googletest::prelude::near;
use crate::default_tuple_sketch_builder;
use crate::tuple_sketch_with_range;
@@ -30,10 +34,7 @@ fn assert_jaccard_exact(actual: JaccardSimilarity, expected:
f64) {
}
fn assert_close(actual: f64, expected: f64, margin: f64) {
- assert!(
- (actual - expected).abs() <= margin,
- "actual={actual}, expected={expected}, margin={margin}"
- );
+ assert_that!(actual, near(expected, margin));
}
fn assert_jaccard_estimate(actual: JaccardSimilarity, expected: f64) {
@@ -111,15 +112,13 @@ fn test_custom_seed_and_seed_mismatch() {
let jaccard = operator.compute(&sketch_a, &sketch_b).unwrap();
assert_jaccard_exact(jaccard, 1.0);
assert!(operator.exactly_equal(&sketch_a, &sketch_b).unwrap());
- assert!(
- TupleJaccardSimilarity::default()
- .compute(&sketch_a, &sketch_b)
- .is_err()
+ assert_that!(
+ TupleJaccardSimilarity::default().compute(&sketch_a, &sketch_b),
+ err(anything())
);
- assert!(
- TupleJaccardSimilarity::default()
- .exactly_equal(&sketch_a, &sketch_b)
- .is_err()
+ assert_that!(
+ TupleJaccardSimilarity::default().exactly_equal(&sketch_a, &sketch_b),
+ err(anything())
);
assert!(
!TupleJaccardSimilarity::default()
diff --git a/datasketches/tests/tuple_test/sketch.rs
b/datasketches/tests/tuple_test/sketch.rs
index 34110e7..154a8b8 100644
--- a/datasketches/tests/tuple_test/sketch.rs
+++ b/datasketches/tests/tuple_test/sketch.rs
@@ -23,6 +23,10 @@ use datasketches::tuple::SummaryPolicy;
use datasketches::tuple::SummaryUpdatePolicy;
use datasketches::tuple::TupleSketch;
use datasketches::tuple::TupleSketchBuilder;
+use googletest::assert_that;
+use googletest::prelude::gt;
+use googletest::prelude::le;
+use googletest::prelude::lt;
use super::default_tuple_sketch_builder;
@@ -137,10 +141,10 @@ fn bounds_cover_exact_and_estimation_results() {
let upper_three = estimated.upper_bound(NumStdDev::Three);
assert!(estimated.is_estimation_mode());
- assert!(lower_three <= lower_one);
- assert!(lower_one < estimate);
- assert!(estimate < upper_one);
- assert!(upper_one <= upper_three);
+ assert_that!(lower_three, le(lower_one));
+ assert_that!(estimate, gt(lower_one));
+ assert_that!(estimate, lt(upper_one));
+ assert_that!(upper_one, le(upper_three));
}
#[test]
diff --git a/datasketches/tests/tuple_test/union.rs
b/datasketches/tests/tuple_test/union.rs
index 23e75aa..5c3422c 100644
--- a/datasketches/tests/tuple_test/union.rs
+++ b/datasketches/tests/tuple_test/union.rs
@@ -21,6 +21,10 @@ use datasketches::tuple::DefaultUnionPolicy;
use datasketches::tuple::SummaryCombinePolicy;
use datasketches::tuple::SummaryPolicy;
use datasketches::tuple::TupleUnionBuilder;
+use googletest::assert_that;
+use googletest::prelude::all;
+use googletest::prelude::ge;
+use googletest::prelude::le;
use super::default_tuple_sketch_builder;
use super::tuple_sketch_with_range;
@@ -146,10 +150,7 @@ fn estimation_bounds_cover_the_true_union() {
let upper = result.upper_bound(NumStdDev::Three);
assert!(result.is_estimation_mode());
- assert!(
- lower <= 75_000.0 && 75_000.0 <= upper,
- "expected 75000 in [{lower}, {upper}]"
- );
+ assert_that!(75_000.0, all!(ge(lower), le(upper)));
}
#[test]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]