xref: /aosp_15_r20/external/cronet/base/files/file_path_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <sstream>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/files/safe_base_name.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_ostream_operators.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
14*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
15*6777b538SAndroid Build Coastguard Worker #include "build/buildflag.h"
16*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
17*6777b538SAndroid Build Coastguard Worker #include "testing/platform_test.h"
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING)
20*6777b538SAndroid Build Coastguard Worker #include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h"  // no-presubmit-check nogncheck
21*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
24*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_locale.h"
25*6777b538SAndroid Build Coastguard Worker #endif
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker // This macro helps test `FILE_PATH_LITERAL` macro expansion.
28*6777b538SAndroid Build Coastguard Worker #define TEST_FILE "TestFile"
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker // This macro helps avoid wrapped lines in the test structs.
31*6777b538SAndroid Build Coastguard Worker #define FPL(x) FILE_PATH_LITERAL(x)
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker // This macro constructs strings which can contain NULs.
34*6777b538SAndroid Build Coastguard Worker #define FPS(x) FilePath::StringType(FPL(x), std::size(FPL(x)) - 1)
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker namespace base {
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker struct UnaryTestData {
39*6777b538SAndroid Build Coastguard Worker   FilePath::StringPieceType input;
40*6777b538SAndroid Build Coastguard Worker   FilePath::StringPieceType expected;
41*6777b538SAndroid Build Coastguard Worker };
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker struct UnaryBooleanTestData {
44*6777b538SAndroid Build Coastguard Worker   FilePath::StringPieceType input;
45*6777b538SAndroid Build Coastguard Worker   bool expected;
46*6777b538SAndroid Build Coastguard Worker };
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker struct BinaryTestData {
49*6777b538SAndroid Build Coastguard Worker   FilePath::StringPieceType inputs[2];
50*6777b538SAndroid Build Coastguard Worker   FilePath::StringPieceType expected;
51*6777b538SAndroid Build Coastguard Worker };
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker struct BinaryBooleanTestData {
54*6777b538SAndroid Build Coastguard Worker   FilePath::StringPieceType inputs[2];
55*6777b538SAndroid Build Coastguard Worker   bool expected;
56*6777b538SAndroid Build Coastguard Worker };
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker struct BinaryIntTestData {
59*6777b538SAndroid Build Coastguard Worker   FilePath::StringPieceType inputs[2];
60*6777b538SAndroid Build Coastguard Worker   int expected;
61*6777b538SAndroid Build Coastguard Worker };
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker struct UTF8TestData {
64*6777b538SAndroid Build Coastguard Worker   FilePath::StringPieceType native;
65*6777b538SAndroid Build Coastguard Worker   StringPiece utf8;
66*6777b538SAndroid Build Coastguard Worker };
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker // file_util winds up using autoreleased objects on the Mac, so this needs
69*6777b538SAndroid Build Coastguard Worker // to be a PlatformTest
70*6777b538SAndroid Build Coastguard Worker typedef PlatformTest FilePathTest;
71*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,DirName)72*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, DirName) {
73*6777b538SAndroid Build Coastguard Worker   const struct UnaryTestData cases[] = {
74*6777b538SAndroid Build Coastguard Worker     {FPL(""), FPL(".")},
75*6777b538SAndroid Build Coastguard Worker     {FPL("aa"), FPL(".")},
76*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/bb"), FPL("/aa")},
77*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/bb/"), FPL("/aa")},
78*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/bb//"), FPL("/aa")},
79*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/bb/ccc"), FPL("/aa/bb")},
80*6777b538SAndroid Build Coastguard Worker     {FPL("/aa"), FPL("/")},
81*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/"), FPL("/")},
82*6777b538SAndroid Build Coastguard Worker     {FPL("/"), FPL("/")},
83*6777b538SAndroid Build Coastguard Worker     {FPL("//"), FPL("//")},
84*6777b538SAndroid Build Coastguard Worker     {FPL("///"), FPL("/")},
85*6777b538SAndroid Build Coastguard Worker     {FPL("aa/"), FPL(".")},
86*6777b538SAndroid Build Coastguard Worker     {FPL("aa/bb"), FPL("aa")},
87*6777b538SAndroid Build Coastguard Worker     {FPL("aa/bb/"), FPL("aa")},
88*6777b538SAndroid Build Coastguard Worker     {FPL("aa/bb//"), FPL("aa")},
89*6777b538SAndroid Build Coastguard Worker     {FPL("aa//bb//"), FPL("aa")},
90*6777b538SAndroid Build Coastguard Worker     {FPL("aa//bb/"), FPL("aa")},
91*6777b538SAndroid Build Coastguard Worker     {FPL("aa//bb"), FPL("aa")},
92*6777b538SAndroid Build Coastguard Worker     {FPL("//aa/bb"), FPL("//aa")},
93*6777b538SAndroid Build Coastguard Worker     {FPL("//aa/"), FPL("//")},
94*6777b538SAndroid Build Coastguard Worker     {FPL("//aa"), FPL("//")},
95*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX)
96*6777b538SAndroid Build Coastguard Worker     {FPL("///aa/"), FPL("/")},
97*6777b538SAndroid Build Coastguard Worker     {FPL("///aa"), FPL("/")},
98*6777b538SAndroid Build Coastguard Worker     {FPL("///"), FPL("/")},
99*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX)
100*6777b538SAndroid Build Coastguard Worker     {FPL("0:"), FPL(".")},
101*6777b538SAndroid Build Coastguard Worker     {FPL("@:"), FPL(".")},
102*6777b538SAndroid Build Coastguard Worker     {FPL("[:"), FPL(".")},
103*6777b538SAndroid Build Coastguard Worker     {FPL("`:"), FPL(".")},
104*6777b538SAndroid Build Coastguard Worker     {FPL("{:"), FPL(".")},
105*6777b538SAndroid Build Coastguard Worker     {FPL("\xB3:"), FPL(".")},
106*6777b538SAndroid Build Coastguard Worker     {FPL("\xC5:"), FPL(".")},
107*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/../bb/cc"), FPL("/aa/../bb")},
108*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
109*6777b538SAndroid Build Coastguard Worker     {FPL("\x0143:"), FPL(".")},
110*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
111*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
112*6777b538SAndroid Build Coastguard Worker     {FPL("c:"), FPL("c:")},
113*6777b538SAndroid Build Coastguard Worker     {FPL("C:"), FPL("C:")},
114*6777b538SAndroid Build Coastguard Worker     {FPL("A:"), FPL("A:")},
115*6777b538SAndroid Build Coastguard Worker     {FPL("Z:"), FPL("Z:")},
116*6777b538SAndroid Build Coastguard Worker     {FPL("a:"), FPL("a:")},
117*6777b538SAndroid Build Coastguard Worker     {FPL("z:"), FPL("z:")},
118*6777b538SAndroid Build Coastguard Worker     {FPL("c:aa"), FPL("c:")},
119*6777b538SAndroid Build Coastguard Worker     {FPL("c:/"), FPL("c:/")},
120*6777b538SAndroid Build Coastguard Worker     {FPL("c://"), FPL("c://")},
121*6777b538SAndroid Build Coastguard Worker     {FPL("c:///"), FPL("c:/")},
122*6777b538SAndroid Build Coastguard Worker     {FPL("c:/aa"), FPL("c:/")},
123*6777b538SAndroid Build Coastguard Worker     {FPL("c:/aa/"), FPL("c:/")},
124*6777b538SAndroid Build Coastguard Worker     {FPL("c:/aa/bb"), FPL("c:/aa")},
125*6777b538SAndroid Build Coastguard Worker     {FPL("c:aa/bb"), FPL("c:aa")},
126*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
127*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
128*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\bb"), FPL("\\aa")},
129*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\bb\\"), FPL("\\aa")},
130*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\bb\\\\"), FPL("\\aa")},
131*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\bb\\ccc"), FPL("\\aa\\bb")},
132*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa"), FPL("\\")},
133*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\"), FPL("\\")},
134*6777b538SAndroid Build Coastguard Worker     {FPL("\\"), FPL("\\")},
135*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\"), FPL("\\\\")},
136*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\\\"), FPL("\\")},
137*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\"), FPL(".")},
138*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\bb"), FPL("aa")},
139*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\bb\\"), FPL("aa")},
140*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\bb\\\\"), FPL("aa")},
141*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\\\bb\\\\"), FPL("aa")},
142*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\\\bb\\"), FPL("aa")},
143*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\\\bb"), FPL("aa")},
144*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\aa\\bb"), FPL("\\\\aa")},
145*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\aa\\"), FPL("\\\\")},
146*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\aa"), FPL("\\\\")},
147*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\..\\bb\\c"), FPL("aa\\..\\bb")},
148*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
149*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\"), FPL("c:\\")},
150*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\\\"), FPL("c:\\\\")},
151*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\\\\\"), FPL("c:\\")},
152*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\aa"), FPL("c:\\")},
153*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\aa\\"), FPL("c:\\")},
154*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\aa\\bb"), FPL("c:\\aa")},
155*6777b538SAndroid Build Coastguard Worker     {FPL("c:aa\\bb"), FPL("c:aa")},
156*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
157*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
158*6777b538SAndroid Build Coastguard Worker   };
159*6777b538SAndroid Build Coastguard Worker 
160*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
161*6777b538SAndroid Build Coastguard Worker     FilePath input(cases[i].input);
162*6777b538SAndroid Build Coastguard Worker     FilePath observed = input.DirName();
163*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].expected), observed.value()) <<
164*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
165*6777b538SAndroid Build Coastguard Worker   }
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,BaseName)168*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, BaseName) {
169*6777b538SAndroid Build Coastguard Worker   const struct UnaryTestData cases[] = {
170*6777b538SAndroid Build Coastguard Worker     {FPL(""), FPL("")},
171*6777b538SAndroid Build Coastguard Worker     {FPL("aa"), FPL("aa")},
172*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/bb"), FPL("bb")},
173*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/bb/"), FPL("bb")},
174*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/bb//"), FPL("bb")},
175*6777b538SAndroid Build Coastguard Worker     {FPL("/aa/bb/ccc"), FPL("ccc")},
176*6777b538SAndroid Build Coastguard Worker     {FPL("/aa"), FPL("aa")},
177*6777b538SAndroid Build Coastguard Worker     {FPL("/"), FPL("/")},
178*6777b538SAndroid Build Coastguard Worker     {FPL("//"), FPL("//")},
179*6777b538SAndroid Build Coastguard Worker     {FPL("///"), FPL("/")},
180*6777b538SAndroid Build Coastguard Worker     {FPL("aa/"), FPL("aa")},
181*6777b538SAndroid Build Coastguard Worker     {FPL("aa/bb"), FPL("bb")},
182*6777b538SAndroid Build Coastguard Worker     {FPL("aa/bb/"), FPL("bb")},
183*6777b538SAndroid Build Coastguard Worker     {FPL("aa/bb//"), FPL("bb")},
184*6777b538SAndroid Build Coastguard Worker     {FPL("aa//bb//"), FPL("bb")},
185*6777b538SAndroid Build Coastguard Worker     {FPL("aa//bb/"), FPL("bb")},
186*6777b538SAndroid Build Coastguard Worker     {FPL("aa//bb"), FPL("bb")},
187*6777b538SAndroid Build Coastguard Worker     {FPL("//aa/bb"), FPL("bb")},
188*6777b538SAndroid Build Coastguard Worker     {FPL("//aa/"), FPL("aa")},
189*6777b538SAndroid Build Coastguard Worker     {FPL("//aa"), FPL("aa")},
190*6777b538SAndroid Build Coastguard Worker     {FPL("0:"), FPL("0:")},
191*6777b538SAndroid Build Coastguard Worker     {FPL("@:"), FPL("@:")},
192*6777b538SAndroid Build Coastguard Worker     {FPL("[:"), FPL("[:")},
193*6777b538SAndroid Build Coastguard Worker     {FPL("`:"), FPL("`:")},
194*6777b538SAndroid Build Coastguard Worker     {FPL("{:"), FPL("{:")},
195*6777b538SAndroid Build Coastguard Worker     {FPL("\xB3:"), FPL("\xB3:")},
196*6777b538SAndroid Build Coastguard Worker     {FPL("\xC5:"), FPL("\xC5:")},
197*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
198*6777b538SAndroid Build Coastguard Worker     {FPL("\x0143:"), FPL("\x0143:")},
199*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
200*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
201*6777b538SAndroid Build Coastguard Worker     {FPL("c:"), FPL("")},
202*6777b538SAndroid Build Coastguard Worker     {FPL("C:"), FPL("")},
203*6777b538SAndroid Build Coastguard Worker     {FPL("A:"), FPL("")},
204*6777b538SAndroid Build Coastguard Worker     {FPL("Z:"), FPL("")},
205*6777b538SAndroid Build Coastguard Worker     {FPL("a:"), FPL("")},
206*6777b538SAndroid Build Coastguard Worker     {FPL("z:"), FPL("")},
207*6777b538SAndroid Build Coastguard Worker     {FPL("c:aa"), FPL("aa")},
208*6777b538SAndroid Build Coastguard Worker     {FPL("c:/"), FPL("/")},
209*6777b538SAndroid Build Coastguard Worker     {FPL("c://"), FPL("//")},
210*6777b538SAndroid Build Coastguard Worker     {FPL("c:///"), FPL("/")},
211*6777b538SAndroid Build Coastguard Worker     {FPL("c:/aa"), FPL("aa")},
212*6777b538SAndroid Build Coastguard Worker     {FPL("c:/aa/"), FPL("aa")},
213*6777b538SAndroid Build Coastguard Worker     {FPL("c:/aa/bb"), FPL("bb")},
214*6777b538SAndroid Build Coastguard Worker     {FPL("c:aa/bb"), FPL("bb")},
215*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
216*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
217*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\bb"), FPL("bb")},
218*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\bb\\"), FPL("bb")},
219*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\bb\\\\"), FPL("bb")},
220*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa\\bb\\ccc"), FPL("ccc")},
221*6777b538SAndroid Build Coastguard Worker     {FPL("\\aa"), FPL("aa")},
222*6777b538SAndroid Build Coastguard Worker     {FPL("\\"), FPL("\\")},
223*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\"), FPL("\\\\")},
224*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\\\"), FPL("\\")},
225*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\"), FPL("aa")},
226*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\bb"), FPL("bb")},
227*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\bb\\"), FPL("bb")},
228*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\bb\\\\"), FPL("bb")},
229*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\\\bb\\\\"), FPL("bb")},
230*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\\\bb\\"), FPL("bb")},
231*6777b538SAndroid Build Coastguard Worker     {FPL("aa\\\\bb"), FPL("bb")},
232*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\aa\\bb"), FPL("bb")},
233*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\aa\\"), FPL("aa")},
234*6777b538SAndroid Build Coastguard Worker     {FPL("\\\\aa"), FPL("aa")},
235*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
236*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\"), FPL("\\")},
237*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\\\"), FPL("\\\\")},
238*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\\\\\"), FPL("\\")},
239*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\aa"), FPL("aa")},
240*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\aa\\"), FPL("aa")},
241*6777b538SAndroid Build Coastguard Worker     {FPL("c:\\aa\\bb"), FPL("bb")},
242*6777b538SAndroid Build Coastguard Worker     {FPL("c:aa\\bb"), FPL("bb")},
243*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
244*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
245*6777b538SAndroid Build Coastguard Worker   };
246*6777b538SAndroid Build Coastguard Worker 
247*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
248*6777b538SAndroid Build Coastguard Worker     FilePath input(cases[i].input);
249*6777b538SAndroid Build Coastguard Worker     FilePath observed = input.BaseName();
250*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].expected), observed.value()) <<
251*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
252*6777b538SAndroid Build Coastguard Worker   }
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,Append)255*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, Append) {
256*6777b538SAndroid Build Coastguard Worker   const struct BinaryTestData cases[] = {
257*6777b538SAndroid Build Coastguard Worker     { { FPL(""),           FPL("cc") }, FPL("cc") },
258*6777b538SAndroid Build Coastguard Worker     { { FPL("."),          FPL("ff") }, FPL("ff") },
259*6777b538SAndroid Build Coastguard Worker     { { FPL("."),          FPL("") },   FPL(".") },
260*6777b538SAndroid Build Coastguard Worker     { { FPL("/"),          FPL("cc") }, FPL("/cc") },
261*6777b538SAndroid Build Coastguard Worker     { { FPL("/aa"),        FPL("") },   FPL("/aa") },
262*6777b538SAndroid Build Coastguard Worker     { { FPL("/aa/"),       FPL("") },   FPL("/aa") },
263*6777b538SAndroid Build Coastguard Worker     { { FPL("//aa"),       FPL("") },   FPL("//aa") },
264*6777b538SAndroid Build Coastguard Worker     { { FPL("//aa/"),      FPL("") },   FPL("//aa") },
265*6777b538SAndroid Build Coastguard Worker     { { FPL("//"),         FPL("aa") }, FPL("//aa") },
266*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
267*6777b538SAndroid Build Coastguard Worker     { { FPL("c:"),         FPL("a") },  FPL("c:a") },
268*6777b538SAndroid Build Coastguard Worker     { { FPL("c:"),         FPL("") },   FPL("c:") },
269*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/"),        FPL("a") },  FPL("c:/a") },
270*6777b538SAndroid Build Coastguard Worker     { { FPL("c://"),       FPL("a") },  FPL("c://a") },
271*6777b538SAndroid Build Coastguard Worker     { { FPL("c:///"),      FPL("a") },  FPL("c:/a") },
272*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
273*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
274*6777b538SAndroid Build Coastguard Worker     // Append introduces the default separator character, so these test cases
275*6777b538SAndroid Build Coastguard Worker     // need to be defined with different expected results on platforms that use
276*6777b538SAndroid Build Coastguard Worker     // different default separator characters.
277*6777b538SAndroid Build Coastguard Worker     { { FPL("\\"),         FPL("cc") }, FPL("\\cc") },
278*6777b538SAndroid Build Coastguard Worker     { { FPL("\\aa"),       FPL("") },   FPL("\\aa") },
279*6777b538SAndroid Build Coastguard Worker     { { FPL("\\aa\\"),     FPL("") },   FPL("\\aa") },
280*6777b538SAndroid Build Coastguard Worker     { { FPL("\\\\aa"),     FPL("") },   FPL("\\\\aa") },
281*6777b538SAndroid Build Coastguard Worker     { { FPL("\\\\aa\\"),   FPL("") },   FPL("\\\\aa") },
282*6777b538SAndroid Build Coastguard Worker     { { FPL("\\\\"),       FPL("aa") }, FPL("\\\\aa") },
283*6777b538SAndroid Build Coastguard Worker     { { FPL("/aa/bb"),     FPL("cc") }, FPL("/aa/bb\\cc") },
284*6777b538SAndroid Build Coastguard Worker     { { FPL("/aa/bb/"),    FPL("cc") }, FPL("/aa/bb\\cc") },
285*6777b538SAndroid Build Coastguard Worker     { { FPL("aa/bb/"),     FPL("cc") }, FPL("aa/bb\\cc") },
286*6777b538SAndroid Build Coastguard Worker     { { FPL("aa/bb"),      FPL("cc") }, FPL("aa/bb\\cc") },
287*6777b538SAndroid Build Coastguard Worker     { { FPL("a/b"),        FPL("c") },  FPL("a/b\\c") },
288*6777b538SAndroid Build Coastguard Worker     { { FPL("a/b/"),       FPL("c") },  FPL("a/b\\c") },
289*6777b538SAndroid Build Coastguard Worker     { { FPL("//aa"),       FPL("bb") }, FPL("//aa\\bb") },
290*6777b538SAndroid Build Coastguard Worker     { { FPL("//aa/"),      FPL("bb") }, FPL("//aa\\bb") },
291*6777b538SAndroid Build Coastguard Worker     { { FPL("\\aa\\bb"),   FPL("cc") }, FPL("\\aa\\bb\\cc") },
292*6777b538SAndroid Build Coastguard Worker     { { FPL("\\aa\\bb\\"), FPL("cc") }, FPL("\\aa\\bb\\cc") },
293*6777b538SAndroid Build Coastguard Worker     { { FPL("aa\\bb\\"),   FPL("cc") }, FPL("aa\\bb\\cc") },
294*6777b538SAndroid Build Coastguard Worker     { { FPL("aa\\bb"),     FPL("cc") }, FPL("aa\\bb\\cc") },
295*6777b538SAndroid Build Coastguard Worker     { { FPL("a\\b"),       FPL("c") },  FPL("a\\b\\c") },
296*6777b538SAndroid Build Coastguard Worker     { { FPL("a\\b\\"),     FPL("c") },  FPL("a\\b\\c") },
297*6777b538SAndroid Build Coastguard Worker     { { FPL("\\\\aa"),     FPL("bb") }, FPL("\\\\aa\\bb") },
298*6777b538SAndroid Build Coastguard Worker     { { FPL("\\\\aa\\"),   FPL("bb") }, FPL("\\\\aa\\bb") },
299*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
300*6777b538SAndroid Build Coastguard Worker     { { FPL("c:\\"),       FPL("a") },  FPL("c:\\a") },
301*6777b538SAndroid Build Coastguard Worker     { { FPL("c:\\\\"),     FPL("a") },  FPL("c:\\\\a") },
302*6777b538SAndroid Build Coastguard Worker     { { FPL("c:\\\\\\"),   FPL("a") },  FPL("c:\\a") },
303*6777b538SAndroid Build Coastguard Worker     { { FPL("c:\\"),       FPL("") },   FPL("c:\\") },
304*6777b538SAndroid Build Coastguard Worker     { { FPL("c:\\a"),      FPL("b") },  FPL("c:\\a\\b") },
305*6777b538SAndroid Build Coastguard Worker     { { FPL("c:\\a\\"),    FPL("b") },  FPL("c:\\a\\b") },
306*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
307*6777b538SAndroid Build Coastguard Worker #else  // FILE_PATH_USES_WIN_SEPARATORS
308*6777b538SAndroid Build Coastguard Worker     { { FPL("/aa/bb"),     FPL("cc") }, FPL("/aa/bb/cc") },
309*6777b538SAndroid Build Coastguard Worker     { { FPL("/aa/bb/"),    FPL("cc") }, FPL("/aa/bb/cc") },
310*6777b538SAndroid Build Coastguard Worker     { { FPL("aa/bb/"),     FPL("cc") }, FPL("aa/bb/cc") },
311*6777b538SAndroid Build Coastguard Worker     { { FPL("aa/bb"),      FPL("cc") }, FPL("aa/bb/cc") },
312*6777b538SAndroid Build Coastguard Worker     { { FPL("a/b"),        FPL("c") },  FPL("a/b/c") },
313*6777b538SAndroid Build Coastguard Worker     { { FPL("a/b/"),       FPL("c") },  FPL("a/b/c") },
314*6777b538SAndroid Build Coastguard Worker     { { FPL("//aa"),       FPL("bb") }, FPL("//aa/bb") },
315*6777b538SAndroid Build Coastguard Worker     { { FPL("//aa/"),      FPL("bb") }, FPL("//aa/bb") },
316*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
317*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/"),        FPL("a") },  FPL("c:/a") },
318*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/"),        FPL("") },   FPL("c:/") },
319*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/a"),       FPL("b") },  FPL("c:/a/b") },
320*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/a/"),      FPL("b") },  FPL("c:/a/b") },
321*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
322*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
323*6777b538SAndroid Build Coastguard Worker   };
324*6777b538SAndroid Build Coastguard Worker 
325*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
326*6777b538SAndroid Build Coastguard Worker     FilePath root(cases[i].inputs[0]);
327*6777b538SAndroid Build Coastguard Worker     FilePath::StringType leaf(cases[i].inputs[1]);
328*6777b538SAndroid Build Coastguard Worker     FilePath observed_str = root.Append(leaf);
329*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].expected), observed_str.value()) <<
330*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", root: " << root.value() << ", leaf: " << leaf;
331*6777b538SAndroid Build Coastguard Worker     FilePath observed_path = root.Append(FilePath(leaf));
332*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].expected), observed_path.value()) <<
333*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", root: " << root.value() << ", leaf: " << leaf;
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker     // TODO(erikkay): It would be nice to have a unicode test append value to
336*6777b538SAndroid Build Coastguard Worker     // handle the case when AppendASCII is passed UTF8
337*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
338*6777b538SAndroid Build Coastguard Worker     std::string ascii = WideToUTF8(leaf);
339*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
340*6777b538SAndroid Build Coastguard Worker     std::string ascii = leaf;
341*6777b538SAndroid Build Coastguard Worker #endif
342*6777b538SAndroid Build Coastguard Worker     observed_str = root.AppendASCII(ascii);
343*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].expected), observed_str.value()) <<
344*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", root: " << root.value() << ", leaf: " << leaf;
345*6777b538SAndroid Build Coastguard Worker   }
346*6777b538SAndroid Build Coastguard Worker }
347*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,StripTrailingSeparators)348*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, StripTrailingSeparators) {
349*6777b538SAndroid Build Coastguard Worker   const struct UnaryTestData cases[] = {
350*6777b538SAndroid Build Coastguard Worker     { FPL(""),              FPL("") },
351*6777b538SAndroid Build Coastguard Worker     { FPL("/"),             FPL("/") },
352*6777b538SAndroid Build Coastguard Worker     { FPL("//"),            FPL("//") },
353*6777b538SAndroid Build Coastguard Worker     { FPL("///"),           FPL("/") },
354*6777b538SAndroid Build Coastguard Worker     { FPL("////"),          FPL("/") },
355*6777b538SAndroid Build Coastguard Worker     { FPL("a/"),            FPL("a") },
356*6777b538SAndroid Build Coastguard Worker     { FPL("a//"),           FPL("a") },
357*6777b538SAndroid Build Coastguard Worker     { FPL("a///"),          FPL("a") },
358*6777b538SAndroid Build Coastguard Worker     { FPL("a////"),         FPL("a") },
359*6777b538SAndroid Build Coastguard Worker     { FPL("/a"),            FPL("/a") },
360*6777b538SAndroid Build Coastguard Worker     { FPL("/a/"),           FPL("/a") },
361*6777b538SAndroid Build Coastguard Worker     { FPL("/a//"),          FPL("/a") },
362*6777b538SAndroid Build Coastguard Worker     { FPL("/a///"),         FPL("/a") },
363*6777b538SAndroid Build Coastguard Worker     { FPL("/a////"),        FPL("/a") },
364*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
365*6777b538SAndroid Build Coastguard Worker     { FPL("c:"),            FPL("c:") },
366*6777b538SAndroid Build Coastguard Worker     { FPL("c:/"),           FPL("c:/") },
367*6777b538SAndroid Build Coastguard Worker     { FPL("c://"),          FPL("c://") },
368*6777b538SAndroid Build Coastguard Worker     { FPL("c:///"),         FPL("c:/") },
369*6777b538SAndroid Build Coastguard Worker     { FPL("c:////"),        FPL("c:/") },
370*6777b538SAndroid Build Coastguard Worker     { FPL("c:/a"),          FPL("c:/a") },
371*6777b538SAndroid Build Coastguard Worker     { FPL("c:/a/"),         FPL("c:/a") },
372*6777b538SAndroid Build Coastguard Worker     { FPL("c:/a//"),        FPL("c:/a") },
373*6777b538SAndroid Build Coastguard Worker     { FPL("c:/a///"),       FPL("c:/a") },
374*6777b538SAndroid Build Coastguard Worker     { FPL("c:/a////"),      FPL("c:/a") },
375*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
376*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
377*6777b538SAndroid Build Coastguard Worker     { FPL("\\"),            FPL("\\") },
378*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\"),          FPL("\\\\") },
379*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\\\"),        FPL("\\") },
380*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\\\\\"),      FPL("\\") },
381*6777b538SAndroid Build Coastguard Worker     { FPL("a\\"),           FPL("a") },
382*6777b538SAndroid Build Coastguard Worker     { FPL("a\\\\"),         FPL("a") },
383*6777b538SAndroid Build Coastguard Worker     { FPL("a\\\\\\"),       FPL("a") },
384*6777b538SAndroid Build Coastguard Worker     { FPL("a\\\\\\\\"),     FPL("a") },
385*6777b538SAndroid Build Coastguard Worker     { FPL("\\a"),           FPL("\\a") },
386*6777b538SAndroid Build Coastguard Worker     { FPL("\\a\\"),         FPL("\\a") },
387*6777b538SAndroid Build Coastguard Worker     { FPL("\\a\\\\"),       FPL("\\a") },
388*6777b538SAndroid Build Coastguard Worker     { FPL("\\a\\\\\\"),     FPL("\\a") },
389*6777b538SAndroid Build Coastguard Worker     { FPL("\\a\\\\\\\\"),   FPL("\\a") },
390*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
391*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\"),          FPL("c:\\") },
392*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\\\"),        FPL("c:\\\\") },
393*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\\\\\"),      FPL("c:\\") },
394*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\\\\\\\"),    FPL("c:\\") },
395*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\a"),         FPL("c:\\a") },
396*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\a\\"),       FPL("c:\\a") },
397*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\a\\\\"),     FPL("c:\\a") },
398*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\a\\\\\\"),   FPL("c:\\a") },
399*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\a\\\\\\\\"), FPL("c:\\a") },
400*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
401*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
402*6777b538SAndroid Build Coastguard Worker   };
403*6777b538SAndroid Build Coastguard Worker 
404*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
405*6777b538SAndroid Build Coastguard Worker     FilePath input(cases[i].input);
406*6777b538SAndroid Build Coastguard Worker     FilePath observed = input.StripTrailingSeparators();
407*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].expected), observed.value()) <<
408*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
409*6777b538SAndroid Build Coastguard Worker   }
410*6777b538SAndroid Build Coastguard Worker }
411*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,IsAbsoluteOrNetwork)412*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, IsAbsoluteOrNetwork) {
413*6777b538SAndroid Build Coastguard Worker   const struct {
414*6777b538SAndroid Build Coastguard Worker     FilePath::StringPieceType input;
415*6777b538SAndroid Build Coastguard Worker     bool expected_is_absolute;
416*6777b538SAndroid Build Coastguard Worker     bool expected_is_network;
417*6777b538SAndroid Build Coastguard Worker   } cases[] = {
418*6777b538SAndroid Build Coastguard Worker     { FPL(""),       false, false },
419*6777b538SAndroid Build Coastguard Worker     { FPL("a"),      false, false },
420*6777b538SAndroid Build Coastguard Worker     { FPL("c:"),     false, false },
421*6777b538SAndroid Build Coastguard Worker     { FPL("c:a"),    false, false },
422*6777b538SAndroid Build Coastguard Worker     { FPL("a/b"),    false, false },
423*6777b538SAndroid Build Coastguard Worker     { FPL("//"),     true,  true },
424*6777b538SAndroid Build Coastguard Worker     { FPL("//a"),    true,  true },
425*6777b538SAndroid Build Coastguard Worker     { FPL("c:a/b"),  false, false },
426*6777b538SAndroid Build Coastguard Worker     { FPL("?:/a"),   false, false },
427*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
428*6777b538SAndroid Build Coastguard Worker     { FPL("/"),      false, false },
429*6777b538SAndroid Build Coastguard Worker     { FPL("/a"),     false, false },
430*6777b538SAndroid Build Coastguard Worker     { FPL("/."),     false, false },
431*6777b538SAndroid Build Coastguard Worker     { FPL("/.."),    false, false },
432*6777b538SAndroid Build Coastguard Worker     { FPL("c:/"),    true,  false },
433*6777b538SAndroid Build Coastguard Worker     { FPL("c:/a"),   true,  false },
434*6777b538SAndroid Build Coastguard Worker     { FPL("c:/."),   true,  false },
435*6777b538SAndroid Build Coastguard Worker     { FPL("c:/.."),  true,  false },
436*6777b538SAndroid Build Coastguard Worker     { FPL("C:/a"),   true,  false },
437*6777b538SAndroid Build Coastguard Worker     { FPL("d:/a"),   true,  false },
438*6777b538SAndroid Build Coastguard Worker #else  // FILE_PATH_USES_DRIVE_LETTERS
439*6777b538SAndroid Build Coastguard Worker     { FPL("/"),      true,  false },
440*6777b538SAndroid Build Coastguard Worker     { FPL("/a"),     true,  false },
441*6777b538SAndroid Build Coastguard Worker     { FPL("/."),     true,  false },
442*6777b538SAndroid Build Coastguard Worker     { FPL("/.."),    true,  false },
443*6777b538SAndroid Build Coastguard Worker     { FPL("c:/"),    false, false },
444*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
445*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
446*6777b538SAndroid Build Coastguard Worker     { FPL("a\\b"),   false, false },
447*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\"),   true,  true },
448*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\a"),  true,  true },
449*6777b538SAndroid Build Coastguard Worker     { FPL("a\\b"),   false, false },
450*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\"),   true,  true },
451*6777b538SAndroid Build Coastguard Worker     { FPL("//a"),    true,  true },
452*6777b538SAndroid Build Coastguard Worker     { FPL("c:a\\b"), false, false },
453*6777b538SAndroid Build Coastguard Worker     { FPL("?:\\a"),  false, false },
454*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
455*6777b538SAndroid Build Coastguard Worker     { FPL("\\"),     false, false },
456*6777b538SAndroid Build Coastguard Worker     { FPL("\\a"),    false, false },
457*6777b538SAndroid Build Coastguard Worker     { FPL("\\."),    false, false },
458*6777b538SAndroid Build Coastguard Worker     { FPL("\\.."),   false, false },
459*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\"),   true,  false },
460*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\"),   true,  false },
461*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\a"),  true,  false },
462*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\."),  true,  false },
463*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\.."), true,  false },
464*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\a"),  true,  false },
465*6777b538SAndroid Build Coastguard Worker     { FPL("d:\\a"),  true,  false },
466*6777b538SAndroid Build Coastguard Worker #else  // FILE_PATH_USES_DRIVE_LETTERS
467*6777b538SAndroid Build Coastguard Worker     { FPL("\\"),     true,  false },
468*6777b538SAndroid Build Coastguard Worker     { FPL("\\a"),    true,  false },
469*6777b538SAndroid Build Coastguard Worker     { FPL("\\."),    true,  false },
470*6777b538SAndroid Build Coastguard Worker     { FPL("\\.."),   true,  false },
471*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\"),   false, false },
472*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
473*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
474*6777b538SAndroid Build Coastguard Worker   };
475*6777b538SAndroid Build Coastguard Worker 
476*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
477*6777b538SAndroid Build Coastguard Worker     FilePath input(cases[i].input);
478*6777b538SAndroid Build Coastguard Worker     bool observed_is_absolute = input.IsAbsolute();
479*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected_is_absolute, observed_is_absolute) <<
480*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
481*6777b538SAndroid Build Coastguard Worker     bool observed_is_network = input.IsNetwork();
482*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected_is_network, observed_is_network) <<
483*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
484*6777b538SAndroid Build Coastguard Worker   }
485*6777b538SAndroid Build Coastguard Worker }
486*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,PathComponentsTest)487*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, PathComponentsTest) {
488*6777b538SAndroid Build Coastguard Worker   const struct UnaryTestData cases[] = {
489*6777b538SAndroid Build Coastguard Worker     { FPL("//foo/bar/baz/"),          FPL("|//|foo|bar|baz")},
490*6777b538SAndroid Build Coastguard Worker     { FPL("///"),                     FPL("|/")},
491*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX)
492*6777b538SAndroid Build Coastguard Worker     {FPL("///foo//bar/baz"),          FPL("|/|foo|bar|baz")},
493*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX)
494*6777b538SAndroid Build Coastguard Worker     { FPL("/foo//bar//baz/"),         FPL("|/|foo|bar|baz")},
495*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz/"),           FPL("|/|foo|bar|baz")},
496*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz//"),          FPL("|/|foo|bar|baz")},
497*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz///"),         FPL("|/|foo|bar|baz")},
498*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz"),            FPL("|/|foo|bar|baz")},
499*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar.bot/baz.txt"),    FPL("|/|foo|bar.bot|baz.txt")},
500*6777b538SAndroid Build Coastguard Worker     { FPL("//foo//bar/baz"),          FPL("|//|foo|bar|baz")},
501*6777b538SAndroid Build Coastguard Worker     { FPL("/"),                       FPL("|/")},
502*6777b538SAndroid Build Coastguard Worker     { FPL("foo"),                     FPL("|foo")},
503*6777b538SAndroid Build Coastguard Worker     { FPL(""),                        FPL("")},
504*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
505*6777b538SAndroid Build Coastguard Worker     { FPL("e:/foo"),                  FPL("|e:|/|foo")},
506*6777b538SAndroid Build Coastguard Worker     { FPL("e:/"),                     FPL("|e:|/")},
507*6777b538SAndroid Build Coastguard Worker     { FPL("e:"),                      FPL("|e:")},
508*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
509*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
510*6777b538SAndroid Build Coastguard Worker     { FPL("../foo"),                  FPL("|..|foo")},
511*6777b538SAndroid Build Coastguard Worker     { FPL("./foo"),                   FPL("|foo")},
512*6777b538SAndroid Build Coastguard Worker     { FPL("../foo/bar/"),             FPL("|..|foo|bar") },
513*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\foo\\bar\\baz\\"),     FPL("|\\\\|foo|bar|baz")},
514*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\\\"),                  FPL("|\\")},
515*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo\\\\bar\\\\baz\\"),   FPL("|\\|foo|bar|baz")},
516*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo\\bar\\baz\\"),       FPL("|\\|foo|bar|baz")},
517*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo\\bar\\baz\\\\"),     FPL("|\\|foo|bar|baz")},
518*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo\\bar\\baz\\\\\\"),   FPL("|\\|foo|bar|baz")},
519*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo\\bar\\baz"),         FPL("|\\|foo|bar|baz")},
520*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo\\bar/baz\\\\\\"),    FPL("|\\|foo|bar|baz")},
521*6777b538SAndroid Build Coastguard Worker     { FPL("/foo\\bar\\baz"),          FPL("|/|foo|bar|baz")},
522*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo\\bar.bot\\baz.txt"), FPL("|\\|foo|bar.bot|baz.txt")},
523*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\foo\\\\bar\\baz"),     FPL("|\\\\|foo|bar|baz")},
524*6777b538SAndroid Build Coastguard Worker     { FPL("\\"),                      FPL("|\\")},
525*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
526*6777b538SAndroid Build Coastguard Worker   };
527*6777b538SAndroid Build Coastguard Worker 
528*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
529*6777b538SAndroid Build Coastguard Worker     FilePath input(cases[i].input);
530*6777b538SAndroid Build Coastguard Worker     std::vector<FilePath::StringType> comps = input.GetComponents();
531*6777b538SAndroid Build Coastguard Worker 
532*6777b538SAndroid Build Coastguard Worker     FilePath::StringType observed;
533*6777b538SAndroid Build Coastguard Worker     for (const auto& j : comps) {
534*6777b538SAndroid Build Coastguard Worker       observed.append(FILE_PATH_LITERAL("|"), 1);
535*6777b538SAndroid Build Coastguard Worker       observed.append(j);
536*6777b538SAndroid Build Coastguard Worker     }
537*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].expected), observed) <<
538*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
539*6777b538SAndroid Build Coastguard Worker   }
540*6777b538SAndroid Build Coastguard Worker }
541*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,IsParentTest)542*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, IsParentTest) {
543*6777b538SAndroid Build Coastguard Worker   const struct BinaryBooleanTestData cases[] = {
544*6777b538SAndroid Build Coastguard Worker     { { FPL("/"),             FPL("/foo/bar/baz") },      true},
545*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo"),          FPL("/foo/bar/baz") },      true},
546*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo/bar/baz") },      true},
547*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar/"),     FPL("/foo/bar/baz") },      true},
548*6777b538SAndroid Build Coastguard Worker     { { FPL("//foo/bar/"),    FPL("//foo/bar/baz") },     true},
549*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo2/bar/baz") },     false},
550*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar.txt"),  FPL("/foo/bar/baz") },      false},
551*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo/bar2/baz") },     false},
552*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo/bar") },          false},
553*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar/baz"),  FPL("/foo/bar") },          false},
554*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL("foo/bar/baz") },       true},
555*6777b538SAndroid Build Coastguard Worker     { { FPL("foo/bar"),       FPL("foo/bar/baz") },       true},
556*6777b538SAndroid Build Coastguard Worker     { { FPL("foo/bar"),       FPL("foo2/bar/baz") },      false},
557*6777b538SAndroid Build Coastguard Worker     { { FPL("foo/bar"),       FPL("foo/bar2/baz") },      false},
558*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("foo") },               false},
559*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
560*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("c:/foo/bar/baz") },    true},
561*6777b538SAndroid Build Coastguard Worker     { { FPL("E:/foo/bar"),    FPL("e:/foo/bar/baz") },    true},
562*6777b538SAndroid Build Coastguard Worker     { { FPL("f:/foo/bar"),    FPL("F:/foo/bar/baz") },    true},
563*6777b538SAndroid Build Coastguard Worker     { { FPL("E:/Foo/bar"),    FPL("e:/foo/bar/baz") },    false},
564*6777b538SAndroid Build Coastguard Worker     { { FPL("f:/foo/bar"),    FPL("F:/foo/Bar/baz") },    false},
565*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/"),           FPL("c:/foo/bar/baz") },    true},
566*6777b538SAndroid Build Coastguard Worker     { { FPL("c:"),            FPL("c:/foo/bar/baz") },    true},
567*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("d:/foo/bar/baz") },    false},
568*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("D:/foo/bar/baz") },    false},
569*6777b538SAndroid Build Coastguard Worker     { { FPL("C:/foo/bar"),    FPL("d:/foo/bar/baz") },    false},
570*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("c:/foo2/bar/baz") },   false},
571*6777b538SAndroid Build Coastguard Worker     { { FPL("e:/foo/bar"),    FPL("E:/foo2/bar/baz") },   false},
572*6777b538SAndroid Build Coastguard Worker     { { FPL("F:/foo/bar"),    FPL("f:/foo2/bar/baz") },   false},
573*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("c:/foo/bar2/baz") },   false},
574*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
575*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
576*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo\\bar\\baz") },   true},
577*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo/bar"),     FPL("\\foo\\bar\\baz") },   true},
578*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo/bar"),     FPL("\\foo/bar/baz") },     true},
579*6777b538SAndroid Build Coastguard Worker     { { FPL("\\"),            FPL("\\foo\\bar\\baz") },   true},
580*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("\\foo\\bar\\baz") },   false},
581*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo2\\bar\\baz") },  false},
582*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo\\bar2\\baz") },  false},
583*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
584*6777b538SAndroid Build Coastguard Worker   };
585*6777b538SAndroid Build Coastguard Worker 
586*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
587*6777b538SAndroid Build Coastguard Worker     FilePath parent(cases[i].inputs[0]);
588*6777b538SAndroid Build Coastguard Worker     FilePath child(cases[i].inputs[1]);
589*6777b538SAndroid Build Coastguard Worker 
590*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(parent.IsParent(child), cases[i].expected) <<
591*6777b538SAndroid Build Coastguard Worker         "i: " << i << ", parent: " << parent.value() << ", child: " <<
592*6777b538SAndroid Build Coastguard Worker         child.value();
593*6777b538SAndroid Build Coastguard Worker   }
594*6777b538SAndroid Build Coastguard Worker }
595*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,AppendRelativePathTest)596*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, AppendRelativePathTest) {
597*6777b538SAndroid Build Coastguard Worker   const struct BinaryTestData cases[] = {
598*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
599*6777b538SAndroid Build Coastguard Worker     { { FPL("/"),             FPL("/foo/bar/baz") },      FPL("foo\\bar\\baz")},
600*6777b538SAndroid Build Coastguard Worker #else  // FILE_PATH_USES_WIN_SEPARATORS
601*6777b538SAndroid Build Coastguard Worker     { { FPL("/"),             FPL("/foo/bar/baz") },      FPL("foo/bar/baz")},
602*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
603*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo/bar/baz") },      FPL("baz")},
604*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar/"),     FPL("/foo/bar/baz") },      FPL("baz")},
605*6777b538SAndroid Build Coastguard Worker     { { FPL("//foo/bar/"),    FPL("//foo/bar/baz") },     FPL("baz")},
606*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo2/bar/baz") },     FPL("")},
607*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar.txt"),  FPL("/foo/bar/baz") },      FPL("")},
608*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo/bar2/baz") },     FPL("")},
609*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo/bar") },          FPL("")},
610*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar/baz"),  FPL("/foo/bar") },          FPL("")},
611*6777b538SAndroid Build Coastguard Worker     { { FPL("foo/bar"),       FPL("foo/bar/baz") },       FPL("baz")},
612*6777b538SAndroid Build Coastguard Worker     { { FPL("foo/bar"),       FPL("foo2/bar/baz") },      FPL("")},
613*6777b538SAndroid Build Coastguard Worker     { { FPL("foo/bar"),       FPL("foo/bar2/baz") },      FPL("")},
614*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("foo") },               FPL("")},
615*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
616*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("c:/foo/bar/baz") },    FPL("baz")},
617*6777b538SAndroid Build Coastguard Worker     { { FPL("E:/foo/bar"),    FPL("e:/foo/bar/baz") },    FPL("baz")},
618*6777b538SAndroid Build Coastguard Worker     { { FPL("f:/foo/bar"),    FPL("F:/foo/bar/baz") },    FPL("baz")},
619*6777b538SAndroid Build Coastguard Worker     { { FPL("E:/Foo/bar"),    FPL("e:/foo/bar/baz") },    FPL("")},
620*6777b538SAndroid Build Coastguard Worker     { { FPL("f:/foo/bar"),    FPL("F:/foo/Bar/baz") },    FPL("")},
621*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
622*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/"),           FPL("c:/foo/bar/baz") },    FPL("foo\\bar\\baz")},
623*6777b538SAndroid Build Coastguard Worker     // TODO(akalin): Figure out how to handle the corner case in the
624*6777b538SAndroid Build Coastguard Worker     // commented-out test case below.  Appending to an empty path gives
625*6777b538SAndroid Build Coastguard Worker     // /foo\bar\baz but appending to a nonempty path "blah" gives
626*6777b538SAndroid Build Coastguard Worker     // blah\foo\bar\baz.
627*6777b538SAndroid Build Coastguard Worker     // { { FPL("c:"),            FPL("c:/foo/bar/baz") }, FPL("foo\\bar\\baz")},
628*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
629*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("d:/foo/bar/baz") },    FPL("")},
630*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("D:/foo/bar/baz") },    FPL("")},
631*6777b538SAndroid Build Coastguard Worker     { { FPL("C:/foo/bar"),    FPL("d:/foo/bar/baz") },    FPL("")},
632*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("c:/foo2/bar/baz") },   FPL("")},
633*6777b538SAndroid Build Coastguard Worker     { { FPL("e:/foo/bar"),    FPL("E:/foo2/bar/baz") },   FPL("")},
634*6777b538SAndroid Build Coastguard Worker     { { FPL("F:/foo/bar"),    FPL("f:/foo2/bar/baz") },   FPL("")},
635*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("c:/foo/bar2/baz") },   FPL("")},
636*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
637*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
638*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo\\bar\\baz") },   FPL("baz")},
639*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo/bar"),     FPL("\\foo\\bar\\baz") },   FPL("baz")},
640*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo/bar"),     FPL("\\foo/bar/baz") },     FPL("baz")},
641*6777b538SAndroid Build Coastguard Worker     { { FPL("\\"),            FPL("\\foo\\bar\\baz") },   FPL("foo\\bar\\baz")},
642*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("\\foo\\bar\\baz") },   FPL("")},
643*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo2\\bar\\baz") },  FPL("")},
644*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo\\bar2\\baz") },  FPL("")},
645*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
646*6777b538SAndroid Build Coastguard Worker 
647*6777b538SAndroid Build Coastguard Worker     // For network paths, the hosts are compared ignoring case, while the rest
648*6777b538SAndroid Build Coastguard Worker     // of the path is compared using case.
649*6777b538SAndroid Build Coastguard Worker     { { FPL("//FOO/bar/"),    FPL("//foo/bar/baz") },     FPL("baz")},
650*6777b538SAndroid Build Coastguard Worker     { { FPL("//foo/BAR/"),    FPL("//foo/bar/baz") },     FPL("")},
651*6777b538SAndroid Build Coastguard Worker     // For non-network paths, the first component is not a host and should be
652*6777b538SAndroid Build Coastguard Worker     // compared using case.
653*6777b538SAndroid Build Coastguard Worker     { { FPL("/FOO/bar/"),     FPL("/foo/bar/baz") },      FPL("")},
654*6777b538SAndroid Build Coastguard Worker     // Degenerate case when parent has no hostname.
655*6777b538SAndroid Build Coastguard Worker     { { FPL("//"),            FPL("//foo") },             FPL("foo")},
656*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
657*6777b538SAndroid Build Coastguard Worker     // Network path tests but using Windows path separators.
658*6777b538SAndroid Build Coastguard Worker     { { FPL("\\\\FOO\\bar"),  FPL("\\\\foo\\bar\\baz") }, FPL("baz")},
659*6777b538SAndroid Build Coastguard Worker     { { FPL("\\\\fOO\\Bar"),  FPL("\\\\foo\\bar\\baz") }, FPL("")},
660*6777b538SAndroid Build Coastguard Worker     { { FPL("\\FOO\\bar"),    FPL("\\foo\\bar\\baz") },   FPL("")},
661*6777b538SAndroid Build Coastguard Worker     { { FPL("\\\\"),          FPL("\\\\foo") },           FPL("foo")},
662*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
663*6777b538SAndroid Build Coastguard Worker 
664*6777b538SAndroid Build Coastguard Worker   };
665*6777b538SAndroid Build Coastguard Worker 
666*6777b538SAndroid Build Coastguard Worker   const FilePath base(FPL("blah"));
667*6777b538SAndroid Build Coastguard Worker 
668*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
669*6777b538SAndroid Build Coastguard Worker     FilePath parent(cases[i].inputs[0]);
670*6777b538SAndroid Build Coastguard Worker     FilePath child(cases[i].inputs[1]);
671*6777b538SAndroid Build Coastguard Worker     {
672*6777b538SAndroid Build Coastguard Worker       FilePath result;
673*6777b538SAndroid Build Coastguard Worker       bool success = parent.AppendRelativePath(child, &result);
674*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(!cases[i].expected.empty(), success)
675*6777b538SAndroid Build Coastguard Worker           << "i: " << i << ", parent: " << parent.value()
676*6777b538SAndroid Build Coastguard Worker           << ", child: " << child.value();
677*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(cases[i].expected, result.value())
678*6777b538SAndroid Build Coastguard Worker           << "i: " << i << ", parent: " << parent.value()
679*6777b538SAndroid Build Coastguard Worker           << ", child: " << child.value();
680*6777b538SAndroid Build Coastguard Worker     }
681*6777b538SAndroid Build Coastguard Worker     {
682*6777b538SAndroid Build Coastguard Worker       FilePath result(base);
683*6777b538SAndroid Build Coastguard Worker       bool success = parent.AppendRelativePath(child, &result);
684*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(!cases[i].expected.empty(), success)
685*6777b538SAndroid Build Coastguard Worker           << "i: " << i << ", parent: " << parent.value()
686*6777b538SAndroid Build Coastguard Worker           << ", child: " << child.value();
687*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(base.Append(cases[i].expected).value(), result.value()) <<
688*6777b538SAndroid Build Coastguard Worker         "i: " << i << ", parent: " << parent.value() << ", child: " <<
689*6777b538SAndroid Build Coastguard Worker         child.value();
690*6777b538SAndroid Build Coastguard Worker     }
691*6777b538SAndroid Build Coastguard Worker   }
692*6777b538SAndroid Build Coastguard Worker }
693*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,EqualityTest)694*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, EqualityTest) {
695*6777b538SAndroid Build Coastguard Worker   const struct BinaryBooleanTestData cases[] = {
696*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar/baz"),  FPL("/foo/bar/baz") },      true},
697*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo/bar/baz") },      false},
698*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar/baz"),  FPL("/foo/bar") },          false},
699*6777b538SAndroid Build Coastguard Worker     { { FPL("//foo/bar/"),    FPL("//foo/bar/") },        true},
700*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar"),      FPL("/foo2/bar") },         false},
701*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo/bar.txt"),  FPL("/foo/bar") },          false},
702*6777b538SAndroid Build Coastguard Worker     { { FPL("foo/bar"),       FPL("foo/bar") },           true},
703*6777b538SAndroid Build Coastguard Worker     { { FPL("foo/bar"),       FPL("foo/bar/baz") },       false},
704*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("foo") },               false},
705*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
706*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("c:/foo/bar") },        true},
707*6777b538SAndroid Build Coastguard Worker     { { FPL("E:/foo/bar"),    FPL("e:/foo/bar") },        true},
708*6777b538SAndroid Build Coastguard Worker     { { FPL("f:/foo/bar"),    FPL("F:/foo/bar") },        true},
709*6777b538SAndroid Build Coastguard Worker     { { FPL("E:/Foo/bar"),    FPL("e:/foo/bar") },        false},
710*6777b538SAndroid Build Coastguard Worker     { { FPL("f:/foo/bar"),    FPL("F:/foo/Bar") },        false},
711*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/"),           FPL("c:/") },               true},
712*6777b538SAndroid Build Coastguard Worker     { { FPL("c:"),            FPL("c:") },                true},
713*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("d:/foo/bar") },        false},
714*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("D:/foo/bar") },        false},
715*6777b538SAndroid Build Coastguard Worker     { { FPL("C:/foo/bar"),    FPL("d:/foo/bar") },        false},
716*6777b538SAndroid Build Coastguard Worker     { { FPL("c:/foo/bar"),    FPL("c:/foo2/bar") },       false},
717*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
718*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
719*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo\\bar") },        true},
720*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo/bar"),     FPL("\\foo/bar") },         true},
721*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo/bar"),     FPL("\\foo\\bar") },        false},
722*6777b538SAndroid Build Coastguard Worker     { { FPL("\\"),            FPL("\\") },                true},
723*6777b538SAndroid Build Coastguard Worker     { { FPL("\\"),            FPL("/") },                 false},
724*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("\\") },                false},
725*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo2\\bar") },       false},
726*6777b538SAndroid Build Coastguard Worker     { { FPL("\\foo\\bar"),    FPL("\\foo\\bar2") },       false},
727*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
728*6777b538SAndroid Build Coastguard Worker     { { FPL("c:\\foo\\bar"),    FPL("c:\\foo\\bar") },    true},
729*6777b538SAndroid Build Coastguard Worker     { { FPL("E:\\foo\\bar"),    FPL("e:\\foo\\bar") },    true},
730*6777b538SAndroid Build Coastguard Worker     { { FPL("f:\\foo\\bar"),    FPL("F:\\foo/bar") },     false},
731*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
732*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_WIN_SEPARATORS
733*6777b538SAndroid Build Coastguard Worker   };
734*6777b538SAndroid Build Coastguard Worker 
735*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
736*6777b538SAndroid Build Coastguard Worker     FilePath a(cases[i].inputs[0]);
737*6777b538SAndroid Build Coastguard Worker     FilePath b(cases[i].inputs[1]);
738*6777b538SAndroid Build Coastguard Worker 
739*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(a == b, cases[i].expected) <<
740*6777b538SAndroid Build Coastguard Worker       "equality i: " << i << ", a: " << a.value() << ", b: " <<
741*6777b538SAndroid Build Coastguard Worker       b.value();
742*6777b538SAndroid Build Coastguard Worker   }
743*6777b538SAndroid Build Coastguard Worker 
744*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
745*6777b538SAndroid Build Coastguard Worker     FilePath a(cases[i].inputs[0]);
746*6777b538SAndroid Build Coastguard Worker     FilePath b(cases[i].inputs[1]);
747*6777b538SAndroid Build Coastguard Worker 
748*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(a != b, !cases[i].expected) <<
749*6777b538SAndroid Build Coastguard Worker       "inequality i: " << i << ", a: " << a.value() << ", b: " <<
750*6777b538SAndroid Build Coastguard Worker       b.value();
751*6777b538SAndroid Build Coastguard Worker   }
752*6777b538SAndroid Build Coastguard Worker }
753*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,MacroExpansion)754*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, MacroExpansion) {
755*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FILE_PATH_LITERAL(TEST_FILE), FILE_PATH_LITERAL("TestFile"));
756*6777b538SAndroid Build Coastguard Worker }
757*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,Extension)758*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, Extension) {
759*6777b538SAndroid Build Coastguard Worker   FilePath base_dir(FILE_PATH_LITERAL("base_dir"));
760*6777b538SAndroid Build Coastguard Worker 
761*6777b538SAndroid Build Coastguard Worker   FilePath jpg = base_dir.Append(FILE_PATH_LITERAL("foo.jpg"));
762*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FILE_PATH_LITERAL(".jpg"), jpg.Extension());
763*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FILE_PATH_LITERAL(".jpg"), jpg.FinalExtension());
764*6777b538SAndroid Build Coastguard Worker 
765*6777b538SAndroid Build Coastguard Worker   FilePath base = jpg.BaseName().RemoveExtension();
766*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FILE_PATH_LITERAL("foo"), base.value());
767*6777b538SAndroid Build Coastguard Worker 
768*6777b538SAndroid Build Coastguard Worker   FilePath path_no_ext = base_dir.Append(base);
769*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(path_no_ext.value(), jpg.RemoveExtension().value());
770*6777b538SAndroid Build Coastguard Worker 
771*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(path_no_ext.value(), path_no_ext.RemoveExtension().value());
772*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FILE_PATH_LITERAL(""), path_no_ext.Extension());
773*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FILE_PATH_LITERAL(""), path_no_ext.FinalExtension());
774*6777b538SAndroid Build Coastguard Worker }
775*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,Extension2)776*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, Extension2) {
777*6777b538SAndroid Build Coastguard Worker   // clang-format off
778*6777b538SAndroid Build Coastguard Worker   const struct UnaryTestData cases[] = {
779*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
780*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\a\\b\\c.ext"),        FPL(".ext") },
781*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\a\\b\\c."),           FPL(".") },
782*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\a\\b\\c"),            FPL("") },
783*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\a\\b\\"),             FPL("") },
784*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\a\\b.\\"),            FPL(".") },
785*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\a\\b\\c.ext1.ext2"),  FPL(".ext2") },
786*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\foo.bar\\\\\\"),      FPL(".bar") },
787*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\foo.bar\\.."),        FPL("") },
788*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\foo.bar\\..\\\\"),    FPL("") },
789*6777b538SAndroid Build Coastguard Worker #endif
790*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz.EXT"),       FPL(".EXT") },
791*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz.Ext"),       FPL(".Ext") },
792*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz.ext"),       FPL(".ext") },
793*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz."),          FPL(".") },
794*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz.."),         FPL(".") },
795*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz"),           FPL("") },
796*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/"),              FPL("") },
797*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar./"),             FPL(".") },
798*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/baz.ext1.ext2"), FPL(".ext2") },
799*6777b538SAndroid Build Coastguard Worker     { FPL("/subversion-1.6.12.zip"), FPL(".zip") },
800*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.12345.gz"),          FPL(".gz") },
801*6777b538SAndroid Build Coastguard Worker     { FPL("/foo..gz"),               FPL(".gz") },
802*6777b538SAndroid Build Coastguard Worker     { FPL("."),                      FPL("") },
803*6777b538SAndroid Build Coastguard Worker     { FPL(".."),                     FPL("") },
804*6777b538SAndroid Build Coastguard Worker     { FPL("./foo"),                  FPL("") },
805*6777b538SAndroid Build Coastguard Worker     { FPL("./foo.ext"),              FPL(".ext") },
806*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.ext1/bar.ext2"),     FPL(".ext2") },
807*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.bar////"),           FPL(".bar") },
808*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.bar/.."),            FPL("") },
809*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.bar/..////"),        FPL("") },
810*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.1234.luser.js"),     FPL(".js") },
811*6777b538SAndroid Build Coastguard Worker     { FPL("/user.js"),               FPL(".js") },
812*6777b538SAndroid Build Coastguard Worker   };
813*6777b538SAndroid Build Coastguard Worker   const struct UnaryTestData double_extension_cases[] = {
814*6777b538SAndroid Build Coastguard Worker     // `kCommonDoubleExtensionSuffixes` cases. Blah is not on that allow-list.
815*6777b538SAndroid Build Coastguard Worker     // Membership is (ASCII) case-insensitive: both ".Z" and ".z" match.
816*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.TAR.bz2"),           FPL(".TAR.bz2") },
817*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.Z"),             FPL(".tar.Z") },
818*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.blah"),          FPL(".blah") },
819*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.bz"),            FPL(".tar.bz") },
820*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.bz2"),           FPL(".tar.bz2") },
821*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.gz"),            FPL(".tar.gz") },
822*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.lz"),            FPL(".tar.lz") },
823*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.lzma"),          FPL(".tar.lzma") },
824*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.lzo"),           FPL(".tar.lzo") },
825*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.xz"),            FPL(".tar.xz") },
826*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.z"),             FPL(".tar.z") },
827*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.zst"),           FPL(".tar.zst") },
828*6777b538SAndroid Build Coastguard Worker     // `kCommonDoubleExtensions` cases.
829*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.1234.user.js"),      FPL(".user.js") },
830*6777b538SAndroid Build Coastguard Worker     { FPL("foo.user.js"),            FPL(".user.js") },
831*6777b538SAndroid Build Coastguard Worker     // Other cases.
832*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.1234.gz"),           FPL(".1234.gz") },
833*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.1234.gz."),          FPL(".") },
834*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.1234.tar.gz"),       FPL(".tar.gz") },
835*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.tar.gz"),        FPL(".tar.gz") },
836*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.tar.gz.gz"),         FPL(".gz.gz") },
837*6777b538SAndroid Build Coastguard Worker   };
838*6777b538SAndroid Build Coastguard Worker   // clang-format on
839*6777b538SAndroid Build Coastguard Worker 
840*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
841*6777b538SAndroid Build Coastguard Worker     FilePath path(cases[i].input);
842*6777b538SAndroid Build Coastguard Worker     FilePath::StringType extension = path.Extension();
843*6777b538SAndroid Build Coastguard Worker     FilePath::StringType final_extension = path.FinalExtension();
844*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, extension)
845*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", path: " << path.value();
846*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, final_extension)
847*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", path: " << path.value();
848*6777b538SAndroid Build Coastguard Worker   }
849*6777b538SAndroid Build Coastguard Worker 
850*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(double_extension_cases); ++i) {
851*6777b538SAndroid Build Coastguard Worker     FilePath path(double_extension_cases[i].input);
852*6777b538SAndroid Build Coastguard Worker     FilePath::StringType extension = path.Extension();
853*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(double_extension_cases[i].expected, extension)
854*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", path: " << path.value();
855*6777b538SAndroid Build Coastguard Worker   }
856*6777b538SAndroid Build Coastguard Worker }
857*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,InsertBeforeExtension)858*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, InsertBeforeExtension) {
859*6777b538SAndroid Build Coastguard Worker   const struct BinaryTestData cases[] = {
860*6777b538SAndroid Build Coastguard Worker     { { FPL(""),                FPL("") },        FPL("") },
861*6777b538SAndroid Build Coastguard Worker     { { FPL(""),                FPL("txt") },     FPL("") },
862*6777b538SAndroid Build Coastguard Worker     { { FPL("."),               FPL("txt") },     FPL("") },
863*6777b538SAndroid Build Coastguard Worker     { { FPL(".."),              FPL("txt") },     FPL("") },
864*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),         FPL("txt") },     FPL("footxt.dll") },
865*6777b538SAndroid Build Coastguard Worker     { { FPL("."),               FPL("") },        FPL(".") },
866*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),         FPL(".txt") },    FPL("foo.txt.dll") },
867*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),             FPL("txt") },     FPL("footxt") },
868*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),             FPL(".txt") },    FPL("foo.txt") },
869*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),     FPL("txt") },     FPL("foo.baztxt.dll") },
870*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),     FPL(".txt") },    FPL("foo.baz.txt.dll") },
871*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),         FPL("") },        FPL("foo.dll") },
872*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),         FPL(".") },       FPL("foo..dll") },
873*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),             FPL("") },        FPL("foo") },
874*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),             FPL(".") },       FPL("foo.") },
875*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),     FPL("") },        FPL("foo.baz.dll") },
876*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),     FPL(".") },       FPL("foo.baz..dll") },
877*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
878*6777b538SAndroid Build Coastguard Worker     { { FPL("\\"),              FPL("") },        FPL("\\") },
879*6777b538SAndroid Build Coastguard Worker     { { FPL("\\"),              FPL("txt") },     FPL("\\txt") },
880*6777b538SAndroid Build Coastguard Worker     { { FPL("\\."),             FPL("txt") },     FPL("") },
881*6777b538SAndroid Build Coastguard Worker     { { FPL("\\.."),            FPL("txt") },     FPL("") },
882*6777b538SAndroid Build Coastguard Worker     { { FPL("\\."),             FPL("") },        FPL("\\.") },
883*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\bar\\foo.dll"), FPL("txt") },
884*6777b538SAndroid Build Coastguard Worker         FPL("C:\\bar\\footxt.dll") },
885*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\bar.baz\\foodll"), FPL("txt") },
886*6777b538SAndroid Build Coastguard Worker         FPL("C:\\bar.baz\\foodlltxt") },
887*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\bar.baz\\foo.dll"), FPL("txt") },
888*6777b538SAndroid Build Coastguard Worker         FPL("C:\\bar.baz\\footxt.dll") },
889*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\bar.baz\\foo.dll.exe"), FPL("txt") },
890*6777b538SAndroid Build Coastguard Worker         FPL("C:\\bar.baz\\foo.dlltxt.exe") },
891*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\bar.baz\\foo"), FPL("") },
892*6777b538SAndroid Build Coastguard Worker         FPL("C:\\bar.baz\\foo") },
893*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\bar.baz\\foo.exe"), FPL("") },
894*6777b538SAndroid Build Coastguard Worker         FPL("C:\\bar.baz\\foo.exe") },
895*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\bar.baz\\foo.dll.exe"), FPL("") },
896*6777b538SAndroid Build Coastguard Worker         FPL("C:\\bar.baz\\foo.dll.exe") },
897*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\bar\\baz\\foo.exe"), FPL(" (1)") },
898*6777b538SAndroid Build Coastguard Worker         FPL("C:\\bar\\baz\\foo (1).exe") },
899*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\foo.baz\\\\"), FPL(" (1)") },    FPL("C:\\foo (1).baz") },
900*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\foo.baz\\..\\"), FPL(" (1)") },  FPL("") },
901*6777b538SAndroid Build Coastguard Worker #endif
902*6777b538SAndroid Build Coastguard Worker     { { FPL("/"),               FPL("") },        FPL("/") },
903*6777b538SAndroid Build Coastguard Worker     { { FPL("/"),               FPL("txt") },     FPL("/txt") },
904*6777b538SAndroid Build Coastguard Worker     { { FPL("/."),              FPL("txt") },     FPL("") },
905*6777b538SAndroid Build Coastguard Worker     { { FPL("/.."),             FPL("txt") },     FPL("") },
906*6777b538SAndroid Build Coastguard Worker     { { FPL("/."),              FPL("") },        FPL("/.") },
907*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar/foo.dll"),    FPL("txt") },     FPL("/bar/footxt.dll") },
908*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar.baz/foodll"), FPL("txt") },     FPL("/bar.baz/foodlltxt") },
909*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar.baz/foo.dll"), FPL("txt") },    FPL("/bar.baz/footxt.dll") },
910*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar.baz/foo.dll.exe"), FPL("txt") },
911*6777b538SAndroid Build Coastguard Worker         FPL("/bar.baz/foo.dlltxt.exe") },
912*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar.baz/foo"),    FPL("") },        FPL("/bar.baz/foo") },
913*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar.baz/foo.exe"), FPL("") },       FPL("/bar.baz/foo.exe") },
914*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar.baz/foo.dll.exe"), FPL("") },   FPL("/bar.baz/foo.dll.exe") },
915*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar/baz/foo.exe"), FPL(" (1)") },   FPL("/bar/baz/foo (1).exe") },
916*6777b538SAndroid Build Coastguard Worker     { { FPL("/bar/baz/..////"), FPL(" (1)") },    FPL("") },
917*6777b538SAndroid Build Coastguard Worker   };
918*6777b538SAndroid Build Coastguard Worker   for (unsigned int i = 0; i < std::size(cases); ++i) {
919*6777b538SAndroid Build Coastguard Worker     FilePath path(cases[i].inputs[0]);
920*6777b538SAndroid Build Coastguard Worker     FilePath result = path.InsertBeforeExtension(cases[i].inputs[1]);
921*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, result.value())
922*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", path: " << path.value()
923*6777b538SAndroid Build Coastguard Worker         << ", insert: " << cases[i].inputs[1];
924*6777b538SAndroid Build Coastguard Worker   }
925*6777b538SAndroid Build Coastguard Worker }
926*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,RemoveExtension)927*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, RemoveExtension) {
928*6777b538SAndroid Build Coastguard Worker   const struct UnaryTestData cases[] = {
929*6777b538SAndroid Build Coastguard Worker     { FPL(""),                    FPL("") },
930*6777b538SAndroid Build Coastguard Worker     { FPL("."),                   FPL(".") },
931*6777b538SAndroid Build Coastguard Worker     { FPL(".."),                  FPL("..") },
932*6777b538SAndroid Build Coastguard Worker     { FPL("foo.dll"),             FPL("foo") },
933*6777b538SAndroid Build Coastguard Worker     { FPL("./foo.dll"),           FPL("./foo") },
934*6777b538SAndroid Build Coastguard Worker     { FPL("foo..dll"),            FPL("foo.") },
935*6777b538SAndroid Build Coastguard Worker     { FPL("foo"),                 FPL("foo") },
936*6777b538SAndroid Build Coastguard Worker     { FPL("foo."),                FPL("foo") },
937*6777b538SAndroid Build Coastguard Worker     { FPL("foo.."),               FPL("foo.") },
938*6777b538SAndroid Build Coastguard Worker     { FPL("foo.baz.dll"),         FPL("foo.baz") },
939*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
940*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\foo.bar\\foo"),    FPL("C:\\foo.bar\\foo") },
941*6777b538SAndroid Build Coastguard Worker     { FPL("C:\\foo.bar\\..\\\\"), FPL("C:\\foo.bar\\..\\\\") },
942*6777b538SAndroid Build Coastguard Worker #endif
943*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.bar/foo"),        FPL("/foo.bar/foo") },
944*6777b538SAndroid Build Coastguard Worker     { FPL("/foo.bar/..////"),     FPL("/foo.bar/..////") },
945*6777b538SAndroid Build Coastguard Worker   };
946*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
947*6777b538SAndroid Build Coastguard Worker     FilePath path(cases[i].input);
948*6777b538SAndroid Build Coastguard Worker     FilePath removed = path.RemoveExtension();
949*6777b538SAndroid Build Coastguard Worker     FilePath removed_final = path.RemoveFinalExtension();
950*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, removed.value()) << "i: " << i <<
951*6777b538SAndroid Build Coastguard Worker         ", path: " << path.value();
952*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, removed_final.value()) << "i: " << i <<
953*6777b538SAndroid Build Coastguard Worker         ", path: " << path.value();
954*6777b538SAndroid Build Coastguard Worker   }
955*6777b538SAndroid Build Coastguard Worker 
956*6777b538SAndroid Build Coastguard Worker   const FilePath::StringPieceType tarballs[] = {
957*6777b538SAndroid Build Coastguard Worker       FPL("foo.tar.gz"), FPL("foo.tar.xz"), FPL("foo.tar.bz2"),
958*6777b538SAndroid Build Coastguard Worker       FPL("foo.tar.Z"), FPL("foo.tar.bz")};
959*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(tarballs); ++i) {
960*6777b538SAndroid Build Coastguard Worker     FilePath path(FPL("foo.tar.gz"));
961*6777b538SAndroid Build Coastguard Worker     FilePath removed = path.RemoveExtension();
962*6777b538SAndroid Build Coastguard Worker     FilePath removed_final = path.RemoveFinalExtension();
963*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FPL("foo"), removed.value())
964*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", path: " << path.value();
965*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FPL("foo.tar"), removed_final.value())
966*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", path: " << path.value();
967*6777b538SAndroid Build Coastguard Worker   }
968*6777b538SAndroid Build Coastguard Worker }
969*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,ReplaceExtension)970*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, ReplaceExtension) {
971*6777b538SAndroid Build Coastguard Worker   const struct BinaryTestData cases[] = {
972*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("") },      FPL("") },
973*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("txt") },   FPL("") },
974*6777b538SAndroid Build Coastguard Worker     { { FPL("."),             FPL("txt") },   FPL("") },
975*6777b538SAndroid Build Coastguard Worker     { { FPL(".."),            FPL("txt") },   FPL("") },
976*6777b538SAndroid Build Coastguard Worker     { { FPL("."),             FPL("") },      FPL("") },
977*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),       FPL("txt") },   FPL("foo.txt") },
978*6777b538SAndroid Build Coastguard Worker     { { FPL("./foo.dll"),     FPL("txt") },   FPL("./foo.txt") },
979*6777b538SAndroid Build Coastguard Worker     { { FPL("foo..dll"),      FPL("txt") },   FPL("foo..txt") },
980*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),       FPL(".txt") },  FPL("foo.txt") },
981*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL("txt") },   FPL("foo.txt") },
982*6777b538SAndroid Build Coastguard Worker     { { FPL("foo."),          FPL("txt") },   FPL("foo.txt") },
983*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.."),         FPL("txt") },   FPL("foo..txt") },
984*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL(".txt") },  FPL("foo.txt") },
985*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),   FPL("txt") },   FPL("foo.baz.txt") },
986*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),   FPL(".txt") },  FPL("foo.baz.txt") },
987*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),       FPL("") },      FPL("foo") },
988*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),       FPL(".") },     FPL("foo") },
989*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL("") },      FPL("foo") },
990*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL(".") },     FPL("foo") },
991*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),   FPL("") },      FPL("foo.baz") },
992*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),   FPL(".") },     FPL("foo.baz") },
993*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
994*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\foo.bar\\foo"),    FPL("baz") }, FPL("C:\\foo.bar\\foo.baz") },
995*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\foo.bar\\..\\\\"), FPL("baz") }, FPL("") },
996*6777b538SAndroid Build Coastguard Worker #endif
997*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo.bar/foo"),        FPL("baz") }, FPL("/foo.bar/foo.baz") },
998*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo.bar/..////"),     FPL("baz") }, FPL("") },
999*6777b538SAndroid Build Coastguard Worker   };
1000*6777b538SAndroid Build Coastguard Worker   for (unsigned int i = 0; i < std::size(cases); ++i) {
1001*6777b538SAndroid Build Coastguard Worker     FilePath path(cases[i].inputs[0]);
1002*6777b538SAndroid Build Coastguard Worker     FilePath replaced = path.ReplaceExtension(cases[i].inputs[1]);
1003*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, replaced.value()) << "i: " << i <<
1004*6777b538SAndroid Build Coastguard Worker         ", path: " << path.value() << ", replace: " << cases[i].inputs[1];
1005*6777b538SAndroid Build Coastguard Worker   }
1006*6777b538SAndroid Build Coastguard Worker }
1007*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,AddExtension)1008*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, AddExtension) {
1009*6777b538SAndroid Build Coastguard Worker   const struct BinaryTestData cases[] = {
1010*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("") },      FPL("") },
1011*6777b538SAndroid Build Coastguard Worker     { { FPL(""),              FPL("txt") },   FPL("") },
1012*6777b538SAndroid Build Coastguard Worker     { { FPL("."),             FPL("txt") },   FPL("") },
1013*6777b538SAndroid Build Coastguard Worker     { { FPL(".."),            FPL("txt") },   FPL("") },
1014*6777b538SAndroid Build Coastguard Worker     { { FPL("."),             FPL("") },      FPL("") },
1015*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),       FPL("txt") },   FPL("foo.dll.txt") },
1016*6777b538SAndroid Build Coastguard Worker     { { FPL("./foo.dll"),     FPL("txt") },   FPL("./foo.dll.txt") },
1017*6777b538SAndroid Build Coastguard Worker     { { FPL("foo..dll"),      FPL("txt") },   FPL("foo..dll.txt") },
1018*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),       FPL(".txt") },  FPL("foo.dll.txt") },
1019*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL("txt") },   FPL("foo.txt") },
1020*6777b538SAndroid Build Coastguard Worker     { { FPL("foo."),          FPL("txt") },   FPL("foo.txt") },
1021*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.."),         FPL("txt") },   FPL("foo..txt") },
1022*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL(".txt") },  FPL("foo.txt") },
1023*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),   FPL("txt") },   FPL("foo.baz.dll.txt") },
1024*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),   FPL(".txt") },  FPL("foo.baz.dll.txt") },
1025*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),       FPL("") },      FPL("foo.dll") },
1026*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.dll"),       FPL(".") },     FPL("foo.dll") },
1027*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL("") },      FPL("foo") },
1028*6777b538SAndroid Build Coastguard Worker     { { FPL("foo"),           FPL(".") },     FPL("foo") },
1029*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),   FPL("") },      FPL("foo.baz.dll") },
1030*6777b538SAndroid Build Coastguard Worker     { { FPL("foo.baz.dll"),   FPL(".") },     FPL("foo.baz.dll") },
1031*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
1032*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\foo.bar\\foo"),    FPL("baz") }, FPL("C:\\foo.bar\\foo.baz") },
1033*6777b538SAndroid Build Coastguard Worker     { { FPL("C:\\foo.bar\\..\\\\"), FPL("baz") }, FPL("") },
1034*6777b538SAndroid Build Coastguard Worker #endif
1035*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo.bar/foo"),        FPL("baz") }, FPL("/foo.bar/foo.baz") },
1036*6777b538SAndroid Build Coastguard Worker     { { FPL("/foo.bar/..////"),     FPL("baz") }, FPL("") },
1037*6777b538SAndroid Build Coastguard Worker   };
1038*6777b538SAndroid Build Coastguard Worker   for (unsigned int i = 0; i < std::size(cases); ++i) {
1039*6777b538SAndroid Build Coastguard Worker     FilePath path(cases[i].inputs[0]);
1040*6777b538SAndroid Build Coastguard Worker     FilePath added = path.AddExtension(cases[i].inputs[1]);
1041*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, added.value()) << "i: " << i <<
1042*6777b538SAndroid Build Coastguard Worker         ", path: " << path.value() << ", add: " << cases[i].inputs[1];
1043*6777b538SAndroid Build Coastguard Worker   }
1044*6777b538SAndroid Build Coastguard Worker }
1045*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,MatchesExtension)1046*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, MatchesExtension) {
1047*6777b538SAndroid Build Coastguard Worker   const struct BinaryBooleanTestData cases[] = {
1048*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL("")}, true},
1049*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL(".")}, false},
1050*6777b538SAndroid Build Coastguard Worker     {{FPL("foo."), FPL("")}, false},
1051*6777b538SAndroid Build Coastguard Worker     {{FPL("foo."), FPL(".")}, true},
1052*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt"), FPL(".dll")}, false},
1053*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt"), FPL(".txt")}, true},
1054*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt.dll"), FPL(".txt")}, false},
1055*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt.dll"), FPL(".dll")}, true},
1056*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tar.gz"), FPL(".gz")}, false},
1057*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tar.lzma"), FPL(".tar.lzma")}, true},
1058*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.TXT"), FPL(".txt")}, true},
1059*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt"), FPL(".TXT")}, true},
1060*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tXt"), FPL(".txt")}, true},
1061*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt"), FPL(".tXt")}, true},
1062*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tXt"), FPL(".TXT")}, true},
1063*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tXt"), FPL(".tXt")}, true},
1064*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
1065*6777b538SAndroid Build Coastguard Worker     {{FPL("c:/foo.txt.dll"), FPL(".txt")}, false},
1066*6777b538SAndroid Build Coastguard Worker     {{FPL("c:/foo.txt"), FPL(".txt")}, true},
1067*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
1068*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
1069*6777b538SAndroid Build Coastguard Worker     {{FPL("c:\\bar\\foo.txt.dll"), FPL(".txt")}, false},
1070*6777b538SAndroid Build Coastguard Worker     {{FPL("c:\\bar\\foo.txt"), FPL(".txt")}, true},
1071*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
1072*6777b538SAndroid Build Coastguard Worker     {{FPL("/bar/foo.txt.dll"), FPL(".txt")}, false},
1073*6777b538SAndroid Build Coastguard Worker     {{FPL("/bar/foo.txt"), FPL(".txt")}, true},
1074*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
1075*6777b538SAndroid Build Coastguard Worker     // Umlauts A, O, U: direct comparison, and upper case vs. lower case
1076*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.\u00E4\u00F6\u00FC"), FPL(".\u00E4\u00F6\u00FC")}, true},
1077*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.\u00C4\u00D6\u00DC"), FPL(".\u00E4\u00F6\u00FC")}, true},
1078*6777b538SAndroid Build Coastguard Worker     // C with circumflex: direct comparison, and upper case vs. lower case
1079*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.\u0109"), FPL(".\u0109")}, true},
1080*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.\u0108"), FPL(".\u0109")}, true},
1081*6777b538SAndroid Build Coastguard Worker #endif
1082*6777b538SAndroid Build Coastguard Worker   };
1083*6777b538SAndroid Build Coastguard Worker 
1084*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
1085*6777b538SAndroid Build Coastguard Worker     FilePath path(cases[i].inputs[0]);
1086*6777b538SAndroid Build Coastguard Worker     FilePath::StringType ext(cases[i].inputs[1]);
1087*6777b538SAndroid Build Coastguard Worker 
1088*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, path.MatchesExtension(ext)) <<
1089*6777b538SAndroid Build Coastguard Worker         "i: " << i << ", path: " << path.value() << ", ext: " << ext;
1090*6777b538SAndroid Build Coastguard Worker   }
1091*6777b538SAndroid Build Coastguard Worker }
1092*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,MatchesFinalExtension)1093*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, MatchesFinalExtension) {
1094*6777b538SAndroid Build Coastguard Worker   const struct BinaryBooleanTestData cases[] = {
1095*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL("")}, true},
1096*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL(".")}, false},
1097*6777b538SAndroid Build Coastguard Worker     {{FPL("foo."), FPL("")}, false},
1098*6777b538SAndroid Build Coastguard Worker     {{FPL("foo."), FPL(".")}, true},
1099*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt"), FPL(".dll")}, false},
1100*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt"), FPL(".txt")}, true},
1101*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt.dll"), FPL(".txt")}, false},
1102*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt.dll"), FPL(".dll")}, true},
1103*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tar.gz"), FPL(".gz")}, true},
1104*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tar.lzma"), FPL(".lzma")}, true},
1105*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tar.lzma"), FPL(".tar.lzma")}, false},
1106*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tlzma"), FPL(".tlzma")}, true},
1107*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.TXT"), FPL(".txt")}, true},
1108*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt"), FPL(".TXT")}, true},
1109*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tXt"), FPL(".txt")}, true},
1110*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.txt"), FPL(".tXt")}, true},
1111*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tXt"), FPL(".TXT")}, true},
1112*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.tXt"), FPL(".tXt")}, true},
1113*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_DRIVE_LETTERS)
1114*6777b538SAndroid Build Coastguard Worker     {{FPL("c:/foo.txt.dll"), FPL(".txt")}, false},
1115*6777b538SAndroid Build Coastguard Worker     {{FPL("c:/foo.txt"), FPL(".txt")}, true},
1116*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
1117*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
1118*6777b538SAndroid Build Coastguard Worker     {{FPL("c:\\bar\\foo.txt.dll"), FPL(".txt")}, false},
1119*6777b538SAndroid Build Coastguard Worker     {{FPL("c:\\bar\\foo.txt"), FPL(".txt")}, true},
1120*6777b538SAndroid Build Coastguard Worker #endif  // FILE_PATH_USES_DRIVE_LETTERS
1121*6777b538SAndroid Build Coastguard Worker     {{FPL("/bar/foo.txt.dll"), FPL(".txt")}, false},
1122*6777b538SAndroid Build Coastguard Worker     {{FPL("/bar/foo.txt"), FPL(".txt")}, true},
1123*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
1124*6777b538SAndroid Build Coastguard Worker     // Umlauts A, O, U: direct comparison, and upper case vs. lower case
1125*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.\u00E4\u00F6\u00FC"), FPL(".\u00E4\u00F6\u00FC")}, true},
1126*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.\u00C4\u00D6\u00DC"), FPL(".\u00E4\u00F6\u00FC")}, true},
1127*6777b538SAndroid Build Coastguard Worker     // C with circumflex: direct comparison, and upper case vs. lower case
1128*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.\u0109"), FPL(".\u0109")}, true},
1129*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.\u0108"), FPL(".\u0109")}, true},
1130*6777b538SAndroid Build Coastguard Worker #endif
1131*6777b538SAndroid Build Coastguard Worker   };
1132*6777b538SAndroid Build Coastguard Worker 
1133*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
1134*6777b538SAndroid Build Coastguard Worker     FilePath path(cases[i].inputs[0]);
1135*6777b538SAndroid Build Coastguard Worker     FilePath::StringType ext(cases[i].inputs[1]);
1136*6777b538SAndroid Build Coastguard Worker 
1137*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, path.MatchesFinalExtension(ext))
1138*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", path: " << path.value() << ", ext: " << ext;
1139*6777b538SAndroid Build Coastguard Worker   }
1140*6777b538SAndroid Build Coastguard Worker }
1141*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,CompareIgnoreCase)1142*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, CompareIgnoreCase) {
1143*6777b538SAndroid Build Coastguard Worker   const struct BinaryIntTestData cases[] = {
1144*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL("foo")}, 0},
1145*6777b538SAndroid Build Coastguard Worker     {{FPL("FOO"), FPL("foo")}, 0},
1146*6777b538SAndroid Build Coastguard Worker     {{FPL("foo.ext"), FPL("foo.ext")}, 0},
1147*6777b538SAndroid Build Coastguard Worker     {{FPL("FOO.EXT"), FPL("foo.ext")}, 0},
1148*6777b538SAndroid Build Coastguard Worker     {{FPL("Foo.Ext"), FPL("foo.ext")}, 0},
1149*6777b538SAndroid Build Coastguard Worker     {{FPL("foO"), FPL("foo")}, 0},
1150*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL("foO")}, 0},
1151*6777b538SAndroid Build Coastguard Worker     {{FPL("fOo"), FPL("foo")}, 0},
1152*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL("fOo")}, 0},
1153*6777b538SAndroid Build Coastguard Worker     {{FPL("bar"), FPL("foo")}, -1},
1154*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL("bar")}, 1},
1155*6777b538SAndroid Build Coastguard Worker     {{FPL("BAR"), FPL("foo")}, -1},
1156*6777b538SAndroid Build Coastguard Worker     {{FPL("FOO"), FPL("bar")}, 1},
1157*6777b538SAndroid Build Coastguard Worker     {{FPL("bar"), FPL("FOO")}, -1},
1158*6777b538SAndroid Build Coastguard Worker     {{FPL("foo"), FPL("BAR")}, 1},
1159*6777b538SAndroid Build Coastguard Worker     {{FPL("BAR"), FPL("FOO")}, -1},
1160*6777b538SAndroid Build Coastguard Worker     {{FPL("FOO"), FPL("BAR")}, 1},
1161*6777b538SAndroid Build Coastguard Worker     // German "Eszett" (lower case and the new-fangled upper case)
1162*6777b538SAndroid Build Coastguard Worker     // Note that uc(<lowercase eszett>) => "SS", NOT <uppercase eszett>!
1163*6777b538SAndroid Build Coastguard Worker     // However, neither Windows nor Mac OSX converts these.
1164*6777b538SAndroid Build Coastguard Worker     // (or even have glyphs for <uppercase eszett>)
1165*6777b538SAndroid Build Coastguard Worker     {{FPL("\u00DF"), FPL("\u00DF")}, 0},
1166*6777b538SAndroid Build Coastguard Worker     {{FPL("\u1E9E"), FPL("\u1E9E")}, 0},
1167*6777b538SAndroid Build Coastguard Worker     {{FPL("\u00DF"), FPL("\u1E9E")}, -1},
1168*6777b538SAndroid Build Coastguard Worker     {{FPL("SS"), FPL("\u00DF")}, -1},
1169*6777b538SAndroid Build Coastguard Worker     {{FPL("SS"), FPL("\u1E9E")}, -1},
1170*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
1171*6777b538SAndroid Build Coastguard Worker     // Umlauts A, O, U: direct comparison, and upper case vs. lower case
1172*6777b538SAndroid Build Coastguard Worker     {{FPL("\u00E4\u00F6\u00FC"), FPL("\u00E4\u00F6\u00FC")}, 0},
1173*6777b538SAndroid Build Coastguard Worker     {{FPL("\u00C4\u00D6\u00DC"), FPL("\u00E4\u00F6\u00FC")}, 0},
1174*6777b538SAndroid Build Coastguard Worker     // C with circumflex: direct comparison, and upper case vs. lower case
1175*6777b538SAndroid Build Coastguard Worker     {{FPL("\u0109"), FPL("\u0109")}, 0},
1176*6777b538SAndroid Build Coastguard Worker     {{FPL("\u0108"), FPL("\u0109")}, 0},
1177*6777b538SAndroid Build Coastguard Worker     // Cyrillic letter SHA: direct comparison, and upper case vs. lower case
1178*6777b538SAndroid Build Coastguard Worker     {{FPL("\u0428"), FPL("\u0428")}, 0},
1179*6777b538SAndroid Build Coastguard Worker     {{FPL("\u0428"), FPL("\u0448")}, 0},
1180*6777b538SAndroid Build Coastguard Worker     // Greek letter DELTA: direct comparison, and upper case vs. lower case
1181*6777b538SAndroid Build Coastguard Worker     {{FPL("\u0394"), FPL("\u0394")}, 0},
1182*6777b538SAndroid Build Coastguard Worker     {{FPL("\u0394"), FPL("\u03B4")}, 0},
1183*6777b538SAndroid Build Coastguard Worker     // Japanese full-width A: direct comparison, and upper case vs. lower case
1184*6777b538SAndroid Build Coastguard Worker     // Note that full-width and standard characters are considered different.
1185*6777b538SAndroid Build Coastguard Worker     {{FPL("\uFF21"), FPL("\uFF21")}, 0},
1186*6777b538SAndroid Build Coastguard Worker     {{FPL("\uFF21"), FPL("\uFF41")}, 0},
1187*6777b538SAndroid Build Coastguard Worker     {{FPL("A"), FPL("\uFF21")}, -1},
1188*6777b538SAndroid Build Coastguard Worker     {{FPL("A"), FPL("\uFF41")}, -1},
1189*6777b538SAndroid Build Coastguard Worker     {{FPL("a"), FPL("\uFF21")}, -1},
1190*6777b538SAndroid Build Coastguard Worker     {{FPL("a"), FPL("\uFF41")}, -1},
1191*6777b538SAndroid Build Coastguard Worker #endif
1192*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
1193*6777b538SAndroid Build Coastguard Worker     // Codepoints > 0x1000
1194*6777b538SAndroid Build Coastguard Worker     // Georgian letter DON: direct comparison, and upper case vs. lower case
1195*6777b538SAndroid Build Coastguard Worker     {{FPL("\u10A3"), FPL("\u10A3")}, 0},
1196*6777b538SAndroid Build Coastguard Worker     {{FPL("\u10A3"), FPL("\u10D3")}, 0},
1197*6777b538SAndroid Build Coastguard Worker     // Combining characters vs. pre-composed characters, upper and lower case
1198*6777b538SAndroid Build Coastguard Worker     {{FPL("k\u0301u\u032Do\u0304\u0301n"), FPL("\u1E31\u1E77\u1E53n")}, 0},
1199*6777b538SAndroid Build Coastguard Worker     {{FPL("k\u0301u\u032Do\u0304\u0301n"), FPL("kuon")}, 1},
1200*6777b538SAndroid Build Coastguard Worker     {{FPL("kuon"), FPL("k\u0301u\u032Do\u0304\u0301n")}, -1},
1201*6777b538SAndroid Build Coastguard Worker     {{FPL("K\u0301U\u032DO\u0304\u0301N"), FPL("KUON")}, 1},
1202*6777b538SAndroid Build Coastguard Worker     {{FPL("KUON"), FPL("K\u0301U\u032DO\u0304\u0301N")}, -1},
1203*6777b538SAndroid Build Coastguard Worker     {{FPL("k\u0301u\u032Do\u0304\u0301n"), FPL("KUON")}, 1},
1204*6777b538SAndroid Build Coastguard Worker     {{FPL("K\u0301U\u032DO\u0304\u0301N"), FPL("\u1E31\u1E77\u1E53n")}, 0},
1205*6777b538SAndroid Build Coastguard Worker     {{FPL("k\u0301u\u032Do\u0304\u0301n"), FPL("\u1E30\u1E76\u1E52n")}, 0},
1206*6777b538SAndroid Build Coastguard Worker     {{FPL("k\u0301u\u032Do\u0304\u0302n"), FPL("\u1E30\u1E76\u1E52n")}, 1},
1207*6777b538SAndroid Build Coastguard Worker 
1208*6777b538SAndroid Build Coastguard Worker     // Codepoints > 0xFFFF
1209*6777b538SAndroid Build Coastguard Worker     // Here, we compare the `Adlam Letter Shu` in its capital and small version.
1210*6777b538SAndroid Build Coastguard Worker     {{FPL("\U0001E921"), FPL("\U0001E943")}, -1},
1211*6777b538SAndroid Build Coastguard Worker     {{FPL("\U0001E943"), FPL("\U0001E921")}, 1},
1212*6777b538SAndroid Build Coastguard Worker     {{FPL("\U0001E921"), FPL("\U0001E921")}, 0},
1213*6777b538SAndroid Build Coastguard Worker     {{FPL("\U0001E943"), FPL("\U0001E943")}, 0},
1214*6777b538SAndroid Build Coastguard Worker #endif
1215*6777b538SAndroid Build Coastguard Worker   };
1216*6777b538SAndroid Build Coastguard Worker 
1217*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
1218*6777b538SAndroid Build Coastguard Worker     FilePath::StringType s1(cases[i].inputs[0]);
1219*6777b538SAndroid Build Coastguard Worker     FilePath::StringType s2(cases[i].inputs[1]);
1220*6777b538SAndroid Build Coastguard Worker     int result = FilePath::CompareIgnoreCase(s1, s2);
1221*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, result) <<
1222*6777b538SAndroid Build Coastguard Worker         "i: " << i << ", s1: " << s1 << ", s2: " << s2;
1223*6777b538SAndroid Build Coastguard Worker   }
1224*6777b538SAndroid Build Coastguard Worker }
1225*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,ReferencesParent)1226*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, ReferencesParent) {
1227*6777b538SAndroid Build Coastguard Worker   const struct UnaryBooleanTestData cases[] = {
1228*6777b538SAndroid Build Coastguard Worker     { FPL("."),        false },
1229*6777b538SAndroid Build Coastguard Worker     { FPL(".."),       true },
1230*6777b538SAndroid Build Coastguard Worker     { FPL(".. "),      true },
1231*6777b538SAndroid Build Coastguard Worker     { FPL(" .."),      true },
1232*6777b538SAndroid Build Coastguard Worker     { FPL("..."),      true },
1233*6777b538SAndroid Build Coastguard Worker     { FPL("a.."),      false },
1234*6777b538SAndroid Build Coastguard Worker     { FPL("..a"),      false },
1235*6777b538SAndroid Build Coastguard Worker     { FPL("../"),      true },
1236*6777b538SAndroid Build Coastguard Worker     { FPL("/.."),      true },
1237*6777b538SAndroid Build Coastguard Worker     { FPL("/../"),     true },
1238*6777b538SAndroid Build Coastguard Worker     { FPL("/a../"),    false },
1239*6777b538SAndroid Build Coastguard Worker     { FPL("/..a/"),    false },
1240*6777b538SAndroid Build Coastguard Worker     { FPL("//.."),     true },
1241*6777b538SAndroid Build Coastguard Worker     { FPL("..//"),     true },
1242*6777b538SAndroid Build Coastguard Worker     { FPL("//..//"),   true },
1243*6777b538SAndroid Build Coastguard Worker     { FPL("a//..//c"), true },
1244*6777b538SAndroid Build Coastguard Worker     { FPL("../b/c"),   true },
1245*6777b538SAndroid Build Coastguard Worker     { FPL("/../b/c"),  true },
1246*6777b538SAndroid Build Coastguard Worker     { FPL("a/b/.."),   true },
1247*6777b538SAndroid Build Coastguard Worker     { FPL("a/b/../"),  true },
1248*6777b538SAndroid Build Coastguard Worker     { FPL("a/../c"),   true },
1249*6777b538SAndroid Build Coastguard Worker     { FPL("a/b/c"),    false },
1250*6777b538SAndroid Build Coastguard Worker   };
1251*6777b538SAndroid Build Coastguard Worker 
1252*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
1253*6777b538SAndroid Build Coastguard Worker     FilePath input(cases[i].input);
1254*6777b538SAndroid Build Coastguard Worker     bool observed = input.ReferencesParent();
1255*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, observed) <<
1256*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
1257*6777b538SAndroid Build Coastguard Worker   }
1258*6777b538SAndroid Build Coastguard Worker }
1259*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,FromASCII)1260*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, FromASCII) {
1261*6777b538SAndroid Build Coastguard Worker   const struct UTF8TestData cases[] = {
1262*6777b538SAndroid Build Coastguard Worker       {FPL("foo.txt"), "foo.txt"},
1263*6777b538SAndroid Build Coastguard Worker       {FPL("!#$%&'()"), "!#$%&'()"},
1264*6777b538SAndroid Build Coastguard Worker   };
1265*6777b538SAndroid Build Coastguard Worker 
1266*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
1267*6777b538SAndroid Build Coastguard Worker     FilePath from_ascii = FilePath::FromASCII(cases[i].utf8);
1268*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].native), from_ascii.value())
1269*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", input: " << cases[i].utf8;
1270*6777b538SAndroid Build Coastguard Worker   }
1271*6777b538SAndroid Build Coastguard Worker }
1272*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,FromUTF8Unsafe_And_AsUTF8Unsafe)1273*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, FromUTF8Unsafe_And_AsUTF8Unsafe) {
1274*6777b538SAndroid Build Coastguard Worker   const struct UTF8TestData cases[] = {
1275*6777b538SAndroid Build Coastguard Worker     { FPL("foo.txt"), "foo.txt" },
1276*6777b538SAndroid Build Coastguard Worker     // "aeo" with accents. Use http://0xcc.net/jsescape/ to decode them.
1277*6777b538SAndroid Build Coastguard Worker     { FPL("\u00E0\u00E8\u00F2.txt"), "\xC3\xA0\xC3\xA8\xC3\xB2.txt" },
1278*6777b538SAndroid Build Coastguard Worker     // Full-width "ABC".
1279*6777b538SAndroid Build Coastguard Worker     { FPL("\uFF21\uFF22\uFF23.txt"),
1280*6777b538SAndroid Build Coastguard Worker       "\xEF\xBC\xA1\xEF\xBC\xA2\xEF\xBC\xA3.txt" },
1281*6777b538SAndroid Build Coastguard Worker   };
1282*6777b538SAndroid Build Coastguard Worker 
1283*6777b538SAndroid Build Coastguard Worker #if !defined(SYSTEM_NATIVE_UTF8) && \
1284*6777b538SAndroid Build Coastguard Worker     (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
1285*6777b538SAndroid Build Coastguard Worker   ScopedLocale locale("en_US.UTF-8");
1286*6777b538SAndroid Build Coastguard Worker #endif
1287*6777b538SAndroid Build Coastguard Worker 
1288*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
1289*6777b538SAndroid Build Coastguard Worker     // Test FromUTF8Unsafe() works.
1290*6777b538SAndroid Build Coastguard Worker     FilePath from_utf8 = FilePath::FromUTF8Unsafe(cases[i].utf8);
1291*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].native, from_utf8.value())
1292*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", input: " << cases[i].native;
1293*6777b538SAndroid Build Coastguard Worker     // Test AsUTF8Unsafe() works.
1294*6777b538SAndroid Build Coastguard Worker     FilePath from_native = FilePath(cases[i].native);
1295*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].utf8, from_native.AsUTF8Unsafe())
1296*6777b538SAndroid Build Coastguard Worker         << "i: " << i << ", input: " << cases[i].native;
1297*6777b538SAndroid Build Coastguard Worker     // Test the two file paths are identical.
1298*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(from_utf8.value(), from_native.value());
1299*6777b538SAndroid Build Coastguard Worker   }
1300*6777b538SAndroid Build Coastguard Worker }
1301*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,ConstructWithNUL)1302*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, ConstructWithNUL) {
1303*6777b538SAndroid Build Coastguard Worker   // Assert FPS() works.
1304*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(3U, FPS("a\0b").length());
1305*6777b538SAndroid Build Coastguard Worker 
1306*6777b538SAndroid Build Coastguard Worker   // Test constructor strips '\0'
1307*6777b538SAndroid Build Coastguard Worker   FilePath path(FPS("a\0b"));
1308*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, path.value().length());
1309*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FPL("a"), path.value());
1310*6777b538SAndroid Build Coastguard Worker }
1311*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,AppendWithNUL)1312*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, AppendWithNUL) {
1313*6777b538SAndroid Build Coastguard Worker   // Assert FPS() works.
1314*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(3U, FPS("b\0b").length());
1315*6777b538SAndroid Build Coastguard Worker 
1316*6777b538SAndroid Build Coastguard Worker   // Test Append() strips '\0'
1317*6777b538SAndroid Build Coastguard Worker   FilePath path(FPL("a"));
1318*6777b538SAndroid Build Coastguard Worker   path = path.Append(FPS("b\0b"));
1319*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, path.value().length());
1320*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
1321*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FPL("a\\b"), path.value());
1322*6777b538SAndroid Build Coastguard Worker #else
1323*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(FPL("a/b"), path.value());
1324*6777b538SAndroid Build Coastguard Worker #endif
1325*6777b538SAndroid Build Coastguard Worker }
1326*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,AppendBaseName)1327*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, AppendBaseName) {
1328*6777b538SAndroid Build Coastguard Worker   FilePath dir(FPL("foo"));
1329*6777b538SAndroid Build Coastguard Worker   auto file(SafeBaseName::Create(FPL("bar.txt")));
1330*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(file);
1331*6777b538SAndroid Build Coastguard Worker 
1332*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
1333*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(dir.Append(*file), FilePath(FPL("foo\\bar.txt")));
1334*6777b538SAndroid Build Coastguard Worker #else
1335*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(dir.Append(*file), FilePath(FPL("foo/bar.txt")));
1336*6777b538SAndroid Build Coastguard Worker #endif
1337*6777b538SAndroid Build Coastguard Worker }
1338*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,ReferencesParentWithNUL)1339*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, ReferencesParentWithNUL) {
1340*6777b538SAndroid Build Coastguard Worker   // Assert FPS() works.
1341*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(3U, FPS("..\0").length());
1342*6777b538SAndroid Build Coastguard Worker 
1343*6777b538SAndroid Build Coastguard Worker   // Test ReferencesParent() doesn't break with "..\0"
1344*6777b538SAndroid Build Coastguard Worker   FilePath path(FPS("..\0"));
1345*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(path.ReferencesParent());
1346*6777b538SAndroid Build Coastguard Worker }
1347*6777b538SAndroid Build Coastguard Worker 
1348*6777b538SAndroid Build Coastguard Worker #if defined(FILE_PATH_USES_WIN_SEPARATORS)
TEST_F(FilePathTest,NormalizePathSeparators)1349*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, NormalizePathSeparators) {
1350*6777b538SAndroid Build Coastguard Worker   const struct UnaryTestData cases[] = {
1351*6777b538SAndroid Build Coastguard Worker     { FPL("foo/bar"), FPL("foo\\bar") },
1352*6777b538SAndroid Build Coastguard Worker     { FPL("foo/bar\\betz"), FPL("foo\\bar\\betz") },
1353*6777b538SAndroid Build Coastguard Worker     { FPL("foo\\bar"), FPL("foo\\bar") },
1354*6777b538SAndroid Build Coastguard Worker     { FPL("foo\\bar/betz"), FPL("foo\\bar\\betz") },
1355*6777b538SAndroid Build Coastguard Worker     { FPL("foo"), FPL("foo") },
1356*6777b538SAndroid Build Coastguard Worker     // Trailing slashes don't automatically get stripped.  That's what
1357*6777b538SAndroid Build Coastguard Worker     // StripTrailingSeparators() is for.
1358*6777b538SAndroid Build Coastguard Worker     { FPL("foo\\"), FPL("foo\\") },
1359*6777b538SAndroid Build Coastguard Worker     { FPL("foo/"), FPL("foo\\") },
1360*6777b538SAndroid Build Coastguard Worker     { FPL("foo/bar\\"), FPL("foo\\bar\\") },
1361*6777b538SAndroid Build Coastguard Worker     { FPL("foo\\bar/"), FPL("foo\\bar\\") },
1362*6777b538SAndroid Build Coastguard Worker     { FPL("foo/bar/"), FPL("foo\\bar\\") },
1363*6777b538SAndroid Build Coastguard Worker     { FPL("foo\\bar\\"), FPL("foo\\bar\\") },
1364*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo/bar"), FPL("\\foo\\bar") },
1365*6777b538SAndroid Build Coastguard Worker     { FPL("/foo\\bar"), FPL("\\foo\\bar") },
1366*6777b538SAndroid Build Coastguard Worker     { FPL("c:/foo/bar/"), FPL("c:\\foo\\bar\\") },
1367*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar/"), FPL("\\foo\\bar\\") },
1368*6777b538SAndroid Build Coastguard Worker     { FPL("\\foo\\bar\\"), FPL("\\foo\\bar\\") },
1369*6777b538SAndroid Build Coastguard Worker     { FPL("c:\\foo/bar"), FPL("c:\\foo\\bar") },
1370*6777b538SAndroid Build Coastguard Worker     { FPL("//foo\\bar\\"), FPL("\\\\foo\\bar\\") },
1371*6777b538SAndroid Build Coastguard Worker     { FPL("\\\\foo\\bar\\"), FPL("\\\\foo\\bar\\") },
1372*6777b538SAndroid Build Coastguard Worker     { FPL("//foo\\bar\\"), FPL("\\\\foo\\bar\\") },
1373*6777b538SAndroid Build Coastguard Worker     // This method does not normalize the number of path separators.
1374*6777b538SAndroid Build Coastguard Worker     { FPL("foo\\\\bar"), FPL("foo\\\\bar") },
1375*6777b538SAndroid Build Coastguard Worker     { FPL("foo//bar"), FPL("foo\\\\bar") },
1376*6777b538SAndroid Build Coastguard Worker     { FPL("foo/\\bar"), FPL("foo\\\\bar") },
1377*6777b538SAndroid Build Coastguard Worker     { FPL("foo\\/bar"), FPL("foo\\\\bar") },
1378*6777b538SAndroid Build Coastguard Worker     { FPL("///foo\\\\bar"), FPL("\\\\\\foo\\\\bar") },
1379*6777b538SAndroid Build Coastguard Worker     { FPL("foo//bar///"), FPL("foo\\\\bar\\\\\\") },
1380*6777b538SAndroid Build Coastguard Worker     { FPL("foo/\\bar/\\"), FPL("foo\\\\bar\\\\") },
1381*6777b538SAndroid Build Coastguard Worker     { FPL("/\\foo\\/bar"), FPL("\\\\foo\\\\bar") },
1382*6777b538SAndroid Build Coastguard Worker   };
1383*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
1384*6777b538SAndroid Build Coastguard Worker     FilePath input(cases[i].input);
1385*6777b538SAndroid Build Coastguard Worker     FilePath observed = input.NormalizePathSeparators();
1386*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::StringType(cases[i].expected), observed.value()) <<
1387*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
1388*6777b538SAndroid Build Coastguard Worker   }
1389*6777b538SAndroid Build Coastguard Worker }
1390*6777b538SAndroid Build Coastguard Worker #endif
1391*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,EndsWithSeparator)1392*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, EndsWithSeparator) {
1393*6777b538SAndroid Build Coastguard Worker   const UnaryBooleanTestData cases[] = {
1394*6777b538SAndroid Build Coastguard Worker     { FPL(""), false },
1395*6777b538SAndroid Build Coastguard Worker     { FPL("/"), true },
1396*6777b538SAndroid Build Coastguard Worker     { FPL("foo/"), true },
1397*6777b538SAndroid Build Coastguard Worker     { FPL("bar"), false },
1398*6777b538SAndroid Build Coastguard Worker     { FPL("/foo/bar"), false },
1399*6777b538SAndroid Build Coastguard Worker   };
1400*6777b538SAndroid Build Coastguard Worker   for (const auto& i : cases) {
1401*6777b538SAndroid Build Coastguard Worker     FilePath input = FilePath(i.input).NormalizePathSeparators();
1402*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(i.expected, input.EndsWithSeparator());
1403*6777b538SAndroid Build Coastguard Worker   }
1404*6777b538SAndroid Build Coastguard Worker }
1405*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,AsEndingWithSeparator)1406*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, AsEndingWithSeparator) {
1407*6777b538SAndroid Build Coastguard Worker   const UnaryTestData cases[] = {
1408*6777b538SAndroid Build Coastguard Worker     { FPL(""), FPL("") },
1409*6777b538SAndroid Build Coastguard Worker     { FPL("/"), FPL("/") },
1410*6777b538SAndroid Build Coastguard Worker     { FPL("foo"), FPL("foo/") },
1411*6777b538SAndroid Build Coastguard Worker     { FPL("foo/"), FPL("foo/") }
1412*6777b538SAndroid Build Coastguard Worker   };
1413*6777b538SAndroid Build Coastguard Worker   for (const auto& i : cases) {
1414*6777b538SAndroid Build Coastguard Worker     FilePath input = FilePath(i.input).NormalizePathSeparators();
1415*6777b538SAndroid Build Coastguard Worker     FilePath expected = FilePath(i.expected).NormalizePathSeparators();
1416*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected.value(), input.AsEndingWithSeparator().value());
1417*6777b538SAndroid Build Coastguard Worker   }
1418*6777b538SAndroid Build Coastguard Worker }
1419*6777b538SAndroid Build Coastguard Worker 
1420*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
TEST_F(FilePathTest,ContentUriTest)1421*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, ContentUriTest) {
1422*6777b538SAndroid Build Coastguard Worker   const struct UnaryBooleanTestData cases[] = {
1423*6777b538SAndroid Build Coastguard Worker     { FPL("content://foo.bar"),    true },
1424*6777b538SAndroid Build Coastguard Worker     { FPL("content://foo.bar/"),   true },
1425*6777b538SAndroid Build Coastguard Worker     { FPL("content://foo/bar"),    true },
1426*6777b538SAndroid Build Coastguard Worker     { FPL("CoNTenT://foo.bar"),    true },
1427*6777b538SAndroid Build Coastguard Worker     { FPL("content://"),           true },
1428*6777b538SAndroid Build Coastguard Worker     { FPL("content:///foo.bar"),   true },
1429*6777b538SAndroid Build Coastguard Worker     { FPL("content://3foo/bar"),   true },
1430*6777b538SAndroid Build Coastguard Worker     { FPL("content://_foo/bar"),   true },
1431*6777b538SAndroid Build Coastguard Worker     { FPL(".. "),                  false },
1432*6777b538SAndroid Build Coastguard Worker     { FPL("foo.bar"),              false },
1433*6777b538SAndroid Build Coastguard Worker     { FPL("content:foo.bar"),      false },
1434*6777b538SAndroid Build Coastguard Worker     { FPL("content:/foo.ba"),      false },
1435*6777b538SAndroid Build Coastguard Worker     { FPL("content:/dir/foo.bar"), false },
1436*6777b538SAndroid Build Coastguard Worker     { FPL("content: //foo.bar"),   false },
1437*6777b538SAndroid Build Coastguard Worker     { FPL("content%2a%2f%2f"),     false },
1438*6777b538SAndroid Build Coastguard Worker   };
1439*6777b538SAndroid Build Coastguard Worker 
1440*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(cases); ++i) {
1441*6777b538SAndroid Build Coastguard Worker     FilePath input(cases[i].input);
1442*6777b538SAndroid Build Coastguard Worker     bool observed = input.IsContentUri();
1443*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(cases[i].expected, observed) <<
1444*6777b538SAndroid Build Coastguard Worker               "i: " << i << ", input: " << input.value();
1445*6777b538SAndroid Build Coastguard Worker   }
1446*6777b538SAndroid Build Coastguard Worker }
1447*6777b538SAndroid Build Coastguard Worker #endif
1448*6777b538SAndroid Build Coastguard Worker 
1449*6777b538SAndroid Build Coastguard Worker // Test the operator<<(ostream, FilePath).
TEST_F(FilePathTest,PrintToOstream)1450*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, PrintToOstream) {
1451*6777b538SAndroid Build Coastguard Worker   std::stringstream ss;
1452*6777b538SAndroid Build Coastguard Worker   FilePath fp(FPL("foo"));
1453*6777b538SAndroid Build Coastguard Worker   ss << fp;
1454*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("foo", ss.str());
1455*6777b538SAndroid Build Coastguard Worker }
1456*6777b538SAndroid Build Coastguard Worker 
1457*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING)
TEST_F(FilePathTest,TracedValueSupport)1458*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, TracedValueSupport) {
1459*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(perfetto::TracedValueToString(FilePath(FPL("foo"))), "foo");
1460*6777b538SAndroid Build Coastguard Worker }
1461*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
1462*6777b538SAndroid Build Coastguard Worker 
1463*6777b538SAndroid Build Coastguard Worker // Test GetHFSDecomposedForm should return empty result for invalid UTF-8
1464*6777b538SAndroid Build Coastguard Worker // strings.
1465*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
TEST_F(FilePathTest,GetHFSDecomposedFormWithInvalidInput)1466*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, GetHFSDecomposedFormWithInvalidInput) {
1467*6777b538SAndroid Build Coastguard Worker   const FilePath::CharType* cases[] = {
1468*6777b538SAndroid Build Coastguard Worker     FPL("\xc3\x28"),
1469*6777b538SAndroid Build Coastguard Worker     FPL("\xe2\x82\x28"),
1470*6777b538SAndroid Build Coastguard Worker     FPL("\xe2\x28\xa1"),
1471*6777b538SAndroid Build Coastguard Worker     FPL("\xf0\x28\x8c\xbc"),
1472*6777b538SAndroid Build Coastguard Worker     FPL("\xf0\x28\x8c\x28"),
1473*6777b538SAndroid Build Coastguard Worker   };
1474*6777b538SAndroid Build Coastguard Worker   for (auto* invalid_input : cases) {
1475*6777b538SAndroid Build Coastguard Worker     FilePath::StringType observed = FilePath::GetHFSDecomposedForm(
1476*6777b538SAndroid Build Coastguard Worker         invalid_input);
1477*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(observed.empty());
1478*6777b538SAndroid Build Coastguard Worker   }
1479*6777b538SAndroid Build Coastguard Worker }
1480*6777b538SAndroid Build Coastguard Worker 
TEST_F(FilePathTest,CompareIgnoreCaseWithInvalidInput)1481*6777b538SAndroid Build Coastguard Worker TEST_F(FilePathTest, CompareIgnoreCaseWithInvalidInput) {
1482*6777b538SAndroid Build Coastguard Worker   const FilePath::CharType* cases[] = {
1483*6777b538SAndroid Build Coastguard Worker       FPL("\xc3\x28"),         FPL("\xe2\x82\x28"),     FPL("\xe2\x28\xa1"),
1484*6777b538SAndroid Build Coastguard Worker       FPL("\xf0\x28\x8c\xbc"), FPL("\xf0\x28\x8c\x28"),
1485*6777b538SAndroid Build Coastguard Worker   };
1486*6777b538SAndroid Build Coastguard Worker   for (auto* invalid_input : cases) {
1487*6777b538SAndroid Build Coastguard Worker     // All example inputs will be greater than the string "fixed".
1488*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(FilePath::CompareIgnoreCase(invalid_input, FPL("fixed")), 1);
1489*6777b538SAndroid Build Coastguard Worker   }
1490*6777b538SAndroid Build Coastguard Worker }
1491*6777b538SAndroid Build Coastguard Worker #endif
1492*6777b538SAndroid Build Coastguard Worker 
1493*6777b538SAndroid Build Coastguard Worker }  // namespace base
1494