#[macro_export] macro_rules! vertex_map_tests { ($T:ty) => { #[test] fn initial_values_are_default() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let map = graph.vertex_map(42); assert_eq!(map[v1], 42); assert_eq!(map[v2], 42); } #[test] fn write_and_read() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let mut map = graph.vertex_map(0); map[v1] = 7; assert_eq!(map[v1], 7); assert_eq!(map[v2], 0); } #[test] fn lazy_growth_on_read() { let mut graph = <$T>::new(); graph.add_vertex(); let map = graph.vertex_map(99); let v = graph.add_vertex(); assert_eq!(map[v], 99); } #[test] fn lazy_growth_on_write() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let mut map = graph.vertex_map(0); let v2 = graph.add_vertex(); map[v2] = 7; assert_eq!(map[v1], 0); assert_eq!(map[v2], 7); } #[test] fn sync_expands_to_new_vertices() { let mut graph = <$T>::new(); graph.add_vertex(); let mut map = graph.vertex_map(42); let initial_len = map.len(); while graph.vertex_capacity() <= initial_len { graph.add_vertex(); } assert!( map.len() < graph.vertex_capacity(), "precondition: map is stale before sync" ); map.sync(&graph); assert_eq!(map.len(), graph.vertex_capacity()); } #[test] fn sync_does_not_overwrite_existing_values() { let mut graph = <$T>::new(); let v = graph.add_vertex(); let mut map = graph.vertex_map(0); map[v] = 5; graph.add_vertex(); map.sync(&graph); assert_eq!(map[v], 5); } }; } #[macro_export] macro_rules! vertex_map_deletion_tests { ($T:ty) => { #[test] fn surviving_vertex_readable_after_delete() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let mut map = graph.vertex_map(0); map[v1] = 1; map[v2] = 2; graph.delete_vertex(v2); assert_eq!(map[v1], 1); } #[test] fn capacity_does_not_shrink_after_delete() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let mut map = graph.vertex_map(0); map[v1] = 5; let capacity_before = graph.vertex_capacity(); graph.delete_vertex(v2); map.sync(&graph); assert_eq!(map.len(), capacity_before); assert_eq!(map[v1], 5); } #[test] fn reused_slot_returns_old_value() { let mut graph = <$T>::new(); graph.add_vertex(); let v1 = graph.add_vertex(); let mut map = graph.vertex_map(0); map[v1] = 99; graph.delete_vertex(v1); let v2 = graph.add_vertex(); // VertexMap uses raw indices, not vertex identity. A new vertex v2 reusing the slot // of previously deleted v1 sees the old value. Callers must reinitialize stale slots // after deletion. assert_eq!(map[v2], 99); } }; } #[macro_export] macro_rules! edge_map_tests { ($T:ty) => { #[test] fn initial_values_are_default() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let e1 = graph.add_edge(v1, v2); let e2 = graph.add_edge(v1, v2); let map = graph.edge_map(42); assert_eq!(map[e1], 42); assert_eq!(map[e2], 42); } #[test] fn write_and_read() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let e1 = graph.add_edge(v1, v2); let e2 = graph.add_edge(v1, v2); let mut map = graph.edge_map(0); map[e1] = 7; assert_eq!(map[e1], 7); assert_eq!(map[e2], 0); } #[test] fn lazy_growth_on_read() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); graph.add_edge(v1, v2); let map = graph.edge_map(99); let e = graph.add_edge(v1, v2); assert_eq!(map[e], 99); } #[test] fn lazy_growth_on_write() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let e1 = graph.add_edge(v1, v2); let mut map = graph.edge_map(0); let e2 = graph.add_edge(v1, v2); map[e2] = 7; assert_eq!(map[e1], 0); assert_eq!(map[e2], 7); } #[test] fn sync_expands_to_new_edges() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); graph.add_edge(v1, v2); let mut map = graph.edge_map(42); let initial_len = map.len(); while graph.edge_capacity() <= initial_len { graph.add_edge(v1, v2); } assert!( map.len() < graph.edge_capacity(), "precondition: map is stale before sync" ); map.sync(&graph); assert_eq!(map.len(), graph.edge_capacity()); } #[test] fn sync_does_not_overwrite_existing_values() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let e = graph.add_edge(v1, v2); let mut map = graph.edge_map(0); map[e] = 5; graph.add_edge(v1, v2); map.sync(&graph); assert_eq!(map[e], 5); } }; } #[macro_export] macro_rules! edge_map_deletion_tests { ($T:ty) => { #[test] fn surviving_edge_readable_after_delete() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let e1 = graph.add_edge(v1, v2); let e2 = graph.add_edge(v1, v2); let mut map = graph.edge_map(0); map[e1] = 1; map[e2] = 2; graph.delete_edge(e2); assert_eq!(map[e1], 1); } #[test] fn capacity_does_not_shrink_after_delete() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); let e1 = graph.add_edge(v1, v2); let e2 = graph.add_edge(v1, v2); let mut map = graph.edge_map(0); map[e1] = 5; let capacity_before = graph.edge_capacity(); graph.delete_edge(e2); map.sync(&graph); assert_eq!(map.len(), capacity_before); assert_eq!(map[e1], 5); } #[test] fn reused_slot_returns_old_value() { let mut graph = <$T>::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); graph.add_edge(v1, v2); let e1 = graph.add_edge(v1, v2); let mut map = graph.edge_map(0); map[e1] = 99; graph.delete_edge(e1); let e2 = graph.add_edge(v1, v2); // EdgeMap uses raw indices, not edge identity. Because to_index uses arr_idx/2, // both halves of a deleted edge pair map to the same index, so a new edge reusing // either slot sees the old value. Callers must reinitialize stale slots after deletion. assert_eq!(map[e2], 99); } }; }