aboutsummaryrefslogtreecommitdiff
path: root/kotlin/common/testing/testing_rules.bzl
diff options
context:
space:
mode:
Diffstat (limited to 'kotlin/common/testing/testing_rules.bzl')
-rw-r--r--kotlin/common/testing/testing_rules.bzl143
1 files changed, 143 insertions, 0 deletions
diff --git a/kotlin/common/testing/testing_rules.bzl b/kotlin/common/testing/testing_rules.bzl
new file mode 100644
index 0000000..35359f7
--- /dev/null
+++ b/kotlin/common/testing/testing_rules.bzl
@@ -0,0 +1,143 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""kt_testing_rules"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load(":analysis.bzl", "kt_analysis")
+
+visibility(RULES_KOTLIN)
+
+# Mark targets that's aren't expected to build, but are needed for analysis test assertions.
+_ONLY_FOR_ANALYSIS_TAGS = ["manual", "nobuilder", "notap"]
+
+def _wrap_for_analysis(inner_rule):
+ """Wrap an existing rule to make it easier to use in analysis tests.
+
+ Args:
+ inner_rule: [rule|macro]
+
+ Returns:
+ [macro] Calls inner_rule with appropate tags, returning the target name
+ """
+
+ def wrapper(name, tags = [], **kwargs):
+ inner_rule(
+ name = name,
+ tags = tags + _ONLY_FOR_ANALYSIS_TAGS,
+ **kwargs
+ )
+ return name
+
+ return wrapper
+
+_assert_failure_test = analysistest.make(
+ impl = lambda ctx: _assert_failure_test_impl(ctx),
+ expect_failure = True,
+ attrs = dict(
+ msg_contains = attr.string(mandatory = True),
+ ),
+)
+
+def _assert_failure_test_impl(ctx):
+ kt_analysis.check_endswith_test(ctx)
+
+ env = analysistest.begin(ctx)
+ asserts.expect_failure(env, ctx.attr.msg_contains)
+ return analysistest.end(env)
+
+_coverage_instrumentation_test = analysistest.make(
+ impl = lambda ctx: _coverage_instrumentation_test_impl(ctx),
+ attrs = dict(
+ expected_instrumented_file_names = attr.string_list(),
+ ),
+ config_settings = {
+ "//command_line_option:collect_code_coverage": "1",
+ "//command_line_option:instrument_test_targets": "1",
+ "//command_line_option:instrumentation_filter": "+",
+ },
+)
+
+def _coverage_instrumentation_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ target_under_test = analysistest.target_under_test(env)
+ instrumented_files_info = target_under_test[InstrumentedFilesInfo]
+ instrumented_files = instrumented_files_info.instrumented_files.to_list()
+ asserts.equals(
+ env,
+ ctx.attr.expected_instrumented_file_names,
+ [file.basename for file in instrumented_files],
+ )
+ return analysistest.end(env)
+
+def _create_file(name, content = ""):
+ """Declare a generated file with optional content.
+
+ Args:
+ name: [string] The relative file path
+ content: [string]
+
+ Returns:
+ [File] The label of the file
+ """
+
+ if content.startswith("\n"):
+ content = content[1:-1]
+
+ native.genrule(
+ name = "gen_" + name,
+ outs = [name],
+ cmd = """
+cat > $@ <<EOF
+%s
+EOF
+""" % content,
+ )
+
+ return name
+
+_create_dir = rule(
+ implementation = lambda ctx: _create_dir_impl(ctx),
+ attrs = dict(
+ subdir = attr.string(),
+ srcs = attr.label_list(allow_files = True),
+ ),
+)
+
+def _create_dir_impl(ctx):
+ dir = ctx.actions.declare_directory(ctx.attr.name)
+
+ command = "mkdir -p {0} " + ("&& cp {1} {0}" if ctx.files.srcs else "# {1}")
+ ctx.actions.run_shell(
+ command = command.format(
+ dir.path + "/" + ctx.attr.subdir,
+ " ".join([s.path for s in ctx.files.srcs]),
+ ),
+ inputs = ctx.files.srcs,
+ outputs = [dir],
+ )
+
+ return [DefaultInfo(files = depset([dir]))]
+
+kt_testing_rules = struct(
+ # go/keep-sorted start
+ ONLY_FOR_ANALYSIS_TAGS = _ONLY_FOR_ANALYSIS_TAGS,
+ assert_failure_test = _assert_failure_test,
+ coverage_instrumentation_test = _coverage_instrumentation_test,
+ create_dir = _wrap_for_analysis(_create_dir),
+ create_file = _create_file,
+ wrap_for_analysis = _wrap_for_analysis,
+ # go/keep-sorted end
+)