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