Implement the easy java_test unit tests in Starlark.

PiperOrigin-RevId: 881395705
Change-Id: I63ec4d6489a15fd854b75176a3a216e715bded6a
diff --git a/test/java/bazel/rules/BUILD.bazel b/test/java/bazel/rules/BUILD.bazel
index 01655c2..6f97d15 100644
--- a/test/java/bazel/rules/BUILD.bazel
+++ b/test/java/bazel/rules/BUILD.bazel
@@ -1,9 +1,12 @@
 load(":java_binary_tests.bzl", "java_binary_tests")
 load(":java_library_tests.bzl", "java_library_tests")
 load(":java_plugin_tests.bzl", "java_plugin_tests")
+load(":java_test_tests.bzl", "java_test_tests")
 
 java_binary_tests(name = "java_binary_tests")
 
 java_library_tests(name = "java_library_tests")
 
 java_plugin_tests(name = "java_plugin_tests")
+
+java_test_tests(name = "java_test_tests")
diff --git a/test/java/bazel/rules/java_test_tests.bzl b/test/java/bazel/rules/java_test_tests.bzl
new file mode 100644
index 0000000..9ee618d
--- /dev/null
+++ b/test/java/bazel/rules/java_test_tests.bzl
@@ -0,0 +1,44 @@
+"""Tests for the Bazel java_test rule"""
+
+load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
+load("@rules_testing//lib:truth.bzl", "matching", "subjects")
+load("@rules_testing//lib:util.bzl", "util")
+load("//java:java_test.bzl", "java_test")
+
+def _test_deduced_test_class(name):
+    util.helper_target(
+        java_test,
+        name = name + "/foo",
+        srcs = [name + "/Foo.java"],
+    )
+
+    analysis_test(
+        name = name,
+        impl = _test_deduced_test_class_impl,
+        target = name + "/foo",
+    )
+
+def _test_deduced_test_class_impl(env, target):
+    executable = target[DefaultInfo].files_to_run.executable.short_path
+    assert_action = env.expect.that_target(target).action_generating(executable)
+
+    if assert_action.actual.substitutions:
+        # TemplateExpansion action on linux/mac
+        assert_jvm_flags = assert_action.substitutions().get(
+            "%jvm_flags%",
+            factory = lambda v, meta: subjects.collection([v], meta),
+        )
+    else:
+        # Windows
+        assert_jvm_flags = assert_action.argv()
+    assert_jvm_flags.contains_predicate(
+        matching.str_matches("-Dbazel.test_suite=bazel.rules.test_deduced_test_class.foo"),
+    )
+
+def java_test_tests(name):
+    test_suite(
+        name = name,
+        tests = [
+            _test_deduced_test_class,
+        ],
+    )
diff --git a/test/java/common/rules/java_test_tests.bzl b/test/java/common/rules/java_test_tests.bzl
index f4db104..13362dc 100644
--- a/test/java/common/rules/java_test_tests.bzl
+++ b/test/java/common/rules/java_test_tests.bzl
@@ -1,5 +1,6 @@
 """Tests for the java_test rule"""
 
+load("@bazel_features//:features.bzl", "bazel_features")
 load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
 load("@rules_cc//cc:cc_library.bzl", "cc_library")
 load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
@@ -7,8 +8,86 @@
 load("@rules_testing//lib:util.bzl", "util")
 load("//java:java_library.bzl", "java_library")
 load("//java:java_test.bzl", "java_test")
+load("//test/java/testutil:helper.bzl", "always_passes")
 load("//test/java/testutil:rules/custom_java_info_rule.bzl", "custom_java_info_rule")
 
