use super::*;
use crate::test_support::{make_batch, make_schema_u64_i64, trace_cursor, weighted_rows};
use gnitz_wire::ClampKind::{Distinct, PositivePart};
pub(super) type ClampRow = (u64, i64, i64);
fn clamped(kind: ClampKind, w: i64) -> i64 {
match kind {
Distinct => i64::from(w > 0),
PositivePart => w.max(0),
}
}
fn reference(kind: ClampKind, delta: &[ClampRow], trace: &[ClampRow]) -> Vec<ClampRow> {
delta
.iter()
.filter_map(|&(pk, dw, val)| {
let w_old: i64 = trace
.iter()
.filter(|&&(p, _, v)| (p, v) == (pk, val))
.map(|&(_, w, _)| w)
.sum();
let out = clamped(kind, w_old + dw) - clamped(kind, w_old);
(out != 0).then_some((pk, out, val))
})
.collect()
}
#[test]
fn weight_clamp_emits_each_elements_transition() {
let schema = make_schema_u64_i64();
let cases: [(&[ClampRow], &[ClampRow]); 12] = [
(&[(1, 3, 10)], &[]),
(&[(1, -2, 10)], &[(1, 3, 10)]),
(&[(1, -1, 10)], &[(1, 1, 10)]),
(&[(1, 1, 10)], &[(1, 1, 10)]),
(&[(1, -2, 10)], &[]),
(&[(1, 3, 10)], &[(1, 5, 10)]),
(&[(1, -10, 10)], &[(1, 8, 10)]),
(&[(1, 4, 10)], &[(1, -2, 10)]),
(&[(1, 1, 5), (2, 1, 20)], &[]),
(
&[(1, 1, 10), (1, -1, 11), (5, 1, 50)],
&[(1, 1, 11), (1, 1, 12), (1, 1, 13), (5, 1, 55)],
),
(
&[(1, -1, 10), (1, 1, 20), (1, 1, 40), (3, 1, 30)],
&[(0, 1, 5), (1, 1, 10), (1, 1, 20), (1, 1, 30), (2, 1, 7)],
),
(&[(1, 4, 10), (2, 1, 20)], &[(1, -2, 10), (2, -1, 20)]),
];
for (delta, trace) in cases {
for kind in [Distinct, PositivePart] {
let mut ch = trace_cursor(make_batch(&schema, trace));
let out = op_weight_clamp(&make_batch(&schema, delta), &mut ch, kind);
assert!(out.is_consolidated());
assert_eq!(
weighted_rows(&out),
weighted_rows(&make_batch(&schema, &reference(kind, delta, trace))),
"{kind:?}: delta={delta:?} trace={trace:?}"
);
}
}
}