/* * test_java_lsp_coverage.c — Comprehensive coverage tests for the Java LSP. * * This is the deep-coverage suite that exercises every code path in the * resolver and every stdlib type in the registry. ~200 tests organized by: * * 1. Literals (10) — all numeric / string / char / bool variants * 2. Type-name resolution (12) — every path in java_resolve_type_name * 3. Primitive expressions (10) — arithmetic, comparison, logical, bitwise * 4. Type-AST parsing (12) — every kind handled by java_parse_type_node * 5. Identifier resolution (10) — scope chain, fields, imports, types * 6. Field access (10) — instance, static (System.out), arrays, scope * 7. Method invocation (15) — bare, this, super, static, instance, chain * 8. Object creation (8) — generic, raw, anonymous, nested * 9. Cast / instanceof (8) * 10. Generic substitution (15) — every entry in is_value_typed_container/is_map_like * 11. Lambda SAM inference (12) — every functional-interface category * 12. Method references (10) — Class::method, instance::method, ::new, super:: * 13. Inheritance walking (10) — multi-level, interfaces, sole-impl * 14. java.lang stdlib (15) — Object/String/StringBuilder/Math/System/Thread/Class/Throwable * 15. java.util stdlib (15) — collections, Optional, Iterator, regex * 16. java.io stdlib (10) * 17. java.nio.file (5) * 18. java.util.stream (10) * 19. java.util.function (10) * 20. java.util.concurrent (10) * 21. java.time (10) * 22. Imports (8) — single, on-demand, static, static on-demand * 23. Inner / nested types (10) * 24. Variable / scope binding (10) * 25. Control flow (10) — if, for, while, switch, try * 26. Diagnostics (8) — unresolved markers * 27. Cross-file (5) * 28. Stress / edge (10) — pathological inputs, recursion, deep nesting * * Total: ~278 tests. */ #include "test_framework.h" #include "cbm.h" #include "lsp/java_lsp.h" #include #include /* ── Helpers (shared form, kept local to avoid linker collisions) ─── */ static CBMFileResult *cov_extract(const char *source) { return cbm_extract_file(source, (int)strlen(source), CBM_LANG_JAVA, "test", "Main.java", 0, NULL, NULL); } static int cov_find(const CBMFileResult *r, const char *callerSub, const char *calleeSub) { for (int i = 0; i < r->resolved_calls.count; i++) { const CBMResolvedCall *rc = &r->resolved_calls.items[i]; if (rc->confidence < 0.5f) continue; if (rc->caller_qn && strstr(rc->caller_qn, callerSub) && rc->callee_qn && strstr(rc->callee_qn, calleeSub)) { return i; } } return -1; } static int cov_require(const CBMFileResult *r, const char *callerSub, const char *calleeSub) { int idx = cov_find(r, callerSub, calleeSub); if (idx < 0) { printf("\n MISSING: %s -> %s (have %d entries)\n", callerSub, calleeSub, r->resolved_calls.count); for (int i = 0; i < r->resolved_calls.count; i++) { const CBMResolvedCall *rc = &r->resolved_calls.items[i]; printf(" %s -> %s [%s %.2f]\n", rc->caller_qn ? rc->caller_qn : "(null)", rc->callee_qn ? rc->callee_qn : "(null)", rc->strategy ? rc->strategy : "(null)", rc->confidence); } } return idx; } static int cov_count_strict(const CBMFileResult *r) { int n = 0; for (int i = 0; i < r->resolved_calls.count; i++) { if (r->resolved_calls.items[i].confidence >= 0.85f) n++; } return n; } static int cov_no_crash(CBMFileResult *r) { return r != NULL; } /* Macro for quick "wrap source in a Main class with run() that returns * void and contains the body" pattern. */ #define WRAP_RUN(body) \ "public class Main {\n public void run(){\n " body "\n }\n}\n" /* ── 1. Literals ─────────────────────────────────────────────────── */ TEST(cov_lit_int) { CBMFileResult *r = cov_extract( "public class Main { public int run() { int x = 42; return x; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_lit_long) { CBMFileResult *r = cov_extract("public class Main {\n" " public long run() { long x = 99L; return x; }\n" "}"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_lit_hex) { CBMFileResult *r = cov_extract("public class Main { public int f() { int x = 0xFF; return x; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_lit_binary) { CBMFileResult *r = cov_extract("public class Main { public int f() { int x = 0b1010; return x; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_lit_octal) { CBMFileResult *r = cov_extract("public class Main { public int f() { int x = 0777; return x; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_lit_float_suffix) { CBMFileResult *r = cov_extract( "public class Main { public float f() { float x = 1.5f; return x; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_lit_double) { CBMFileResult *r = cov_extract( "public class Main { public double f() { double x = 3.14; return x; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_lit_char) { CBMFileResult *r = cov_extract( "public class Main { public int f() { char c = 'a'; return Character.getNumericValue(c); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Character.getNumericValue"), 0); cbm_free_result(r); PASS(); } TEST(cov_lit_string_method) { CBMFileResult *r = cov_extract( "public class Main { public int f() { return \"hello\".length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_lit_bool_method) { CBMFileResult *r = cov_extract( "public class Main { public String f() { return Boolean.toString(true); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Boolean.toString"), 0); cbm_free_result(r); PASS(); } TEST(cov_lit_null_no_crash) { CBMFileResult *r = cov_extract( "public class Main { public Object f() { return null; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } /* ── 2. Type-name resolution paths ───────────────────────────────── */ TEST(cov_typename_java_lang_implicit) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_typename_via_single_import) { CBMFileResult *r = cov_extract("import java.util.HashMap;\n" "public class Main { public int f(HashMap m) { return m.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_typename_via_on_demand_import) { CBMFileResult *r = cov_extract("import java.util.*;\n" "public class Main { public int f(HashMap m) { return m.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_typename_via_static_import) { CBMFileResult *r = cov_extract("import static java.lang.Math.PI;\n" "public class Main { public double f() { return PI; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typename_qualified_path) { CBMFileResult *r = cov_extract( "public class Main { public int f(java.util.HashMap m) { return m.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_typename_inner_via_outer) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class Inner { public String tag() { return \"x\"; } }\n" " public String f() { Inner i = new Inner(); return i.tag(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_typename_nested_two_levels) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A {\n" " static class B { public String tag() { return \"b\"; } }\n" " }\n" " public String f() { Main.A.B b = new Main.A.B(); return b.tag(); }\n" "}"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typename_array_type) { CBMFileResult *r = cov_extract( "public class Main { public int f(String[] xs) { return xs.length; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typename_2d_array) { CBMFileResult *r = cov_extract( "public class Main { public int f(int[][] m) { return m[0].length; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typename_generic_type) { CBMFileResult *r = cov_extract("import java.util.List;\n" "public class Main { public int f(List xs) { return xs.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "List.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_typename_wildcard) { CBMFileResult *r = cov_extract("import java.util.List;\n" "public class Main { public int f(List xs) { return xs.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "List.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_typename_bounded_wildcard) { CBMFileResult *r = cov_extract("import java.util.List;\n" "public class Main { public int f(List xs) { return xs.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "List.size"), 0); cbm_free_result(r); PASS(); } /* ── 3. Primitive operations ─────────────────────────────────────── */ TEST(cov_op_arith) { CBMFileResult *r = cov_extract( "public class Main { public int f(int a, int b) { return a + b * 2 - 1 / 3 % 4; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_op_compare) { CBMFileResult *r = cov_extract( "public class Main { public boolean f(int a, int b) { return a < b && a >= 0 && a != b; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_op_bitwise) { CBMFileResult *r = cov_extract( "public class Main { public int f(int a) { return (a & 0xFF) | (a << 8) ^ (a >> 4); } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_op_unary_negate) { CBMFileResult *r = cov_extract( "public class Main { public int f(int a) { return -a; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_op_logical_not) { CBMFileResult *r = cov_extract( "public class Main { public boolean f(boolean b) { return !b; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_op_increment) { CBMFileResult *r = cov_extract( "public class Main { public int f() { int a = 0; a++; ++a; return a; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_op_string_concat) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { String t = \"a\" + s + 1; return t.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_op_ternary_simple) { CBMFileResult *r = cov_extract( "public class Main { public int f(boolean b) { return b ? 1 : 2; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_op_assignment) { CBMFileResult *r = cov_extract( "public class Main { public int f() { int a = 0; a += 1; a -= 1; return a; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_op_paren_expr) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { return ((s)).length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } /* ── 4. Type-AST parsing kinds ───────────────────────────────────── */ TEST(cov_typeast_void_method) { CBMFileResult *r = cov_extract("public class Main { public void f() {} }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_byte_param) { CBMFileResult *r = cov_extract("public class Main { public int f(byte b) { return b + 1; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_short_param) { CBMFileResult *r = cov_extract("public class Main { public int f(short s) { return s + 1; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_int_param) { CBMFileResult *r = cov_extract("public class Main { public int f(int i) { return i + 1; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_long_param) { CBMFileResult *r = cov_extract("public class Main { public long f(long l) { return l + 1; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_float_param) { CBMFileResult *r = cov_extract("public class Main { public float f(float f) { return f + 1; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_double_param) { CBMFileResult *r = cov_extract("public class Main { public double f(double d) { return d + 1; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_char_param) { CBMFileResult *r = cov_extract("public class Main { public char f(char c) { return c; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_boolean_param) { CBMFileResult *r = cov_extract("public class Main { public boolean f(boolean b) { return b; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_typeast_string_param) { CBMFileResult *r = cov_extract("public class Main { public int f(String s) { return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_typeast_array_of_string) { CBMFileResult *r = cov_extract( "public class Main { public int f(String[] xs) { return xs[0].length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_typeast_generic_list) { CBMFileResult *r = cov_extract( "import java.util.List;\n" "public class Main { public int f(List xs) { return xs.get(0).length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } /* ── 5. Identifier resolution ────────────────────────────────────── */ TEST(cov_id_local_var) { CBMFileResult *r = cov_extract( "public class Main { public int f() { String s = \"x\"; return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_id_param) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_id_field) { CBMFileResult *r = cov_extract( "public class Main { private String s = \"x\"; public int f() { return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_id_inherited_field) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A { protected String s = \"x\"; }\n" " static class B extends A { public int f() { return s.length(); } }\n" "}"); ASSERT_NOT_NULL(r); /* Fields of inner classes — the LSP propagates parent fields via * the class registry. The exact resolution rate isn't asserted but * the test must not crash. */ cbm_free_result(r); PASS(); } TEST(cov_id_shadow_param) { CBMFileResult *r = cov_extract( "public class Main {\n" " private String s = \"x\";\n" " public int f(String s) { return s.length(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_id_block_shadow) { CBMFileResult *r = cov_extract( "public class Main {\n" " public int f() {\n" " String s = \"a\";\n" " if (true) { String s2 = s.trim(); return s2.length(); }\n" " return s.length();\n" " }\n" "}"); ASSERT_NOT_NULL(r); /* Both String.length and String.trim should appear. */ ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_id_outer_class_field) { CBMFileResult *r = cov_extract( "public class Main {\n" " private String name = \"x\";\n" " class Inner { public int f() { return name.length(); } }\n" "}"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_id_class_as_static) { CBMFileResult *r = cov_extract( "public class Main { public int f() { return Integer.MAX_VALUE; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_id_unresolved_emits_diagnostic) { CBMFileResult *r = cov_extract( "public class Main { public int f() { return undefined.size(); } }"); ASSERT_NOT_NULL(r); int diag = 0; for (int i = 0; i < r->resolved_calls.count; i++) { if (r->resolved_calls.items[i].confidence == 0.0f) diag++; } ASSERT_GTE(diag, 1); cbm_free_result(r); PASS(); } TEST(cov_id_for_loop_var) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main {\n" " public int total(ArrayList xs) {\n" " int n = 0;\n" " for (int i = 0; i < xs.size(); i++) n += xs.get(i).length();\n" " return n;\n" " }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "total", "ArrayList.size"), 0); ASSERT_GTE(cov_require(r, "total", "ArrayList.get"), 0); ASSERT_GTE(cov_require(r, "total", "String.length"), 0); cbm_free_result(r); PASS(); } /* ── 6. Field access ─────────────────────────────────────────────── */ TEST(cov_fa_system_out) { CBMFileResult *r = cov_extract( "public class Main { public void f() { System.out.println(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "PrintStream.println"), 0); cbm_free_result(r); PASS(); } TEST(cov_fa_system_err) { CBMFileResult *r = cov_extract( "public class Main { public void f() { System.err.println(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "PrintStream.println"), 0); cbm_free_result(r); PASS(); } TEST(cov_fa_array_length) { CBMFileResult *r = cov_extract( "public class Main { public int f(int[] xs) { return xs.length; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_fa_chained_field_method) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class Box { public String s = \"x\"; }\n" " public int f(Box b) { return b.s.length(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_fa_this_field) { CBMFileResult *r = cov_extract( "public class Main { private String s = \"x\"; public int f() { return this.s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_fa_static_class_field) { CBMFileResult *r = cov_extract("public class Main { public int f() { return Integer.MAX_VALUE; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_fa_method_then_field) { CBMFileResult *r = cov_extract("import java.util.ArrayList;\n" "public class Main { public int f(ArrayList xs) { return xs.toArray().length; } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ArrayList.toArray"), 0); cbm_free_result(r); PASS(); } TEST(cov_fa_field_through_param) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class Bag { public String tag = \"x\"; }\n" " public int f(Bag b) { return b.tag.length(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_fa_field_through_chained_call) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A { public String tag = \"x\"; public A self() { return this; } }\n" " public int f(A a) { return a.self().tag.length(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "self"), 0); cbm_free_result(r); PASS(); } TEST(cov_fa_unresolved_field_no_crash) { CBMFileResult *r = cov_extract( "public class Main { public int f() { return some.weird.thing.length; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } /* ── 7. Method invocation paths ──────────────────────────────────── */ TEST(cov_mi_bare_local) { CBMFileResult *r = cov_extract( "public class Main { String greet() { return \"hi\"; } public void f() { greet(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "greet"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_this) { CBMFileResult *r = cov_extract( "public class Main { String greet() { return \"\"; } public void f() { this.greet(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "greet"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_super) { CBMFileResult *r = cov_extract( "public class Main extends Object {\n" " public String f() { return super.toString(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Object.toString"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_static) { CBMFileResult *r = cov_extract( "public class Main { public double f() { return Math.sqrt(4); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Math.sqrt"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_chained_static) { CBMFileResult *r = cov_extract( "public class Main { public String f() { return Integer.toBinaryString(Integer.parseInt(\"5\")); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Integer.toBinaryString"), 0); ASSERT_GTE(cov_require(r, "f", "Integer.parseInt"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_instance) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_chain_3hop) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { return s.trim().toUpperCase().length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); ASSERT_GTE(cov_require(r, "f", "String.toUpperCase"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_recursive_self) { CBMFileResult *r = cov_extract( "public class Main { public int fact(int n) { return n <= 1 ? 1 : n * fact(n-1); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "fact", "fact"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_overload_by_arity) { CBMFileResult *r = cov_extract( "public class Main {\n" " String fmt(String s) { return s; }\n" " String fmt(String s, int i) { return s; }\n" " public String f() { return fmt(\"a\") + fmt(\"b\", 1); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "fmt"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_param_chain) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { return s.toUpperCase().length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.toUpperCase"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_return_chain) { CBMFileResult *r = cov_extract( "public class Main {\n" " String tag() { return \"x\"; }\n" " public int f() { return tag().length(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_args_walked) { CBMFileResult *r = cov_extract( "import java.util.Objects;\n" "public class Main { public int f(String a, String b) { return Objects.hash(a.length(), b.trim()); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Objects.hash"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_nested_args) { CBMFileResult *r = cov_extract( "public class Main { public double f() { return Math.max(Math.abs(-1), Math.sqrt(4)); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Math.max"), 0); ASSERT_GTE(cov_require(r, "f", "Math.abs"), 0); ASSERT_GTE(cov_require(r, "f", "Math.sqrt"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_through_field_getter) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class Box { public String getTag() { return \"x\"; } }\n" " private Box b = new Box();\n" " public int f() { return b.getTag().length(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "getTag"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_mi_call_in_condition) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { if (s.isEmpty()) return 0; return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.isEmpty"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } /* ── 8. Object creation paths ────────────────────────────────────── */ TEST(cov_oc_simple) { CBMFileResult *r = cov_extract( "public class Main { public StringBuilder f() { return new StringBuilder(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "StringBuilder"), 0); cbm_free_result(r); PASS(); } TEST(cov_oc_with_args) { CBMFileResult *r = cov_extract("import java.util.ArrayList;\n" "public class Main { public ArrayList f() { return new ArrayList<>(10); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ArrayList"), 0); cbm_free_result(r); PASS(); } TEST(cov_oc_diamond) { CBMFileResult *r = cov_extract("import java.util.HashMap;\n" "public class Main { public HashMap f() { return new HashMap<>(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap"), 0); cbm_free_result(r); PASS(); } TEST(cov_oc_generic_explicit) { CBMFileResult *r = cov_extract("import java.util.ArrayList;\n" "public class Main { public ArrayList f() { return new ArrayList(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ArrayList"), 0); cbm_free_result(r); PASS(); } TEST(cov_oc_user_class) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class Box { public Box() {} }\n" " public Box f() { return new Box(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Box"), 0); cbm_free_result(r); PASS(); } TEST(cov_oc_with_chained_method) { CBMFileResult *r = cov_extract( "public class Main { public String f() { return new StringBuilder().append(\"x\").toString(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "StringBuilder.append"), 0); ASSERT_GTE(cov_require(r, "f", "StringBuilder.toString"), 0); cbm_free_result(r); PASS(); } TEST(cov_oc_array) { CBMFileResult *r = cov_extract("public class Main { public int[] f() { return new int[10]; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_oc_array_init) { CBMFileResult *r = cov_extract( "public class Main { public int[] f() { int[] xs = {1,2,3}; return xs; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } /* ── 9. Cast / instanceof ────────────────────────────────────────── */ TEST(cov_cast_to_string) { CBMFileResult *r = cov_extract( "public class Main { public int f(Object o) { return ((String)o).length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_cast_chained) { CBMFileResult *r = cov_extract( "public class Main { public int f(Object o) { return ((String)((Object)o)).length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_cast_primitive) { CBMFileResult *r = cov_extract("public class Main { public int f(double d) { return (int) d; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_instanceof_basic) { CBMFileResult *r = cov_extract("public class Main { public boolean f(Object o) { return o instanceof String; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_cast_from_iterator) { CBMFileResult *r = cov_extract("import java.util.Iterator;\n" "public class Main { public int f(Iterator it) {\n" " return ((String) it.next()).length();\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_cast_arr_elem) { CBMFileResult *r = cov_extract( "public class Main { public int f(Object[] xs) { return ((String)xs[0]).length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_cast_in_ternary) { CBMFileResult *r = cov_extract( "public class Main { public int f(Object o, boolean b) { return b ? ((String)o).length() : 0; } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_cast_then_chain) { CBMFileResult *r = cov_extract( "public class Main { public String f(Object o) { return ((String)o).toUpperCase().trim(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.toUpperCase"), 0); ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); cbm_free_result(r); PASS(); } /* ── 10. Generic substitution table coverage ─────────────────────── */ TEST(cov_gen_list_get) { CBMFileResult *r = cov_extract( "import java.util.List;\n" "public class Main { public int f(List xs) { return xs.get(0).length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_arraylist_get) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public int f(ArrayList xs) { return xs.get(0).length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_linkedlist_first) { CBMFileResult *r = cov_extract( "import java.util.LinkedList;\n" "public class Main { public int f(LinkedList xs) { return xs.getFirst().length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_set_iterator_next) { CBMFileResult *r = cov_extract( "import java.util.Set;\n" "import java.util.Iterator;\n" "public class Main { public int f(Set s) {\n" " Iterator it = s.iterator();\n" " return it.next().length();\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Iterator.next"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_map_get) { CBMFileResult *r = cov_extract( "import java.util.Map;\n" "public class Main { public int f(Map m) { return m.get(\"k\").length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_hashmap_get) { CBMFileResult *r = cov_extract( "import java.util.HashMap;\n" "public class Main { public int f(HashMap m) { return m.get(\"k\").length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_optional_orElse) { CBMFileResult *r = cov_extract( "import java.util.Optional;\n" "public class Main { public int f(Optional o) { return o.orElse(\"\").length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_optional_get) { CBMFileResult *r = cov_extract( "import java.util.Optional;\n" "public class Main { public int f(Optional o) { return o.get().length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_iterator_next_chain) { CBMFileResult *r = cov_extract( "import java.util.Iterator;\n" "public class Main { public int f(Iterator it) { return it.next().length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_function_apply) { CBMFileResult *r = cov_extract( "import java.util.function.Function;\n" "public class Main { public int f(Function fn, String s) { return fn.apply(s).length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_supplier_get) { CBMFileResult *r = cov_extract( "import java.util.function.Supplier;\n" "public class Main { public int f(Supplier sup) { return sup.get().length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_bifunction_apply) { CBMFileResult *r = cov_extract( "import java.util.function.BiFunction;\n" "public class Main { public int f(BiFunction fn, String s) {\n" " return fn.apply(s, 1).length();\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_map_keyset) { CBMFileResult *r = cov_extract( "import java.util.HashMap;\n" "import java.util.Set;\n" "public class Main { public int f(HashMap m) { return m.keySet().size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Set.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_map_values) { CBMFileResult *r = cov_extract( "import java.util.HashMap;\n" "public class Main { public int f(HashMap m) { return m.values().size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Collection.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_gen_collection_iterator) { CBMFileResult *r = cov_extract( "import java.util.Collection;\n" "public class Main { public int f(Collection c) { return c.iterator().next().length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } /* ── 11. Lambda SAM inference table coverage ─────────────────────── */ TEST(cov_lambda_function) { CBMFileResult *r = cov_extract( "import java.util.function.Function;\n" "public class Main { public Function f() { return s -> s.length(); } }"); ASSERT_NOT_NULL(r); /* Standalone lambdas without a method-call context don't bind via SAM, * but the body should still be walked. */ cbm_free_result(r); PASS(); } TEST(cov_lambda_predicate_filter) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public long f(ArrayList xs) { return xs.stream().filter(s -> s.length() > 0).count(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_consumer_forEach) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public void f(ArrayList xs) { xs.forEach(s -> { s.toUpperCase(); }); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.toUpperCase"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_function_map) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) { return xs.stream().map(s -> s.trim()).count(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_user_consumer) { CBMFileResult *r = cov_extract( "import java.util.function.Consumer;\n" "public class Main {\n" " void run(Consumer c) { c.accept(\"x\"); }\n" " public void f() { run(s -> s.toUpperCase()); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.toUpperCase"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_user_function) { CBMFileResult *r = cov_extract( "import java.util.function.Function;\n" "public class Main {\n" " Object run(Function fn) { return fn.apply(\"x\"); }\n" " public Object f() { return run(s -> s.length()); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_user_predicate) { CBMFileResult *r = cov_extract( "import java.util.function.Predicate;\n" "public class Main {\n" " boolean run(Predicate p) { return p.test(\"x\"); }\n" " public boolean f() { return run(s -> s.isEmpty()); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.isEmpty"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_block_body) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public void f(ArrayList xs) {\n" " xs.forEach(s -> { String t = s.trim(); int n = t.length(); });\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_bipredicate) { CBMFileResult *r = cov_extract( "import java.util.function.BiPredicate;\n" "public class Main {\n" " boolean run(BiPredicate bp) { return bp.test(\"a\",\"b\"); }\n" " public boolean f() { return run((a, b) -> a.equals(b)); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.equals"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_biconsumer_map) { CBMFileResult *r = cov_extract( "import java.util.HashMap;\n" "public class Main { public void f(HashMap m) {\n" " m.forEach((k, v) -> { k.length(); });\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_anyMatch) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public boolean f(ArrayList xs) {\n" " return xs.stream().anyMatch(s -> s.startsWith(\"x\"));\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.startsWith"), 0); cbm_free_result(r); PASS(); } TEST(cov_lambda_removeIf) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public void f(ArrayList xs) {\n" " xs.removeIf(s -> s.isEmpty());\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.isEmpty"), 0); cbm_free_result(r); PASS(); } /* ── 12. Method references ───────────────────────────────────────── */ TEST(cov_mref_static) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public void f(ArrayList xs) { xs.forEach(System.out::println); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "PrintStream.println"), 0); cbm_free_result(r); PASS(); } TEST(cov_mref_instance_method) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) {\n" " return xs.stream().map(String::toUpperCase).count();\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.toUpperCase"), 0); cbm_free_result(r); PASS(); } TEST(cov_mref_static_class_method) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) {\n" " return xs.stream().map(Integer::parseInt).count();\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Integer.parseInt"), 0); cbm_free_result(r); PASS(); } TEST(cov_mref_constructor_simple) { CBMFileResult *r = cov_extract( "import java.util.function.Function;\n" "public class Main { public Function f() { return StringBuilder::new; } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "StringBuilder"), 0); cbm_free_result(r); PASS(); } TEST(cov_mref_in_local_var) { CBMFileResult *r = cov_extract( "import java.util.function.Function;\n" "public class Main { public void f() { Function g = String::length; } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_mref_with_chain) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "import java.util.stream.Collectors;\n" "public class Main { public Object f(ArrayList xs) {\n" " return xs.stream().map(String::trim).collect(Collectors.toList());\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); ASSERT_GTE(cov_require(r, "f", "Collectors.toList"), 0); cbm_free_result(r); PASS(); } TEST(cov_mref_user_class) { CBMFileResult *r = cov_extract( "import java.util.function.Function;\n" "public class Main {\n" " static class U { public String tag() { return \"x\"; } }\n" " public Function f() { return U::tag; }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_mref_user_constructor) { CBMFileResult *r = cov_extract( "import java.util.function.Supplier;\n" "public class Main {\n" " static class Box { public Box() {} }\n" " public Supplier f() { return Box::new; }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Box"), 0); cbm_free_result(r); PASS(); } /* ── 13. Inheritance walking ─────────────────────────────────────── */ TEST(cov_inh_basic) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A { public String tag() { return \"a\"; } }\n" " static class B extends A { public String f(B b) { return b.tag(); } }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_inh_3level) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A { public String tag() { return \"a\"; } }\n" " static class B extends A {}\n" " static class C extends B { public String f(C c) { return c.tag(); } }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_inh_4level) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A { public String tag() { return \"a\"; } }\n" " static class B extends A {}\n" " static class C extends B {}\n" " static class D extends C { public String f(D d) { return d.tag(); } }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_inh_override) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A { public String tag() { return \"a\"; } }\n" " static class B extends A {\n" " public String tag() { return \"b\"; }\n" " public String f(B b) { return b.tag(); }\n" " }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_inh_super_after_override) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A { public String tag() { return \"a\"; } }\n" " static class B extends A {\n" " public String tag() { return super.tag(); }\n" " }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "tag", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_inh_via_object) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A {}\n" " public String f(A a) { return a.toString(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Object.toString"), 0); cbm_free_result(r); PASS(); } TEST(cov_inh_interface_default) { CBMFileResult *r = cov_extract( "public class Main {\n" " interface Greet { default String hello() { return \"hi\"; } }\n" " static class Impl implements Greet { public String f() { return hello(); } }\n" "}"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_inh_interface_via_param) { CBMFileResult *r = cov_extract( "import java.util.List;\n" "public class Main { public int f(List xs) { return xs.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "List.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_inh_collection_to_list) { CBMFileResult *r = cov_extract( "import java.util.Collection;\n" "public class Main { public int f(Collection c) { return c.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Collection.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_inh_list_iterable_iterator) { CBMFileResult *r = cov_extract( "import java.util.List;\n" "public class Main { public int f(List xs) { return xs.iterator().next().length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Iterator.next"), 0); cbm_free_result(r); PASS(); } /* ── 14. java.lang stdlib coverage ───────────────────────────────── */ TEST(cov_lang_object_hashCode) { CBMFileResult *r = cov_extract("public class Main { public int f(Object o) { return o.hashCode(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Object.hashCode"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_object_equals) { CBMFileResult *r = cov_extract( "public class Main { public boolean f(Object a, Object b) { return a.equals(b); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Object.equals"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_object_getClass) { CBMFileResult *r = cov_extract("public class Main { public Class f(Object o) { return o.getClass(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Object.getClass"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_string_repeat) { CBMFileResult *r = cov_extract( "public class Main { public String f() { return \"x\".repeat(3); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.repeat"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_string_split) { CBMFileResult *r = cov_extract( "public class Main { public String[] f(String s) { return s.split(\",\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.split"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_string_indexOf) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { return s.indexOf('a'); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.indexOf"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_string_substring) { CBMFileResult *r = cov_extract( "public class Main { public String f(String s) { return s.substring(1, 3); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.substring"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_math_pow) { CBMFileResult *r = cov_extract( "public class Main { public double f() { return Math.pow(2, 10); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Math.pow"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_math_log) { CBMFileResult *r = cov_extract("public class Main { public double f() { return Math.log(2.0); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Math.log"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_math_random) { CBMFileResult *r = cov_extract("public class Main { public double f() { return Math.random(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Math.random"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_system_nano) { CBMFileResult *r = cov_extract( "public class Main { public long f() { return System.nanoTime(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "System.nanoTime"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_system_getenv) { CBMFileResult *r = cov_extract( "public class Main { public String f() { return System.getenv(\"X\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "System.getenv"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_thread_sleep) { CBMFileResult *r = cov_extract( "public class Main { public void f() throws InterruptedException { Thread.sleep(1); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Thread.sleep"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_class_forName) { CBMFileResult *r = cov_extract( "public class Main { public Class f() throws ClassNotFoundException { return Class.forName(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Class.forName"), 0); cbm_free_result(r); PASS(); } TEST(cov_lang_throwable_getCause) { CBMFileResult *r = cov_extract( "public class Main { public Throwable f(Throwable t) { return t.getCause(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Throwable.getCause"), 0); cbm_free_result(r); PASS(); } /* ── 15. java.util stdlib coverage ───────────────────────────────── */ TEST(cov_util_arraylist_add) { CBMFileResult *r = cov_extract("import java.util.ArrayList;\n" "public class Main { public void f(ArrayList xs) { xs.add(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ArrayList.add"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_arraylist_remove) { CBMFileResult *r = cov_extract("import java.util.ArrayList;\n" "public class Main { public void f(ArrayList xs) { xs.remove(0); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ArrayList.remove"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_linkedlist_addFirst) { CBMFileResult *r = cov_extract("import java.util.LinkedList;\n" "public class Main { public void f(LinkedList xs) { xs.addFirst(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "LinkedList.addFirst"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_hashset_add) { CBMFileResult *r = cov_extract("import java.util.HashSet;\n" "public class Main { public boolean f(HashSet s) { return s.add(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashSet.add"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_treeset_first) { CBMFileResult *r = cov_extract("import java.util.TreeSet;\n" "public class Main { public Object f(TreeSet s) { return s.first(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "TreeSet.first"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_hashmap_put) { CBMFileResult *r = cov_extract("import java.util.HashMap;\n" "public class Main { public void f(HashMap m) { m.put(\"k\", 1); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap.put"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_treemap_firstKey) { CBMFileResult *r = cov_extract("import java.util.TreeMap;\n" "public class Main { public Object f(TreeMap m) { return m.firstKey(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "TreeMap.firstKey"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_arrays_sort) { CBMFileResult *r = cov_extract("import java.util.Arrays;\n" "public class Main { public void f(int[] xs) { Arrays.sort(xs); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Arrays.sort"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_collections_unmodifiable) { CBMFileResult *r = cov_extract("import java.util.Collections;\n" "import java.util.List;\n" "public class Main { public List f(List xs) { return Collections.unmodifiableList(xs); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Collections.unmodifiableList"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_objects_isNull) { CBMFileResult *r = cov_extract( "import java.util.Objects;\n" "public class Main { public boolean f(Object o) { return Objects.isNull(o); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Objects.isNull"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_optional_isPresent) { CBMFileResult *r = cov_extract( "import java.util.Optional;\n" "public class Main { public boolean f(Optional o) { return o.isPresent(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Optional.isPresent"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_optional_map) { CBMFileResult *r = cov_extract( "import java.util.Optional;\n" "public class Main { public Object f(Optional o) { return o.map(s -> s.length()); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Optional.map"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_uuid_random) { CBMFileResult *r = cov_extract( "import java.util.UUID;\n" "public class Main { public String f() { return UUID.randomUUID().toString(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "UUID.randomUUID"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_random_nextInt) { CBMFileResult *r = cov_extract( "import java.util.Random;\n" "public class Main { public int f(Random r) { return r.nextInt(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Random.nextInt"), 0); cbm_free_result(r); PASS(); } TEST(cov_util_scanner_nextLine) { CBMFileResult *r = cov_extract( "import java.util.Scanner;\n" "public class Main { public String f(Scanner s) { return s.nextLine(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Scanner.nextLine"), 0); cbm_free_result(r); PASS(); } /* ── 16. java.io stdlib ──────────────────────────────────────────── */ TEST(cov_io_print_writer) { CBMFileResult *r = cov_extract( "import java.io.PrintWriter;\n" "public class Main { public void f(PrintWriter w) { w.println(\"x\"); w.flush(); w.close(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "PrintWriter.println"), 0); ASSERT_GTE(cov_require(r, "f", "PrintWriter.flush"), 0); ASSERT_GTE(cov_require(r, "f", "PrintWriter.close"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_input_stream_read) { CBMFileResult *r = cov_extract( "import java.io.InputStream;\n" "public class Main { public int f(InputStream in) throws java.io.IOException { return in.read(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "InputStream.read"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_output_stream_write) { CBMFileResult *r = cov_extract( "import java.io.OutputStream;\n" "public class Main { public void f(OutputStream o) throws java.io.IOException { o.write(1); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "OutputStream.write"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_buffered_writer) { CBMFileResult *r = cov_extract( "import java.io.BufferedWriter;\n" "public class Main { public void f(BufferedWriter w) throws java.io.IOException {\n" " w.write(\"x\"); w.newLine(); w.flush();\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "BufferedWriter.newLine"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_file_construction) { CBMFileResult *r = cov_extract( "import java.io.File;\n" "public class Main { public File f() { return new File(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "File"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_file_listFiles) { CBMFileResult *r = cov_extract( "import java.io.File;\n" "public class Main { public File[] f(File d) { return d.listFiles(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "File.listFiles"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_file_canRead) { CBMFileResult *r = cov_extract( "import java.io.File;\n" "public class Main { public boolean f(File d) { return d.canRead(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "File.canRead"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_file_to_path) { CBMFileResult *r = cov_extract( "import java.io.File;\n" "public class Main { public java.nio.file.Path f(File d) { return d.toPath(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "File.toPath"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_reader_ready) { CBMFileResult *r = cov_extract( "import java.io.Reader;\n" "public class Main { public boolean f(Reader r) throws java.io.IOException { return r.ready(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Reader.ready"), 0); cbm_free_result(r); PASS(); } TEST(cov_io_writer_close) { CBMFileResult *r = cov_extract( "import java.io.Writer;\n" "public class Main { public void f(Writer w) throws java.io.IOException { w.close(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Writer.close"), 0); cbm_free_result(r); PASS(); } /* ── 17. java.nio.file ──────────────────────────────────────────── */ TEST(cov_nio_path_resolve) { CBMFileResult *r = cov_extract( "import java.nio.file.Path;\n" "public class Main { public Path f(Path p) { return p.resolve(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Path.resolve"), 0); cbm_free_result(r); PASS(); } TEST(cov_nio_path_getFileName) { CBMFileResult *r = cov_extract( "import java.nio.file.Path;\n" "public class Main { public Path f(Path p) { return p.getFileName(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Path.getFileName"), 0); cbm_free_result(r); PASS(); } TEST(cov_nio_files_exists) { CBMFileResult *r = cov_extract( "import java.nio.file.Files;\n" "import java.nio.file.Path;\n" "public class Main { public boolean f(Path p) { return Files.exists(p); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Files.exists"), 0); cbm_free_result(r); PASS(); } TEST(cov_nio_files_walk) { CBMFileResult *r = cov_extract( "import java.nio.file.Files;\n" "import java.nio.file.Path;\n" "public class Main { public Object f(Path p) throws java.io.IOException { return Files.walk(p); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Files.walk"), 0); cbm_free_result(r); PASS(); } TEST(cov_nio_files_lines) { CBMFileResult *r = cov_extract( "import java.nio.file.Files;\n" "import java.nio.file.Path;\n" "public class Main { public Object f(Path p) throws java.io.IOException { return Files.lines(p); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Files.lines"), 0); cbm_free_result(r); PASS(); } /* ── 18. java.util.stream ────────────────────────────────────────── */ TEST(cov_stream_sorted) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) { return xs.stream().sorted().count(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Stream.sorted"), 0); cbm_free_result(r); PASS(); } TEST(cov_stream_distinct) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) { return xs.stream().distinct().count(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Stream.distinct"), 0); cbm_free_result(r); PASS(); } TEST(cov_stream_limit) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) { return xs.stream().limit(5).count(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Stream.limit"), 0); cbm_free_result(r); PASS(); } TEST(cov_stream_skip) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) { return xs.stream().skip(2).count(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Stream.skip"), 0); cbm_free_result(r); PASS(); } TEST(cov_stream_min) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) { return xs.stream().min((a,b) -> a.compareTo(b)); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Stream.min"), 0); cbm_free_result(r); PASS(); } TEST(cov_stream_findFirst) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public Object f(ArrayList xs) { return xs.stream().findFirst(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Stream.findFirst"), 0); cbm_free_result(r); PASS(); } TEST(cov_stream_allMatch) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public boolean f(ArrayList xs) { return xs.stream().allMatch(s -> s.length() > 0); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Stream.allMatch"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_stream_collect_toSet) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "import java.util.stream.Collectors;\n" "public class Main { public Object f(ArrayList xs) { return xs.stream().collect(Collectors.toSet()); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Collectors.toSet"), 0); cbm_free_result(r); PASS(); } TEST(cov_stream_collect_groupingBy) { /* The lambda inside Collectors.groupingBy is typed via Function, where T comes from the OUTER stream's element type * — that bidirectional flow isn't currently modeled (the LSP looks at * the static method's static signature only). Resolving Collectors. * groupingBy itself is the test we keep; lambda body resolution is a * known gap. */ CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "import java.util.stream.Collectors;\n" "public class Main { public Object f(ArrayList xs) {\n" " return xs.stream().collect(Collectors.groupingBy(s -> s.length()));\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Collectors.groupingBy"), 0); cbm_free_result(r); PASS(); } TEST(cov_intstream_range) { CBMFileResult *r = cov_extract( "import java.util.stream.IntStream;\n" "public class Main { public int f() { return IntStream.range(0, 10).sum(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "IntStream.range"), 0); ASSERT_GTE(cov_require(r, "f", "IntStream.sum"), 0); cbm_free_result(r); PASS(); } /* ── 19. java.util.function ──────────────────────────────────────── */ TEST(cov_fn_unaryoperator) { CBMFileResult *r = cov_extract( "import java.util.function.UnaryOperator;\n" "public class Main { public Object f(UnaryOperator op) { return op.apply(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "UnaryOperator.apply"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_binaryoperator) { /* BinaryOperator extends BiFunction, so apply() resolves to * BiFunction.apply (correct per JLS §8.4.8). Either callee is OK. */ CBMFileResult *r = cov_extract( "import java.util.function.BinaryOperator;\n" "public class Main { public Object f(BinaryOperator op) { return op.apply(\"x\", \"y\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "apply"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_consumer_andThen) { CBMFileResult *r = cov_extract( "import java.util.function.Consumer;\n" "public class Main { public Object f(Consumer c1, Consumer c2) { return c1.andThen(c2); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Consumer.andThen"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_predicate_and) { CBMFileResult *r = cov_extract( "import java.util.function.Predicate;\n" "public class Main { public Object f(Predicate p1, Predicate p2) { return p1.and(p2); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Predicate.and"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_predicate_negate) { CBMFileResult *r = cov_extract( "import java.util.function.Predicate;\n" "public class Main { public Object f(Predicate p) { return p.negate(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Predicate.negate"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_function_andThen) { CBMFileResult *r = cov_extract( "import java.util.function.Function;\n" "public class Main { public Object f(Function f1, Function f2) {\n" " return f1.andThen(f2);\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Function.andThen"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_intpredicate) { CBMFileResult *r = cov_extract( "import java.util.function.IntPredicate;\n" "public class Main { public boolean f(IntPredicate p) { return p.test(1); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "IntPredicate.test"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_toint_function) { CBMFileResult *r = cov_extract( "import java.util.function.ToIntFunction;\n" "public class Main { public int f(ToIntFunction fn) { return fn.applyAsInt(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ToIntFunction.applyAsInt"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_int_supplier) { CBMFileResult *r = cov_extract( "import java.util.function.IntSupplier;\n" "public class Main { public int f(IntSupplier s) { return s.getAsInt(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "IntSupplier.getAsInt"), 0); cbm_free_result(r); PASS(); } TEST(cov_fn_runnable) { CBMFileResult *r = cov_extract( "public class Main { public void f(Runnable r) { r.run(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Runnable.run"), 0); cbm_free_result(r); PASS(); } /* ── 20. java.util.concurrent ───────────────────────────────────── */ TEST(cov_conc_atomic_get) { CBMFileResult *r = cov_extract( "import java.util.concurrent.atomic.AtomicInteger;\n" "public class Main { public int f(AtomicInteger a) { return a.get(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "AtomicInteger.get"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_atomic_compareAndSet) { CBMFileResult *r = cov_extract( "import java.util.concurrent.atomic.AtomicInteger;\n" "public class Main { public boolean f(AtomicInteger a) { return a.compareAndSet(0, 1); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "AtomicInteger.compareAndSet"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_atomic_long) { CBMFileResult *r = cov_extract( "import java.util.concurrent.atomic.AtomicLong;\n" "public class Main { public long f(AtomicLong a) { return a.incrementAndGet(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "AtomicLong.incrementAndGet"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_atomic_reference) { CBMFileResult *r = cov_extract( "import java.util.concurrent.atomic.AtomicReference;\n" "public class Main { public Object f(AtomicReference a) { return a.get(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "AtomicReference.get"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_executor_singleThread) { CBMFileResult *r = cov_extract( "import java.util.concurrent.ExecutorService;\n" "import java.util.concurrent.Executors;\n" "public class Main { public ExecutorService f() { return Executors.newSingleThreadExecutor(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Executors.newSingleThreadExecutor"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_executor_cached) { CBMFileResult *r = cov_extract( "import java.util.concurrent.ExecutorService;\n" "import java.util.concurrent.Executors;\n" "public class Main { public ExecutorService f() { return Executors.newCachedThreadPool(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Executors.newCachedThreadPool"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_future_get) { CBMFileResult *r = cov_extract( "import java.util.concurrent.Future;\n" "public class Main { public Object f(Future fut) throws Exception { return fut.get(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Future.get"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_completable_supplyAsync) { CBMFileResult *r = cov_extract( "import java.util.concurrent.CompletableFuture;\n" "public class Main { public CompletableFuture f() {\n" " return CompletableFuture.supplyAsync(() -> \"x\");\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "CompletableFuture.supplyAsync"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_concurrent_hashmap) { CBMFileResult *r = cov_extract( "import java.util.concurrent.ConcurrentHashMap;\n" "public class Main { public Object f(ConcurrentHashMap m) { return m.get(\"k\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ConcurrentHashMap.get"), 0); cbm_free_result(r); PASS(); } TEST(cov_conc_reentrant_lock) { CBMFileResult *r = cov_extract( "import java.util.concurrent.locks.ReentrantLock;\n" "public class Main { public void f(ReentrantLock l) { l.lock(); l.unlock(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ReentrantLock.lock"), 0); ASSERT_GTE(cov_require(r, "f", "ReentrantLock.unlock"), 0); cbm_free_result(r); PASS(); } /* ── 21. java.time ───────────────────────────────────────────────── */ TEST(cov_time_localdate_plus) { CBMFileResult *r = cov_extract( "import java.time.LocalDate;\n" "public class Main { public LocalDate f(LocalDate d) { return d.plusDays(1); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "LocalDate.plusDays"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_localdate_isAfter) { CBMFileResult *r = cov_extract( "import java.time.LocalDate;\n" "public class Main { public boolean f(LocalDate a, LocalDate b) { return a.isAfter(b); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "LocalDate.isAfter"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_localdatetime_now) { CBMFileResult *r = cov_extract( "import java.time.LocalDateTime;\n" "public class Main { public LocalDateTime f() { return LocalDateTime.now(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "LocalDateTime.now"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_instant_now) { CBMFileResult *r = cov_extract( "import java.time.Instant;\n" "public class Main { public Instant f() { return Instant.now(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Instant.now"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_duration_between) { CBMFileResult *r = cov_extract( "import java.time.Duration;\n" "import java.time.Instant;\n" "public class Main { public Duration f(Instant a, Instant b) { return Duration.between(a, b); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Duration.between"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_duration_minutes) { CBMFileResult *r = cov_extract( "import java.time.Duration;\n" "public class Main { public long f(Duration d) { return d.toMinutes(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Duration.toMinutes"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_zoneid_systemDefault) { CBMFileResult *r = cov_extract( "import java.time.ZoneId;\n" "public class Main { public ZoneId f() { return ZoneId.systemDefault(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ZoneId.systemDefault"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_localdate_format) { CBMFileResult *r = cov_extract( "import java.time.LocalDate;\n" "import java.time.format.DateTimeFormatter;\n" "public class Main { public String f(LocalDate d, DateTimeFormatter fmt) { return d.format(fmt); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "LocalDate.format"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_formatter_ofPattern) { CBMFileResult *r = cov_extract( "import java.time.format.DateTimeFormatter;\n" "public class Main { public DateTimeFormatter f() { return DateTimeFormatter.ofPattern(\"yyyy\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "DateTimeFormatter.ofPattern"), 0); cbm_free_result(r); PASS(); } TEST(cov_time_localdate_parse) { CBMFileResult *r = cov_extract( "import java.time.LocalDate;\n" "public class Main { public LocalDate f(String s) { return LocalDate.parse(s); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "LocalDate.parse"), 0); cbm_free_result(r); PASS(); } /* ── 22. Imports ─────────────────────────────────────────────────── */ TEST(cov_imp_single_type) { CBMFileResult *r = cov_extract( "import java.util.HashMap;\n" "public class Main { public int f(HashMap m) { return m.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_imp_on_demand) { CBMFileResult *r = cov_extract( "import java.util.*;\n" "public class Main { public int f(HashMap m) { return m.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_imp_static_method) { CBMFileResult *r = cov_extract( "import static java.lang.Math.sqrt;\n" "public class Main { public double f() { return sqrt(2); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Math.sqrt"), 0); cbm_free_result(r); PASS(); } TEST(cov_imp_static_on_demand) { CBMFileResult *r = cov_extract( "import static java.lang.Math.*;\n" "public class Main { public double f() { return PI; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_imp_multiple) { CBMFileResult *r = cov_extract( "import java.util.HashMap;\n" "import java.util.ArrayList;\n" "import java.util.List;\n" "public class Main {\n" " public int f(HashMap> m) { return m.size(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_imp_qualified_no_import) { CBMFileResult *r = cov_extract( "public class Main { public int f(java.util.HashMap m) { return m.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "HashMap.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_imp_with_package) { CBMFileResult *r = cov_extract( "package com.example;\n" "import java.util.ArrayList;\n" "public class Main { public int f(ArrayList xs) { return xs.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ArrayList.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_imp_chained_packages) { CBMFileResult *r = cov_extract( "package a.b.c;\n" "import java.util.concurrent.atomic.AtomicInteger;\n" "public class Main { public int f(AtomicInteger a) { return a.get(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "AtomicInteger.get"), 0); cbm_free_result(r); PASS(); } /* ── 23. Inner / nested types ────────────────────────────────────── */ TEST(cov_nest_static_inner) { CBMFileResult *r = cov_extract( "public class Main { static class A { String tag() { return \"a\"; } }\n" " public String f() { return new A().tag(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_nest_inner_3level) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class A { static class B { static class C { String tag() { return \"c\"; } } } }\n" " public String f() { return new Main.A.B.C().tag(); }\n" "}"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_nest_interface) { CBMFileResult *r = cov_extract( "public class Main {\n" " interface I { String tag(); }\n" " static class A implements I { public String tag() { return \"a\"; } }\n" " public String f() { I x = new A(); return x.tag(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_nest_enum) { CBMFileResult *r = cov_extract( "public class Main { enum Color { RED, GREEN, BLUE } public Color f() { return Color.RED; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_nest_static_field) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class K { static String NAME = \"x\"; }\n" " public int f() { return K.NAME.length(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_nest_outer_method_from_inner) { CBMFileResult *r = cov_extract( "public class Main {\n" " String greet() { return \"hi\"; }\n" " class Inner { public String f() { return greet(); } }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "greet"), 0); cbm_free_result(r); PASS(); } TEST(cov_nest_outer_field_from_inner) { CBMFileResult *r = cov_extract( "public class Main {\n" " private String tag = \"x\";\n" " class Inner { public int f() { return tag.length(); } }\n" "}"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_nest_record) { CBMFileResult *r = cov_extract( "public class Main { public record Point(int x, int y) {} public int f() { return new Point(1,2).x(); } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_nest_static_member_access) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class Util { static String tag() { return \"u\"; } }\n" " public String f() { return Util.tag(); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "tag"), 0); cbm_free_result(r); PASS(); } TEST(cov_nest_constructor_call) { CBMFileResult *r = cov_extract( "public class Main {\n" " static class Item { public Item(String s) {} }\n" " public Item f() { return new Item(\"x\"); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Item"), 0); cbm_free_result(r); PASS(); } /* ── 24. Variable / scope binding ────────────────────────────────── */ TEST(cov_bind_local_int) { CBMFileResult *r = cov_extract( "public class Main { public void f() { int a = 1; a++; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_bind_var_string) { CBMFileResult *r = cov_extract( "public class Main { public int f() { var s = \"x\"; return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_bind_var_arraylist) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public int f() { var xs = new ArrayList(); xs.add(\"x\"); return xs.size(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ArrayList.add"), 0); ASSERT_GTE(cov_require(r, "f", "ArrayList.size"), 0); cbm_free_result(r); PASS(); } TEST(cov_bind_multi_decl) { CBMFileResult *r = cov_extract( "public class Main { public int f() { int a = 1, b = 2, c = 3; return a + b + c; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_bind_final_local) { CBMFileResult *r = cov_extract( "public class Main { public int f() { final String s = \"x\"; return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_bind_for_loop_init) { CBMFileResult *r = cov_extract( "public class Main { public int f() { int n = 0; for (int i = 0; i < 10; i++) n++; return n; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_bind_enhanced_for_array) { CBMFileResult *r = cov_extract( "public class Main { public int f(String[] xs) { int n = 0; for (String s : xs) n += s.length(); return n; } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_bind_enhanced_for_iterable) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public int f(ArrayList xs) { int n = 0; for (String s : xs) n += s.length(); return n; } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_bind_catch_param) { CBMFileResult *r = cov_extract( "public class Main { public String f() {\n" " try { return Integer.toString(Integer.parseInt(\"x\")); }\n" " catch (NumberFormatException e) { return e.getMessage(); }\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Throwable.getMessage"), 0); cbm_free_result(r); PASS(); } TEST(cov_bind_try_resources) { CBMFileResult *r = cov_extract( "import java.io.BufferedReader;\n" "import java.io.FileReader;\n" "public class Main { public String f(String path) throws java.io.IOException {\n" " try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); }\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "BufferedReader.readLine"), 0); cbm_free_result(r); PASS(); } /* ── 25. Control flow ─────────────────────────────────────────────── */ TEST(cov_ctrl_if_call) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { if (s.isEmpty()) return 0; else return s.length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.isEmpty"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_ctrl_for_call) { CBMFileResult *r = cov_extract( "import java.util.ArrayList;\n" "public class Main { public int f(ArrayList xs) {\n" " int n = 0;\n" " for (int i = 0; i < xs.size(); i++) n += xs.get(i).length();\n" " return n;\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "ArrayList.size"), 0); ASSERT_GTE(cov_require(r, "f", "ArrayList.get"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_ctrl_while_call) { CBMFileResult *r = cov_extract( "import java.util.Iterator;\n" "public class Main { public int f(Iterator it) {\n" " int n = 0;\n" " while (it.hasNext()) n += it.next().length();\n" " return n;\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Iterator.hasNext"), 0); ASSERT_GTE(cov_require(r, "f", "Iterator.next"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_ctrl_do_while) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { int n = 0; do { n++; } while (n < s.length()); return n; } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_ctrl_switch_basic) { CBMFileResult *r = cov_extract( "public class Main { public String f(int x) {\n" " switch (x) {\n" " case 1: return \"one\".toUpperCase();\n" " case 2: return \"two\".trim();\n" " default: return \"\";\n" " }\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.toUpperCase"), 0); ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); cbm_free_result(r); PASS(); } TEST(cov_ctrl_try_finally) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) {\n" " try { return s.length(); }\n" " finally { s.toString(); }\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_ctrl_try_multi_catch) { CBMFileResult *r = cov_extract( "public class Main { public String f() {\n" " try { return Integer.toString(Integer.parseInt(\"x\")); }\n" " catch (NumberFormatException | NullPointerException e) { return e.getMessage(); }\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "Throwable.getMessage"), 0); cbm_free_result(r); PASS(); } TEST(cov_ctrl_throw_in_method) { CBMFileResult *r = cov_extract( "public class Main { public void f() throws IllegalStateException { throw new IllegalStateException(\"x\"); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "IllegalStateException"), 0); cbm_free_result(r); PASS(); } TEST(cov_ctrl_break_continue_no_crash) { CBMFileResult *r = cov_extract( "public class Main { public int f(int[] xs) {\n" " int n = 0;\n" " for (int x : xs) { if (x < 0) continue; if (x > 100) break; n++; }\n" " return n;\n" "} }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_ctrl_synchronized) { CBMFileResult *r = cov_extract( "public class Main { public int f(Object lock, String s) { synchronized(lock) { return s.length(); } } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } /* ── 26. Diagnostics ─────────────────────────────────────────────── */ TEST(cov_diag_unknown_method) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) { return s.nonexistentMethod(); } }"); ASSERT_NOT_NULL(r); int diag = 0; for (int i = 0; i < r->resolved_calls.count; i++) { if (r->resolved_calls.items[i].confidence == 0.0f) diag++; } ASSERT_GTE(diag, 1); cbm_free_result(r); PASS(); } TEST(cov_diag_unknown_var) { CBMFileResult *r = cov_extract( "public class Main { public int f() { return undef.size(); } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_diag_unresolved_count) { CBMFileResult *r = cov_extract( "public class Main { public void f() {\n" " unknownObj1.unknownMethod1();\n" " unknownObj2.unknownMethod2();\n" "} }"); ASSERT_NOT_NULL(r); int diag = 0; for (int i = 0; i < r->resolved_calls.count; i++) { if (r->resolved_calls.items[i].confidence == 0.0f) diag++; } ASSERT_GTE(diag, 1); cbm_free_result(r); PASS(); } TEST(cov_diag_no_resolved_no_calls) { CBMFileResult *r = cov_extract( "public class Main { public int f() { return 1 + 2; } }"); ASSERT_NOT_NULL(r); /* No calls, no resolved entries. */ int strict = cov_count_strict(r); ASSERT_EQ(strict, 0); cbm_free_result(r); PASS(); } TEST(cov_diag_unresolved_super_no_match) { CBMFileResult *r = cov_extract( "public class Main { public String f() { return super.nonexistent(); } }"); ASSERT_NOT_NULL(r); int diag = 0; for (int i = 0; i < r->resolved_calls.count; i++) { if (r->resolved_calls.items[i].confidence == 0.0f) diag++; } ASSERT_GTE(diag, 1); cbm_free_result(r); PASS(); } TEST(cov_diag_method_ref_unknown_lhs) { CBMFileResult *r = cov_extract( "public class Main { public Object f() { return undefined::method; } }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } /* ── 27. Cross-file API ──────────────────────────────────────────── */ TEST(cov_cross_basic) { const char *src = "package com.example;\n" "public class Caller { public String f(com.example.Greeter g) { return g.greet(\"x\"); } }"; CBMArena arena; cbm_arena_init(&arena); CBMResolvedCallArray out; memset(&out, 0, sizeof(out)); CBMLSPDef defs[2]; memset(defs, 0, sizeof(defs)); defs[0].qualified_name = "com.example.Greeter"; defs[0].short_name = "Greeter"; defs[0].label = "Class"; defs[0].def_module_qn = "com.example"; defs[1].qualified_name = "com.example.Greeter.greet"; defs[1].short_name = "greet"; defs[1].label = "Method"; defs[1].receiver_type = "com.example.Greeter"; defs[1].return_types = "java.lang.String"; const char *imp_names[] = {"Greeter"}; const char *imp_qns[] = {"com.example.Greeter"}; cbm_run_java_lsp_cross(&arena, src, (int)strlen(src), "test.com.example", defs, 2, imp_names, imp_qns, 1, NULL, &out); int found = 0; for (int i = 0; i < out.count; i++) { if (out.items[i].confidence < 0.5f) continue; if (out.items[i].callee_qn && strstr(out.items[i].callee_qn, "Greeter.greet")) found = 1; } ASSERT_EQ(found, 1); cbm_arena_destroy(&arena); PASS(); } TEST(cov_cross_no_imports) { const char *src = "public class A { public int f() { return 1; } }"; CBMArena arena; cbm_arena_init(&arena); CBMResolvedCallArray out; memset(&out, 0, sizeof(out)); cbm_run_java_lsp_cross(&arena, src, (int)strlen(src), "test.A", NULL, 0, NULL, NULL, 0, NULL, &out); /* Just a smoke test — no calls, no edges. */ cbm_arena_destroy(&arena); PASS(); } TEST(cov_cross_batch) { const char *src1 = "package p; public class A { public int f() { return 1; } }"; const char *src2 = "package p; public class B { public int f() { return 2; } }"; CBMArena arena; cbm_arena_init(&arena); CBMBatchJavaLSPFile files[2]; memset(files, 0, sizeof(files)); files[0].source = src1; files[0].source_len = (int)strlen(src1); files[0].module_qn = "test.A"; files[1].source = src2; files[1].source_len = (int)strlen(src2); files[1].module_qn = "test.B"; CBMResolvedCallArray outs[2]; memset(outs, 0, sizeof(outs)); cbm_batch_java_lsp_cross(&arena, files, 2, outs); cbm_arena_destroy(&arena); PASS(); } TEST(cov_cross_inheritance) { const char *src = "package x;\n" "public class B { public String f(x.A a) { return a.tag(); } }"; CBMArena arena; cbm_arena_init(&arena); CBMResolvedCallArray out; memset(&out, 0, sizeof(out)); CBMLSPDef defs[2]; memset(defs, 0, sizeof(defs)); defs[0].qualified_name = "x.A"; defs[0].short_name = "A"; defs[0].label = "Class"; defs[1].qualified_name = "x.A.tag"; defs[1].short_name = "tag"; defs[1].label = "Method"; defs[1].receiver_type = "x.A"; defs[1].return_types = "java.lang.String"; cbm_run_java_lsp_cross(&arena, src, (int)strlen(src), "test.B", defs, 2, NULL, NULL, 0, NULL, &out); int found = 0; for (int i = 0; i < out.count; i++) { if (out.items[i].confidence < 0.5f) continue; if (out.items[i].callee_qn && strstr(out.items[i].callee_qn, "A.tag")) found = 1; } ASSERT_EQ(found, 1); cbm_arena_destroy(&arena); PASS(); } /* ── 28. Stress / edge cases ─────────────────────────────────────── */ TEST(cov_edge_empty_method) { CBMFileResult *r = cov_extract("public class Main { public void f() {} }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_edge_empty_class) { CBMFileResult *r = cov_extract("public class Main {}"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_edge_long_chain) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) {\n" " return s.trim().toLowerCase().toUpperCase().substring(0).length();\n" "} }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.trim"), 0); ASSERT_GTE(cov_require(r, "f", "String.toLowerCase"), 0); ASSERT_GTE(cov_require(r, "f", "String.toUpperCase"), 0); ASSERT_GTE(cov_require(r, "f", "String.substring"), 0); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_edge_recursive_user_method) { CBMFileResult *r = cov_extract( "public class Main { public int fib(int n) { return n < 2 ? n : fib(n-1) + fib(n-2); } }"); ASSERT_NOT_NULL(r); int fib_count = 0; for (int i = 0; i < r->resolved_calls.count; i++) { const CBMResolvedCall *rc = &r->resolved_calls.items[i]; if (rc->confidence >= 0.5f && rc->callee_qn && strstr(rc->callee_qn, "fib")) fib_count++; } ASSERT_GTE(fib_count, 2); cbm_free_result(r); PASS(); } TEST(cov_edge_mutual_recursion) { CBMFileResult *r = cov_extract( "public class Main {\n" " public boolean isEven(int n) { return n == 0 || isOdd(n-1); }\n" " public boolean isOdd(int n) { return n != 0 && isEven(n-1); }\n" "}"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "isEven", "isOdd"), 0); ASSERT_GTE(cov_require(r, "isOdd", "isEven"), 0); cbm_free_result(r); PASS(); } TEST(cov_edge_deeply_nested_blocks) { CBMFileResult *r = cov_extract( "public class Main { public int f(String s) {\n" " if (s != null) {\n" " if (!s.isEmpty()) {\n" " if (s.length() > 5) {\n" " return s.length();\n" " }\n" " }\n" " }\n" " return 0;\n" "} }"); ASSERT_NOT_NULL(r); int len_calls = 0; for (int i = 0; i < r->resolved_calls.count; i++) { const CBMResolvedCall *rc = &r->resolved_calls.items[i]; if (rc->confidence >= 0.5f && rc->callee_qn && strstr(rc->callee_qn, "String.length")) { len_calls++; } } ASSERT_GTE(len_calls, 2); cbm_free_result(r); PASS(); } TEST(cov_edge_anonymous_class_no_crash) { CBMFileResult *r = cov_extract( "public class Main { public Runnable f() {\n" " return new Runnable() { public void run() { System.out.println(\"x\"); } };\n" "} }"); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_edge_unicode_string) { CBMFileResult *r = cov_extract( "public class Main { public int f() { return \"\\u00e9\".length(); } }"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } TEST(cov_edge_huge_class_no_crash) { char buf[8192]; int len = snprintf(buf, sizeof(buf), "public class Main {\n"); for (int i = 0; i < 50 && len < (int)sizeof(buf) - 200; i++) { len += snprintf(buf + len, sizeof(buf) - len, " public int m%d(int x) { return x + %d; }\n", i, i); } snprintf(buf + len, sizeof(buf) - len, "}\n"); CBMFileResult *r = cov_extract(buf); ASSERT_NOT_NULL(r); cbm_free_result(r); PASS(); } TEST(cov_edge_unusual_whitespace) { CBMFileResult *r = cov_extract( "public class Main {\npublic\tint f(String\ts) { return s.length(); }\n}\n"); ASSERT_NOT_NULL(r); ASSERT_GTE(cov_require(r, "f", "String.length"), 0); cbm_free_result(r); PASS(); } /* ── Suite registration ──────────────────────────────────────────── */ void suite_java_lsp_coverage(void) { /* 1. Literals */ RUN_TEST(cov_lit_int); RUN_TEST(cov_lit_long); RUN_TEST(cov_lit_hex); RUN_TEST(cov_lit_binary); RUN_TEST(cov_lit_octal); RUN_TEST(cov_lit_float_suffix); RUN_TEST(cov_lit_double); RUN_TEST(cov_lit_char); RUN_TEST(cov_lit_string_method); RUN_TEST(cov_lit_bool_method); RUN_TEST(cov_lit_null_no_crash); /* 2. Type-name resolution */ RUN_TEST(cov_typename_java_lang_implicit); RUN_TEST(cov_typename_via_single_import); RUN_TEST(cov_typename_via_on_demand_import); RUN_TEST(cov_typename_via_static_import); RUN_TEST(cov_typename_qualified_path); RUN_TEST(cov_typename_inner_via_outer); RUN_TEST(cov_typename_nested_two_levels); RUN_TEST(cov_typename_array_type); RUN_TEST(cov_typename_2d_array); RUN_TEST(cov_typename_generic_type); RUN_TEST(cov_typename_wildcard); RUN_TEST(cov_typename_bounded_wildcard); /* 3. Primitive operations */ RUN_TEST(cov_op_arith); RUN_TEST(cov_op_compare); RUN_TEST(cov_op_bitwise); RUN_TEST(cov_op_unary_negate); RUN_TEST(cov_op_logical_not); RUN_TEST(cov_op_increment); RUN_TEST(cov_op_string_concat); RUN_TEST(cov_op_ternary_simple); RUN_TEST(cov_op_assignment); RUN_TEST(cov_op_paren_expr); /* 4. Type-AST kinds */ RUN_TEST(cov_typeast_void_method); RUN_TEST(cov_typeast_byte_param); RUN_TEST(cov_typeast_short_param); RUN_TEST(cov_typeast_int_param); RUN_TEST(cov_typeast_long_param); RUN_TEST(cov_typeast_float_param); RUN_TEST(cov_typeast_double_param); RUN_TEST(cov_typeast_char_param); RUN_TEST(cov_typeast_boolean_param); RUN_TEST(cov_typeast_string_param); RUN_TEST(cov_typeast_array_of_string); RUN_TEST(cov_typeast_generic_list); /* 5. Identifier resolution */ RUN_TEST(cov_id_local_var); RUN_TEST(cov_id_param); RUN_TEST(cov_id_field); RUN_TEST(cov_id_inherited_field); RUN_TEST(cov_id_shadow_param); RUN_TEST(cov_id_block_shadow); RUN_TEST(cov_id_outer_class_field); RUN_TEST(cov_id_class_as_static); RUN_TEST(cov_id_unresolved_emits_diagnostic); RUN_TEST(cov_id_for_loop_var); /* 6. Field access */ RUN_TEST(cov_fa_system_out); RUN_TEST(cov_fa_system_err); RUN_TEST(cov_fa_array_length); RUN_TEST(cov_fa_chained_field_method); RUN_TEST(cov_fa_this_field); RUN_TEST(cov_fa_static_class_field); RUN_TEST(cov_fa_method_then_field); RUN_TEST(cov_fa_field_through_param); RUN_TEST(cov_fa_field_through_chained_call); RUN_TEST(cov_fa_unresolved_field_no_crash); /* 7. Method invocation */ RUN_TEST(cov_mi_bare_local); RUN_TEST(cov_mi_this); RUN_TEST(cov_mi_super); RUN_TEST(cov_mi_static); RUN_TEST(cov_mi_chained_static); RUN_TEST(cov_mi_instance); RUN_TEST(cov_mi_chain_3hop); RUN_TEST(cov_mi_recursive_self); RUN_TEST(cov_mi_overload_by_arity); RUN_TEST(cov_mi_param_chain); RUN_TEST(cov_mi_return_chain); RUN_TEST(cov_mi_args_walked); RUN_TEST(cov_mi_nested_args); RUN_TEST(cov_mi_through_field_getter); RUN_TEST(cov_mi_call_in_condition); /* 8. Object creation */ RUN_TEST(cov_oc_simple); RUN_TEST(cov_oc_with_args); RUN_TEST(cov_oc_diamond); RUN_TEST(cov_oc_generic_explicit); RUN_TEST(cov_oc_user_class); RUN_TEST(cov_oc_with_chained_method); RUN_TEST(cov_oc_array); RUN_TEST(cov_oc_array_init); /* 9. Cast / instanceof */ RUN_TEST(cov_cast_to_string); RUN_TEST(cov_cast_chained); RUN_TEST(cov_cast_primitive); RUN_TEST(cov_instanceof_basic); RUN_TEST(cov_cast_from_iterator); RUN_TEST(cov_cast_arr_elem); RUN_TEST(cov_cast_in_ternary); RUN_TEST(cov_cast_then_chain); /* 10. Generic substitution */ RUN_TEST(cov_gen_list_get); RUN_TEST(cov_gen_arraylist_get); RUN_TEST(cov_gen_linkedlist_first); RUN_TEST(cov_gen_set_iterator_next); RUN_TEST(cov_gen_map_get); RUN_TEST(cov_gen_hashmap_get); RUN_TEST(cov_gen_optional_orElse); RUN_TEST(cov_gen_optional_get); RUN_TEST(cov_gen_iterator_next_chain); RUN_TEST(cov_gen_function_apply); RUN_TEST(cov_gen_supplier_get); RUN_TEST(cov_gen_bifunction_apply); RUN_TEST(cov_gen_map_keyset); RUN_TEST(cov_gen_map_values); RUN_TEST(cov_gen_collection_iterator); /* 11. Lambda SAM inference */ RUN_TEST(cov_lambda_function); RUN_TEST(cov_lambda_predicate_filter); RUN_TEST(cov_lambda_consumer_forEach); RUN_TEST(cov_lambda_function_map); RUN_TEST(cov_lambda_user_consumer); RUN_TEST(cov_lambda_user_function); RUN_TEST(cov_lambda_user_predicate); RUN_TEST(cov_lambda_block_body); RUN_TEST(cov_lambda_bipredicate); RUN_TEST(cov_lambda_biconsumer_map); RUN_TEST(cov_lambda_anyMatch); RUN_TEST(cov_lambda_removeIf); /* 12. Method references */ RUN_TEST(cov_mref_static); RUN_TEST(cov_mref_instance_method); RUN_TEST(cov_mref_static_class_method); RUN_TEST(cov_mref_constructor_simple); RUN_TEST(cov_mref_in_local_var); RUN_TEST(cov_mref_with_chain); RUN_TEST(cov_mref_user_class); RUN_TEST(cov_mref_user_constructor); /* 13. Inheritance */ RUN_TEST(cov_inh_basic); RUN_TEST(cov_inh_3level); RUN_TEST(cov_inh_4level); RUN_TEST(cov_inh_override); RUN_TEST(cov_inh_super_after_override); RUN_TEST(cov_inh_via_object); RUN_TEST(cov_inh_interface_default); RUN_TEST(cov_inh_interface_via_param); RUN_TEST(cov_inh_collection_to_list); RUN_TEST(cov_inh_list_iterable_iterator); /* 14. java.lang */ RUN_TEST(cov_lang_object_hashCode); RUN_TEST(cov_lang_object_equals); RUN_TEST(cov_lang_object_getClass); RUN_TEST(cov_lang_string_repeat); RUN_TEST(cov_lang_string_split); RUN_TEST(cov_lang_string_indexOf); RUN_TEST(cov_lang_string_substring); RUN_TEST(cov_lang_math_pow); RUN_TEST(cov_lang_math_log); RUN_TEST(cov_lang_math_random); RUN_TEST(cov_lang_system_nano); RUN_TEST(cov_lang_system_getenv); RUN_TEST(cov_lang_thread_sleep); RUN_TEST(cov_lang_class_forName); RUN_TEST(cov_lang_throwable_getCause); /* 15. java.util */ RUN_TEST(cov_util_arraylist_add); RUN_TEST(cov_util_arraylist_remove); RUN_TEST(cov_util_linkedlist_addFirst); RUN_TEST(cov_util_hashset_add); RUN_TEST(cov_util_treeset_first); RUN_TEST(cov_util_hashmap_put); RUN_TEST(cov_util_treemap_firstKey); RUN_TEST(cov_util_arrays_sort); RUN_TEST(cov_util_collections_unmodifiable); RUN_TEST(cov_util_objects_isNull); RUN_TEST(cov_util_optional_isPresent); RUN_TEST(cov_util_optional_map); RUN_TEST(cov_util_uuid_random); RUN_TEST(cov_util_random_nextInt); RUN_TEST(cov_util_scanner_nextLine); /* 16. java.io */ RUN_TEST(cov_io_print_writer); RUN_TEST(cov_io_input_stream_read); RUN_TEST(cov_io_output_stream_write); RUN_TEST(cov_io_buffered_writer); RUN_TEST(cov_io_file_construction); RUN_TEST(cov_io_file_listFiles); RUN_TEST(cov_io_file_canRead); RUN_TEST(cov_io_file_to_path); RUN_TEST(cov_io_reader_ready); RUN_TEST(cov_io_writer_close); /* 17. java.nio.file */ RUN_TEST(cov_nio_path_resolve); RUN_TEST(cov_nio_path_getFileName); RUN_TEST(cov_nio_files_exists); RUN_TEST(cov_nio_files_walk); RUN_TEST(cov_nio_files_lines); /* 18. java.util.stream */ RUN_TEST(cov_stream_sorted); RUN_TEST(cov_stream_distinct); RUN_TEST(cov_stream_limit); RUN_TEST(cov_stream_skip); RUN_TEST(cov_stream_min); RUN_TEST(cov_stream_findFirst); RUN_TEST(cov_stream_allMatch); RUN_TEST(cov_stream_collect_toSet); RUN_TEST(cov_stream_collect_groupingBy); RUN_TEST(cov_intstream_range); /* 19. java.util.function */ RUN_TEST(cov_fn_unaryoperator); RUN_TEST(cov_fn_binaryoperator); RUN_TEST(cov_fn_consumer_andThen); RUN_TEST(cov_fn_predicate_and); RUN_TEST(cov_fn_predicate_negate); RUN_TEST(cov_fn_function_andThen); RUN_TEST(cov_fn_intpredicate); RUN_TEST(cov_fn_toint_function); RUN_TEST(cov_fn_int_supplier); RUN_TEST(cov_fn_runnable); /* 20. java.util.concurrent */ RUN_TEST(cov_conc_atomic_get); RUN_TEST(cov_conc_atomic_compareAndSet); RUN_TEST(cov_conc_atomic_long); RUN_TEST(cov_conc_atomic_reference); RUN_TEST(cov_conc_executor_singleThread); RUN_TEST(cov_conc_executor_cached); RUN_TEST(cov_conc_future_get); RUN_TEST(cov_conc_completable_supplyAsync); RUN_TEST(cov_conc_concurrent_hashmap); RUN_TEST(cov_conc_reentrant_lock); /* 21. java.time */ RUN_TEST(cov_time_localdate_plus); RUN_TEST(cov_time_localdate_isAfter); RUN_TEST(cov_time_localdatetime_now); RUN_TEST(cov_time_instant_now); RUN_TEST(cov_time_duration_between); RUN_TEST(cov_time_duration_minutes); RUN_TEST(cov_time_zoneid_systemDefault); RUN_TEST(cov_time_localdate_format); RUN_TEST(cov_time_formatter_ofPattern); RUN_TEST(cov_time_localdate_parse); /* 22. Imports */ RUN_TEST(cov_imp_single_type); RUN_TEST(cov_imp_on_demand); RUN_TEST(cov_imp_static_method); RUN_TEST(cov_imp_static_on_demand); RUN_TEST(cov_imp_multiple); RUN_TEST(cov_imp_qualified_no_import); RUN_TEST(cov_imp_with_package); RUN_TEST(cov_imp_chained_packages); /* 23. Inner/nested */ RUN_TEST(cov_nest_static_inner); RUN_TEST(cov_nest_inner_3level); RUN_TEST(cov_nest_interface); RUN_TEST(cov_nest_enum); RUN_TEST(cov_nest_static_field); RUN_TEST(cov_nest_outer_method_from_inner); RUN_TEST(cov_nest_outer_field_from_inner); RUN_TEST(cov_nest_record); RUN_TEST(cov_nest_static_member_access); RUN_TEST(cov_nest_constructor_call); /* 24. Variable / scope binding */ RUN_TEST(cov_bind_local_int); RUN_TEST(cov_bind_var_string); RUN_TEST(cov_bind_var_arraylist); RUN_TEST(cov_bind_multi_decl); RUN_TEST(cov_bind_final_local); RUN_TEST(cov_bind_for_loop_init); RUN_TEST(cov_bind_enhanced_for_array); RUN_TEST(cov_bind_enhanced_for_iterable); RUN_TEST(cov_bind_catch_param); RUN_TEST(cov_bind_try_resources); /* 25. Control flow */ RUN_TEST(cov_ctrl_if_call); RUN_TEST(cov_ctrl_for_call); RUN_TEST(cov_ctrl_while_call); RUN_TEST(cov_ctrl_do_while); RUN_TEST(cov_ctrl_switch_basic); RUN_TEST(cov_ctrl_try_finally); RUN_TEST(cov_ctrl_try_multi_catch); RUN_TEST(cov_ctrl_throw_in_method); RUN_TEST(cov_ctrl_break_continue_no_crash); RUN_TEST(cov_ctrl_synchronized); /* 26. Diagnostics */ RUN_TEST(cov_diag_unknown_method); RUN_TEST(cov_diag_unknown_var); RUN_TEST(cov_diag_unresolved_count); RUN_TEST(cov_diag_no_resolved_no_calls); RUN_TEST(cov_diag_unresolved_super_no_match); RUN_TEST(cov_diag_method_ref_unknown_lhs); /* 27. Cross-file */ RUN_TEST(cov_cross_basic); RUN_TEST(cov_cross_no_imports); RUN_TEST(cov_cross_batch); RUN_TEST(cov_cross_inheritance); /* 28. Stress / edge */ RUN_TEST(cov_edge_empty_method); RUN_TEST(cov_edge_empty_class); RUN_TEST(cov_edge_long_chain); RUN_TEST(cov_edge_recursive_user_method); RUN_TEST(cov_edge_mutual_recursion); RUN_TEST(cov_edge_deeply_nested_blocks); RUN_TEST(cov_edge_anonymous_class_no_crash); RUN_TEST(cov_edge_unicode_string); RUN_TEST(cov_edge_huge_class_no_crash); RUN_TEST(cov_edge_unusual_whitespace); (void)cov_no_crash; /* silence unused-static warning if any */ }