Implement CcBadDependenciesTest in Starlark.

PiperOrigin-RevId: 956569708
Change-Id: Ia1323e1f56ab3907ea8a0546914cfbbd0ad4d8f4
diff --git a/tests/cc/common/BUILD b/tests/cc/common/BUILD
index d314b7c..b3b414a 100644
--- a/tests/cc/common/BUILD
+++ b/tests/cc/common/BUILD
@@ -1,3 +1,4 @@
+load(":cc_bad_dependencies_test.bzl", "cc_bad_dependencies_tests")
 load(":cc_binary_configured_target_tests.bzl", "cc_binary_configured_target_tests")
 load(":cc_binary_thin_lto_tests.bzl", "cc_binary_thin_lto_tests")
 load(":cc_common_test.bzl", "cc_common_tests")
@@ -31,3 +32,5 @@
 link_build_variables_tests(name = "link_build_variables_tests")
 
 cc_dwp_tests(name = "cc_dwp_tests")
+
+cc_bad_dependencies_tests(name = "cc_bad_dependencies_tests")
diff --git a/tests/cc/common/cc_bad_dependencies_test.bzl b/tests/cc/common/cc_bad_dependencies_test.bzl
new file mode 100644
index 0000000..a9817ec
--- /dev/null
+++ b/tests/cc/common/cc_bad_dependencies_test.bzl
@@ -0,0 +1,96 @@
+"""Tests for bad dependencies between C++ libraries."""
+
+load("@rules_testing//lib:analysis_test.bzl", "test_suite")
+load("@rules_testing//lib:truth.bzl", "matching")
+load("@rules_testing//lib:util.bzl", "util")
+load("//cc:cc_library.bzl", "cc_library")
+load("//tests/cc/testutil:cc_analysis_test.bzl", "cc_analysis_test")
+
+def test_reject_unknown_source_file(name, **kwargs):
+    util.helper_target(
+        rule = cc_library,
+        name = name + "/foo",
+        srcs = ["unknown.oops"],
+    )
+
+    cc_analysis_test(
+        name = name,
+        impl = test_reject_unknown_source_file_impl,
+        target = name + "/foo",
+        expect_failure = True,
+        **kwargs
+    )
+
+def test_reject_unknown_source_file_impl(env, target):
+    env.expect.that_target(target).failures().contains_predicate(
+        matching.str_matches("source file '*:unknown.oops' is misplaced here"),
+    )
+
+def test_reject_bad_generated_file(name, **kwargs):
+    util.helper_target(
+        rule = native.genrule,
+        name = name + "/gen",
+        outs = [name + "/bad.oops"],
+        cmd = "touch $@",
+    )
+
+    util.helper_target(
+        rule = cc_library,
+        name = name + "/foo",
+        srcs = [name + "/gen"],
+    )
+
+    cc_analysis_test(
+        name = name,
+        impl = test_reject_bad_generated_file_impl,
+        target = name + "/foo",
+        expect_failure = True,
+        **kwargs
+    )
+
+def test_reject_bad_generated_file_impl(env, target):
+    env.expect.that_target(target).failures().contains_predicate(
+        matching.str_matches("attribute srcs: '*/gen' does not produce any cc_library srcs files"),
+    )
+
+def test_accept_mixed_generated_files(name, **kwargs):
+    util.helper_target(
+        rule = native.genrule,
+        name = name + "/gen",
+        outs = [
+            name + "/bad.oops",
+            name + "/good.cc",
+        ],
+        cmd = "touch $(OUTS)",
+    )
+
+    util.helper_target(
+        rule = cc_library,
+        name = name + "/foo",
+        srcs = [name + "/gen"],
+    )
+
+    cc_analysis_test(
+        name = name,
+        impl = test_accept_mixed_generated_files_impl,
+        target = name + "/foo",
+        **kwargs
+    )
+
+def test_accept_mixed_generated_files_impl(env, target):
+    env.expect.that_target(target).action_named("CppCompile").inputs().contains(
+        "{package}/{test_name}/good.cc",
+    )
+    env.expect.that_target(target).action_named("CppCompile").inputs().not_contains(
+        "{package}/{test_name}/bad.oops",
+    )
+
+def cc_bad_dependencies_tests(name):
+    test_suite(
+        name = name,
+        tests = [
+            test_reject_unknown_source_file,
+            test_reject_bad_generated_file,
+            test_accept_mixed_generated_files,
+        ],
+    )