PathOps.java revision 893:f06f30b29f36
1/*
2 * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/* @test
25 * @bug 4313887
26 * @summary Unit test for java.nio.file.Path path operations
27 */
28
29import java.nio.file.*;
30
31public class PathOps {
32
33    static final java.io.PrintStream out = System.out;
34
35    private String input;
36    private Path path;
37    private Exception exc;
38
39    private PathOps(String s) {
40        out.println();
41        input = s;
42        try {
43            path = FileSystems.getDefault().getPath(s);
44            out.format("%s -> %s", s, path);
45        } catch (Exception x) {
46            exc = x;
47            out.format("%s -> %s", s, x);
48        }
49        out.println();
50    }
51
52    Path path() {
53        return path;
54    }
55
56    void fail() {
57        throw new RuntimeException("PathOps failed");
58    }
59
60    void checkPath() {
61        if (path == null) {
62            throw new InternalError("path is null");
63        }
64    }
65
66    void check(Object result, String expected) {
67        out.format("\tExpected: %s\n", expected);
68        out.format("\tActual: %s\n",  result);
69        if (result == null) {
70            if (expected == null) return;
71        } else {
72            // compare string representations
73            if (expected != null && result.toString().equals(expected.toString()))
74                return;
75        }
76        fail();
77    }
78
79    void check(Object result, boolean expected) {
80        check(result, Boolean.toString(expected));
81    }
82
83    PathOps root(String expected) {
84        out.println("check root");
85        checkPath();
86        check(path.getRoot(), expected);
87        return this;
88    }
89
90    PathOps parent(String expected) {
91        out.println("check parent");
92        checkPath();
93        check(path.getParent(), expected);
94        return this;
95    }
96
97    PathOps name(String expected) {
98        out.println("check name");
99        checkPath();
100        check(path.getName(), expected);
101        return this;
102    }
103
104    PathOps element(int index, String expected) {
105        out.format("check element %d\n", index);
106        checkPath();
107        check(path.getName(index), expected);
108        return this;
109    }
110
111    PathOps subpath(int startIndex, int endIndex, String expected) {
112        out.format("test subpath(%d,%d)\n", startIndex, endIndex);
113        checkPath();
114        check(path.subpath(startIndex, endIndex), expected);
115        return this;
116    }
117
118    PathOps starts(String prefix) {
119        out.format("test startsWith with %s\n", prefix);
120        checkPath();
121        Path s = FileSystems.getDefault().getPath(prefix);
122        check(path.startsWith(s), true);
123        return this;
124    }
125
126    PathOps notStarts(String prefix) {
127        out.format("test not startsWith with %s\n", prefix);
128        checkPath();
129        Path s = FileSystems.getDefault().getPath(prefix);
130        check(path.startsWith(s), false);
131        return this;
132    }
133
134    PathOps ends(String suffix) {
135        out.format("test endsWith %s\n", suffix);
136        checkPath();
137        Path s = FileSystems.getDefault().getPath(suffix);
138        check(path.endsWith(s), true);
139        return this;
140    }
141
142    PathOps notEnds(String suffix) {
143        out.format("test not endsWith %s\n", suffix);
144        checkPath();
145        Path s = FileSystems.getDefault().getPath(suffix);
146        check(path.endsWith(s), false);
147        return this;
148    }
149
150    PathOps absolute() {
151        out.println("check path is absolute");
152        checkPath();
153        check(path.isAbsolute(), true);
154        return this;
155    }
156
157    PathOps notAbsolute() {
158        out.println("check path is not absolute");
159        checkPath();
160        check(path.isAbsolute(), false);
161        return this;
162    }
163
164    PathOps resolve(String other, String expected) {
165        out.format("test resolve %s\n", other);
166        checkPath();
167        check(path.resolve(other), expected);
168        return this;
169    }
170
171    PathOps relativize(String other, String expected) {
172        out.format("test relativize %s\n", other);
173        checkPath();
174        Path that = FileSystems.getDefault().getPath(other);
175        check(path.relativize(that), expected);
176        return this;
177    }
178
179    PathOps normalize(String expected) {
180        out.println("check normalized path");
181        checkPath();
182        check(path.normalize(), expected);
183        return this;
184    }
185
186    PathOps string(String expected) {
187        out.println("check string representation");
188        checkPath();
189        check(path, expected);
190        return this;
191    }
192
193    PathOps invalid() {
194        if (!(exc instanceof InvalidPathException)) {
195            out.println("InvalidPathException not thrown as expected");
196            fail();
197        }
198        return this;
199    }
200
201    static PathOps test(String s) {
202        return new PathOps(s);
203    }
204
205    // -- PathOpss --
206
207    static void header(String s) {
208        out.println();
209        out.println();
210        out.println("-- " + s + " --");
211    }
212
213    static void doWindowsTests() {
214        header("Windows specific tests");
215
216        // all components present
217        test("C:\\a\\b\\c")
218            .root("C:\\")
219            .parent("C:\\a\\b")
220            .name("c");
221        test("C:a\\b\\c")
222            .root("C:")
223            .parent("C:a\\b")
224            .name("c");
225        test("\\\\server\\share\\a")
226            .root("\\\\server\\share\\")
227            .parent("\\\\server\\share\\")
228            .name("a");
229
230        // root component only
231        test("C:\\")
232            .root("C:\\")
233            .parent(null)
234            .name(null);
235        test("C:")
236            .root("C:")
237            .parent(null)
238            .name(null);
239        test("\\\\server\\share\\")
240            .root("\\\\server\\share\\")
241            .parent(null)
242            .name(null);
243
244        // no root component
245        test("a\\b")
246            .root(null)
247            .parent("a")
248            .name("b");
249
250        // name component only
251        test("foo")
252            .root(null)
253            .parent(null)
254            .name("foo");
255
256        // startsWith
257        test("C:\\")
258            .starts("C:\\")
259            .starts("c:\\")
260            .notStarts("C")
261            .notStarts("C:");
262        test("C:")
263            .starts("C:")
264            .starts("c:")
265            .notStarts("C");
266        test("\\")
267            .starts("\\");
268        test("C:\\foo\\bar")
269            .starts("C:\\")
270            .starts("C:\\foo")
271            .starts("C:\\FOO")
272            .starts("C:\\foo\\bar")
273            .starts("C:\\Foo\\Bar")
274            .notStarts("C:")
275            .notStarts("C")
276            .notStarts("C:foo");
277        test("\\foo\\bar")
278            .starts("\\")
279            .starts("\\foo")
280            .starts("\\foO")
281            .starts("\\foo\\bar")
282            .starts("\\fOo\\BaR")
283            .notStarts("foo")
284            .notStarts("foo\\bar");
285        test("foo\\bar")
286            .starts("foo")
287            .starts("foo\\bar")
288            .notStarts("\\");
289        test("\\\\server\\share")
290            .starts("\\\\server\\share")
291            .starts("\\\\server\\share\\")
292            .notStarts("\\");
293
294        // endsWith
295        test("C:\\")
296            .ends("C:\\")
297            .ends("c:\\")
298            .notEnds("\\");
299        test("C:")
300            .ends("C:")
301            .ends("c:");
302        test("\\")
303            .ends("\\");
304        test("C:\\foo\\bar")
305            .ends("bar")
306            .ends("BAR")
307            .ends("foo\\bar")
308            .ends("Foo\\Bar")
309            .ends("C:\\foo\\bar")
310            .ends("c:\\foO\\baR")
311            .notEnds("r")
312            .notEnds("\\foo\\bar");
313        test("\\foo\\bar")
314            .ends("bar")
315            .ends("BaR")
316            .ends("foo\\bar")
317            .ends("foO\\baR")
318            .ends("\\foo\\bar")
319            .ends("\\Foo\\Bar")
320            .notEnds("oo\\bar");
321        test("foo\\bar")
322            .ends("bar")
323            .ends("BAR")
324            .ends("foo\\bar")
325            .ends("Foo\\Bar")
326            .notEnds("ar");
327        test("\\\\server\\share")
328            .ends("\\\\server\\share")
329            .ends("\\\\server\\share\\")
330            .notEnds("shared")
331            .notEnds("\\");
332
333        // elements
334        test("C:\\a\\b\\c")
335            .element(0, "a")
336            .element(1, "b")
337            .element(2, "c");
338        test("foo.bar\\gus.alice")
339            .element(0, "foo.bar")
340            .element(1, "gus.alice");
341
342        // subpath
343        test("C:\\foo")
344            .subpath(0, 1, "foo");
345        test("C:foo")
346            .subpath(0, 1, "foo");
347        test("foo")
348            .subpath(0, 1, "foo");
349        test("C:\\foo\\bar\\gus")
350            .subpath(0, 1, "foo")
351            .subpath(0, 2, "foo\\bar")
352            .subpath(0, 3, "foo\\bar\\gus")
353            .subpath(1, 2, "bar")
354            .subpath(1, 3, "bar\\gus")
355            .subpath(2, 3, "gus");
356        test("\\\\server\\share\\foo")
357            .subpath(0, 1, "foo");
358
359        // isAbsolute
360        test("foo").notAbsolute();
361        test("C:").notAbsolute();
362        test("C:\\").absolute();
363        test("C:\\abc").absolute();
364        test("\\\\server\\share\\").absolute();
365
366        // resolve
367        test("C:\\")
368            .resolve("foo", "C:\\foo")
369            .resolve("D:\\bar", "D:\\bar")
370            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
371            .resolve("C:foo", "C:\\foo")
372            .resolve("D:foo", "D:foo");
373        test("\\")
374            .resolve("foo", "\\foo")
375            .resolve("D:bar", "D:bar")
376            .resolve("C:\\bar", "C:\\bar")
377            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
378            .resolve("\\foo", "\\foo");
379        test("\\foo")
380            .resolve("bar", "\\foo\\bar")
381            .resolve("D:bar", "D:bar")
382            .resolve("C:\\bar", "C:\\bar")
383            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
384            .resolve("\\bar", "\\bar");
385        test("foo")
386            .resolve("bar", "foo\\bar")
387            .resolve("D:\\bar", "D:\\bar")
388            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
389            .resolve("C:bar", "C:bar")
390            .resolve("D:foo", "D:foo");
391        test("C:")
392            .resolve("foo", "C:foo");
393        test("\\\\server\\share\\foo")
394            .resolve("bar", "\\\\server\\share\\foo\\bar")
395            .resolve("\\bar", "\\\\server\\share\\bar")
396            .resolve("D:\\bar", "D:\\bar")
397            .resolve("\\\\other\\share\\bar", "\\\\other\\share\\bar")
398            .resolve("D:bar", "D:bar");
399
400        // relativize
401        test("foo\\bar")
402            .relativize("foo\\bar", null)
403            .relativize("foo", "..");
404        test("C:\\a\\b\\c")
405            .relativize("C:\\a", "..\\..");
406        test("\\\\server\\share\\foo")
407            .relativize("\\\\server\\share\\bar", "..\\bar");
408
409        // normalize
410        test("C:\\")
411            .normalize("C:\\");
412        test("C:\\.")
413            .normalize("C:\\");
414        test("C:\\..")
415            .normalize("C:\\");
416        test("\\\\server\\share")
417            .normalize("\\\\server\\share\\");
418        test("\\\\server\\share\\.")
419            .normalize("\\\\server\\share\\");
420        test("\\\\server\\share\\..")
421            .normalize("\\\\server\\share\\");
422        test("C:")
423            .normalize("C:");
424        test("C:.")
425            .normalize("C:");
426        test("C:..")
427            .normalize("C:..");
428        test("\\")
429            .normalize("\\");
430        test("\\.")
431            .normalize("\\");
432        test("\\..")
433            .normalize("\\");
434        test("foo")
435            .normalize("foo");
436        test("foo\\.")
437            .normalize("foo");
438        test("foo\\..")
439            .normalize(null);
440        test("C:\\foo")
441            .normalize("C:\\foo");
442        test("C:\\foo\\.")
443            .normalize("C:\\foo");
444        test("C:\\.\\foo")
445            .normalize("C:\\foo");
446        test("C:\\foo\\..")
447            .normalize("C:\\");
448        test("C:\\..\\foo")
449            .normalize("C:\\foo");
450        test("\\\\server\\share\\foo")
451            .normalize("\\\\server\\share\\foo");
452        test("\\\\server\\share\\foo\\.")
453            .normalize("\\\\server\\share\\foo");
454        test("\\\\server\\share\\.\\foo")
455            .normalize("\\\\server\\share\\foo");
456        test("\\\\server\\share\\foo\\..")
457            .normalize("\\\\server\\share\\");
458        test("\\\\server\\share\\..\\foo")
459            .normalize("\\\\server\\share\\foo");
460        test("C:foo")
461            .normalize("C:foo");
462        test("C:foo\\.")
463            .normalize("C:foo");
464        test("C:.\\foo")
465            .normalize("C:foo");
466        test("C:foo\\..")
467            .normalize("C:");
468        test("C:..\\foo")
469            .normalize("C:..\\foo");
470        test("\\foo")
471            .normalize("\\foo");
472        test("\\foo\\.")
473            .normalize("\\foo");
474        test("\\.\\foo")
475            .normalize("\\foo");
476        test("\\foo\\..")
477            .normalize("\\");
478        test("\\..\\foo")
479            .normalize("\\foo");
480        test(".")
481            .normalize(null);
482        test("..")
483            .normalize("..");
484        test("\\..\\..")
485            .normalize("\\");
486        test("..\\..\\foo")
487            .normalize("..\\..\\foo");
488        test("foo\\bar\\..")
489            .normalize("foo");
490        test("foo\\bar\\.\\..")
491            .normalize("foo");
492        test("foo\\bar\\gus\\..\\..")
493            .normalize("foo");
494        test(".\\foo\\.\\bar\\.\\gus\\..\\.\\..")
495            .normalize("foo");
496
497        // UNC corner cases
498        test("\\\\server\\share\\")
499            .root("\\\\server\\share\\")
500            .parent(null)
501            .name(null);
502        test("\\\\server")
503            .invalid();
504        test("\\\\server\\")
505            .invalid();
506        test("\\\\server\\share")
507            .root("\\\\server\\share\\")
508            .parent(null)
509            .name(null);
510
511        // invalid
512        test(":\\foo")
513            .invalid();
514        test("C::")
515            .invalid();
516        test("C:\\?")           // invalid character
517            .invalid();
518        test("C:\\*")           // invalid character
519            .invalid();
520        test("C:\\abc\u0001\\foo")
521            .invalid();
522        test("C:\\\u0019\\foo")
523            .invalid();
524        test("\\\\server\u0019\\share")
525            .invalid();
526        test("\\\\server\\share\u0019")
527            .invalid();
528        test("foo\u0000\bar")
529            .invalid();
530        test("C:\\foo ")                // trailing space
531             .invalid();
532        test("C:\\foo \\bar")
533            .invalid();
534        //test("C:\\foo.")              // trailing dot
535            //.invalid();
536        //test("C:\\foo...\\bar")
537            //.invalid();
538
539        // normalization at construction time (remove redundant and replace slashes)
540        test("C:/a/b/c")
541            .string("C:\\a\\b\\c")
542            .root("C:\\")
543            .parent("C:\\a\\b");
544        test("C://a//b//c")
545            .string("C:\\a\\b\\c")
546            .root("C:\\")
547            .parent("C:\\a\\b");
548
549        // hashCode
550        header("hashCode");
551        int h1 = test("C:\\foo").path().hashCode();
552        int h2 = test("c:\\FOO").path().hashCode();
553        if (h1 != h2)
554            throw new RuntimeException("PathOps failed");
555    }
556
557    static void doUnixTests() {
558        header("Unix specific tests");
559
560        // all components
561        test("/a/b/c")
562            .root("/")
563            .parent("/a/b")
564            .name("c");
565
566        // root component only
567        test("/")
568            .root("/")
569            .parent(null)
570            .name(null);
571
572        // no root component
573        test("a/b")
574            .root(null)
575            .parent("a")
576            .name("b");
577
578        // name component only
579        test("foo")
580            .root(null)
581            .parent(null)
582            .name("foo");
583
584        // startsWith
585        test("/")
586            .starts("/")
587            .notStarts("/foo");
588        test("/foo")
589            .starts("/")
590            .starts("/foo")
591            .notStarts("/f");
592        test("/foo/bar")
593            .starts("/")
594            .starts("/foo")
595            .starts("/foo/bar")
596            .notStarts("/f")
597            .notStarts("foo")
598            .notStarts("foo/bar");
599        test("foo")
600            .starts("foo")
601            .notStarts("f");
602        test("foo/bar")
603            .starts("foo")
604            .starts("foo/bar")
605            .notStarts("f")
606            .notStarts("/foo")
607            .notStarts("/foo/bar");
608
609        // endsWith
610        test("/")
611            .ends("/")
612            .notEnds("foo")
613            .notEnds("/foo");
614        test("/foo")
615            .ends("foo")
616            .ends("/foo")
617            .notEnds("/");
618        test("/foo/bar")
619            .ends("bar")
620            .ends("foo/bar")
621            .ends("/foo/bar")
622            .notEnds("/bar");
623        test("foo")
624            .ends("foo");
625        test("foo/bar")
626            .ends("bar")
627            .ends("foo/bar");
628
629        // elements
630        test("a/b/c")
631            .element(0,"a")
632            .element(1,"b")
633            .element(2,"c");
634
635        // isAbsolute
636        test("/")
637            .absolute();
638        test("/tmp")
639            .absolute();
640        test("tmp")
641            .notAbsolute();
642
643        // resolve
644        test("/tmp")
645            .resolve("foo", "/tmp/foo")
646            .resolve("/foo", "/foo");
647        test("tmp")
648            .resolve("foo", "tmp/foo")
649            .resolve("/foo", "/foo");
650
651        // relativize
652        test("/a/b/c")
653            .relativize("/a/b/c", null)
654            .relativize("/a/b/c/d/e", "d/e")
655            .relativize("/a/x", "../../x");
656
657        // normalize
658        test("/")
659            .normalize("/");
660        test("foo")
661            .normalize("foo");
662        test("/foo")
663            .normalize("/foo");
664        test(".")
665            .normalize(null);
666        test("..")
667            .normalize("..");
668        test("/..")
669            .normalize("/");
670        test("/../..")
671            .normalize("/");
672        test("foo/.")
673            .normalize("foo");
674        test("./foo")
675            .normalize("foo");
676        test("foo/..")
677            .normalize(null);
678        test("../foo")
679            .normalize("../foo");
680        test("../../foo")
681            .normalize("../../foo");
682        test("foo/bar/..")
683            .normalize("foo");
684        test("foo/bar/gus/../..")
685            .normalize("foo");
686        test("/foo/bar/gus/../..")
687            .normalize("/foo");
688
689        // invalid
690        test("foo\u0000\bar")
691            .invalid();
692
693        // normalization
694        test("//foo//bar")
695            .string("/foo/bar")
696            .root("/")
697            .parent("/foo")
698            .name("bar");
699    }
700
701    static void npes() {
702        header("NullPointerException");
703
704        Path path = FileSystems.getDefault().getPath("foo");
705
706        try {
707            path.resolve((String)null);
708            throw new RuntimeException("NullPointerException not thrown");
709        } catch (NullPointerException npe) {
710        }
711
712        try {
713            path.relativize(null);
714            throw new RuntimeException("NullPointerException not thrown");
715        } catch (NullPointerException npe) {
716        }
717
718        try {
719            path.compareTo(null);
720            throw new RuntimeException("NullPointerException not thrown");
721        } catch (NullPointerException npe) {
722        }
723
724        try {
725            path.startsWith(null);
726            throw new RuntimeException("NullPointerException not thrown");
727        } catch (NullPointerException npe) {
728        }
729
730        try {
731            path.endsWith(null);
732            throw new RuntimeException("NullPointerException not thrown");
733        } catch (NullPointerException npe) {
734        }
735
736    }
737
738    public static void main(String[] args) {
739        // all platforms
740        npes();
741
742        // operating system specific
743        String osname = System.getProperty("os.name");
744        if (osname.startsWith("Windows")) {
745            doWindowsTests();
746        }
747        if (osname.equals("SunOS") || osname.equals("Linux")) {
748            doUnixTests();
749        }
750
751    }
752}
753