Summary
Inline Rust test functions — #[test], #[tokio::test], #[async_std::test], #[actix_rt::test], and #[cfg(test)] mod tests { … } bodies — that live inside a regular source file (e.g. src/lib.rs) are not detected as tests. They are indexed as ordinary Function nodes with is_test = false, so they are not filtered by the is_test != 1 clause in store.c and leak into graph queries / agent context, polluting it with test code.
Root cause
Test detection is file-path-based only:
cbm_is_test_file(rel_path, lang) (internal/cbm/helpers.c:292) marks a file/module as a test only by path. For Rust it is return has_suffix(base, "_test.rs") || has_prefix(base, "test_"); (with the code comment "Rust tests are typically mod tests inside the file, but test files too"). A file like src/lib.rs is therefore never a test file, regardless of its contents.
CBMDefinition.is_test (internal/cbm/cbm.h:213) is the per-function flag. It is read by src/pipeline/pass_definitions.c and src/pipeline/pass_parallel.c (emitted into node properties) but is never assigned in the extraction layer — the only is_test write is mod.is_test = ctx->result->is_test_file; (internal/cbm/extract_defs.c:6316), which is module/file-level. So def->is_test stays at its zero-initialized default (false).
Because functions are never marked, the store.c filter (json_extract(properties, '$.is_test') != 1) only ever drops whole test-files, never inline test functions.
Repro
Index any repo containing, in a non-test-named file:
// src/lib.rs
pub fn real_fn() {}
#[cfg(test)]
mod tests {
#[tokio::test]
async fn something_works() {}
}
cbm cli --json search_graph '{"project":"…","name_pattern":"something_works"}' returns something_works as a Function with is_test absent/false — i.e. it is not filtered and appears alongside real_fn in graph context.
Proposed fix (Rust-scoped)
In the Rust function-extraction path in internal/cbm/extract_defs.c, scan each function's attribute_item / meta_item children for test macros and set def->is_test = true. Initial attribute set:
- bare
#[test]
#[tokio::test] (the case that surfaced this — async tests)
#[async_std::test]
#[actix_rt::test]
#[test_case::case] (optionally)
Plus a regression test in tests/test_extraction.c asserting a Rust snippet with #[tokio::test] async fn … yields def->is_test == true. make -f Makefile.cbm test + scripts/lint.sh clean.
Scope
Rust only in the follow-up PR. Rust is a high-value first target because inline #[cfg(test)] mod tests { … } is idiomatic, so these unmarked test functions leak into the graph for any typical Rust crate — not an edge case. Go / Python / JS / Java / C# can follow in separate PRs per the one-issue-per-PR guidance.
Ask
Status: PR #857 implements this (Rust-scoped, with a regression test; scripts/test.sh green, red→green verified). Feedback on the attribute set and the extraction-hook point welcome there or here — happy to adjust. (Filed for alignment first; went ahead since it's a focused correctness fix.)
Citations verified against main at 37c00d1.
Summary
Inline Rust test functions —
#[test],#[tokio::test],#[async_std::test],#[actix_rt::test], and#[cfg(test)] mod tests { … }bodies — that live inside a regular source file (e.g.src/lib.rs) are not detected as tests. They are indexed as ordinaryFunctionnodes withis_test = false, so they are not filtered by theis_test != 1clause instore.cand leak into graph queries / agent context, polluting it with test code.Root cause
Test detection is file-path-based only:
cbm_is_test_file(rel_path, lang)(internal/cbm/helpers.c:292) marks a file/module as a test only by path. For Rust it isreturn has_suffix(base, "_test.rs") || has_prefix(base, "test_");(with the code comment "Rust tests are typically mod tests inside the file, but test files too"). A file likesrc/lib.rsis therefore never a test file, regardless of its contents.CBMDefinition.is_test(internal/cbm/cbm.h:213) is the per-function flag. It is read bysrc/pipeline/pass_definitions.candsrc/pipeline/pass_parallel.c(emitted into node properties) but is never assigned in the extraction layer — the onlyis_testwrite ismod.is_test = ctx->result->is_test_file;(internal/cbm/extract_defs.c:6316), which is module/file-level. Sodef->is_teststays at its zero-initialized default (false).Because functions are never marked, the
store.cfilter (json_extract(properties, '$.is_test') != 1) only ever drops whole test-files, never inline test functions.Repro
Index any repo containing, in a non-test-named file:
cbm cli --json search_graph '{"project":"…","name_pattern":"something_works"}'returnssomething_worksas aFunctionwithis_testabsent/false — i.e. it is not filtered and appears alongsidereal_fnin graph context.Proposed fix (Rust-scoped)
In the Rust function-extraction path in
internal/cbm/extract_defs.c, scan each function'sattribute_item/meta_itemchildren for test macros and setdef->is_test = true. Initial attribute set:#[test]#[tokio::test](the case that surfaced this — async tests)#[async_std::test]#[actix_rt::test]#[test_case::case](optionally)Plus a regression test in
tests/test_extraction.casserting a Rust snippet with#[tokio::test] async fn …yieldsdef->is_test == true.make -f Makefile.cbm test+scripts/lint.shclean.Scope
Rust only in the follow-up PR. Rust is a high-value first target because inline
#[cfg(test)] mod tests { … }is idiomatic, so these unmarked test functions leak into the graph for any typical Rust crate — not an edge case. Go / Python / JS / Java / C# can follow in separate PRs per the one-issue-per-PR guidance.Ask
Status: PR #857 implements this (Rust-scoped, with a regression test;
scripts/test.shgreen, red→green verified). Feedback on the attribute set and the extraction-hook point welcome there or here — happy to adjust. (Filed for alignment first; went ahead since it's a focused correctness fix.)Citations verified against
mainat37c00d1.