| """Bazel-only tests for C++ modules.""" | |
| load("@bazel_features//:features.bzl", "bazel_features") | |
| 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:action_names.bzl", "ACTION_NAMES") | |
| load("//cc:cc_binary.bzl", "cc_binary") | |
| load("//cc:cc_library.bzl", "cc_library") | |
| load("//cc:cc_test.bzl", "cc_test") | |
| load("//tests/cc/testutil:cc_analysis_test.bzl", "cc_analysis_test") | |
| def _setup_with_features_target(name, rule_fn, suffix): | |
| util.empty_file(name + "/foo.cppm") | |
| util.helper_target( | |
| rule_fn, | |
| name = name + suffix, | |
| module_interfaces = [name + "/foo.cppm"], | |
| ) | |
| def _test_cpp_modules_cc_library_configuration_with_features(name, **kwargs): | |
| _setup_with_features_target(name, cc_library, "_lib") | |
| cc_analysis_test( | |
| name = name, | |
| target = name + "_lib", | |
| impl = _test_cpp_modules_with_features_impl, | |
| test_features = ["cpp_modules"], | |
| with_action_configs = [ | |
| ACTION_NAMES.cpp_module_deps_scanning, | |
| ACTION_NAMES.cpp20_module_compile, | |
| ], | |
| config_settings = { | |
| "//command_line_option:experimental_cpp_modules": True, | |
| }, | |
| **kwargs | |
| ) | |
| def _test_cpp_modules_cc_binary_configuration_with_features(name, **kwargs): | |
| _setup_with_features_target(name, cc_binary, "_bin") | |
| cc_analysis_test( | |
| name = name, | |
| target = name + "_bin", | |
| impl = _test_cpp_modules_with_features_impl, | |
| test_features = ["cpp_modules"], | |
| with_action_configs = [ | |
| ACTION_NAMES.cpp_module_deps_scanning, | |
| ACTION_NAMES.cpp20_module_compile, | |
| ], | |
| config_settings = { | |
| "//command_line_option:experimental_cpp_modules": True, | |
| }, | |
| **kwargs | |
| ) | |
| def _test_cpp_modules_cc_test_configuration_with_features(name, **kwargs): | |
| _setup_with_features_target(name, cc_test, "_test") | |
| cc_analysis_test( | |
| name = name, | |
| target = name + "_test", | |
| impl = _test_cpp_modules_with_features_impl, | |
| test_features = ["cpp_modules"], | |
| with_action_configs = [ | |
| ACTION_NAMES.cpp_module_deps_scanning, | |
| ACTION_NAMES.cpp20_module_compile, | |
| ], | |
| config_settings = { | |
| "//command_line_option:experimental_cpp_modules": True, | |
| }, | |
| **kwargs | |
| ) | |
| def _test_cpp_modules_with_features_impl(env, target): | |
| env.expect.that_target(target).action_named("CppDepsScanning") | |
| env.expect.that_target(target).action_named("CppCompile") | |
| env.expect.that_target(target).action_named("CppAggregateDdi") | |
| env.expect.that_target(target).action_named("CppGenModmap") | |
| def _setup_duplicated_interfaces_target(name, rule_fn, suffix): | |
| util.empty_file(name + "/a.cppm") | |
| util.helper_target( | |
| native.filegroup, | |
| name = name + "_a1", | |
| srcs = [name + "/a.cppm"], | |
| ) | |
| util.helper_target( | |
| native.filegroup, | |
| name = name + "_a2", | |
| srcs = [name + "/a.cppm"], | |
| ) | |
| util.helper_target( | |
| rule_fn, | |
| name = name + suffix, | |
| module_interfaces = [ | |
| name + "_a1", | |
| name + "_a2", | |
| ], | |
| ) | |
| def _test_same_module_interfaces_file_in_cc_library_twice(name, **kwargs): | |
| _setup_duplicated_interfaces_target(name, cc_library, "_lib") | |
| cc_analysis_test( | |
| name = name, | |
| target = name + "_lib", | |
| impl = _test_same_module_interfaces_twice_impl, | |
| expect_failure = True, | |
| test_features = ["cpp_modules"], | |
| with_action_configs = [ | |
| ACTION_NAMES.cpp_module_deps_scanning, | |
| ACTION_NAMES.cpp20_module_compile, | |
| ], | |
| config_settings = { | |
| "//command_line_option:experimental_cpp_modules": True, | |
| }, | |
| **kwargs | |
| ) | |
| def _test_same_module_interfaces_file_in_cc_binary_twice(name, **kwargs): | |
| _setup_duplicated_interfaces_target(name, cc_binary, "_bin") | |
| cc_analysis_test( | |
| name = name, | |
| target = name + "_bin", | |
| impl = _test_same_module_interfaces_twice_impl, | |
| expect_failure = True, | |
| test_features = ["cpp_modules"], | |
| with_action_configs = [ | |
| ACTION_NAMES.cpp_module_deps_scanning, | |
| ACTION_NAMES.cpp20_module_compile, | |
| ], | |
| config_settings = { | |
| "//command_line_option:experimental_cpp_modules": True, | |
| }, | |
| **kwargs | |
| ) | |
| def _test_same_module_interfaces_file_in_cc_test_twice(name, **kwargs): | |
| _setup_duplicated_interfaces_target(name, cc_test, "_test") | |
| cc_analysis_test( | |
| name = name, | |
| target = name + "_test", | |
| impl = _test_same_module_interfaces_twice_impl, | |
| expect_failure = True, | |
| test_features = ["cpp_modules"], | |
| with_action_configs = [ | |
| ACTION_NAMES.cpp_module_deps_scanning, | |
| ACTION_NAMES.cpp20_module_compile, | |
| ], | |
| config_settings = { | |
| "//command_line_option:experimental_cpp_modules": True, | |
| }, | |
| **kwargs | |
| ) | |
| def _test_same_module_interfaces_twice_impl(env, target): | |
| package = target.label.package | |
| name = env.ctx.label.name | |
| expected_path = "%s/%s/a.cppm" % (package, name) | |
| expected_error = "file %s>' is duplicated" % expected_path | |
| env.expect.that_target(target).failures().contains_predicate( | |
| matching.contains(expected_error), | |
| ) | |
| def cpp_modules_tests(name, **kwargs): | |
| tests = [] | |
| if bazel_features.cc.cc_common_is_in_rules_cc: | |
| tests.extend([ | |
| _test_cpp_modules_cc_library_configuration_with_features, | |
| _test_cpp_modules_cc_binary_configuration_with_features, | |
| _test_cpp_modules_cc_test_configuration_with_features, | |
| _test_same_module_interfaces_file_in_cc_library_twice, | |
| _test_same_module_interfaces_file_in_cc_binary_twice, | |
| _test_same_module_interfaces_file_in_cc_test_twice, | |
| ]) | |
| test_suite( | |
| name = name, | |
| tests = tests, | |
| **kwargs | |
| ) |