blob: 8962b2a60d4c5731ee73f32816ec175421d26d10 [file]
#!/usr/bin/env fuchsia-vendored-python
# Copyright 2026 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tests for trim_visibility.py.
To run:
$ fx test //build/bazel/scripts:trim_visibility_test
"""
import textwrap
import unittest
from typing import Sequence
from trim_visibility import (
PRIVATE,
PUBLIC,
Entry,
Kind,
Label,
PackageGroup,
Status,
analyze_list,
build_file_package,
covers,
entry_covers_path,
entry_to_bazel,
entry_to_gn,
expected_gn_entries,
format_bazel2gn_overwrite,
format_bazel_list,
gn_list_to_bazel,
gn_target_is_generated_by_bazel2gn,
label_reference_regex,
package_group_contains,
parse_bazel_build_output,
parse_bazel_entry,
parse_gn_entry,
parse_gn_instances,
parse_label,
parse_labels,
parse_macro_locations,
parse_ninja_depfile_inputs,
parse_package_group_build_output,
parse_source_visibility,
sorted_labels,
subsumes,
)
OWN = "foo/lib"
def pkg(package: str) -> Entry:
return Entry(Kind.PACKAGE, package)
def subpkgs(package: str) -> Entry:
return Entry(Kind.SUBPACKAGES, package)
def target(label: str) -> Entry:
parsed = parse_label(label)
return Entry(Kind.TARGET, parsed.package, parsed.name)
class LabelTest(unittest.TestCase):
def test_parse_label(self) -> None:
self.assertEqual(parse_label("//a/b:c"), Label("a/b", "c"))
self.assertEqual(parse_label("//a/b"), Label("a/b", "b"))
self.assertEqual(parse_label("@//a/b:c"), Label("a/b", "c"))
self.assertEqual(parse_label("@@//a/b:c"), Label("a/b", "c"))
self.assertEqual(
parse_label("//a/b:c(//build/toolchain:host_x64)"),
Label("a/b", "c"),
)
self.assertEqual(parse_label(":c", "a/b"), Label("a/b", "c"))
self.assertEqual(parse_label("//:c"), Label("", "c"))
self.assertEqual(parse_label("//.:c"), Label("", "c"))
self.assertEqual(str(Label("a/b", "c")), "//a/b:c")
def test_parse_label_errors(self) -> None:
for text in ("@rules_cc//cc:defs", "a/b:c", "//a/b:", ":c"):
with self.assertRaises(ValueError, msg=text):
parse_label(text)
def test_parse_labels(self) -> None:
self.assertEqual(
parse_labels(
[
"//a:b",
"//a:b(//build/toolchain:host_x64)",
"@@rules_cc+//cc:foo",
"INFO: something",
" //c/d:e ",
]
),
{Label("a", "b"), Label("c/d", "e")},
)
class EntryTest(unittest.TestCase):
def test_parse_bazel_entry(self) -> None:
self.assertEqual(parse_bazel_entry("//visibility:public", OWN), PUBLIC)
self.assertEqual(
parse_bazel_entry("//visibility:private", OWN), PRIVATE
)
self.assertEqual(parse_bazel_entry("//a/b:__pkg__", OWN), pkg("a/b"))
self.assertEqual(
parse_bazel_entry("//a/b:__subpackages__", OWN), subpkgs("a/b")
)
self.assertEqual(parse_bazel_entry(":__pkg__", OWN), pkg(OWN))
self.assertEqual(
parse_bazel_entry("//:__subpackages__", OWN), subpkgs("")
)
self.assertEqual(
parse_bazel_entry("//a/b:group", OWN),
Entry(Kind.PACKAGE_GROUP, "a/b", "group"),
)
def test_parse_gn_entry(self) -> None:
self.assertEqual(parse_gn_entry("*", OWN), PUBLIC)
self.assertEqual(parse_gn_entry("//*", OWN), subpkgs(""))
self.assertEqual(parse_gn_entry("//a/b/*", OWN), subpkgs("a/b"))
self.assertEqual(parse_gn_entry("//a/b:*", OWN), pkg("a/b"))
self.assertEqual(parse_gn_entry("//:*", OWN), pkg(""))
self.assertEqual(parse_gn_entry("//.:*", OWN), pkg(""))
self.assertEqual(parse_gn_entry(":*", OWN), pkg(OWN))
self.assertEqual(parse_gn_entry("./*", OWN), subpkgs(OWN))
self.assertEqual(parse_gn_entry("//a/b:c", OWN), target("//a/b:c"))
self.assertEqual(parse_gn_entry("//a/b", OWN), target("//a/b:b"))
self.assertEqual(
parse_gn_entry("//a/b:*(//build/toolchain:host_x64)", OWN),
pkg("a/b"),
)
def test_bazel_round_trip(self) -> None:
for text in (
"//visibility:public",
"//visibility:private",
"//a/b:__pkg__",
"//a/b:__subpackages__",
"//:__subpackages__",
"//a/b:group",
):
self.assertEqual(
entry_to_bazel(parse_bazel_entry(text, OWN), OWN), text
)
def test_gn_round_trip(self) -> None:
for text in ("*", "//*", "//a/b/*", "//a/b:*", "//a/b:c", ":*", "./*"):
self.assertEqual(entry_to_gn(parse_gn_entry(text, OWN), OWN), text)
def test_bazel_to_gn_matches_bazel2gn(self) -> None:
# See bazelVisibilityToGN in //build/tools/bazel2gn/transformers.go.
cases = {
"//visibility:public": "*",
"//visibility:private": ":*",
":__subpackages__": "./*",
"//:__subpackages__": "//*",
"//a/b:__pkg__": "//a/b:*",
"//a/b:__subpackages__": "//a/b/*",
"//a/b:group": "//a/b:group",
}
for bazel, gn in cases.items():
self.assertEqual(
entry_to_gn(parse_bazel_entry(bazel, OWN), OWN), gn, bazel
)
def test_gn_to_bazel(self) -> None:
self.assertIsNone(entry_to_bazel(pkg(OWN), OWN))
self.assertIsNone(entry_to_bazel(target(f"//{OWN}:x"), OWN))
self.assertEqual(
entry_to_bazel(target("//a/b:c"), OWN), "//a/b:__pkg__"
)
self.assertEqual(
gn_list_to_bazel(
[
subpkgs("a"),
pkg("a/b"),
target("//c:d"),
target("//c:e"),
pkg(OWN),
],
OWN,
),
["//a:__subpackages__", "//c:__pkg__"],
)
def test_covers(self) -> None:
consumer = Label("a/b", "c")
self.assertTrue(covers(PUBLIC, consumer, {}))
self.assertFalse(covers(PRIVATE, consumer, {}))
self.assertTrue(covers(pkg("a/b"), consumer, {}))
self.assertFalse(covers(pkg("a"), consumer, {}))
self.assertFalse(covers(pkg("a/b/c"), consumer, {}))
self.assertTrue(covers(subpkgs("a"), consumer, {}))
self.assertTrue(covers(subpkgs("a/b"), consumer, {}))
self.assertTrue(covers(subpkgs(""), consumer, {}))
self.assertFalse(covers(subpkgs("a/bc"), Label("a/b", "c"), {}))
self.assertFalse(covers(subpkgs("a/b"), Label("a/bc", "c"), {}))
self.assertTrue(covers(target("//a/b:c"), consumer, {}))
self.assertFalse(covers(target("//a/b:d"), consumer, {}))
group = Entry(Kind.PACKAGE_GROUP, "g", "group")
self.assertIsNone(covers(group, consumer, {}))
def test_subsumes(self) -> None:
self.assertTrue(subsumes(PUBLIC, pkg("a")))
self.assertTrue(subsumes(subpkgs("a"), pkg("a/b")))
self.assertTrue(subsumes(subpkgs("a"), subpkgs("a/b")))
self.assertTrue(subsumes(subpkgs("a"), pkg("a")))
self.assertTrue(subsumes(pkg("a"), target("//a:b")))
self.assertTrue(subsumes(pkg("a"), pkg("a")))
self.assertFalse(subsumes(pkg("a"), pkg("a/b")))
self.assertFalse(subsumes(subpkgs("a/b"), subpkgs("a")))
self.assertFalse(subsumes(subpkgs("a"), pkg("ab")))
self.assertFalse(subsumes(pkg("a"), PRIVATE))
self.assertFalse(
subsumes(subpkgs(""), Entry(Kind.PACKAGE_GROUP, "a", "g"))
)
class PackageGroupTest(unittest.TestCase):
def test_contains(self) -> None:
groups = {
Label("g", "a"): PackageGroup(
packages=["//foo/...", "-//foo/private", "//bar"],
includes=[Label("g", "b")],
),
Label("g", "b"): PackageGroup(packages=["//baz"], includes=[]),
Label("g", "c"): PackageGroup(
packages=[], includes=[Label("g", "missing")]
),
}
a = Label("g", "a")
self.assertTrue(package_group_contains(a, "foo", groups))
self.assertTrue(package_group_contains(a, "foo/x", groups))
self.assertFalse(package_group_contains(a, "foo/private", groups))
self.assertTrue(package_group_contains(a, "bar", groups))
self.assertFalse(package_group_contains(a, "bar/x", groups))
self.assertTrue(package_group_contains(a, "baz", groups))
self.assertFalse(package_group_contains(a, "qux", groups))
self.assertIsNone(package_group_contains(Label("g", "c"), "x", groups))
self.assertIsNone(package_group_contains(Label("g", "x"), "x", groups))
def test_public(self) -> None:
groups = {Label("g", "p"): PackageGroup(["public"], [])}
self.assertTrue(package_group_contains(Label("g", "p"), "x", groups))
class ParseOutputTest(unittest.TestCase):
def test_parse_bazel_build_output(self) -> None:
output = textwrap.dedent(
"""\
# /out/workspace/sdk/lib/vfs/cpp/BUILD.bazel:9:22
cc_library(
name = "cpp",
visibility = ["//sdk:__pkg__", "//sdk/lib/vfs/cpp:__pkg__"],
generator_name = "cpp",
generator_function = "idk_cc_source_library",
deps = ["//zircon/system/ulib/zx:zx"],
)
# Rule cpp instantiated at (most recent call last):
"""
)
info = parse_bazel_build_output(output)
assert info is not None
self.assertEqual(info.kind, "cc_library")
self.assertEqual(
info.visibility, ["//sdk:__pkg__", "//sdk/lib/vfs/cpp:__pkg__"]
)
self.assertEqual(info.generator_name, "cpp")
def test_parse_bazel_build_output_no_visibility(self) -> None:
info = parse_bazel_build_output('alias(\n name = "a",\n)\n')
assert info is not None
self.assertIsNone(info.visibility)
self.assertIsNone(info.generator_name)
def test_parse_package_group(self) -> None:
output = textwrap.dedent(
"""\
# /out/workspace/src/testing/fidl/BUILD.bazel:35:14
package_group(
name = "fidl_macro_visibility",
includes = ["//other:group"],
packages = ["//build/bazel/rules/fidl", "-//x/..."],
)
"""
)
group = parse_package_group_build_output(output)
assert group is not None
self.assertEqual(
group.packages, ["//build/bazel/rules/fidl", "-//x/..."]
)
self.assertEqual(group.includes, [Label("other", "group")])
self.assertIsNone(
parse_package_group_build_output('cc_library(\n name = "a",\n)\n')
)
def test_parse_macro_locations(self) -> None:
ws = "/out/gen/build/bazel/workspace"
output = textwrap.dedent(
f"""\
# {ws}/sdk/fidl/fuchsia.ui.views/BUILD.bazel:9:13
cc_library(
name = "fuchsia.ui.views_hlcpp",
visibility = ["//visibility:public"],
)
# Rule fuchsia.ui.views_hlcpp instantiated at (most recent call last):
# {ws}/sdk/fidl/fuchsia.ui.views/BUILD.bazel:9:13 in <toplevel>
# {ws}/build/bazel/rules/fidl/fidl_library.bzl:647:18 in fidl_library
# {ws}/build/bazel/rules/fidl/fidl_cc_library.bzl:399:19 in _fidl_cc_library
# /out/output_base/external/rules_cc+/cc/cc_library.bzl:19:16 in cc_library
# Rule cc_library defined at (most recent call last):
# /virtual_builtins_bzl/common/cc/cc_library.bzl:565:18 in <toplevel>
# {ws}/src/foo/BUILD.bazel:3:11
cc_binary(
name = "bin",
)
# Rule bin instantiated at (most recent call last):
# {ws}/src/foo/BUILD.bazel:3:11 in <toplevel>
# Rule cc_binary defined at (most recent call last):
# {ws}/build/bazel/rules/cc/defs.bzl:1:1 in <toplevel>
"""
)
views = Label("sdk/fidl/fuchsia.ui.views", "fuchsia.ui.views_hlcpp")
self.assertEqual(
parse_macro_locations(output, [views, Label("src/foo", "bin")]),
{views: ["build/bazel/rules/fidl"]},
)
def test_parse_macro_locations_suffix_packages(self) -> None:
ws = "/out/gen/build/bazel/workspace"
output = textwrap.dedent(
f"""\
# {ws}/sdk/lib/vfs/cpp/BUILD.bazel:9:13
cc_library(
name = "lib",
)
# Rule lib instantiated at (most recent call last):
# {ws}/sdk/lib/vfs/cpp/BUILD.bazel:9:13 in <toplevel>
# {ws}/build/bazel/rules/cc/macro.bzl:10:5 in my_macro
# Rule cc_library defined at (most recent call last):
"""
)
short = Label("cpp", "lib")
specific = Label("sdk/lib/vfs/cpp", "lib")
self.assertEqual(
parse_macro_locations(output, [short, specific]),
{specific: ["build/bazel/rules/cc"]},
)
def test_parse_gn_instances(self) -> None:
output = textwrap.dedent(
"""\
//foo/lib:lib
//foo/lib:lib_unittests
//foo/lib:lib(//build/toolchain:host_x64)
//foo/lib:other(//build/toolchain:host_x64)
"""
)
self.assertEqual(
parse_gn_instances(output, Label("foo/lib", "lib")),
["//foo/lib:lib", "//foo/lib:lib(//build/toolchain:host_x64)"],
)
def test_parse_ninja_depfile_inputs(self) -> None:
self.assertEqual(
parse_ninja_depfile_inputs(
"build.ninja.stamp: ../../BUILD.gn ../../a/BUILD.gn \\\n"
" ../../b/c.gni\n"
),
["../../BUILD.gn", "../../a/BUILD.gn", "../../b/c.gni"],
)
def test_gn_target_is_generated_by_bazel2gn(self) -> None:
build_gn = textwrap.dedent(
"""\
group("tests") {
}
## BAZEL2GN SENTINEL - DO NOT EDIT BELOW THIS LINE ##
if (is_fuchsia) {
sdk_source_set("cpp") {
}
}
"""
)
self.assertTrue(gn_target_is_generated_by_bazel2gn(build_gn, "cpp"))
self.assertFalse(gn_target_is_generated_by_bazel2gn(build_gn, "tests"))
self.assertFalse(
gn_target_is_generated_by_bazel2gn('group("cpp") {}', "cpp")
)
class SourceVisibilityTest(unittest.TestCase):
BUILD = textwrap.dedent(
"""\
load("//build/bazel/rules:foo.bzl", "foo_library")
package(default_applicable_licenses = ["//:license"])
# @bazel2gn:transformer=visibility
shared_visibility = [
"//a:__pkg__",
"//b:__subpackages__",
]
foo_library(
name = "plain",
visibility = [
"//c:__pkg__",
":__subpackages__",
],
)
foo_library(
name = "split",
visibility = [
"//d:__pkg__",
], # @bazel2gn:raw_overwrite:[ "//*" ]
)
foo_library(
name = "empty_split",
visibility = [], # @bazel2gn:raw_overwrite:[ "//e/*" ]
)
foo_library(
name = "element_split",
visibility = [
"//visibility:private", # @bazel2gn:raw_overwrite:":*", "//f:*"
],
)
foo_library(
name = "skip_annotation",
visibility = ["//a:__pkg__"], # @bazel2gn:skip
)
foo_library(
name = "variable",
visibility = shared_visibility + ["//g:__pkg__"],
)
foo_library(
name = "dynamic",
visibility = some_function(),
)
foo_library(
name = "default",
)
"""
)
def parse(self, name: str) -> tuple[bool, list[str] | None, list[str]]:
result = parse_source_visibility(self.BUILD, name)
assert result is not None
return result.present, result.entries, result.overwrites
def test_plain(self) -> None:
self.assertEqual(
self.parse("plain"), (True, ["//c:__pkg__", ":__subpackages__"], [])
)
def test_split(self) -> None:
self.assertEqual(
self.parse("split"),
(True, ["//d:__pkg__"], ['raw_overwrite:[ "//*" ]']),
)
self.assertEqual(
self.parse("empty_split"),
(True, [], ['raw_overwrite:[ "//e/*" ]']),
)
self.assertEqual(
self.parse("element_split"),
(True, ["//visibility:private"], ['raw_overwrite:":*", "//f:*"']),
)
self.assertEqual(
self.parse("skip_annotation"),
(True, ["//a:__pkg__"], ["skip"]),
)
def test_variable(self) -> None:
self.assertEqual(
self.parse("variable"),
(True, ["//a:__pkg__", "//b:__subpackages__", "//g:__pkg__"], []),
)
def test_unresolvable(self) -> None:
self.assertEqual(self.parse("dynamic"), (True, None, []))
def test_absent(self) -> None:
self.assertEqual(self.parse("default"), (False, None, []))
def test_missing_target(self) -> None:
self.assertIsNone(parse_source_visibility(self.BUILD, "missing"))
self.assertIsNone(parse_source_visibility("foo(", "missing"))
class TextSearchTest(unittest.TestCase):
def test_label_reference_regex(self) -> None:
self.assertEqual(
label_reference_regex(Label("zircon/system/ulib/svc", "svc")),
'"//zircon/system/ulib/svc(:svc)?["(]',
)
self.assertEqual(
label_reference_regex(Label("sdk/lib/vfs/cpp", "cpp")),
'"//sdk/lib/vfs/cpp(:cpp)?["(]',
)
self.assertEqual(
label_reference_regex(Label("sdk/lib/c++", "lib.x")),
'"//sdk/lib/c\\+\\+:lib\\.x["(]',
)
def test_entry_covers_path(self) -> None:
self.assertTrue(entry_covers_path(pkg("a/b"), "a/b/BUILD.gn", {}))
self.assertFalse(entry_covers_path(pkg("a/b"), "a/b/c/BUILD.gn", {}))
self.assertTrue(entry_covers_path(subpkgs("a/b"), "a/b/c/BUILD.gn", {}))
self.assertTrue(
entry_covers_path(subpkgs("a/b"), "a/b/BUILD.bazel", {})
)
self.assertFalse(entry_covers_path(subpkgs("a/b"), "a/bc/BUILD.gn", {}))
self.assertTrue(entry_covers_path(target("//a/b:c"), "a/b/x.gni", {}))
self.assertTrue(entry_covers_path(PUBLIC, "a/BUILD.gn", {}))
self.assertFalse(entry_covers_path(PRIVATE, "a/BUILD.gn", {}))
group = Entry(Kind.PACKAGE_GROUP, "g", "group")
self.assertIsNone(entry_covers_path(group, "a/BUILD.gn", {}))
def test_entry_covers_secondary_source(self) -> None:
self.assertEqual(
build_file_package("build/secondary/third_party/ogg/BUILD.gn"),
"third_party/ogg",
)
self.assertEqual(
build_file_package("build/secondary/foo.gni"), "build/secondary"
)
self.assertTrue(
entry_covers_path(
subpkgs("third_party/ogg"),
"build/secondary/third_party/ogg/BUILD.gn",
{},
)
)
self.assertFalse(
entry_covers_path(
subpkgs("build/secondary"),
"build/secondary/third_party/ogg/BUILD.gn",
{},
)
)
class AnalyzeTest(unittest.TestCase):
def statuses(self, report_entries: Sequence[object]) -> dict[str, Status]:
return {e.text: e.status for e in report_entries} # type: ignore[attr-defined]
def test_bazel_list(self) -> None:
report = analyze_list(
[
"//a:__pkg__",
"//b:__subpackages__",
"//b/c:__pkg__",
"//d:__pkg__",
"//e:__pkg__",
f"//{OWN}:__pkg__",
"//a:__pkg__",
],
parse_bazel_entry,
OWN,
consumers=[
Label("a", "x"),
Label("b/c", "y"),
Label("z", "uncovered"),
Label(OWN, "internal"),
Label("sdk", "atom"),
],
implicit_entries=[pkg(OWN), pkg("sdk")],
reference_files=[
"a/BUILD.gn",
"e/BUILD.gn",
"sdk/BUILD.bazel",
"y/BUILD.gn",
],
)
self.assertEqual(
[(e.text, e.status) for e in report.entries],
[
("//a:__pkg__", Status.NEEDED),
("//b:__subpackages__", Status.NEEDED),
("//b/c:__pkg__", Status.REDUNDANT),
("//d:__pkg__", Status.UNUSED),
("//e:__pkg__", Status.UNVERIFIED),
(f"//{OWN}:__pkg__", Status.REDUNDANT),
("//a:__pkg__", Status.REDUNDANT),
],
)
self.assertEqual(report.entries[2].subsumed_by, "//b:__subpackages__")
self.assertEqual(report.entries[4].text_references, ["e/BUILD.gn"])
self.assertEqual(report.uncovered, [Label("z", "uncovered")])
self.assertEqual(report.uncovered_references, ["y/BUILD.gn"])
self.assertEqual(
[e.text for e in report.kept()],
["//a:__pkg__", "//b:__subpackages__", "//e:__pkg__"],
)
def test_gn_list_own_package_is_explicit(self) -> None:
report = analyze_list(
[":*", "//a/*", "//b:c"],
parse_gn_entry,
OWN,
consumers=[Label(OWN, "x"), Label("a/b", "y"), Label("b", "d")],
)
self.assertEqual(
self.statuses(report.entries),
{
":*": Status.NEEDED,
"//a/*": Status.NEEDED,
"//b:c": Status.UNUSED,
},
)
self.assertEqual(report.uncovered, [Label("b", "d")])
def test_package_groups(self) -> None:
groups = {Label("g", "known"): PackageGroup(["//a/..."], [])}
report = analyze_list(
["//g:known", "//g:unknown", "//g:unused_unknown"],
parse_bazel_entry,
OWN,
consumers=[Label("a/b", "x"), Label("c", "y")],
groups=groups,
)
self.assertEqual(
self.statuses(report.entries),
{
"//g:known": Status.NEEDED,
"//g:unknown": Status.UNKNOWN,
"//g:unused_unknown": Status.UNKNOWN,
},
)
self.assertEqual(report.undetermined, [Label("c", "y")])
self.assertEqual(report.uncovered, [])
def test_macro_locations(self) -> None:
macro_consumer = Label("sdk/fidl/x", "x_hlcpp")
report = analyze_list(
["//build/bazel/rules/fidl:__subpackages__", "//sdk/lib:__pkg__"],
parse_bazel_entry,
OWN,
consumers=[macro_consumer, Label("sdk/lib", "y"), Label("z", "z")],
macro_locations={
macro_consumer: ["build/bazel/rules/fidl"],
Label("sdk/lib", "y"): ["build/bazel/rules/fidl"],
},
)
self.assertEqual(report.entries[0].consumers, [macro_consumer])
# The consumer's own package takes precedence.
self.assertEqual(report.entries[1].consumers, [Label("sdk/lib", "y")])
self.assertEqual(report.uncovered, [Label("z", "z")])
def test_check_unused(self) -> None:
report = analyze_list(
[
"//a:__pkg__",
"//vendor:__subpackages__",
"//vendor/x:__pkg__",
"//b:__pkg__",
],
parse_bazel_entry,
OWN,
consumers=[],
check_unused=lambda e: (
(Status.UNKNOWN, "not in checkout")
if e.package.startswith("vendor")
else (Status.UNVERIFIED, "not loaded")
if e.package == "b"
else None
),
)
self.assertEqual(
[(e.status, e.reason) for e in report.entries],
[
(Status.UNUSED, None),
(Status.UNKNOWN, "not in checkout"),
(Status.REDUNDANT, "not in checkout"),
(Status.UNVERIFIED, "not loaded"),
],
)
self.assertEqual(
report.entries[2].subsumed_by, "//vendor:__subpackages__"
)
def test_public(self) -> None:
report = analyze_list(
["//visibility:public"], parse_bazel_entry, OWN, [Label("a", "b")]
)
self.assertEqual(report.entries[0].status, Status.NEEDED)
def test_private(self) -> None:
report = analyze_list(
["//visibility:private"], parse_bazel_entry, OWN, []
)
self.assertEqual(report.entries[0].status, Status.UNKNOWN)
class FormatTest(unittest.TestCase):
def test_format_bazel_list(self) -> None:
self.assertEqual(
format_bazel_list(["//b:__pkg__", "//a:__subpackages__"]),
'visibility = [\n "//a:__subpackages__",\n "//b:__pkg__",\n],',
)
self.assertEqual(
format_bazel_list([]), 'visibility = ["//visibility:private"],'
)
def test_sorted_labels(self) -> None:
self.assertEqual(
sorted_labels(["//a/b:__pkg__", "//a:__pkg__", "//a/b/c:__pkg__"]),
["//a:__pkg__", "//a/b:__pkg__", "//a/b/c:__pkg__"],
)
self.assertEqual(
sorted_labels(
["//a/b/testing:__pkg__", "//a/b:__pkg__", "//a/b:__pkg__"]
),
["//a/b:__pkg__", "//a/b/testing:__pkg__"],
)
def test_format_bazel2gn_overwrite(self) -> None:
self.assertEqual(
format_bazel2gn_overwrite(["//b:*", "//a/*"]),
'# @bazel2gn:raw_overwrite:[ "//a/*", "//b:*" ]',
)
def test_expected_gn_entries(self) -> None:
self.assertEqual(
expected_gn_entries([pkg("a"), PRIVATE], OWN), {pkg("a"), pkg(OWN)}
)
if __name__ == "__main__":
unittest.main()