blob: caf72530e0eae729e335bcbdeba69a81a763c6bc [file] [log] [blame]
# Copyright 2024 The Bazel Authors. 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.
"""Unit tests for the directory_glob rule."""
load("@bazel_skylib//rules/directory:glob.bzl", "directory_glob")
load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo")
# buildifier: disable=bzl-visibility
load("@bazel_skylib//rules/directory/private:glob.bzl", "directory_glob_chunk", "transitive_entries")
load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
load("@rules_testing//lib:truth.bzl", "matching")
load(":utils.bzl", "failure_matching", "failure_test")
def _expect_glob_chunk(env, directory, chunk):
return env.expect.that_collection(
directory_glob_chunk(directory, chunk),
expr = "directory_glob_chunk({}, {})".format(directory.human_readable, repr(chunk)),
)
def _expect_glob(env, directory, include, allow_empty = False):
return env.expect.that_collection(
directory.glob(include, allow_empty = allow_empty),
expr = "directory_glob({}, {}, allow_empty={})".format(directory.human_readable, include, allow_empty),
)
def _with_children(children):
return DirectoryInfo(
entries = {k: k for k in children},
human_readable = repr(children),
)
def _glob_test(name):
simple_name = "_simple_%s" % name
exclude_name = "_exclude_%s" % name
directory_glob(
name = simple_name,
srcs = ["testdata/f1"],
data = ["testdata/subdir/f2"],
directory = ":root",
)
directory_glob(
name = exclude_name,
srcs = [
"testdata/f1",
"nonexistent",
],
allow_empty = True,
data = ["**"],
directory = ":root",
exclude = ["testdata/f1"],
)
analysis_test(
name = name,
impl = _glob_test_impl,
targets = {
"root": ":root",
"f1": ":f1_filegroup",
"f2": ":f2_filegroup",
"simple_glob": simple_name,
"glob_with_exclude": exclude_name,
},
)
def _glob_test_impl(env, targets):
f1 = targets.f1[DefaultInfo].files.to_list()[0]
f2 = targets.f2[DefaultInfo].files.to_list()[0]
root = targets.root[DirectoryInfo]
testdata = root.entries["testdata"]
subdir = testdata.entries["subdir"]
env.expect.that_collection(transitive_entries(root)).contains_exactly([
root,
testdata,
subdir,
f1,
f2,
])
_expect_glob_chunk(env, testdata, "f1").contains_exactly([f1])
_expect_glob_chunk(env, root, "nonexistent").contains_exactly([])
_expect_glob_chunk(env, testdata, "f2").contains_exactly([])
_expect_glob_chunk(env, root, "testdata").contains_exactly([testdata])
_expect_glob_chunk(env, testdata, "*").contains_exactly(
[f1, subdir],
)
_expect_glob_chunk(
env,
_with_children(["a", "d", "abc", "abbc", "ab.bc", ".abbc", "abbc."]),
"ab*bc",
).contains_exactly([
"abbc",
"ab.bc",
])
_expect_glob_chunk(
env,
_with_children(["abbc", "abbbc", "ab.b.bc"]),
"ab*b*bc",
).contains_exactly([
"abbbc",
"ab.b.bc",
])
_expect_glob_chunk(
env,
_with_children(["a", "ab", "ba"]),
"a*",
).contains_exactly([
"a",
"ab",
])
_expect_glob_chunk(
env,
_with_children(["a", "ab", "a.b.", "ba."]),
"a*b*",
).contains_exactly([
"ab",
"a.b.",
])
_expect_glob(env, root, ["testdata/f1"]).contains_exactly([f1])
_expect_glob(env, root, ["testdata/subdir/f2"]).contains_exactly([f2])
_expect_glob(env, root, ["**"]).contains_exactly([f1, f2])
_expect_glob(env, root, ["**/f1"]).contains_exactly([f1])
_expect_glob(env, root, ["**/**/f1"]).contains_exactly([f1])
_expect_glob(env, root, ["testdata/*/f1"], allow_empty = True).contains_exactly([])
simple_glob = env.expect.that_target(targets.simple_glob)
with_exclude = env.expect.that_target(targets.glob_with_exclude)
env.expect.that_collection(
simple_glob.actual[DefaultInfo].files.to_list(),
expr = "simple_glob's files",
).contains_exactly([f1])
env.expect.that_collection(
with_exclude.actual[DefaultInfo].files.to_list(),
expr = "with_exclude's files",
).contains_exactly([])
# target.runfiles().contains_exactly() doesn't do what we want - it converts
# it to a string corresponding to the runfiles import path.
env.expect.that_collection(
simple_glob.runfiles().actual.files.to_list(),
expr = "simple_glob's runfiles",
).contains_exactly([f1, f2])
env.expect.that_collection(
with_exclude.runfiles().actual.files.to_list(),
expr = "with_exclude's runfiles",
).contains_exactly([f2])
def _glob_with_no_match_test(name):
failure_test(
name = name,
impl = failure_matching(matching.contains('"nonexistent" failed to match any files in')),
rule = directory_glob,
srcs = [
"testdata/f1",
"nonexistent",
],
data = ["testdata/f1"],
directory = ":root",
)
# buildifier: disable=function-docstring
def glob_test_suite(name):
test_suite(
name = name,
tests = [
_glob_test,
_glob_with_no_match_test,
],
)