Files
deusdata--codebase-memory-mcp/tests/repro/repro_extraction.c
T
wehub-resource-sync 41cb1c0170
OpenSSF Scorecard / scorecard (push) Failing after 0s
DCO / dco (push) Failing after 0s
CodeQL SAST / analyze (push) Failing after 1s
Deploy Pages / deploy (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:28:05 +08:00

94 lines
4.6 KiB
C

/*
* repro_extraction.c — Reproduce-first cases for OPEN extraction-quality bugs.
*
* Each TEST() asserts the CORRECT behaviour and is RED until the bug is fixed.
* Keep one TEST() per issue; name it repro_issue<N>_<slug> and lead with a
* comment naming the issue, the root cause, and expected-vs-actual.
*
* Cluster (TIER A, in-process via cbm_extract_file):
* #554 — C++ out-of-line method CALLS source = Module, not enclosing Method
* (more added per wave: #495 #521 #382 #408 #523 #56 #333)
*/
#include "test_framework.h"
#include "cbm.h"
/* Convenience: extract, return result (caller frees). Mirrors test_extraction.c. */
static CBMFileResult *rx(const char *src, CBMLanguage lang, const char *proj, const char *path) {
return cbm_extract_file(src, (int)strlen(src), lang, proj, path, 0, NULL, NULL);
}
/* Find the first definition matching label+name (either may be NULL = wildcard). */
static CBMDefinition *find_def(CBMFileResult *r, const char *label, const char *name) {
for (int i = 0; i < r->defs.count; i++) {
CBMDefinition *d = &r->defs.items[i];
if (label && (!d->label || strcmp(d->label, label) != 0))
continue;
if (name && (!d->name || strcmp(d->name, name) != 0))
continue;
return d;
}
return NULL;
}
/* ───────────────────────────────────────────────────────────────────
* #554 — C++ out-of-line method definitions: the CALLS edge source falls
* back to the Module (file-level) instead of the enclosing Method.
*
* Root cause (#621 follow-up to #463/adc8304): for `void Foo::bar() { helper(); }`
* the inner call's `enclosing_func_qn` drops the CLASS qualifier — it resolves to
* the bare method name (e.g. "t.m.bar") instead of the method node's full
* class-qualified QN (e.g. "t.m.Foo.bar"). The pre-existing guard in
* test_extraction.c only checks `enclosing_func_qn != "t.m"` (module), which a
* buggy "t.m.bar" PASSES — so it never caught the class-qualifier drop.
*
* Strong reproduction: tie the call's enclosing_func_qn to the METHOD DEFINITION's
* own qualified_name (format-agnostic) AND require the class qualifier be present.
* Expected: enclosing_func_qn == def(bar).qualified_name, and that QN names "Foo".
* Actual (buggy): enclosing_func_qn loses "Foo" → mismatch → RED.
* ─────────────────────────────────────────────────────────────────── */
TEST(repro_issue554_cpp_out_of_line_method_class_qualified) {
CBMFileResult *r = rx("struct Foo { void bar(); };\n"
"int helper(int x) { return x; }\n"
"void Foo::bar() { helper(1); }\n",
CBM_LANG_CPP, "t", "m.cpp");
ASSERT_NOT_NULL(r);
ASSERT_FALSE(r->has_error);
/* The out-of-line method definition: its qualified_name is the ground truth
* the inner CALLS edge must point at. */
CBMDefinition *method = find_def(r, "Method", "bar");
if (!method)
method = find_def(r, NULL, "bar"); /* tolerate label variance */
ASSERT_NOT_NULL(method);
ASSERT_NOT_NULL(method->qualified_name);
/* The method node must carry the class qualifier — either embedded in the QN
* or via parent_class. This is the heart of #554/#621. */
int qn_has_class = strstr(method->qualified_name, "Foo") != NULL;
int parent_has_class = method->parent_class && strstr(method->parent_class, "Foo") != NULL;
ASSERT_TRUE(qn_has_class || parent_has_class);
/* The helper() call inside Foo::bar must attribute to the method node, i.e.
* its enclosing_func_qn must EQUAL the method's qualified_name (class included),
* not the bare method name and not the module. */
int saw_helper = 0;
for (int i = 0; i < r->calls.count; i++) {
if (strcmp(r->calls.items[i].callee_name, "helper") == 0) {
saw_helper = 1;
const char *enc = r->calls.items[i].enclosing_func_qn;
ASSERT_NOT_NULL(enc);
ASSERT_STR_EQ(enc, method->qualified_name);
ASSERT_TRUE(strstr(enc, "Foo") != NULL); /* class qualifier preserved */
}
}
ASSERT_TRUE(saw_helper);
cbm_free_result(r);
PASS();
}
/* ── Suite ──────────────────────────────────────────────────────── */
SUITE(repro_extraction) {
RUN_TEST(repro_issue554_cpp_out_of_line_method_class_qualified);
}