use crate::stream::collection_extract::{source, ChangeSource};
use crate::stream::joiner::equal_bi;
use crate::stream::relational::operator::{CollectionNode, JoinNode, Operator, Pair};
use crate::stream::relational::Leaf;
use super::fixtures::{
rel_assignments, rel_employees, rel_shifts, sample, RelAssignment, RelEmployee, RelSchedule,
RelShift,
};
fn assignment_key_leaf(row: &Leaf<'_, RelAssignment>) -> u32 {
row.entity.shift_id
}
fn shift_key_leaf(row: &Leaf<'_, RelShift>) -> u32 {
row.entity.id
}
fn employee_code_leaf(row: &Leaf<'_, RelEmployee>) -> String {
row.entity.code.clone()
}
fn pair_employee_code(row: &Pair<Leaf<'_, RelAssignment>, Leaf<'_, RelShift>>) -> String {
row.left.entity.employee_code.clone()
}
fn tri_shift_id(
row: &Pair<Pair<Leaf<'_, RelAssignment>, Leaf<'_, RelShift>>, Leaf<'_, RelEmployee>>,
) -> u32 {
row.left.right.entity.id
}
#[test]
fn four_source_typed_chain_resolves_and_counts() {
let a = CollectionNode::new(
source(
rel_assignments as fn(&RelSchedule) -> &[RelAssignment],
ChangeSource::Descriptor(1),
),
1,
);
let s = CollectionNode::new(
source(
rel_shifts as fn(&RelSchedule) -> &[RelShift],
ChangeSource::Descriptor(0),
),
0,
);
let e = CollectionNode::new(
source(
rel_employees as fn(&RelSchedule) -> &[RelEmployee],
ChangeSource::Descriptor(2),
),
2,
);
let s2 = CollectionNode::new(
source(
rel_shifts as fn(&RelSchedule) -> &[RelShift],
ChangeSource::Descriptor(0),
),
3,
);
let pair = JoinNode::new(a, s, equal_bi(assignment_key_leaf, shift_key_leaf));
let tri = JoinNode::new(pair, e, equal_bi(pair_employee_code, employee_code_leaf));
let quad = JoinNode::new(tri, s2, equal_bi(tri_shift_id, shift_key_leaf));
let schedule = sample();
let mut count = 0usize;
quad.visit_all(&schedule, &mut |_row| {
count += 1;
});
assert_eq!(count, 3);
}