Ninja
util_test.cc
Go to the documentation of this file.
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "util.h"
16 
17 #include "test.h"
18 
19 using namespace std;
20 
21 namespace {
22 
23 void CanonicalizePath(string* path) {
24  uint64_t unused;
25  ::CanonicalizePath(path, &unused);
26 }
27 
28 } // namespace
29 
30 TEST(CanonicalizePath, PathSamples) {
31  string path;
32 
33  CanonicalizePath(&path);
34  EXPECT_EQ("", path);
35 
36  path = "foo.h";
37  CanonicalizePath(&path);
38  EXPECT_EQ("foo.h", path);
39 
40  path = "./foo.h";
41  CanonicalizePath(&path);
42  EXPECT_EQ("foo.h", path);
43 
44  path = "./foo/./bar.h";
45  CanonicalizePath(&path);
46  EXPECT_EQ("foo/bar.h", path);
47 
48  path = "./x/foo/../bar.h";
49  CanonicalizePath(&path);
50  EXPECT_EQ("x/bar.h", path);
51 
52  path = "./x/foo/../../bar.h";
53  CanonicalizePath(&path);
54  EXPECT_EQ("bar.h", path);
55 
56  path = "foo//bar";
57  CanonicalizePath(&path);
58  EXPECT_EQ("foo/bar", path);
59 
60  path = "foo//.//..///bar";
61  CanonicalizePath(&path);
62  EXPECT_EQ("bar", path);
63 
64  path = "./x/../foo/../../bar.h";
65  CanonicalizePath(&path);
66  EXPECT_EQ("../bar.h", path);
67 
68  path = "foo/./.";
69  CanonicalizePath(&path);
70  EXPECT_EQ("foo", path);
71 
72  path = "foo/bar/..";
73  CanonicalizePath(&path);
74  EXPECT_EQ("foo", path);
75 
76  path = "foo/.hidden_bar";
77  CanonicalizePath(&path);
78  EXPECT_EQ("foo/.hidden_bar", path);
79 
80  path = "/foo";
81  CanonicalizePath(&path);
82  EXPECT_EQ("/foo", path);
83 
84  path = "//foo";
85  CanonicalizePath(&path);
86 #ifdef _WIN32
87  EXPECT_EQ("//foo", path);
88 #else
89  EXPECT_EQ("/foo", path);
90 #endif
91 
92  path = "/";
93  CanonicalizePath(&path);
94  EXPECT_EQ("", path);
95 
96  path = "/foo/..";
97  CanonicalizePath(&path);
98  EXPECT_EQ("", path);
99 
100  path = ".";
101  CanonicalizePath(&path);
102  EXPECT_EQ(".", path);
103 
104  path = "./.";
105  CanonicalizePath(&path);
106  EXPECT_EQ(".", path);
107 
108  path = "foo/..";
109  CanonicalizePath(&path);
110  EXPECT_EQ(".", path);
111 }
112 
113 #ifdef _WIN32
114 TEST(CanonicalizePath, PathSamplesWindows) {
115  string path;
116 
117  CanonicalizePath(&path);
118  EXPECT_EQ("", path);
119 
120  path = "foo.h";
121  CanonicalizePath(&path);
122  EXPECT_EQ("foo.h", path);
123 
124  path = ".\\foo.h";
125  CanonicalizePath(&path);
126  EXPECT_EQ("foo.h", path);
127 
128  path = ".\\foo\\.\\bar.h";
129  CanonicalizePath(&path);
130  EXPECT_EQ("foo/bar.h", path);
131 
132  path = ".\\x\\foo\\..\\bar.h";
133  CanonicalizePath(&path);
134  EXPECT_EQ("x/bar.h", path);
135 
136  path = ".\\x\\foo\\..\\..\\bar.h";
137  CanonicalizePath(&path);
138  EXPECT_EQ("bar.h", path);
139 
140  path = "foo\\\\bar";
141  CanonicalizePath(&path);
142  EXPECT_EQ("foo/bar", path);
143 
144  path = "foo\\\\.\\\\..\\\\\\bar";
145  CanonicalizePath(&path);
146  EXPECT_EQ("bar", path);
147 
148  path = ".\\x\\..\\foo\\..\\..\\bar.h";
149  CanonicalizePath(&path);
150  EXPECT_EQ("../bar.h", path);
151 
152  path = "foo\\.\\.";
153  CanonicalizePath(&path);
154  EXPECT_EQ("foo", path);
155 
156  path = "foo\\bar\\..";
157  CanonicalizePath(&path);
158  EXPECT_EQ("foo", path);
159 
160  path = "foo\\.hidden_bar";
161  CanonicalizePath(&path);
162  EXPECT_EQ("foo/.hidden_bar", path);
163 
164  path = "\\foo";
165  CanonicalizePath(&path);
166  EXPECT_EQ("/foo", path);
167 
168  path = "\\\\foo";
169  CanonicalizePath(&path);
170  EXPECT_EQ("//foo", path);
171 
172  path = "\\";
173  CanonicalizePath(&path);
174  EXPECT_EQ("", path);
175 }
176 
177 TEST(CanonicalizePath, SlashTracking) {
178  string path;
179  uint64_t slash_bits;
180 
181  path = "foo.h";
182  CanonicalizePath(&path, &slash_bits);
183  EXPECT_EQ("foo.h", path);
184  EXPECT_EQ(0, slash_bits);
185 
186  path = "a\\foo.h";
187  CanonicalizePath(&path, &slash_bits);
188  EXPECT_EQ("a/foo.h", path);
189  EXPECT_EQ(1, slash_bits);
190 
191  path = "a/bcd/efh\\foo.h";
192  CanonicalizePath(&path, &slash_bits);
193  EXPECT_EQ("a/bcd/efh/foo.h", path);
194  EXPECT_EQ(4, slash_bits);
195 
196  path = "a\\bcd/efh\\foo.h";
197  CanonicalizePath(&path, &slash_bits);
198  EXPECT_EQ("a/bcd/efh/foo.h", path);
199  EXPECT_EQ(5, slash_bits);
200 
201  path = "a\\bcd\\efh\\foo.h";
202  CanonicalizePath(&path, &slash_bits);
203  EXPECT_EQ("a/bcd/efh/foo.h", path);
204  EXPECT_EQ(7, slash_bits);
205 
206  path = "a/bcd/efh/foo.h";
207  CanonicalizePath(&path, &slash_bits);
208  EXPECT_EQ("a/bcd/efh/foo.h", path);
209  EXPECT_EQ(0, slash_bits);
210 
211  path = "a\\./efh\\foo.h";
212  CanonicalizePath(&path, &slash_bits);
213  EXPECT_EQ("a/efh/foo.h", path);
214  EXPECT_EQ(3, slash_bits);
215 
216  path = "a\\../efh\\foo.h";
217  CanonicalizePath(&path, &slash_bits);
218  EXPECT_EQ("efh/foo.h", path);
219  EXPECT_EQ(1, slash_bits);
220 
221  path = "a\\b\\c\\d\\e\\f\\g\\foo.h";
222  CanonicalizePath(&path, &slash_bits);
223  EXPECT_EQ("a/b/c/d/e/f/g/foo.h", path);
224  EXPECT_EQ(127, slash_bits);
225 
226  path = "a\\b\\c\\..\\..\\..\\g\\foo.h";
227  CanonicalizePath(&path, &slash_bits);
228  EXPECT_EQ("g/foo.h", path);
229  EXPECT_EQ(1, slash_bits);
230 
231  path = "a\\b/c\\../../..\\g\\foo.h";
232  CanonicalizePath(&path, &slash_bits);
233  EXPECT_EQ("g/foo.h", path);
234  EXPECT_EQ(1, slash_bits);
235 
236  path = "a\\b/c\\./../..\\g\\foo.h";
237  CanonicalizePath(&path, &slash_bits);
238  EXPECT_EQ("a/g/foo.h", path);
239  EXPECT_EQ(3, slash_bits);
240 
241  path = "a\\b/c\\./../..\\g/foo.h";
242  CanonicalizePath(&path, &slash_bits);
243  EXPECT_EQ("a/g/foo.h", path);
244  EXPECT_EQ(1, slash_bits);
245 
246  path = "a\\\\\\foo.h";
247  CanonicalizePath(&path, &slash_bits);
248  EXPECT_EQ("a/foo.h", path);
249  EXPECT_EQ(1, slash_bits);
250 
251  path = "a/\\\\foo.h";
252  CanonicalizePath(&path, &slash_bits);
253  EXPECT_EQ("a/foo.h", path);
254  EXPECT_EQ(0, slash_bits);
255 
256  path = "a\\//foo.h";
257  CanonicalizePath(&path, &slash_bits);
258  EXPECT_EQ("a/foo.h", path);
259  EXPECT_EQ(1, slash_bits);
260 }
261 
262 TEST(CanonicalizePath, CanonicalizeNotExceedingLen) {
263  // Make sure searching \/ doesn't go past supplied len.
264  char buf[] = "foo/bar\\baz.h\\"; // Last \ past end.
265  uint64_t slash_bits;
266  size_t size = 13;
267  ::CanonicalizePath(buf, &size, &slash_bits);
268  EXPECT_EQ(0, strncmp("foo/bar/baz.h", buf, size));
269  EXPECT_EQ(2, slash_bits); // Not including the trailing one.
270 }
271 
272 TEST(CanonicalizePath, TooManyComponents) {
273  string path;
274  uint64_t slash_bits;
275 
276  // 64 is OK.
277  path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./"
278  "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x.h";
279  CanonicalizePath(&path, &slash_bits);
280  EXPECT_EQ(slash_bits, 0x0);
281 
282  // Backslashes version.
283  path =
284  "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
285  "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
286  "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
287  "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\x.h";
288 
289  CanonicalizePath(&path, &slash_bits);
290  EXPECT_EQ(slash_bits, 0xffffffff);
291 
292  // 65 is OK if #component is less than 60 after path canonicalization.
293  path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./"
294  "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x/y.h";
295  CanonicalizePath(&path, &slash_bits);
296  EXPECT_EQ(slash_bits, 0x0);
297 
298  // Backslashes version.
299  path =
300  "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
301  "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
302  "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
303  "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\x\\y.h";
304  CanonicalizePath(&path, &slash_bits);
305  EXPECT_EQ(slash_bits, 0x1ffffffff);
306 
307 
308  // 59 after canonicalization is OK.
309  path = "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
310  "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/x/y.h";
311  EXPECT_EQ(58, std::count(path.begin(), path.end(), '/'));
312  CanonicalizePath(&path, &slash_bits);
313  EXPECT_EQ(slash_bits, 0x0);
314 
315  // Backslashes version.
316  path =
317  "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
318  "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
319  "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
320  "a\\a\\a\\a\\a\\a\\a\\a\\a\\x\\y.h";
321  EXPECT_EQ(58, std::count(path.begin(), path.end(), '\\'));
322  CanonicalizePath(&path, &slash_bits);
323  EXPECT_EQ(slash_bits, 0x3ffffffffffffff);
324 }
325 #endif
326 
328  string path, err;
329  path = "../../foo/bar.h";
330  CanonicalizePath(&path);
331  EXPECT_EQ("../../foo/bar.h", path);
332 
333  path = "test/../../foo/bar.h";
334  CanonicalizePath(&path);
335  EXPECT_EQ("../foo/bar.h", path);
336 }
337 
338 TEST(CanonicalizePath, AbsolutePath) {
339  string path = "/usr/include/stdio.h";
340  string err;
341  CanonicalizePath(&path);
342  EXPECT_EQ("/usr/include/stdio.h", path);
343 }
344 
345 TEST(CanonicalizePath, NotNullTerminated) {
346  string path;
347  size_t len;
348  uint64_t unused;
349 
350  path = "foo/. bar/.";
351  len = strlen("foo/."); // Canonicalize only the part before the space.
352  CanonicalizePath(&path[0], &len, &unused);
353  EXPECT_EQ(strlen("foo"), len);
354  EXPECT_EQ("foo/. bar/.", string(path));
355 
356  path = "foo/../file bar/.";
357  len = strlen("foo/../file");
358  CanonicalizePath(&path[0], &len, &unused);
359  EXPECT_EQ(strlen("file"), len);
360  EXPECT_EQ("file ./file bar/.", string(path));
361 }
362 
363 TEST(PathEscaping, TortureTest) {
364  string result;
365 
366  GetWin32EscapedString("foo bar\\\"'$@d!st!c'\\path'\\", &result);
367  EXPECT_EQ("\"foo bar\\\\\\\"'$@d!st!c'\\path'\\\\\"", result);
368  result.clear();
369 
370  GetShellEscapedString("foo bar\"/'$@d!st!c'/path'", &result);
371  EXPECT_EQ("'foo bar\"/'\\''$@d!st!c'\\''/path'\\'''", result);
372 }
373 
374 TEST(PathEscaping, SensiblePathsAreNotNeedlesslyEscaped) {
375  const char* path = "some/sensible/path/without/crazy/characters.c++";
376  string result;
377 
378  GetWin32EscapedString(path, &result);
379  EXPECT_EQ(path, result);
380  result.clear();
381 
382  GetShellEscapedString(path, &result);
383  EXPECT_EQ(path, result);
384 }
385 
386 TEST(PathEscaping, SensibleWin32PathsAreNotNeedlesslyEscaped) {
387  const char* path = "some\\sensible\\path\\without\\crazy\\characters.c++";
388  string result;
389 
390  GetWin32EscapedString(path, &result);
391  EXPECT_EQ(path, result);
392 }
393 
394 TEST(StripAnsiEscapeCodes, EscapeAtEnd) {
395  string stripped = StripAnsiEscapeCodes("foo\33");
396  EXPECT_EQ("foo", stripped);
397 
398  stripped = StripAnsiEscapeCodes("foo\33[");
399  EXPECT_EQ("foo", stripped);
400 }
401 
402 TEST(StripAnsiEscapeCodes, StripColors) {
403  // An actual clang warning.
404  string input = "\33[1maffixmgr.cxx:286:15: \33[0m\33[0;1;35mwarning: "
405  "\33[0m\33[1musing the result... [-Wparentheses]\33[0m";
406  string stripped = StripAnsiEscapeCodes(input);
407  EXPECT_EQ("affixmgr.cxx:286:15: warning: using the result... [-Wparentheses]",
408  stripped);
409 }
410 
411 TEST(ElideMiddle, NothingToElide) {
412  string input = "Nothing to elide in this short string.";
413  EXPECT_EQ(input, ElideMiddle(input, 80));
414  EXPECT_EQ(input, ElideMiddle(input, 38));
415  EXPECT_EQ("", ElideMiddle(input, 0));
416  EXPECT_EQ(".", ElideMiddle(input, 1));
417  EXPECT_EQ("..", ElideMiddle(input, 2));
418  EXPECT_EQ("...", ElideMiddle(input, 3));
419 }
420 
421 TEST(ElideMiddle, ElideInTheMiddle) {
422  string input = "01234567890123456789";
423  string elided = ElideMiddle(input, 10);
424  EXPECT_EQ("012...789", elided);
425  EXPECT_EQ("01234567...23456789", ElideMiddle(input, 19));
426 }
void GetWin32EscapedString(const string &input, string *result)
Definition: util.cc:303
void GetShellEscapedString(const string &input, string *result)
Definition: util.cc:276
TEST(CanonicalizePath, PathSamples)
Definition: util_test.cc:30
#define EXPECT_EQ(a, b)
Definition: test.h:64
string StripAnsiEscapeCodes(const string &in)
Definition: util.cc:482
void CanonicalizePath(string *path, uint64_t *slash_bits)
Definition: util.cc:122
unsigned long long uint64_t
Definition: win32port.h:29
string ElideMiddle(const string &str, size_t width)
Definition: util.cc:833