Skip to content

Commit cca3458

Browse files
committed
test(extraction): regression for Java extends+implements INHERITS edges (#279)
Pins the bug-fix from #279 with a Java class declaring both extends and implements. Asserts that base_classes contains: - the superclass name (DefaultDiagramTool) - every implements interface (ILinkTool, Closeable) - bare type names only — no 'extends' / 'implements' keyword text leaking into any entry Without the fix, the field loop returned on the first match (only the extends parent emitted) and cbm_node_text on the field returned the full literal 'extends Bar' / 'implements Baz, Qux' string.
1 parent 323c68e commit cca3458

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

tests/test_extraction.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,52 @@ TEST(java_interface) {
103103
PASS();
104104
}
105105

106+
/* Regression for #279: a Java class declaring both `extends` and
107+
* `implements` must produce one INHERITS edge per base — the extends parent
108+
* AND every implements interface — with bare type names (not the keyword
109+
* text "extends Bar" / "implements Baz, Qux"). Before the fix:
110+
* 1) the field loop returned on the first match → only the superclass
111+
* was emitted, the interfaces were dropped.
112+
* 2) the emitted name was the full field text including the keyword. */
113+
TEST(java_class_extends_and_implements) {
114+
CBMFileResult *r = extract(
115+
"public class DefaultLinkTool extends DefaultDiagramTool implements ILinkTool, Closeable { }",
116+
CBM_LANG_JAVA, "t", "DefaultLinkTool.java");
117+
ASSERT_NOT_NULL(r);
118+
ASSERT_FALSE(r->has_error);
119+
120+
/* Find the class def and inspect its base_classes list. */
121+
CBMDefinition *cls = NULL;
122+
for (int i = 0; i < r->defs.count; i++) {
123+
if (strcmp(r->defs.items[i].label, "Class") == 0 &&
124+
strcmp(r->defs.items[i].name, "DefaultLinkTool") == 0) {
125+
cls = &r->defs.items[i];
126+
break;
127+
}
128+
}
129+
ASSERT_NOT_NULL(cls);
130+
ASSERT_NOT_NULL(cls->base_classes);
131+
132+
bool saw_super = false;
133+
bool saw_iface_a = false;
134+
bool saw_iface_b = false;
135+
for (const char **b = cls->base_classes; *b; b++) {
136+
/* The keyword-text bug would surface as "extends ..." or
137+
* "implements ..." literally inside one of the entries. */
138+
ASSERT_NULL(strstr(*b, "extends"));
139+
ASSERT_NULL(strstr(*b, "implements"));
140+
if (strcmp(*b, "DefaultDiagramTool") == 0) saw_super = true;
141+
if (strcmp(*b, "ILinkTool") == 0) saw_iface_a = true;
142+
if (strcmp(*b, "Closeable") == 0) saw_iface_b = true;
143+
}
144+
ASSERT_TRUE(saw_super);
145+
ASSERT_TRUE(saw_iface_a);
146+
ASSERT_TRUE(saw_iface_b);
147+
148+
cbm_free_result(r);
149+
PASS();
150+
}
151+
106152
/* --- PHP --- */
107153
TEST(php_class) {
108154
CBMFileResult *r = extract("<?php\nclass User { public string $name; public function "
@@ -2226,6 +2272,7 @@ SUITE(extraction) {
22262272
RUN_TEST(java_class);
22272273
RUN_TEST(java_method);
22282274
RUN_TEST(java_interface);
2275+
RUN_TEST(java_class_extends_and_implements);
22292276
RUN_TEST(php_class);
22302277
RUN_TEST(php_function);
22312278
RUN_TEST(ruby_class);

0 commit comments

Comments
 (0)