use super::{FusionError, FusionStrategy};
const NON_FINITE: [f32; 3] = [f32::NAN, f32::INFINITY, f32::NEG_INFINITY];
#[test]
fn weighted_rrf_rejects_non_finite_weights_at_construction() {
for bad in NON_FINITE {
let err = FusionStrategy::weighted_rrf(vec![bad, 1.0], 60.0)
.expect_err("a non-finite weight must not build a strategy");
assert!(
matches!(err, FusionError::NonFiniteWeight { .. }),
"weight {bad} produced {err} instead of NonFiniteWeight"
);
}
}
#[test]
fn weighted_rrf_rejects_non_finite_k_at_construction() {
for bad in NON_FINITE {
let err = FusionStrategy::weighted_rrf(vec![1.0], bad)
.expect_err("a non-finite k must not build a strategy");
assert!(
matches!(err, FusionError::NonFiniteWeight { .. }),
"k {bad} produced {err} instead of NonFiniteWeight"
);
}
}
#[test]
fn weighted_rejects_non_finite_weights_at_construction() {
for bad in NON_FINITE {
let err = FusionStrategy::weighted(bad, 0.3, 0.1)
.expect_err("a non-finite weight must not build a strategy");
assert!(
matches!(err, FusionError::NonFiniteWeight { .. }),
"weight {bad} produced {err} instead of NonFiniteWeight"
);
}
}
#[test]
fn relative_score_rejects_non_finite_weights_at_construction() {
for bad in NON_FINITE {
let err = FusionStrategy::relative_score(bad, 0.5)
.expect_err("a non-finite weight must not build a strategy");
assert!(
matches!(err, FusionError::NonFiniteWeight { .. }),
"weight {bad} produced {err} instead of NonFiniteWeight"
);
}
}
#[test]
fn fuse_rejects_a_non_finite_weight_built_as_an_enum_literal() {
for bad in NON_FINITE {
let strategy = FusionStrategy::WeightedRRF {
weights: vec![bad],
k: 60.0,
};
let err = strategy
.fuse(vec![vec![(1u64, 0.9)]])
.expect_err("fuse must revalidate a literal-built strategy");
assert!(
matches!(err, FusionError::NonFiniteWeight { .. }),
"weight {bad} produced {err} instead of NonFiniteWeight"
);
}
}
#[test]
fn fuse_rejects_a_non_finite_k_built_as_an_enum_literal() {
for bad in NON_FINITE {
let strategy = FusionStrategy::WeightedRRF {
weights: vec![1.0],
k: bad,
};
let err = strategy
.fuse(vec![vec![(1u64, 0.9)]])
.expect_err("fuse must revalidate a literal-built strategy");
assert!(
matches!(err, FusionError::NonFiniteWeight { .. }),
"k {bad} produced {err} instead of NonFiniteWeight"
);
}
}
#[test]
fn a_nan_weight_can_no_longer_sink_a_genuinely_scored_document() {
let strategy = FusionStrategy::WeightedRRF {
weights: vec![f32::NAN, 1.0],
k: 60.0,
};
let branches = vec![
vec![(1u64, 0.9f32), (2u64, 0.5f32)],
vec![(2u64, 0.8f32), (3u64, 0.4f32)],
];
let err = strategy
.fuse(branches)
.expect_err("the NaN branch weight must be refused, not ranked");
assert!(matches!(err, FusionError::NonFiniteWeight { .. }));
}
#[test]
fn finite_weights_still_build_and_fuse() {
let strategy =
FusionStrategy::weighted_rrf(vec![0.7, 0.3], 60.0).expect("finite weights must build");
let fused = strategy
.fuse(vec![
vec![(1u64, 0.9f32), (2u64, 0.5f32)],
vec![(2u64, 0.8f32), (3u64, 0.4f32)],
])
.expect("finite weights must fuse");
assert_eq!(fused.len(), 3, "every document must survive the fusion");
for (id, score) in fused {
assert!(score.is_finite(), "document {id} scored {score}");
}
}