xref: /aosp_15_r20/external/bazel-skylib/tests/directory/directory_test.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1# Copyright 2024 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#    http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Unit tests for the directory rule."""
16
17load("@bazel_skylib//rules/directory:directory.bzl", "directory")
18load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo")
19load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
20load("@rules_testing//lib:truth.bzl", "matching")
21load(":utils.bzl", "directory_subject", "failure_matching", "failure_test")
22
23def _source_root_test(name):
24    analysis_test(
25        name = name,
26        impl = _source_root_test_impl,
27        targets = {
28            "root": ":root",
29            "f1": ":f1_filegroup",
30            "f2": ":f2_filegroup",
31        },
32    )
33
34def _source_root_test_impl(env, targets):
35    f1 = targets.f1.files.to_list()[0]
36    f2 = targets.f2.files.to_list()[0]
37
38    env.expect.that_collection(targets.root.files.to_list()).contains_exactly(
39        [f1, f2],
40    )
41
42    human_readable = str(targets.root.label)
43
44    root = directory_subject(env, targets.root[DirectoryInfo])
45    root.entries().keys().contains_exactly(["testdata"])
46    root.transitive_files().contains_exactly([f1, f2]).in_order()
47    root.human_readable().equals(human_readable)
48    env.expect.that_str(root.actual.path + "/testdata/f1").equals(f1.path)
49
50    testdata = directory_subject(env, root.actual.entries["testdata"])
51    testdata.entries().keys().contains_exactly(["f1", "subdir"])
52    testdata.human_readable().equals(human_readable + "/testdata")
53
54    subdir = directory_subject(env, testdata.actual.entries["subdir"])
55    subdir.entries().contains_exactly({"f2": f2})
56    subdir.transitive_files().contains_exactly([f2])
57    env.expect.that_str(subdir.actual.path + "/f2").equals(f2.path)
58
59def _generated_root_test(name):
60    subject_name = "_%s_subject" % name
61    directory(
62        name = subject_name,
63        srcs = [":generated_file"],
64    )
65
66    analysis_test(
67        name = name,
68        impl = _generated_root_test_impl,
69        targets = {
70            "root": subject_name,
71            "generated": ":generated_file",
72        },
73    )
74
75def _generated_root_test_impl(env, targets):
76    generated = targets.generated.files.to_list()[0]
77
78    env.expect.that_collection(targets.root.files.to_list()).contains_exactly(
79        [generated],
80    )
81
82    human_readable = str(targets.root.label)
83
84    root = directory_subject(env, targets.root[DirectoryInfo])
85    root.entries().keys().contains_exactly(["dir"])
86    root.transitive_files().contains_exactly([generated]).in_order()
87    root.human_readable().equals(human_readable)
88    env.expect.that_str(root.actual.path + "/dir/generated").equals(generated.path)
89
90    dir = directory_subject(env, root.actual.entries["dir"])
91    dir.human_readable().equals(human_readable + "/dir")
92    dir.entries().contains_exactly({"generated": generated})
93    dir.transitive_files().contains_exactly([generated])
94    env.expect.that_str(dir.actual.path + "/generated").equals(generated.path)
95
96def _no_srcs_test(name):
97    subject_name = "_%s_subject" % name
98    directory(
99        name = subject_name,
100    )
101
102    analysis_test(
103        name = name,
104        impl = _no_srcs_test_impl,
105        targets = {
106            "root": subject_name,
107            "f1": ":f1_filegroup",
108        },
109    )
110
111def _no_srcs_test_impl(env, targets):
112    f1 = targets.f1.files.to_list()[0]
113
114    env.expect.that_collection(targets.root.files.to_list()).contains_exactly([])
115
116    d = directory_subject(env, targets.root[DirectoryInfo])
117    d.entries().contains_exactly({})
118    env.expect.that_str(d.actual.path + "/testdata/f1").equals(f1.path)
119
120def _directory_with_self_srcs_test(name):
121    failure_test(
122        name = name,
123        impl = failure_matching(matching.contains("tests/directory to start with")),
124        rule = directory,
125        srcs = ["."],
126    )
127
128def _outside_testdata_test(name):
129    failure_test(
130        name = name,
131        impl = failure_matching(matching.contains("lib/paths.bzl to start with")),
132        rule = directory,
133        srcs = ["@bazel_skylib//lib:paths"],
134    )
135
136def _source_and_generated_root_test(name):
137    failure_test(
138        name = name,
139        impl = failure_matching(matching.contains(
140            "Having both source and generated files in a single directory is unsupported",
141        )),
142        rule = directory,
143        srcs = ["f1", ":generated_file"],
144    )
145
146# buildifier: disable=function-docstring
147def directory_test_suite(name):
148    test_suite(
149        name = name,
150        tests = [
151            _source_root_test,
152            _generated_root_test,
153            _no_srcs_test,
154            _directory_with_self_srcs_test,
155            _outside_testdata_test,
156            _source_and_generated_root_test,
157        ],
158    )
159