• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License.  You may obtain a copy
6  * of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.google.common.io;
18 
19 import static com.google.common.base.Charsets.UTF_8;
20 import static com.google.common.io.Files.simplifyPath;
21 
22 import com.google.common.base.CharMatcher;
23 import com.google.common.base.Splitter;
24 import java.io.IOException;
25 import java.net.URL;
26 import java.util.Iterator;
27 import junit.framework.TestCase;
28 
29 /**
30  * Unit tests for {@link Files#simplifyPath}.
31  *
32  * @author Pablo Bellver
33  */
34 public class FilesSimplifyPathTest extends TestCase {
35 
testSimplifyEmptyString()36   public void testSimplifyEmptyString() {
37     assertEquals(".", simplifyPath(""));
38   }
39 
testSimplifyDot()40   public void testSimplifyDot() {
41     assertEquals(".", simplifyPath("."));
42   }
43 
testSimplifyWhiteSpace()44   public void testSimplifyWhiteSpace() {
45     assertEquals(" ", simplifyPath(" "));
46   }
47 
testSimplify2()48   public void testSimplify2() {
49     assertEquals("x", simplifyPath("x"));
50   }
51 
testSimplify3()52   public void testSimplify3() {
53     assertEquals("/a/b/c/d", simplifyPath("/a/b/c/d"));
54   }
55 
testSimplify4()56   public void testSimplify4() {
57     assertEquals("/a/b/c/d", simplifyPath("/a/b/c/d/"));
58   }
59 
testSimplify5()60   public void testSimplify5() {
61     assertEquals("/a/b", simplifyPath("/a//b"));
62   }
63 
testSimplify6()64   public void testSimplify6() {
65     assertEquals("/a/b", simplifyPath("//a//b/"));
66   }
67 
testSimplify7()68   public void testSimplify7() {
69     assertEquals("/", simplifyPath("/.."));
70   }
71 
testSimplify8()72   public void testSimplify8() {
73     assertEquals("/", simplifyPath("/././././"));
74   }
75 
testSimplify9()76   public void testSimplify9() {
77     assertEquals("/a", simplifyPath("/a/b/.."));
78   }
79 
testSimplify10()80   public void testSimplify10() {
81     assertEquals("/", simplifyPath("/a/b/../../.."));
82   }
83 
testSimplify11()84   public void testSimplify11() {
85     assertEquals("/", simplifyPath("//a//b/..////../..//"));
86   }
87 
testSimplify12()88   public void testSimplify12() {
89     assertEquals("/x", simplifyPath("//a//../x//"));
90   }
91 
testSimplify13()92   public void testSimplify13() {
93     assertEquals("../c", simplifyPath("a/b/../../../c"));
94   }
95 
testSimplifyDotDot()96   public void testSimplifyDotDot() {
97     assertEquals("..", simplifyPath(".."));
98   }
99 
testSimplifyDotDotSlash()100   public void testSimplifyDotDotSlash() {
101     assertEquals("..", simplifyPath("../"));
102     assertEquals("..", simplifyPath("a/../.."));
103     assertEquals("..", simplifyPath("a/../../"));
104   }
105 
testSimplifyDotDots()106   public void testSimplifyDotDots() {
107     assertEquals("../..", simplifyPath("a/../../.."));
108     assertEquals("../../..", simplifyPath("a/../../../.."));
109   }
110 
testSimplifyRootedDotDots()111   public void testSimplifyRootedDotDots() {
112     assertEquals("/", simplifyPath("/../../.."));
113     assertEquals("/", simplifyPath("/../../../"));
114   }
115 
116   // b/4558855
testMadbotsBug()117   public void testMadbotsBug() {
118     assertEquals("../this", simplifyPath("../this"));
119     assertEquals("../this/is/ok", simplifyPath("../this/is/ok"));
120     assertEquals("../ok", simplifyPath("../this/../ok"));
121   }
122 
123   // https://code.google.com/p/guava-libraries/issues/detail?id=705
test705()124   public void test705() {
125     assertEquals("../b", simplifyPath("x/../../b"));
126     assertEquals("b", simplifyPath("x/../b"));
127   }
128 
129   // https://code.google.com/p/guava-libraries/issues/detail?id=716
test716()130   public void test716() {
131     assertEquals("b", simplifyPath("./b"));
132     assertEquals("b", simplifyPath("./b/."));
133     assertEquals("b", simplifyPath("././b/./."));
134     assertEquals("b", simplifyPath("././b"));
135     assertEquals("a/b", simplifyPath("./a/b"));
136   }
137 
testHiddenFiles()138   public void testHiddenFiles() {
139     assertEquals(".b", simplifyPath(".b"));
140     assertEquals(".b", simplifyPath("./.b"));
141     assertEquals(".metadata/b", simplifyPath(".metadata/b"));
142     assertEquals(".metadata/b", simplifyPath("./.metadata/b"));
143   }
144 
145   // https://code.google.com/p/guava-libraries/issues/detail?id=716
testMultipleDotFilenames()146   public void testMultipleDotFilenames() {
147     assertEquals("..a", simplifyPath("..a"));
148     assertEquals("/..a", simplifyPath("/..a"));
149     assertEquals("/..a/..b", simplifyPath("/..a/..b"));
150     assertEquals("/.....a/..b", simplifyPath("/.....a/..b"));
151     assertEquals("..../....", simplifyPath("..../...."));
152     assertEquals("..a../..b..", simplifyPath("..a../..b.."));
153   }
154 
testSlashDot()155   public void testSlashDot() {
156     assertEquals("/", simplifyPath("/."));
157   }
158 
159   // http://code.google.com/p/guava-libraries/issues/detail?id=722
testInitialSlashDotDot()160   public void testInitialSlashDotDot() {
161     assertEquals("/c", simplifyPath("/../c"));
162   }
163 
164   // http://code.google.com/p/guava-libraries/issues/detail?id=722
testInitialSlashDot()165   public void testInitialSlashDot() {
166     assertEquals("/a", simplifyPath("/./a"));
167     assertEquals("/.a", simplifyPath("/.a/a/.."));
168   }
169 
170   // http://code.google.com/p/guava-libraries/issues/detail?id=722
testConsecutiveParentsAfterPresent()171   public void testConsecutiveParentsAfterPresent() {
172     assertEquals("../..", simplifyPath("./../../"));
173     assertEquals("../..", simplifyPath("./.././../"));
174   }
175 
176   /*
177    * We co-opt some URI resolution tests for our purposes.
178    * Some of the tests have queries and anchors that are a little silly here.
179    */
180 
181   /** http://gbiv.com/protocols/uri/rfc/rfc2396.html#rfc.section.C.1 */
testRfc2396Normal()182   public void testRfc2396Normal() {
183     assertEquals("/a/b/c/g", simplifyPath("/a/b/c/g"));
184     assertEquals("/a/b/c/g", simplifyPath("/a/b/c/./g"));
185     assertEquals("/a/b/c/g", simplifyPath("/a/b/c/g/"));
186 
187     assertEquals("/a/b/c/g?y", simplifyPath("/a/b/c/g?y"));
188     assertEquals("/a/b/c/g#s", simplifyPath("/a/b/c/g#s"));
189     assertEquals("/a/b/c/g?y#s", simplifyPath("/a/b/c/g?y#s"));
190     assertEquals("/a/b/c/;x", simplifyPath("/a/b/c/;x"));
191     assertEquals("/a/b/c/g;x", simplifyPath("/a/b/c/g;x"));
192     assertEquals("/a/b/c/g;x?y#s", simplifyPath("/a/b/c/g;x?y#s"));
193     assertEquals("/a/b/c", simplifyPath("/a/b/c/."));
194     assertEquals("/a/b/c", simplifyPath("/a/b/c/./"));
195     assertEquals("/a/b", simplifyPath("/a/b/c/.."));
196     assertEquals("/a/b", simplifyPath("/a/b/c/../"));
197     assertEquals("/a/b/g", simplifyPath("/a/b/c/../g"));
198     assertEquals("/a", simplifyPath("/a/b/c/../.."));
199     assertEquals("/a", simplifyPath("/a/b/c/../../"));
200     assertEquals("/a/g", simplifyPath("/a/b/c/../../g"));
201   }
202 
203   /** http://gbiv.com/protocols/uri/rfc/rfc2396.html#rfc.section.C.2 */
testRfc2396Abnormal()204   public void testRfc2396Abnormal() {
205     assertEquals("/a/b/c/g.", simplifyPath("/a/b/c/g."));
206     assertEquals("/a/b/c/.g", simplifyPath("/a/b/c/.g"));
207     assertEquals("/a/b/c/g..", simplifyPath("/a/b/c/g.."));
208     assertEquals("/a/b/c/..g", simplifyPath("/a/b/c/..g"));
209     assertEquals("/a/b/g", simplifyPath("/a/b/c/./../g"));
210     assertEquals("/a/b/c/g", simplifyPath("/a/b/c/./g/."));
211     assertEquals("/a/b/c/g/h", simplifyPath("/a/b/c/g/./h"));
212     assertEquals("/a/b/c/h", simplifyPath("/a/b/c/g/../h"));
213     assertEquals("/a/b/c/g;x=1/y", simplifyPath("/a/b/c/g;x=1/./y"));
214     assertEquals("/a/b/c/y", simplifyPath("/a/b/c/g;x=1/../y"));
215   }
216 
217   /** http://gbiv.com/protocols/uri/rfc/rfc3986.html#relative-normal */
testRfc3986Normal()218   public void testRfc3986Normal() {
219     assertEquals("/a/b/c/g", simplifyPath("/a/b/c/g"));
220     assertEquals("/a/b/c/g", simplifyPath("/a/b/c/./g"));
221     assertEquals("/a/b/c/g", simplifyPath("/a/b/c/g/"));
222 
223     assertEquals("/a/b/c/g?y", simplifyPath("/a/b/c/g?y"));
224     assertEquals("/a/b/c/g#s", simplifyPath("/a/b/c/g#s"));
225     assertEquals("/a/b/c/g?y#s", simplifyPath("/a/b/c/g?y#s"));
226     assertEquals("/a/b/c/;x", simplifyPath("/a/b/c/;x"));
227     assertEquals("/a/b/c/g;x", simplifyPath("/a/b/c/g;x"));
228     assertEquals("/a/b/c/g;x?y#s", simplifyPath("/a/b/c/g;x?y#s"));
229 
230     assertEquals("/a/b/c", simplifyPath("/a/b/c/."));
231     assertEquals("/a/b/c", simplifyPath("/a/b/c/./"));
232     assertEquals("/a/b", simplifyPath("/a/b/c/.."));
233     assertEquals("/a/b", simplifyPath("/a/b/c/../"));
234     assertEquals("/a/b/g", simplifyPath("/a/b/c/../g"));
235     assertEquals("/a", simplifyPath("/a/b/c/../.."));
236     assertEquals("/a", simplifyPath("/a/b/c/../../"));
237     assertEquals("/a/g", simplifyPath("/a/b/c/../../g"));
238   }
239 
240   /** http://gbiv.com/protocols/uri/rfc/rfc3986.html#relative-abnormal */
testRfc3986Abnormal()241   public void testRfc3986Abnormal() {
242     assertEquals("/g", simplifyPath("/a/b/c/../../../g"));
243     assertEquals("/g", simplifyPath("/a/b/c/../../../../g"));
244 
245     assertEquals("/a/b/c/g.", simplifyPath("/a/b/c/g."));
246     assertEquals("/a/b/c/.g", simplifyPath("/a/b/c/.g"));
247     assertEquals("/a/b/c/g..", simplifyPath("/a/b/c/g.."));
248     assertEquals("/a/b/c/..g", simplifyPath("/a/b/c/..g"));
249     assertEquals("/a/b/g", simplifyPath("/a/b/c/./../g"));
250     assertEquals("/a/b/c/g", simplifyPath("/a/b/c/./g/."));
251     assertEquals("/a/b/c/g/h", simplifyPath("/a/b/c/g/./h"));
252     assertEquals("/a/b/c/h", simplifyPath("/a/b/c/g/../h"));
253     assertEquals("/a/b/c/g;x=1/y", simplifyPath("/a/b/c/g;x=1/./y"));
254     assertEquals("/a/b/c/y", simplifyPath("/a/b/c/g;x=1/../y"));
255   }
256 
testExtensiveWithAbsolutePrefix()257   public void testExtensiveWithAbsolutePrefix() throws IOException {
258     // Inputs are /b/c/<every possible 10-character string of characters "a./">
259     // Expected outputs are from realpath -s.
260     doExtensiveTest("testdata/simplifypathwithabsoluteprefixtests.txt");
261   }
262 
testExtensiveNoPrefix()263   public void testExtensiveNoPrefix() throws IOException {
264     /*
265      * Inputs are <every possible 10-character string of characters "a./">
266      *
267      * Expected outputs are generated by the code itself, but they've been
268      * checked against the inputs under Bash in order to confirm that the two
269      * forms are equivalent (though not necessarily minimal, though we hope this
270      * to be the case). Thus, this test is more of a regression test.
271      *
272      * Rough instructions to regenerate the test outputs and verify correctness:
273      * - Temporarily change this test:
274      * --- Comment out assertEquals.
275      * --- System.out.println(input + " " + simplifyPath(input));
276      * --- fail(). (If the test were to pass, its output would be hidden.)
277      * - Run the test.
278      * - Pull the relevant lines of output from the test into a testcases file.
279      * - Test the output:
280      * --- cat testcases | while read L; do
281      *       X=($L)
282      *       A=$( cd /b/c && sudo mkdir -p ${X[0]} && cd ${X[0]} && pwd |
283      *           sed -e 's#^//*#/#' )
284      *       B=$( cd /b/c && cd ${X[1]} && pwd )
285      *       cmp -s <(echo $A) <(echo $B) || echo "$X[0] -> $A vs. $B"
286      *     done | tee testoutput
287      * - Move that testcases file to the appropriate name under testdata.
288      *
289      * The last test will take hours, and if it passes, the output will be empty.
290      */
291     doExtensiveTest("testdata/simplifypathnoprefixtests.txt");
292   }
293 
doExtensiveTest(String resourceName)294   private void doExtensiveTest(String resourceName) throws IOException {
295     Splitter splitter = Splitter.on(CharMatcher.whitespace());
296     URL url = getClass().getResource(resourceName);
297     for (String line : Resources.readLines(url, UTF_8)) {
298       Iterator<String> iterator = splitter.split(line).iterator();
299       String input = iterator.next();
300       String expectedOutput = iterator.next();
301       assertFalse(iterator.hasNext());
302       assertEquals(expectedOutput, simplifyPath(input));
303     }
304   }
305 }
306