aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornickreid <nickreid@google.com>2023-10-09 12:09:21 -0700
committerCopybara-Service <copybara-worker@google.com>2023-10-09 12:10:03 -0700
commitb3b689f3fb5d2428a37574e3e8f34398765b02a6 (patch)
tree167bb24fd900166214f75583107e9c3081bd813b
parent53879a257620503971d5474b61581aa8749fd9c3 (diff)
downloadbazelbuild-kotlin-rules-b3b689f3fb5d2428a37574e3e8f34398765b02a6.tar.gz
Add kt_asserts for common testing assertions.
PiperOrigin-RevId: 572005221
-rw-r--r--kotlin/common/testing/BUILD35
-rw-r--r--kotlin/common/testing/asserts.bzl114
-rw-r--r--tests/analysis/jvm_library_test.bzl29
3 files changed, 160 insertions, 18 deletions
diff --git a/kotlin/common/testing/BUILD b/kotlin/common/testing/BUILD
new file mode 100644
index 0000000..b7755de
--- /dev/null
+++ b/kotlin/common/testing/BUILD
@@ -0,0 +1,35 @@
+# 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.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+package(
+ default_applicable_licenses = ["//:license"],
+ default_testonly = True,
+ default_visibility = ["//:internal"],
+)
+
+licenses(["notice"])
+
+bzl_library(
+ name = "testing_bzl",
+ srcs = glob(["*.bzl"]),
+ visibility = [
+ "//:internal",
+ ],
+ deps = [
+ "//:visibility_bzl",
+ "@bazel_skylib//lib:unittest",
+ ],
+)
diff --git a/kotlin/common/testing/asserts.bzl b/kotlin/common/testing/asserts.bzl
new file mode 100644
index 0000000..b064eb7
--- /dev/null
+++ b/kotlin/common/testing/asserts.bzl
@@ -0,0 +1,114 @@
+# 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_asserts"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("@bazel_skylib//lib:unittest.bzl", "asserts")
+
+def _equals(a, b):
+ return a == b
+
+def _list_matching(left, right, matcher = None):
+ """Find the overlap between two lists.
+
+ Args:
+ left: [list[A]]
+ right: [list[B]]
+ matcher: [function(A,B):bool] A matcher on the two list types
+
+ Returns:
+ [(list[A], list[(A, B)], list[B])] The left-only, matching-pair, and right-only lists
+ """
+
+ matcher = matcher or _equals
+
+ left_only = []
+ matches = []
+ right_only = list(right)
+
+ def _process_left_ele(left_ele):
+ for index, right_ele in enumerate(right_only):
+ if matcher(left_ele, right_ele):
+ right_only.pop(index)
+ matches.append((left_ele, right_ele))
+ return
+
+ left_only.append(left_ele)
+
+ for left_ele in left:
+ _process_left_ele(left_ele)
+
+ return (left_only, matches, right_only)
+
+def _assert_list_matches(env, expected, actual, matcher = None, items_name = "items"):
+ """Assert two lists have an exact matching.
+
+ Args:
+ env: [unittest.env]
+ expected: [list[A]]
+ actual: [list[B]]
+ matcher: [function(A,B):bool]
+ items_name: [string] The plural noun describing the list items in an error message
+
+ Returns:
+ [None] Fails if assertion violated
+ """
+
+ extra_expected, _, extra_actual = _list_matching(expected, actual, matcher = matcher)
+ asserts.true(
+ env,
+ len(extra_actual) == 0 and len(extra_expected) == 0,
+ "Unmatched expected {name} {expected}\nUnmatched actual {name} {actual}".format(
+ name = items_name,
+ expected = extra_expected,
+ actual = extra_actual,
+ ),
+ )
+
+def _assert_required_mnemonic_counts(env, required_mnemonic_counts, actual_actions):
+ """Assert that some set of menemonics is present/absent within a set of Actions.
+
+ Args:
+ env: [unittest.env]
+ required_mnemonic_counts: [dict[string,string]] The menemonics to check -> expected count
+ actual_actions: [list[Action]]
+
+ Returns:
+ [None] Fails if assertion violated
+ """
+
+ considered_actual_mnemonics = [
+ x.mnemonic
+ for x in actual_actions
+ # Ignore any mnemonics not mentioned by the user
+ if (x.mnemonic in required_mnemonic_counts)
+ ]
+
+ required_mnemonics = []
+ for m, c in required_mnemonic_counts.items():
+ for _ in range(0, int(c)):
+ required_mnemonics.append(m)
+
+ _assert_list_matches(
+ env,
+ required_mnemonics,
+ considered_actual_mnemonics,
+ items_name = "mnemonics",
+ )
+
+kt_asserts = struct(
+ list_matches = _assert_list_matches,
+ required_mnemonic_counts = _assert_required_mnemonic_counts,
+)
diff --git a/tests/analysis/jvm_library_test.bzl b/tests/analysis/jvm_library_test.bzl
index c72aff0..e9d9330 100644
--- a/tests/analysis/jvm_library_test.bzl
+++ b/tests/analysis/jvm_library_test.bzl
@@ -16,6 +16,7 @@
load("//:visibility.bzl", "RULES_KOTLIN")
load("//kotlin:jvm_library.bzl", "kt_jvm_library")
+load("//kotlin/common/testing:asserts.bzl", "kt_asserts")
load("//tests/analysis:util.bzl", "ONLY_FOR_ANALYSIS_TEST_TAGS", "create_file", "get_action", "get_arg")
load("@bazel_skylib//lib:sets.bzl", "sets")
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
@@ -83,8 +84,13 @@ def _test_impl(ctx):
if ctx.attr.expected_friend_jar_names != _DEFAULT_LIST:
friend_paths_arg = get_arg(kt_2_java_compile, "-Xfriend-paths=")
- friend_jar_names = [p.rsplit("/", 1)[1] for p in friend_paths_arg.split(",")] if friend_paths_arg else []
- asserts.set_equals(env, sets.make(ctx.attr.expected_friend_jar_names), sets.make(friend_jar_names))
+ kt_asserts.list_matches(
+ env,
+ expected = ctx.attr.expected_friend_jar_names,
+ actual = ["/" + x for x in (friend_paths_arg.split(",") if friend_paths_arg else [])],
+ matcher = lambda expected, actual: actual.endswith(expected),
+ items_name = "friend JARs",
+ )
asserts.equals(
env,
@@ -93,20 +99,7 @@ def _test_impl(ctx):
"Mismatch: Expected transitive_runtime_jars iff (neverlink == False)",
)
- for mnemonic in ctx.attr.required_mnemonics:
- if mnemonic.startswith("-"):
- mnemonic = mnemonic.removeprefix("-")
- asserts.false(
- env,
- mnemonic in [a.mnemonic for a in actions],
- "Found action with forbidden mnemonic " + mnemonic,
- )
- else:
- asserts.true(
- env,
- mnemonic in [a.mnemonic for a in actions],
- "Missing action with required mnemonic " + mnemonic,
- )
+ kt_asserts.required_mnemonic_counts(env, ctx.attr.required_mnemonic_counts, actions)
return analysistest.end(env)
@@ -142,7 +135,7 @@ _test = analysistest.make(
expect_jdeps = attr.bool(default = True),
expect_processor_classpath = attr.bool(),
expect_neverlink = attr.bool(),
- required_mnemonics = attr.string_list(
+ required_mnemonic_counts = attr.string_dict(
doc = """
Mnemonics that must be registered (or must not be, if starting with '-').
@@ -628,7 +621,7 @@ def _test_kt_jvm_library_with_no_sources_with_exports():
name = test_name,
target_under_test = test_name + "_tut",
expect_jdeps = False,
- required_mnemonics = ["-KtAndroidLint"],
+ required_mnemonic_counts = {"KtAndroidLint": "0"},
)
return test_name