Skip to content

Commit dc23628

Browse files
committed
test(search): pin that nodes_fts.body is indexed raw, not camelCase-split
Only `name` goes through cbm_camel_split; qualified_name, label, file_path and now `body` are indexed verbatim. `body` is natural-language prose, so splitting it would mangle the very text the column exists to make findable, and the unicode61 tokenizer already handles prose correctly. That invariant lived only in the shape of one format string, where the splitter is substituted into the name position alone. Nothing failed if a later edit wrapped the body expression too. cbm_camel_split("getUserById") yields "getUserById get User By Id", so a split body would additionally match the fragment "User" -- seeding a camelCase identifier into the prose and asserting the fragment does NOT match turns the invariant into a test. The mirror assertion, that `name` DOES match its fragment, pins the other half so the guard cannot be satisfied by simply indexing nothing. Verified binding: wrapping the body expression in cbm_camel_split makes body:User match 1 instead of 0 and the test fails. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
1 parent b493b64 commit dc23628

1 file changed

Lines changed: 23 additions & 22 deletions

File tree

‎tests/test_store_search.c‎

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,10 +1008,8 @@ TEST(store_bfs_reachability_is_not_trail_capped) {
10081008
cbm_store_t *s = cbm_store_open_memory();
10091009
cbm_store_upsert_project(s, "test", "/tmp/test");
10101010

1011-
cbm_node_t root = {.project = "test",
1012-
.label = "Function",
1013-
.name = "Root",
1014-
.qualified_name = "test.Root"};
1011+
cbm_node_t root = {
1012+
.project = "test", .label = "Function", .name = "Root", .qualified_name = "test.Root"};
10151013
int64_t root_id = cbm_store_upsert_node(s, &root);
10161014

10171015
enum { NODE_COUNT = 4200 };
@@ -1083,18 +1081,12 @@ TEST(store_bfs_trail_preserves_deeper_match_under_hub_budget) {
10831081
cbm_store_t *s = cbm_store_open_memory();
10841082
cbm_store_upsert_project(s, "test", "/tmp/test");
10851083

1086-
cbm_node_t root = {.project = "test",
1087-
.label = "Function",
1088-
.name = "root",
1089-
.qualified_name = "test.root"};
1090-
cbm_node_t branch = {.project = "test",
1091-
.label = "Function",
1092-
.name = "branch",
1093-
.qualified_name = "test.branch"};
1094-
cbm_node_t target = {.project = "test",
1095-
.label = "Function",
1096-
.name = "target",
1097-
.qualified_name = "test.target"};
1084+
cbm_node_t root = {
1085+
.project = "test", .label = "Function", .name = "root", .qualified_name = "test.root"};
1086+
cbm_node_t branch = {
1087+
.project = "test", .label = "Function", .name = "branch", .qualified_name = "test.branch"};
1088+
cbm_node_t target = {
1089+
.project = "test", .label = "Function", .name = "target", .qualified_name = "test.target"};
10981090
int64_t root_id = cbm_store_upsert_node(s, &root);
10991091
int64_t branch_id = cbm_store_upsert_node(s, &branch);
11001092
int64_t target_id = cbm_store_upsert_node(s, &target);
@@ -1112,10 +1104,8 @@ TEST(store_bfs_trail_preserves_deeper_match_under_hub_budget) {
11121104
for (int i = 0; i < LEAF_COUNT; i++) {
11131105
char name[32];
11141106
snprintf(name, sizeof(name), "leaf-%d", i);
1115-
cbm_node_t leaf = {.project = "test",
1116-
.label = "Function",
1117-
.name = name,
1118-
.qualified_name = name};
1107+
cbm_node_t leaf = {
1108+
.project = "test", .label = "Function", .name = name, .qualified_name = name};
11191109
int64_t leaf_id = cbm_store_upsert_node(s, &leaf);
11201110
edge.source_id = root_id;
11211111
edge.target_id = leaf_id;
@@ -1658,8 +1648,8 @@ static void seed_prose_nodes(cbm_store_t *s) {
16581648
.name = "Installation",
16591649
.qualified_name = "p.README.Installation",
16601650
.file_path = "README.md",
1661-
.properties_json =
1662-
"{\"docstring\":\"provisions an ephemeral workstation runner\"}"};
1651+
.properties_json = "{\"docstring\":\"provisions an ephemeral "
1652+
"workstation runner via getUserById\"}"};
16631653
cbm_store_upsert_node(s, &sec);
16641654
cbm_node_t fn = {.project = "p",
16651655
.label = "Function",
@@ -1689,6 +1679,17 @@ TEST(store_fts_rebuild_indexes_docstring_as_body_issue518) {
16891679
/* Identifier indexing is untouched. */
16901680
ASSERT_EQ(fts_match_count(s, "name:plainFunction"), 1);
16911681

1682+
/* `body` is PROSE and must be indexed RAW — only `name` gets the camelCase
1683+
* splitter. cbm_camel_split("getUserById") yields "getUserById get User By
1684+
* Id", so a split body would additionally match the fragment "User".
1685+
* Asserting the fragment does NOT match is what makes this test fail if
1686+
* anyone ever wraps the body expression in cbm_camel_split(). */
1687+
ASSERT_EQ(fts_match_count(s, "body:getUserById"), 1);
1688+
ASSERT_EQ(fts_match_count(s, "body:User"), 0);
1689+
/* ...and the mirror image: `name` IS split, so its fragment DOES match.
1690+
* Together these pin both halves of the invariant. */
1691+
ASSERT_EQ(fts_match_count(s, "name:plain"), 1);
1692+
16921693
cbm_store_close(s);
16931694
PASS();
16941695
}

0 commit comments

Comments
 (0)