xref: /aosp_15_r20/external/bazel-skylib/tests/paths_tests.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1*bcb5dc79SHONG Yifan# Copyright 2017 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 paths.bzl."""
16*bcb5dc79SHONG Yifan
17*bcb5dc79SHONG Yifanload("//lib:paths.bzl", "paths")
18*bcb5dc79SHONG Yifanload("//lib:unittest.bzl", "asserts", "unittest")
19*bcb5dc79SHONG Yifan
20*bcb5dc79SHONG Yifandef _basename_test(ctx):
21*bcb5dc79SHONG Yifan    """Unit tests for paths.basename."""
22*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
23*bcb5dc79SHONG Yifan
24*bcb5dc79SHONG Yifan    # Verify some degenerate cases.
25*bcb5dc79SHONG Yifan    asserts.equals(env, "", paths.basename(""))
26*bcb5dc79SHONG Yifan    asserts.equals(env, "", paths.basename("/"))
27*bcb5dc79SHONG Yifan    asserts.equals(env, "bar", paths.basename("foo///bar"))
28*bcb5dc79SHONG Yifan
29*bcb5dc79SHONG Yifan    # Verify some realistic cases.
30*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.basename("foo"))
31*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.basename("/foo"))
32*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.basename("bar/foo"))
33*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.basename("/bar/foo"))
34*bcb5dc79SHONG Yifan
35*bcb5dc79SHONG Yifan    # Verify that we correctly duplicate Python's os.path.basename behavior,
36*bcb5dc79SHONG Yifan    # where a trailing slash means the basename is empty.
37*bcb5dc79SHONG Yifan    asserts.equals(env, "", paths.basename("foo/"))
38*bcb5dc79SHONG Yifan    asserts.equals(env, "", paths.basename("/foo/"))
39*bcb5dc79SHONG Yifan
40*bcb5dc79SHONG Yifan    return unittest.end(env)
41*bcb5dc79SHONG Yifan
42*bcb5dc79SHONG Yifanbasename_test = unittest.make(_basename_test)
43*bcb5dc79SHONG Yifan
44*bcb5dc79SHONG Yifandef _dirname_test(ctx):
45*bcb5dc79SHONG Yifan    """Unit tests for paths.dirname."""
46*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
47*bcb5dc79SHONG Yifan
48*bcb5dc79SHONG Yifan    # Verify some degenerate cases.
49*bcb5dc79SHONG Yifan    asserts.equals(env, "", paths.dirname(""))
50*bcb5dc79SHONG Yifan    asserts.equals(env, "/", paths.dirname("/"))
51*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.dirname("foo///bar"))
52*bcb5dc79SHONG Yifan
53*bcb5dc79SHONG Yifan    # Verify some realistic cases.
54*bcb5dc79SHONG Yifan    asserts.equals(env, "", paths.dirname("foo"))
55*bcb5dc79SHONG Yifan    asserts.equals(env, "/", paths.dirname("/foo"))
56*bcb5dc79SHONG Yifan    asserts.equals(env, "bar", paths.dirname("bar/foo"))
57*bcb5dc79SHONG Yifan    asserts.equals(env, "/bar", paths.dirname("/bar/foo"))
58*bcb5dc79SHONG Yifan
59*bcb5dc79SHONG Yifan    # Verify that we correctly duplicate Python's os.path.dirname behavior,
60*bcb5dc79SHONG Yifan    # where a trailing slash means the dirname is the same as the original
61*bcb5dc79SHONG Yifan    # path (without the trailing slash).
62*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.dirname("foo/"))
63*bcb5dc79SHONG Yifan    asserts.equals(env, "/foo", paths.dirname("/foo/"))
64*bcb5dc79SHONG Yifan
65*bcb5dc79SHONG Yifan    return unittest.end(env)
66*bcb5dc79SHONG Yifan
67*bcb5dc79SHONG Yifandirname_test = unittest.make(_dirname_test)
68*bcb5dc79SHONG Yifan
69*bcb5dc79SHONG Yifandef _is_absolute_test(ctx):
70*bcb5dc79SHONG Yifan    """Unit tests for paths.is_absolute."""
71*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
72*bcb5dc79SHONG Yifan
73*bcb5dc79SHONG Yifan    # Try a degenerate case.
74*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_absolute(""))
75*bcb5dc79SHONG Yifan
76*bcb5dc79SHONG Yifan    # Try some relative paths.
77*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_absolute("foo"))
78*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_absolute("foo/"))
79*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_absolute("foo/bar"))
80*bcb5dc79SHONG Yifan
81*bcb5dc79SHONG Yifan    # Try some Linux absolute paths.
82*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_absolute("/"))
83*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_absolute("/foo"))
84*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_absolute("/foo/"))
85*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_absolute("/foo/bar"))
86*bcb5dc79SHONG Yifan
87*bcb5dc79SHONG Yifan    # Try some Windows absolute paths.
88*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_absolute("D:\\"))
89*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_absolute("C:\\"))
90*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_absolute("C:\\foo"))
91*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_absolute("C:\\foo\\bar"))
92*bcb5dc79SHONG Yifan
93*bcb5dc79SHONG Yifan    return unittest.end(env)
94*bcb5dc79SHONG Yifan
95*bcb5dc79SHONG Yifanis_absolute_test = unittest.make(_is_absolute_test)
96*bcb5dc79SHONG Yifan
97*bcb5dc79SHONG Yifandef _join_test(ctx):
98*bcb5dc79SHONG Yifan    """Unit tests for paths.join."""
99*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
100*bcb5dc79SHONG Yifan
101*bcb5dc79SHONG Yifan    # Try a degenerate case.
102*bcb5dc79SHONG Yifan    asserts.equals(env, "", paths.join(""))
103*bcb5dc79SHONG Yifan
104*bcb5dc79SHONG Yifan    # Try some basic paths.
105*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.join("foo"))
106*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar", paths.join("foo", "bar"))
107*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar/baz", paths.join("foo", "bar", "baz"))
108*bcb5dc79SHONG Yifan
109*bcb5dc79SHONG Yifan    # Make sure an initially absolute path stays absolute.
110*bcb5dc79SHONG Yifan    asserts.equals(env, "/foo", paths.join("/foo"))
111*bcb5dc79SHONG Yifan    asserts.equals(env, "/foo/bar", paths.join("/foo", "bar"))
112*bcb5dc79SHONG Yifan
113*bcb5dc79SHONG Yifan    # Make sure an absolute path later in the list resets the result.
114*bcb5dc79SHONG Yifan    asserts.equals(env, "/baz", paths.join("foo", "bar", "/baz"))
115*bcb5dc79SHONG Yifan    asserts.equals(env, "/baz", paths.join("foo", "/bar", "/baz"))
116*bcb5dc79SHONG Yifan    asserts.equals(env, "/bar/baz", paths.join("foo", "/bar", "baz"))
117*bcb5dc79SHONG Yifan    asserts.equals(env, "/bar", paths.join("/foo", "/bar"))
118*bcb5dc79SHONG Yifan
119*bcb5dc79SHONG Yifan    # Make sure a leading empty segment doesn't make it absolute.
120*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.join("", "foo"))
121*bcb5dc79SHONG Yifan
122*bcb5dc79SHONG Yifan    # Try some trailing slash scenarios.
123*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/", paths.join("foo", ""))
124*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/", paths.join("foo/"))
125*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/", paths.join("foo/", ""))
126*bcb5dc79SHONG Yifan    asserts.equals(env, "foo//", paths.join("foo//", ""))
127*bcb5dc79SHONG Yifan    asserts.equals(env, "foo//", paths.join("foo//"))
128*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz", ""))
129*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz/"))
130*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz/", ""))
131*bcb5dc79SHONG Yifan
132*bcb5dc79SHONG Yifan    # Make sure that adjacent empty segments don't add extra path separators.
133*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/", paths.join("foo", "", ""))
134*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.join("", "", "foo"))
135*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar", paths.join("foo", "", "", "bar"))
136*bcb5dc79SHONG Yifan
137*bcb5dc79SHONG Yifan    return unittest.end(env)
138*bcb5dc79SHONG Yifan
139*bcb5dc79SHONG Yifanjoin_test = unittest.make(_join_test)
140*bcb5dc79SHONG Yifan
141*bcb5dc79SHONG Yifandef _normalize_test(ctx):
142*bcb5dc79SHONG Yifan    """Unit tests for paths.normalize."""
143*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
144*bcb5dc79SHONG Yifan
145*bcb5dc79SHONG Yifan    # Try the most basic case.
146*bcb5dc79SHONG Yifan    asserts.equals(env, ".", paths.normalize(""))
147*bcb5dc79SHONG Yifan
148*bcb5dc79SHONG Yifan    # Try some basic adjacent-slash removal.
149*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar", paths.normalize("foo//bar"))
150*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar", paths.normalize("foo////bar"))
151*bcb5dc79SHONG Yifan
152*bcb5dc79SHONG Yifan    # Try some "." removal.
153*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar", paths.normalize("foo/./bar"))
154*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar", paths.normalize("./foo/bar"))
155*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar", paths.normalize("foo/bar/."))
156*bcb5dc79SHONG Yifan    asserts.equals(env, "/", paths.normalize("/."))
157*bcb5dc79SHONG Yifan
158*bcb5dc79SHONG Yifan    # Try some ".." removal.
159*bcb5dc79SHONG Yifan    asserts.equals(env, "bar", paths.normalize("foo/../bar"))
160*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.normalize("foo/bar/.."))
161*bcb5dc79SHONG Yifan    asserts.equals(env, ".", paths.normalize("foo/.."))
162*bcb5dc79SHONG Yifan    asserts.equals(env, ".", paths.normalize("foo/bar/../.."))
163*bcb5dc79SHONG Yifan    asserts.equals(env, "..", paths.normalize("foo/../.."))
164*bcb5dc79SHONG Yifan    asserts.equals(env, "/", paths.normalize("/foo/../.."))
165*bcb5dc79SHONG Yifan    asserts.equals(env, "../../c", paths.normalize("a/b/../../../../c/d/.."))
166*bcb5dc79SHONG Yifan
167*bcb5dc79SHONG Yifan    # Make sure one or two initial slashes are preserved, but three or more are
168*bcb5dc79SHONG Yifan    # collapsed to a single slash.
169*bcb5dc79SHONG Yifan    asserts.equals(env, "/foo", paths.normalize("/foo"))
170*bcb5dc79SHONG Yifan    asserts.equals(env, "//foo", paths.normalize("//foo"))
171*bcb5dc79SHONG Yifan    asserts.equals(env, "/foo", paths.normalize("///foo"))
172*bcb5dc79SHONG Yifan
173*bcb5dc79SHONG Yifan    # Trailing slashes should be removed unless the entire path is a trailing
174*bcb5dc79SHONG Yifan    # slash.
175*bcb5dc79SHONG Yifan    asserts.equals(env, "/", paths.normalize("/"))
176*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.normalize("foo/"))
177*bcb5dc79SHONG Yifan    asserts.equals(env, "foo/bar", paths.normalize("foo/bar/"))
178*bcb5dc79SHONG Yifan
179*bcb5dc79SHONG Yifan    return unittest.end(env)
180*bcb5dc79SHONG Yifan
181*bcb5dc79SHONG Yifannormalize_test = unittest.make(_normalize_test)
182*bcb5dc79SHONG Yifan
183*bcb5dc79SHONG Yifandef _is_normalized_test(ctx):
184*bcb5dc79SHONG Yifan    """Unit tests for paths.is_normalized."""
185*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
186*bcb5dc79SHONG Yifan
187*bcb5dc79SHONG Yifan    # Try the most basic cases.
188*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized(""))
189*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("."))
190*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("/"))
191*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("/tmp"))
192*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("tmp"))
193*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("c:/"))
194*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("../a"))
195*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("a/.."))
196*bcb5dc79SHONG Yifan
197*bcb5dc79SHONG Yifan    # Try some basic adjacent-slash removal.
198*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("foo//bar"))
199*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("foo////bar"))
200*bcb5dc79SHONG Yifan
201*bcb5dc79SHONG Yifan    # Try some "." removal.
202*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("foo/./bar"))
203*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("./foo/bar"))
204*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("foo/bar/."))
205*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("/."))
206*bcb5dc79SHONG Yifan
207*bcb5dc79SHONG Yifan    # Try some ".." removal.
208*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("foo/../bar"))
209*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("foo/bar/.."))
210*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("foo/.."))
211*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("foo/bar/../.."))
212*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("foo/../.."))
213*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("/foo/../.."))
214*bcb5dc79SHONG Yifan    asserts.false(env, paths.is_normalized("a/b/../../../../c/d/.."))
215*bcb5dc79SHONG Yifan
216*bcb5dc79SHONG Yifan    # Make sure one or two initial slashes are preserved, but three or more are
217*bcb5dc79SHONG Yifan    # collapsed to a single slash.
218*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("/foo"))
219*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("//foo"))
220*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("///foo"))
221*bcb5dc79SHONG Yifan
222*bcb5dc79SHONG Yifan    # Trailing slashes should be removed unless the entire path is a trailing
223*bcb5dc79SHONG Yifan    # slash.
224*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("/"))
225*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("foo/"))
226*bcb5dc79SHONG Yifan    asserts.true(env, paths.is_normalized("foo/bar/"))
227*bcb5dc79SHONG Yifan
228*bcb5dc79SHONG Yifan    return unittest.end(env)
229*bcb5dc79SHONG Yifan
230*bcb5dc79SHONG Yifanis_normalized_test = unittest.make(_is_normalized_test)
231*bcb5dc79SHONG Yifan
232*bcb5dc79SHONG Yifandef _relativize_test(ctx):
233*bcb5dc79SHONG Yifan    """Unit tests for paths.relativize."""
234*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
235*bcb5dc79SHONG Yifan
236*bcb5dc79SHONG Yifan    # Make sure that relative-to-current-directory works in all forms.
237*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.relativize("foo", ""))
238*bcb5dc79SHONG Yifan    asserts.equals(env, "foo", paths.relativize("foo", "."))
239*bcb5dc79SHONG Yifan
240*bcb5dc79SHONG Yifan    # Try some regular cases.
241*bcb5dc79SHONG Yifan    asserts.equals(env, "bar", paths.relativize("foo/bar", "foo"))
242*bcb5dc79SHONG Yifan    asserts.equals(env, "baz", paths.relativize("foo/bar/baz", "foo/bar"))
243*bcb5dc79SHONG Yifan    asserts.equals(env, "bar/baz", paths.relativize("foo/bar/baz", "foo"))
244*bcb5dc79SHONG Yifan
245*bcb5dc79SHONG Yifan    # Try a case where a parent directory is normalized away.
246*bcb5dc79SHONG Yifan    asserts.equals(env, "baz", paths.relativize("foo/bar/../baz", "foo"))
247*bcb5dc79SHONG Yifan
248*bcb5dc79SHONG Yifan    # Relative paths work, as long as they share a common start.
249*bcb5dc79SHONG Yifan    asserts.equals(env, "file", paths.relativize("../foo/bar/baz/file", "../foo/bar/baz"))
250*bcb5dc79SHONG Yifan    asserts.equals(env, "baz/file", paths.relativize("../foo/bar/baz/file", "../foo/bar"))
251*bcb5dc79SHONG Yifan
252*bcb5dc79SHONG Yifan    # TODO(allevato): Test failure cases, once that is possible.
253*bcb5dc79SHONG Yifan
254*bcb5dc79SHONG Yifan    return unittest.end(env)
255*bcb5dc79SHONG Yifan
256*bcb5dc79SHONG Yifanrelativize_test = unittest.make(_relativize_test)
257*bcb5dc79SHONG Yifan
258*bcb5dc79SHONG Yifandef _replace_extension_test(ctx):
259*bcb5dc79SHONG Yifan    """Unit tests for paths.replace_extension."""
260*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
261*bcb5dc79SHONG Yifan
262*bcb5dc79SHONG Yifan    # Try some degenerate cases.
263*bcb5dc79SHONG Yifan    asserts.equals(env, ".foo", paths.replace_extension("", ".foo"))
264*bcb5dc79SHONG Yifan    asserts.equals(env, "/.foo", paths.replace_extension("/", ".foo"))
265*bcb5dc79SHONG Yifan    asserts.equals(env, "foo.bar", paths.replace_extension("foo", ".bar"))
266*bcb5dc79SHONG Yifan
267*bcb5dc79SHONG Yifan    # Try a directory with an extension and basename that doesn't have one.
268*bcb5dc79SHONG Yifan    asserts.equals(
269*bcb5dc79SHONG Yifan        env,
270*bcb5dc79SHONG Yifan        "foo.bar/baz.quux",
271*bcb5dc79SHONG Yifan        paths.replace_extension("foo.bar/baz", ".quux"),
272*bcb5dc79SHONG Yifan    )
273*bcb5dc79SHONG Yifan
274*bcb5dc79SHONG Yifan    # Now try some things with legit extensions.
275*bcb5dc79SHONG Yifan    asserts.equals(env, "a.z", paths.replace_extension("a.b", ".z"))
276*bcb5dc79SHONG Yifan    asserts.equals(env, "a.b.z", paths.replace_extension("a.b.c", ".z"))
277*bcb5dc79SHONG Yifan    asserts.equals(env, "a/b.z", paths.replace_extension("a/b.c", ".z"))
278*bcb5dc79SHONG Yifan    asserts.equals(env, "a.b/c.z", paths.replace_extension("a.b/c.d", ".z"))
279*bcb5dc79SHONG Yifan    asserts.equals(env, ".a/b.z", paths.replace_extension(".a/b.c", ".z"))
280*bcb5dc79SHONG Yifan    asserts.equals(env, ".a.z", paths.replace_extension(".a.b", ".z"))
281*bcb5dc79SHONG Yifan
282*bcb5dc79SHONG Yifan    # Verify that we don't insert a period on the extension if none is provided.
283*bcb5dc79SHONG Yifan    asserts.equals(env, "foobaz", paths.replace_extension("foo.bar", "baz"))
284*bcb5dc79SHONG Yifan
285*bcb5dc79SHONG Yifan    return unittest.end(env)
286*bcb5dc79SHONG Yifan
287*bcb5dc79SHONG Yifanreplace_extension_test = unittest.make(_replace_extension_test)
288*bcb5dc79SHONG Yifan
289*bcb5dc79SHONG Yifandef _split_extension_test(ctx):
290*bcb5dc79SHONG Yifan    """Unit tests for paths.split_extension."""
291*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
292*bcb5dc79SHONG Yifan
293*bcb5dc79SHONG Yifan    # Try some degenerate cases.
294*bcb5dc79SHONG Yifan    asserts.equals(env, ("", ""), paths.split_extension(""))
295*bcb5dc79SHONG Yifan    asserts.equals(env, ("/", ""), paths.split_extension("/"))
296*bcb5dc79SHONG Yifan    asserts.equals(env, ("foo", ""), paths.split_extension("foo"))
297*bcb5dc79SHONG Yifan
298*bcb5dc79SHONG Yifan    # Try some paths whose basenames start with ".".
299*bcb5dc79SHONG Yifan    asserts.equals(env, (".", ""), paths.split_extension("."))
300*bcb5dc79SHONG Yifan    asserts.equals(env, (".bashrc", ""), paths.split_extension(".bashrc"))
301*bcb5dc79SHONG Yifan    asserts.equals(env, ("foo/.bashrc", ""), paths.split_extension("foo/.bashrc"))
302*bcb5dc79SHONG Yifan    asserts.equals(
303*bcb5dc79SHONG Yifan        env,
304*bcb5dc79SHONG Yifan        (".foo/.bashrc", ""),
305*bcb5dc79SHONG Yifan        paths.split_extension(".foo/.bashrc"),
306*bcb5dc79SHONG Yifan    )
307*bcb5dc79SHONG Yifan
308*bcb5dc79SHONG Yifan    # Try some directories with extensions with basenames that don't have one.
309*bcb5dc79SHONG Yifan    asserts.equals(env, ("foo.bar/baz", ""), paths.split_extension("foo.bar/baz"))
310*bcb5dc79SHONG Yifan    asserts.equals(
311*bcb5dc79SHONG Yifan        env,
312*bcb5dc79SHONG Yifan        ("foo.bar/.bashrc", ""),
313*bcb5dc79SHONG Yifan        paths.split_extension("foo.bar/.bashrc"),
314*bcb5dc79SHONG Yifan    )
315*bcb5dc79SHONG Yifan
316*bcb5dc79SHONG Yifan    # Now try some things that will actually get split.
317*bcb5dc79SHONG Yifan    asserts.equals(env, ("a", ".b"), paths.split_extension("a.b"))
318*bcb5dc79SHONG Yifan    asserts.equals(env, ("a.b", ".c"), paths.split_extension("a.b.c"))
319*bcb5dc79SHONG Yifan    asserts.equals(env, ("a/b", ".c"), paths.split_extension("a/b.c"))
320*bcb5dc79SHONG Yifan    asserts.equals(env, ("a.b/c", ".d"), paths.split_extension("a.b/c.d"))
321*bcb5dc79SHONG Yifan    asserts.equals(env, (".a/b", ".c"), paths.split_extension(".a/b.c"))
322*bcb5dc79SHONG Yifan    asserts.equals(env, (".a", ".b"), paths.split_extension(".a.b"))
323*bcb5dc79SHONG Yifan
324*bcb5dc79SHONG Yifan    return unittest.end(env)
325*bcb5dc79SHONG Yifan
326*bcb5dc79SHONG Yifansplit_extension_test = unittest.make(_split_extension_test)
327*bcb5dc79SHONG Yifan
328*bcb5dc79SHONG Yifandef _starts_with_test(ctx):
329*bcb5dc79SHONG Yifan    """Unit tests for paths.starts_with."""
330*bcb5dc79SHONG Yifan    env = unittest.begin(ctx)
331*bcb5dc79SHONG Yifan
332*bcb5dc79SHONG Yifan    # Make sure that relative-to-current-directory works in all forms.
333*bcb5dc79SHONG Yifan    asserts.true(env, paths.starts_with("foo", ""))
334*bcb5dc79SHONG Yifan    asserts.false(env, paths.starts_with("foo", "."))
335*bcb5dc79SHONG Yifan
336*bcb5dc79SHONG Yifan    # Try some regular cases.
337*bcb5dc79SHONG Yifan    asserts.true(env, paths.starts_with("foo/bar", "foo"))
338*bcb5dc79SHONG Yifan    asserts.false(env, paths.starts_with("foo/bar", "fo"))
339*bcb5dc79SHONG Yifan    asserts.true(env, paths.starts_with("foo/bar/baz", "foo/bar"))
340*bcb5dc79SHONG Yifan    asserts.true(env, paths.starts_with("foo/bar/baz", "foo"))
341*bcb5dc79SHONG Yifan
342*bcb5dc79SHONG Yifan    # Try a case where a parent directory is normalized away.
343*bcb5dc79SHONG Yifan    asserts.true(env, paths.starts_with("foo/bar/../baz", "foo"))
344*bcb5dc79SHONG Yifan
345*bcb5dc79SHONG Yifan    # Relative paths work, as long as they share a common start.
346*bcb5dc79SHONG Yifan    asserts.true(env, paths.starts_with("../foo/bar/baz/file", "../foo/bar/baz"))
347*bcb5dc79SHONG Yifan    asserts.true(env, paths.starts_with("../foo/bar/baz/file", "../foo/bar"))
348*bcb5dc79SHONG Yifan
349*bcb5dc79SHONG Yifan    return unittest.end(env)
350*bcb5dc79SHONG Yifan
351*bcb5dc79SHONG Yifanstarts_with_test = unittest.make(_starts_with_test)
352*bcb5dc79SHONG Yifan
353*bcb5dc79SHONG Yifandef paths_test_suite():
354*bcb5dc79SHONG Yifan    """Creates the test targets and test suite for paths.bzl tests."""
355*bcb5dc79SHONG Yifan    unittest.suite(
356*bcb5dc79SHONG Yifan        "paths_tests",
357*bcb5dc79SHONG Yifan        basename_test,
358*bcb5dc79SHONG Yifan        dirname_test,
359*bcb5dc79SHONG Yifan        is_absolute_test,
360*bcb5dc79SHONG Yifan        join_test,
361*bcb5dc79SHONG Yifan        normalize_test,
362*bcb5dc79SHONG Yifan        is_normalized_test,
363*bcb5dc79SHONG Yifan        relativize_test,
364*bcb5dc79SHONG Yifan        replace_extension_test,
365*bcb5dc79SHONG Yifan        split_extension_test,
366*bcb5dc79SHONG Yifan        starts_with_test,
367*bcb5dc79SHONG Yifan    )
368