xref: /aosp_15_r20/external/bazel-skylib/tests/directory/glob_test.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1*bcb5dc79SHONG Yifan# Copyright 2024 The Bazel Authors. All rights reserved.
2*bcb5dc79SHONG Yifan#
3*bcb5dc79SHONG Yifan# Licensed under the Apache License, Version 2.0 (the "License");
4*bcb5dc79SHONG Yifan# you may not use this file except in compliance with the License.
5*bcb5dc79SHONG Yifan# You may obtain a copy of the License at
6*bcb5dc79SHONG Yifan#
7*bcb5dc79SHONG Yifan#    http://www.apache.org/licenses/LICENSE-2.0
8*bcb5dc79SHONG Yifan#
9*bcb5dc79SHONG Yifan# Unless required by applicable law or agreed to in writing, software
10*bcb5dc79SHONG Yifan# distributed under the License is distributed on an "AS IS" BASIS,
11*bcb5dc79SHONG Yifan# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*bcb5dc79SHONG Yifan# See the License for the specific language governing permissions and
13*bcb5dc79SHONG Yifan# limitations under the License.
14*bcb5dc79SHONG Yifan
15*bcb5dc79SHONG Yifan"""Unit tests for the directory_glob rule."""
16*bcb5dc79SHONG Yifan
17*bcb5dc79SHONG Yifanload("@bazel_skylib//rules/directory:glob.bzl", "directory_glob")
18*bcb5dc79SHONG Yifanload("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo")
19*bcb5dc79SHONG Yifan
20*bcb5dc79SHONG Yifan# buildifier: disable=bzl-visibility
21*bcb5dc79SHONG Yifanload("@bazel_skylib//rules/directory/private:glob.bzl", "directory_glob_chunk", "transitive_entries")
22*bcb5dc79SHONG Yifanload("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
23*bcb5dc79SHONG Yifanload("@rules_testing//lib:truth.bzl", "matching")
24*bcb5dc79SHONG Yifanload(":utils.bzl", "failure_matching", "failure_test")
25*bcb5dc79SHONG Yifan
26*bcb5dc79SHONG Yifandef _expect_glob_chunk(env, directory, chunk):
27*bcb5dc79SHONG Yifan    return env.expect.that_collection(
28*bcb5dc79SHONG Yifan        directory_glob_chunk(directory, chunk),
29*bcb5dc79SHONG Yifan        expr = "directory_glob_chunk({}, {})".format(directory.human_readable, repr(chunk)),
30*bcb5dc79SHONG Yifan    )
31*bcb5dc79SHONG Yifan
32*bcb5dc79SHONG Yifandef _expect_glob(env, directory, include, allow_empty = False):
33*bcb5dc79SHONG Yifan    return env.expect.that_collection(
34*bcb5dc79SHONG Yifan        directory.glob(include, allow_empty = allow_empty),
35*bcb5dc79SHONG Yifan        expr = "directory_glob({}, {}, allow_empty={})".format(directory.human_readable, include, allow_empty),
36*bcb5dc79SHONG Yifan    )
37*bcb5dc79SHONG Yifan
38*bcb5dc79SHONG Yifandef _with_children(children):
39*bcb5dc79SHONG Yifan    return DirectoryInfo(
40*bcb5dc79SHONG Yifan        entries = {k: k for k in children},
41*bcb5dc79SHONG Yifan        human_readable = repr(children),
42*bcb5dc79SHONG Yifan    )
43*bcb5dc79SHONG Yifan
44*bcb5dc79SHONG Yifandef _glob_test(name):
45*bcb5dc79SHONG Yifan    simple_name = "_simple_%s" % name
46*bcb5dc79SHONG Yifan    exclude_name = "_exclude_%s" % name
47*bcb5dc79SHONG Yifan    directory_glob(
48*bcb5dc79SHONG Yifan        name = simple_name,
49*bcb5dc79SHONG Yifan        srcs = ["testdata/f1"],
50*bcb5dc79SHONG Yifan        data = ["testdata/subdir/f2"],
51*bcb5dc79SHONG Yifan        directory = ":root",
52*bcb5dc79SHONG Yifan    )
53*bcb5dc79SHONG Yifan
54*bcb5dc79SHONG Yifan    directory_glob(
55*bcb5dc79SHONG Yifan        name = exclude_name,
56*bcb5dc79SHONG Yifan        srcs = [
57*bcb5dc79SHONG Yifan            "testdata/f1",
58*bcb5dc79SHONG Yifan            "nonexistent",
59*bcb5dc79SHONG Yifan        ],
60*bcb5dc79SHONG Yifan        allow_empty = True,
61*bcb5dc79SHONG Yifan        data = ["**"],
62*bcb5dc79SHONG Yifan        directory = ":root",
63*bcb5dc79SHONG Yifan        exclude = ["testdata/f1"],
64*bcb5dc79SHONG Yifan    )
65*bcb5dc79SHONG Yifan
66*bcb5dc79SHONG Yifan    analysis_test(
67*bcb5dc79SHONG Yifan        name = name,
68*bcb5dc79SHONG Yifan        impl = _glob_test_impl,
69*bcb5dc79SHONG Yifan        targets = {
70*bcb5dc79SHONG Yifan            "root": ":root",
71*bcb5dc79SHONG Yifan            "f1": ":f1_filegroup",
72*bcb5dc79SHONG Yifan            "f2": ":f2_filegroup",
73*bcb5dc79SHONG Yifan            "simple_glob": simple_name,
74*bcb5dc79SHONG Yifan            "glob_with_exclude": exclude_name,
75*bcb5dc79SHONG Yifan        },
76*bcb5dc79SHONG Yifan    )
77*bcb5dc79SHONG Yifan
78*bcb5dc79SHONG Yifandef _glob_test_impl(env, targets):
79*bcb5dc79SHONG Yifan    f1 = targets.f1.files.to_list()[0]
80*bcb5dc79SHONG Yifan    f2 = targets.f2.files.to_list()[0]
81*bcb5dc79SHONG Yifan    root = targets.root[DirectoryInfo]
82*bcb5dc79SHONG Yifan    testdata = root.entries["testdata"]
83*bcb5dc79SHONG Yifan    subdir = testdata.entries["subdir"]
84*bcb5dc79SHONG Yifan
85*bcb5dc79SHONG Yifan    env.expect.that_collection(transitive_entries(root)).contains_exactly([
86*bcb5dc79SHONG Yifan        root,
87*bcb5dc79SHONG Yifan        testdata,
88*bcb5dc79SHONG Yifan        subdir,
89*bcb5dc79SHONG Yifan        f1,
90*bcb5dc79SHONG Yifan        f2,
91*bcb5dc79SHONG Yifan    ])
92*bcb5dc79SHONG Yifan
93*bcb5dc79SHONG Yifan    _expect_glob_chunk(env, testdata, "f1").contains_exactly([f1])
94*bcb5dc79SHONG Yifan    _expect_glob_chunk(env, root, "nonexistent").contains_exactly([])
95*bcb5dc79SHONG Yifan    _expect_glob_chunk(env, testdata, "f2").contains_exactly([])
96*bcb5dc79SHONG Yifan    _expect_glob_chunk(env, root, "testdata").contains_exactly([testdata])
97*bcb5dc79SHONG Yifan    _expect_glob_chunk(env, testdata, "*").contains_exactly(
98*bcb5dc79SHONG Yifan        [f1, subdir],
99*bcb5dc79SHONG Yifan    )
100*bcb5dc79SHONG Yifan    _expect_glob_chunk(
101*bcb5dc79SHONG Yifan        env,
102*bcb5dc79SHONG Yifan        _with_children(["a", "d", "abc", "abbc", "ab.bc", ".abbc", "abbc."]),
103*bcb5dc79SHONG Yifan        "ab*bc",
104*bcb5dc79SHONG Yifan    ).contains_exactly([
105*bcb5dc79SHONG Yifan        "abbc",
106*bcb5dc79SHONG Yifan        "ab.bc",
107*bcb5dc79SHONG Yifan    ])
108*bcb5dc79SHONG Yifan    _expect_glob_chunk(
109*bcb5dc79SHONG Yifan        env,
110*bcb5dc79SHONG Yifan        _with_children(["abbc", "abbbc", "ab.b.bc"]),
111*bcb5dc79SHONG Yifan        "ab*b*bc",
112*bcb5dc79SHONG Yifan    ).contains_exactly([
113*bcb5dc79SHONG Yifan        "abbbc",
114*bcb5dc79SHONG Yifan        "ab.b.bc",
115*bcb5dc79SHONG Yifan    ])
116*bcb5dc79SHONG Yifan    _expect_glob_chunk(
117*bcb5dc79SHONG Yifan        env,
118*bcb5dc79SHONG Yifan        _with_children(["a", "ab", "ba"]),
119*bcb5dc79SHONG Yifan        "a*",
120*bcb5dc79SHONG Yifan    ).contains_exactly([
121*bcb5dc79SHONG Yifan        "a",
122*bcb5dc79SHONG Yifan        "ab",
123*bcb5dc79SHONG Yifan    ])
124*bcb5dc79SHONG Yifan    _expect_glob_chunk(
125*bcb5dc79SHONG Yifan        env,
126*bcb5dc79SHONG Yifan        _with_children(["a", "ab", "a.b.", "ba."]),
127*bcb5dc79SHONG Yifan        "a*b*",
128*bcb5dc79SHONG Yifan    ).contains_exactly([
129*bcb5dc79SHONG Yifan        "ab",
130*bcb5dc79SHONG Yifan        "a.b.",
131*bcb5dc79SHONG Yifan    ])
132*bcb5dc79SHONG Yifan
133*bcb5dc79SHONG Yifan    _expect_glob(env, root, ["testdata/f1"]).contains_exactly([f1])
134*bcb5dc79SHONG Yifan    _expect_glob(env, root, ["testdata/subdir/f2"]).contains_exactly([f2])
135*bcb5dc79SHONG Yifan    _expect_glob(env, root, ["**"]).contains_exactly([f1, f2])
136*bcb5dc79SHONG Yifan    _expect_glob(env, root, ["**/f1"]).contains_exactly([f1])
137*bcb5dc79SHONG Yifan    _expect_glob(env, root, ["**/**/f1"]).contains_exactly([f1])
138*bcb5dc79SHONG Yifan    _expect_glob(env, root, ["testdata/*/f1"], allow_empty = True).contains_exactly([])
139*bcb5dc79SHONG Yifan
140*bcb5dc79SHONG Yifan    simple_glob = env.expect.that_target(targets.simple_glob)
141*bcb5dc79SHONG Yifan    with_exclude = env.expect.that_target(targets.glob_with_exclude)
142*bcb5dc79SHONG Yifan
143*bcb5dc79SHONG Yifan    env.expect.that_collection(
144*bcb5dc79SHONG Yifan        simple_glob.actual[DefaultInfo].files.to_list(),
145*bcb5dc79SHONG Yifan        expr = "simple_glob's files",
146*bcb5dc79SHONG Yifan    ).contains_exactly([f1])
147*bcb5dc79SHONG Yifan    env.expect.that_collection(
148*bcb5dc79SHONG Yifan        with_exclude.actual[DefaultInfo].files.to_list(),
149*bcb5dc79SHONG Yifan        expr = "with_exclude's files",
150*bcb5dc79SHONG Yifan    ).contains_exactly([])
151*bcb5dc79SHONG Yifan
152*bcb5dc79SHONG Yifan    # target.runfiles().contains_exactly() doesn't do what we want - it converts
153*bcb5dc79SHONG Yifan    # it to a string corresponding to the runfiles import path.
154*bcb5dc79SHONG Yifan    env.expect.that_collection(
155*bcb5dc79SHONG Yifan        simple_glob.runfiles().actual.files.to_list(),
156*bcb5dc79SHONG Yifan        expr = "simple_glob's runfiles",
157*bcb5dc79SHONG Yifan    ).contains_exactly([f1, f2])
158*bcb5dc79SHONG Yifan    env.expect.that_collection(
159*bcb5dc79SHONG Yifan        with_exclude.runfiles().actual.files.to_list(),
160*bcb5dc79SHONG Yifan        expr = "with_exclude's runfiles",
161*bcb5dc79SHONG Yifan    ).contains_exactly([f2])
162*bcb5dc79SHONG Yifan
163*bcb5dc79SHONG Yifandef _glob_with_no_match_test(name):
164*bcb5dc79SHONG Yifan    failure_test(
165*bcb5dc79SHONG Yifan        name = name,
166*bcb5dc79SHONG Yifan        impl = failure_matching(matching.contains('"nonexistent" failed to match any files in')),
167*bcb5dc79SHONG Yifan        rule = directory_glob,
168*bcb5dc79SHONG Yifan        srcs = [
169*bcb5dc79SHONG Yifan            "testdata/f1",
170*bcb5dc79SHONG Yifan            "nonexistent",
171*bcb5dc79SHONG Yifan        ],
172*bcb5dc79SHONG Yifan        data = ["testdata/f1"],
173*bcb5dc79SHONG Yifan        directory = ":root",
174*bcb5dc79SHONG Yifan    )
175*bcb5dc79SHONG Yifan
176*bcb5dc79SHONG Yifan# buildifier: disable=function-docstring
177*bcb5dc79SHONG Yifandef glob_test_suite(name):
178*bcb5dc79SHONG Yifan    test_suite(
179*bcb5dc79SHONG Yifan        name = name,
180*bcb5dc79SHONG Yifan        tests = [
181*bcb5dc79SHONG Yifan            _glob_test,
182*bcb5dc79SHONG Yifan            _glob_with_no_match_test,
183*bcb5dc79SHONG Yifan        ],
184*bcb5dc79SHONG Yifan    )
185