+def _test_java_test_is_test_only(name):
+    util.helper_target(
+        java_test,
+        name = name + "/test",
+        srcs = [name + "/Test.java"],
+    )
+
+    util.helper_target(
+        java_library,
+        name = name + "/lib",
+        srcs = [name + "/Lib.java"],
+        deps = [name + "/test"],
+    )
+
+    analysis_test(
+        name = name,
+        impl = _test_java_test_is_test_only_impl,
+        target = name + "/lib",
+        expect_failure = True,
+    )
+
+def _test_java_test_is_test_only_impl(env, target):
+    env.expect.that_target(target).failures().contains_predicate(
+        matching.str_matches("non-test target '*/lib' depends on testonly target '*/test'"),
+    )
+
+def _test_deps_without_srcs_fails(name):
+    util.helper_target(
+        rule = java_library,
+        name = name + "/lib",
+        srcs = [name + "/Lib.java"],
+    )
+
+    util.helper_target(
+        rule = java_test,
+        name = name + "/test",
+        deps = [name + "/lib"],
+    )
+
+    analysis_test(
+        name = name,
+        target = name + "/test",
+        impl = _test_deps_without_srcs_fails_impl,
+        expect_failure = True,
+    )
+
+def _test_deps_without_srcs_fails_impl(env, target):
+    env.expect.that_target(target).failures().contains_predicate(
+        matching.contains("deps not allowed without srcs"),
+    )
+
+def _test_fix_deps_tool(name):
+    if not bazel_features.rules.analysis_tests_can_transition_on_experimental_incompatible_flags:
+        always_passes(name)
+        return
+    util.helper_target(
+        rule = java_test,
+        name = name + "/test",
+        srcs = [name + "/Test.java"],
+    )
+
+    analysis_test(
+        name = name,
+        target = name + "/test",
+        impl = _test_fix_deps_tool_impl,
+        config_settings = {
+            "//command_line_option:experimental_fix_deps_tool": "customfixer",
+        },
+    )
+
+def _test_fix_deps_tool_impl(env, target):
+    assert_compile_action = env.expect.that_target(target).action_named("Javac")
+    assert_compile_action.argv().contains_at_least([
+        "--experimental_fix_deps_tool",
+        "customfixer",
+    ]).in_order()
+
 def _test_java_test_propagates_direct_native_libraries(name):
     util.helper_target(
         cc_library,
@@ -74,10 +153,90 @@
         matching.str_matches("-Djava.library.path=${JAVA_RUNFILES}/*/test_java_test_propagates_direct_native_libraries"),
     )
 
+def _test_coverage_uses_coverage_runner_for_main(name):
+    util.helper_target(
+        rule = java_test,
+        name = name + "/test",
+        srcs = [name + "/Test.java"],
+    )
+
+    analysis_test(
+        name = name,
+        impl = _test_coverage_uses_coverage_runner_for_main_impl,
+        target = name + "/test",
+        config_settings = {
+            "//command_line_option:collect_code_coverage": True,
+        },
+    )
+
+def _test_coverage_uses_coverage_runner_for_main_impl(env, target):
+    executable = target[DefaultInfo].files_to_run.executable.short_path
+    assert_action = env.expect.that_target(target).action_generating(executable)
+    if assert_action.actual.substitutions:
+        assert_java_start_class = assert_action.substitutions().get(
+            "%java_start_class%",
+            factory = lambda v, meta: subjects.str(v, meta.derive("java_start_class")),
+        )
+        assert_java_start_class.contains("com.google.testing.coverage.JacocoCoverageRunner")
+    else:
+        # Windows
+        assert_java_start_class = assert_action.argv()
+        assert_java_start_class.contains("java_start_class=com.google.testing.coverage.JacocoCoverageRunner")
+
+def _test_stamp_values(name):
+    util.helper_target(
+        rule = java_test,
+        name = name + "/stamp_true",
+        srcs = [name + "/Test.java"],
+        stamp = True,
+    )
+
+    util.helper_target(
+        rule = java_test,
+        name = name + "/stamp_false",
+        srcs = [name + "/Test.java"],
+        stamp = False,
+    )
+
+    util.helper_target(
+        rule = java_test,
+        name = name + "/stamp_auto",
+        srcs = [name + "/Test.java"],
+        stamp = -1,
+    )
+
+    util.helper_target(
+        rule = java_test,
+        name = name + "/stamp_default",
+        srcs = [name + "/Test.java"],
+    )
+
+    analysis_test(
+        name = name,
+        targets = {
+            "stamp": name + "/stamp_true",
+            "nostamp": name + "/stamp_false",
+            "autostamp": name + "/stamp_auto",
+            "defaultstamp": name + "/stamp_default",
+        },
+        impl = _test_stamp_values_impl,
+    )
+
+def _test_stamp_values_impl(env, targets):
+    env.expect.that_target(targets.stamp).attr("stamp", factory = subjects.int).equals(1)
+    env.expect.that_target(targets.nostamp).attr("stamp", factory = subjects.int).equals(0)
+    env.expect.that_target(targets.defaultstamp).attr("stamp", factory = subjects.int).equals(0)
+    env.expect.that_target(targets.autostamp).attr("stamp", factory = subjects.int).equals(-1)
+
 def java_test_tests(name):
     test_suite(
         name = name,
         tests = [
+            _test_java_test_is_test_only,
+            _test_deps_without_srcs_fails,
+            _test_fix_deps_tool,
             _test_java_test_propagates_direct_native_libraries,
+            _test_coverage_uses_coverage_runner_for_main,
+            _test_stamp_values,
         ],
     )