───────────────────────────────────────────────────────────────────────── * INVARIANT 3: No dangling edges (graph integrity guard). * * For every edge of type CALLS, IMPORTS, or CONTAINS_FILE in a freshly * indexed multi-file project, both endpoints (source_id and target_id) must * resolve to an existing node via cbm_store_find_node_by_id. * * This is a REGRESSION GUARD (expected GREEN on c
| 225 | * Two Python files so the pipeline mints IMPORTS and CALLS edges. |
| 226 | * ──────────────────────────────────────────────────────────────────────── */ |
| 227 | static int count_dangling_edges(cbm_store_t *store, const char *project, |
| 228 | const char *edge_type) { |
| 229 | cbm_edge_t *edges = NULL; |
| 230 | int edge_count = 0; |
| 231 | int rc = cbm_store_find_edges_by_type(store, project, edge_type, |
| 232 | &edges, &edge_count); |
| 233 | if (rc != CBM_STORE_OK) { |
| 234 | return -1; |
| 235 | } |
| 236 | |
| 237 | int dangling = 0; |
| 238 | for (int i = 0; i < edge_count; i++) { |
| 239 | cbm_node_t src_node; |
| 240 | cbm_node_t tgt_node; |
| 241 | if (cbm_store_find_node_by_id(store, edges[i].source_id, |
| 242 | &src_node) != CBM_STORE_OK) { |
| 243 | dangling++; |
| 244 | } |
| 245 | if (cbm_store_find_node_by_id(store, edges[i].target_id, |
| 246 | &tgt_node) != CBM_STORE_OK) { |
| 247 | dangling++; |
| 248 | } |
| 249 | } |
| 250 | cbm_store_free_edges(edges, edge_count); |
| 251 | return dangling; |
| 252 | } |
| 253 | |
| 254 | TEST(invariant_no_dangling_edges) { |
| 255 | static const char callee_py[] = |
no test coverage detected