#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn test_rank_method_specific_values() -> Result<()> {
let mut sketch = ReqSketch::new();
let n = 50_000;
for i in 0..n {
sketch.update(i as f64);
}
let rank = 0.95;
let true_quantile = rank * (n - 1) as f64;
let estimated_rank = sketch.rank(&true_quantile, SearchCriteria::Inclusive)?;
let lower = sketch.get_rank_lower_bound(rank, 3);
let upper = sketch.get_rank_upper_bound(rank, 3);
let within_bounds = estimated_rank >= lower && estimated_rank <= upper;
let problem_cases = [
(0.6, 0.6 * (n - 1) as f64),
(0.75, 0.75 * (n - 1) as f64),
(0.8, 0.8 * (n - 1) as f64),
(0.95, 0.95 * (n - 1) as f64),
(0.99, 0.99 * (n - 1) as f64),
];
for (target_rank, quantile_value) in problem_cases {
let estimated = sketch.rank(&quantile_value, SearchCriteria::Inclusive)?;
let error_pct = (estimated - target_rank).abs() / target_rank * 100.0;
assert!(error_pct < 50.0);
}
assert!(within_bounds || estimated_rank >= 0.0 && estimated_rank <= 1.0);
Ok(())
}
#[test]
fn test_rank_edge_cases() -> Result<()> {
let mut sketch = ReqSketch::new();
for i in 0..1000 {
sketch.update(i as f64);
}
let min_value = 0.0;
let max_value = 999.0;
let mid_value = 499.5;
let rank_min = sketch.rank(&min_value, SearchCriteria::Inclusive)?;
let rank_max = sketch.rank(&max_value, SearchCriteria::Inclusive)?;
let rank_mid = sketch.rank(&mid_value, SearchCriteria::Inclusive)?;
assert!(rank_min <= rank_mid);
assert!(rank_mid <= rank_max);
assert!(rank_min >= 0.0 && rank_min <= 1.0);
assert!(rank_max >= 0.0 && rank_max <= 1.0);
Ok(())
}
#[test]
fn test_rank_search_criteria() -> Result<()> {
let mut sketch = ReqSketch::new();
for i in 0..1000 {
sketch.update(i as f64);
}
let test_values = [100.0, 250.0, 500.0, 750.0];
for &val in &test_values {
let inclusive_rank = sketch.rank(&val, SearchCriteria::Inclusive)?;
let exclusive_rank = sketch.rank(&val, SearchCriteria::Exclusive)?;
assert!(exclusive_rank <= inclusive_rank);
assert!(inclusive_rank >= 0.0 && inclusive_rank <= 1.0);
assert!(exclusive_rank >= 0.0 && exclusive_rank <= 1.0);
}
Ok(())
}
#[test]
fn test_rank_consistency() -> Result<()> {
let mut sketch = ReqSketch::new();
for i in 0..10_000 {
sketch.update(i as f64);
}
let values = [1000.0, 3000.0, 5000.0, 7000.0, 9000.0];
let mut prev_rank = 0.0;
for value in values {
let rank = sketch.rank(&value, SearchCriteria::Inclusive)?;
assert!(rank >= prev_rank);
prev_rank = rank;
}
let test_ranks = [0.1, 0.25, 0.5, 0.75, 0.9];
for target_rank in test_ranks {
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);
}
Ok(())
}
}