| 46 | } |
| 47 | |
| 48 | pub fn assert_valid_graph(fixture: &GraphFixture, graph: &Graph) { |
| 49 | // helpers for extracting data from fixtures |
| 50 | let get_fixture_metadata_map = |c_props: &Vec<(String, Prop)>| -> HashMap<ArcStr, Prop> { |
| 51 | c_props |
| 52 | .iter() |
| 53 | .map(|(k, v)| (ArcStr::from(k.as_str()), v.clone())) |
| 54 | .collect() |
| 55 | }; |
| 56 | |
| 57 | // compare histories as multiset as order for values with the same timestamp is ambiguous! |
| 58 | let get_fixture_t_prop_counts = |
| 59 | |t_props: &Vec<(i64, Vec<(String, Prop)>)>| -> HashMap<ArcStr, Vec<(i64, HashMap<Prop, usize>)>> { |
| 60 | let mut grouped: HashMap<ArcStr, HashMap<i64, HashMap<Prop, usize>>> = HashMap::new(); |
| 61 | for (t, props) in t_props { |
| 62 | for (k, v) in props { |
| 63 | grouped.entry(ArcStr::from(k.as_str())) |
| 64 | .or_default().entry(*t).or_default().entry(v.clone()).and_modify(|v| *v += 1).or_insert(1); |
| 65 | } |
| 66 | } |
| 67 | grouped.into_iter().map(|(key, value)| (key, value.into_iter().sorted_by_key(|(t, _)| *t).collect())).collect() |
| 68 | }; |
| 69 | |
| 70 | let get_node_t_prop_map = |
| 71 | |node: &NodeView<&Graph>| -> HashMap<ArcStr, Vec<(i64, HashMap<Prop, usize>)>> { |
| 72 | let out: HashMap<ArcStr, Vec<(i64, HashMap<Prop, usize>)>> = node |
| 73 | .properties() |
| 74 | .temporal() |
| 75 | .iter() |
| 76 | .filter(|(_, props)| !props.is_empty()) |
| 77 | .map(|(key, values)| { |
| 78 | let runs = values |
| 79 | .iter() |
| 80 | .map(|(t, v)| (t, HashMap::from([(v, 1usize)]))) |
| 81 | .coalesce(|(lt, mut lv), (rt, rv)| { |
| 82 | if lt.t() == rt.t() { |
| 83 | for (v, count) in rv { |
| 84 | lv.entry(v).and_modify(|c| *c += count).or_insert(count); |
| 85 | } |
| 86 | Ok((lt, lv)) |
| 87 | } else { |
| 88 | Err(((lt, lv), (rt, rv))) |
| 89 | } |
| 90 | }) |
| 91 | .map(|(t, v)| (t.t(), v)) |
| 92 | .collect(); |
| 93 | (key, runs) |
| 94 | }) |
| 95 | .collect(); |
| 96 | out |
| 97 | }; |
| 98 | let get_edge_t_prop_counts = |
| 99 | |edge: &EdgeView<&Graph>| -> HashMap<ArcStr, Vec<(i64, HashMap<Prop, usize>)>> { |
| 100 | let out: HashMap<ArcStr, Vec<(i64, HashMap<Prop, usize>)>> = edge |
| 101 | .properties() |
| 102 | .temporal() |
| 103 | .iter() |
| 104 | .filter(|(_, props)| !props.is_empty()) |
| 105 | .map(|(key, values)| { |