1/*
2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/* @test
25 * @bug 4313887 6838333 6925932 7006126 8037945 8072495 8140449
26 * @summary Unit test for java.nio.file.Path path operations
27 */
28
29import java.nio.file.FileSystems;
30import java.nio.file.InvalidPathException;
31import java.nio.file.Path;
32import java.nio.file.Paths;
33
34public class PathOps {
35
36    static final java.io.PrintStream out = System.out;
37
38    private Path path;
39    private Exception exc;
40
41    private PathOps(String first, String... more) {
42        out.println();
43        try {
44            path = FileSystems.getDefault().getPath(first, more);
45            out.format("%s -> %s", first, path);
46        } catch (Exception x) {
47            exc = x;
48            out.format("%s -> %s", first, x);
49        }
50        out.println();
51    }
52
53    Path path() {
54        return path;
55    }
56
57    void fail() {
58        throw new RuntimeException("PathOps failed");
59    }
60
61    void checkPath() {
62        if (path == null) {
63            throw new InternalError("path is null");
64        }
65    }
66
67    void check(Object result, String expected) {
68        out.format("\tExpected: %s\n", expected);
69        out.format("\tActual: %s\n",  result);
70        if (result == null) {
71            if (expected == null) return;
72        } else {
73            // compare string representations
74            if (expected != null && result.toString().equals(expected.toString()))
75                return;
76        }
77        fail();
78    }
79
80    void check(Object result, boolean expected) {
81        check(result, Boolean.toString(expected));
82    }
83
84    PathOps root(String expected) {
85        out.println("check root");
86        checkPath();
87        check(path.getRoot(), expected);
88        return this;
89    }
90
91    PathOps hasRoot() {
92        out.println("check has root");
93        checkPath();
94        if (path.getRoot() == null)
95            fail();
96        return this;
97    }
98
99    PathOps parent(String expected) {
100        out.println("check parent");
101        checkPath();
102        check(path.getParent(), expected);
103        return this;
104    }
105
106    PathOps name(String expected) {
107        out.println("check name");
108        checkPath();
109        check(path.getFileName(), expected);
110        return this;
111    }
112
113    PathOps element(int index, String expected) {
114        out.format("check element %d\n", index);
115        checkPath();
116        check(path.getName(index), expected);
117        return this;
118    }
119
120    PathOps subpath(int startIndex, int endIndex, String expected) {
121        out.format("test subpath(%d,%d)\n", startIndex, endIndex);
122        checkPath();
123        check(path.subpath(startIndex, endIndex), expected);
124        return this;
125    }
126
127    PathOps starts(String prefix) {
128        out.format("test startsWith with %s\n", prefix);
129        checkPath();
130        Path s = FileSystems.getDefault().getPath(prefix);
131        check(path.startsWith(s), true);
132        return this;
133    }
134
135    PathOps notStarts(String prefix) {
136        out.format("test not startsWith with %s\n", prefix);
137        checkPath();
138        Path s = FileSystems.getDefault().getPath(prefix);
139        check(path.startsWith(s), false);
140        return this;
141    }
142
143    PathOps ends(String suffix) {
144        out.format("test endsWith %s\n", suffix);
145        checkPath();
146        Path s = FileSystems.getDefault().getPath(suffix);
147        check(path.endsWith(s), true);
148        return this;
149    }
150
151    PathOps notEnds(String suffix) {
152        out.format("test not endsWith %s\n", suffix);
153        checkPath();
154        Path s = FileSystems.getDefault().getPath(suffix);
155        check(path.endsWith(s), false);
156        return this;
157    }
158
159    PathOps makeAbsolute() {
160        this.path = path.toAbsolutePath();
161        return this;
162    }
163
164    PathOps absolute() {
165        out.println("check path is absolute");
166        checkPath();
167        check(path.isAbsolute(), true);
168        return this;
169    }
170
171    PathOps notAbsolute() {
172        out.println("check path is not absolute");
173        checkPath();
174        check(path.isAbsolute(), false);
175        return this;
176    }
177
178    PathOps resolve(String other, String expected) {
179        out.format("test resolve %s\n", other);
180        checkPath();
181        check(path.resolve(other), expected);
182        return this;
183    }
184
185    PathOps resolveSibling(String other, String expected) {
186        out.format("test resolveSibling %s\n", other);
187        checkPath();
188        check(path.resolveSibling(other), expected);
189        return this;
190    }
191
192    PathOps relativize(String other, String expected) {
193        out.format("test relativize %s\n", other);
194        checkPath();
195        Path that = FileSystems.getDefault().getPath(other);
196        check(path.relativize(that), expected);
197        return this;
198    }
199
200    PathOps relativizeFail(String other) {
201        out.format("test relativize %s\n", other);
202        checkPath();
203        Path that = FileSystems.getDefault().getPath(other);
204        try {
205            Path result = path.relativize(that);
206            out.format("\tExpected: IllegalArgumentException");
207            out.format("\tActual: %s\n",  result);
208            fail();
209        } catch (IllegalArgumentException expected) { }
210        return this;
211    }
212
213    PathOps normalize(String expected) {
214        out.println("check normalized path");
215        checkPath();
216        check(path.normalize(), expected);
217        return this;
218    }
219
220    PathOps string(String expected) {
221        out.println("check string representation");
222        checkPath();
223        check(path, expected);
224        return this;
225    }
226
227    PathOps invalid() {
228        if (!(exc instanceof InvalidPathException)) {
229            out.println("InvalidPathException not thrown as expected");
230            fail();
231        }
232        return this;
233    }
234
235    static PathOps test(String first, String... more) {
236        return new PathOps(first, more);
237    }
238
239    static PathOps test(Path path) {
240        return new PathOps(path.toString());
241    }
242
243
244    // -- PathOpss --
245
246    static void header(String s) {
247        out.println();
248        out.println();
249        out.println("-- " + s + " --");
250    }
251
252    static void doWindowsTests() {
253        header("Windows specific tests");
254        Path cwd = Paths.get("").toAbsolutePath();
255
256        // construction
257        test("C:\\")
258            .string("C:\\");
259        test("C:\\", "")
260            .string("C:\\");
261        test("C:\\", "foo")
262            .string("C:\\foo");
263        test("C:\\", "\\foo")
264            .string("C:\\foo");
265        test("C:\\", "foo\\")
266            .string("C:\\foo");
267        test("foo", "bar", "gus")
268            .string("foo\\bar\\gus");
269        test("")
270            .string("");
271        test("", "C:\\")
272            .string("C:\\");
273        test("", "foo", "", "bar", "", "\\gus")
274            .string("foo\\bar\\gus");
275
276        // all components present
277        test("C:\\a\\b\\c")
278            .root("C:\\")
279            .parent("C:\\a\\b")
280            .name("c");
281        test("C:a\\b\\c")
282            .root("C:")
283            .parent("C:a\\b")
284            .name("c");
285        test("\\\\server\\share\\a")
286            .root("\\\\server\\share\\")
287            .parent("\\\\server\\share\\")
288            .name("a");
289
290        // root component only
291        test("C:\\")
292            .root("C:\\")
293            .parent(null)
294            .name(null);
295        test("C:")
296            .root("C:")
297            .parent(null)
298            .name(null);
299        test("\\\\server\\share\\")
300            .root("\\\\server\\share\\")
301            .parent(null)
302            .name(null);
303
304        // no root component
305        test("a\\b")
306            .root(null)
307            .parent("a")
308            .name("b");
309
310        // name component only
311        test("foo")
312            .root(null)
313            .parent(null)
314            .name("foo");
315        test("")
316            .root(null)
317            .parent(null)
318            .name("");
319
320        // startsWith
321        test("C:\\")
322            .starts("C:\\")
323            .starts("c:\\")
324            .notStarts("C")
325            .notStarts("C:")
326            .notStarts("");
327        test("C:")
328            .starts("C:")
329            .starts("c:")
330            .notStarts("C")
331            .notStarts("");
332        test("\\")
333            .starts("\\");
334        test("C:\\foo\\bar")
335            .starts("C:\\")
336            .starts("C:\\foo")
337            .starts("C:\\FOO")
338            .starts("C:\\foo\\bar")
339            .starts("C:\\Foo\\Bar")
340            .notStarts("C:")
341            .notStarts("C")
342            .notStarts("C:foo")
343            .notStarts("");
344        test("\\foo\\bar")
345            .starts("\\")
346            .starts("\\foo")
347            .starts("\\foO")
348            .starts("\\foo\\bar")
349            .starts("\\fOo\\BaR")
350            .notStarts("foo")
351            .notStarts("foo\\bar")
352            .notStarts("");
353        test("foo\\bar")
354            .starts("foo")
355            .starts("foo\\bar")
356            .notStarts("\\")
357            .notStarts("");
358        test("\\\\server\\share")
359            .starts("\\\\server\\share")
360            .starts("\\\\server\\share\\")
361            .notStarts("\\")
362            .notStarts("");
363        test("")
364            .starts("")
365            .notStarts("\\");
366
367        // endsWith
368        test("C:\\")
369            .ends("C:\\")
370            .ends("c:\\")
371            .notEnds("\\")
372            .notEnds("");
373        test("C:")
374            .ends("C:")
375            .ends("c:")
376            .notEnds("");
377        test("\\")
378            .ends("\\")
379            .notEnds("");
380        test("C:\\foo\\bar")
381            .ends("bar")
382            .ends("BAR")
383            .ends("foo\\bar")
384            .ends("Foo\\Bar")
385            .ends("C:\\foo\\bar")
386            .ends("c:\\foO\\baR")
387            .notEnds("r")
388            .notEnds("\\foo\\bar")
389            .notEnds("");
390        test("\\foo\\bar")
391            .ends("bar")
392            .ends("BaR")
393            .ends("foo\\bar")
394            .ends("foO\\baR")
395            .ends("\\foo\\bar")
396            .ends("\\Foo\\Bar")
397            .notEnds("oo\\bar")
398            .notEnds("");
399        test("foo\\bar")
400            .ends("bar")
401            .ends("BAR")
402            .ends("foo\\bar")
403            .ends("Foo\\Bar")
404            .notEnds("ar")
405            .notEnds("");
406        test("\\\\server\\share")
407            .ends("\\\\server\\share")
408            .ends("\\\\server\\share\\")
409            .notEnds("shared")
410            .notEnds("\\")
411            .notEnds("");
412        test("")
413            .ends("")
414            .notEnds("\\");
415
416        // elements
417        test("C:\\a\\b\\c")
418            .element(0, "a")
419            .element(1, "b")
420            .element(2, "c");
421        test("foo.bar\\gus.alice")
422            .element(0, "foo.bar")
423            .element(1, "gus.alice");
424        test("")
425            .element(0, "");
426
427        // subpath
428        test("C:\\foo")
429            .subpath(0, 1, "foo");
430        test("C:foo")
431            .subpath(0, 1, "foo");
432        test("foo")
433            .subpath(0, 1, "foo");
434        test("C:\\foo\\bar\\gus")
435            .subpath(0, 1, "foo")
436            .subpath(0, 2, "foo\\bar")
437            .subpath(0, 3, "foo\\bar\\gus")
438            .subpath(1, 2, "bar")
439            .subpath(1, 3, "bar\\gus")
440            .subpath(2, 3, "gus");
441        test("\\\\server\\share\\foo")
442            .subpath(0, 1, "foo");
443        test("")
444            .subpath(0, 1, "");
445
446        // isAbsolute
447        test("foo").notAbsolute();
448        test("C:").notAbsolute();
449        test("C:\\").absolute();
450        test("C:\\abc").absolute();
451        test("\\\\server\\share\\").absolute();
452        test("").notAbsolute();
453        test(cwd).absolute();
454
455        // toAbsolutePath
456        test("")
457            .makeAbsolute()
458            .absolute()
459            .hasRoot()
460            .string(cwd.toString());
461        test(".")
462            .makeAbsolute()
463            .absolute()
464            .hasRoot()
465            .string(cwd.toString() + "\\.");
466        test("foo")
467            .makeAbsolute()
468            .absolute()
469            .hasRoot()
470            .string(cwd.toString() + "\\foo");
471
472        String rootAsString = cwd.getRoot().toString();
473        if (rootAsString.length() == 3
474                && rootAsString.charAt(1) == ':'
475                && rootAsString.charAt(2) == '\\') {
476            Path root = Paths.get(rootAsString.substring(0, 2));
477
478            // C:
479            test(root)
480                .makeAbsolute()
481                .absolute()
482                .hasRoot()
483                .string(cwd.toString());
484
485            // C:.
486            test(root + ".")
487                .makeAbsolute()
488                .absolute()
489                .hasRoot()
490                .string(cwd.toString() + "\\.");
491
492            // C:foo
493            test(root + "foo")
494                .makeAbsolute()
495                .absolute()
496                .hasRoot()
497                .string(cwd.toString() + "\\foo");
498        }
499
500        // resolve
501        test("C:\\")
502            .resolve("foo", "C:\\foo")
503            .resolve("D:\\bar", "D:\\bar")
504            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
505            .resolve("C:foo", "C:\\foo")
506            .resolve("D:foo", "D:foo")
507            .resolve("", "C:\\");
508        test("\\")
509            .resolve("foo", "\\foo")
510            .resolve("D:bar", "D:bar")
511            .resolve("C:\\bar", "C:\\bar")
512            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
513            .resolve("\\foo", "\\foo")
514            .resolve("", "\\");
515        test("\\foo")
516            .resolve("bar", "\\foo\\bar")
517            .resolve("D:bar", "D:bar")
518            .resolve("C:\\bar", "C:\\bar")
519            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
520            .resolve("\\bar", "\\bar")
521            .resolve("", "\\foo");
522        test("foo")
523            .resolve("bar", "foo\\bar")
524            .resolve("D:\\bar", "D:\\bar")
525            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
526            .resolve("C:bar", "C:bar")
527            .resolve("D:foo", "D:foo")
528            .resolve("", "foo");
529        test("C:")
530            .resolve("foo", "C:foo")
531            .resolve("", "C:");
532        test("\\\\server\\share\\foo")
533            .resolve("bar", "\\\\server\\share\\foo\\bar")
534            .resolve("\\bar", "\\\\server\\share\\bar")
535            .resolve("D:\\bar", "D:\\bar")
536            .resolve("\\\\other\\share\\bar", "\\\\other\\share\\bar")
537            .resolve("D:bar", "D:bar")
538            .resolve("", "\\\\server\\share\\foo");
539        test("")
540            .resolve("", "")
541            .resolve("foo", "foo")
542            .resolve("C:\\", "C:\\")
543            .resolve("C:foo", "C:foo")
544            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar");
545
546        // resolveSibling
547        test("foo")
548            .resolveSibling("bar", "bar")
549            .resolveSibling("D:\\bar", "D:\\bar")
550            .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
551            .resolveSibling("C:bar", "C:bar")
552            .resolveSibling("D:foo", "D:foo")
553            .resolveSibling("", "");
554        test("foo\\bar")
555            .resolveSibling("gus", "foo\\gus")
556            .resolveSibling("D:\\bar", "D:\\bar")
557            .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
558            .resolveSibling("C:bar", "C:bar")
559            .resolveSibling("D:foo", "D:foo")
560            .resolveSibling("", "foo");
561        test("C:\\foo")
562            .resolveSibling("gus", "C:\\gus")
563            .resolveSibling("D:\\bar", "D:\\bar")
564            .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
565            .resolveSibling("C:bar", "C:\\bar")
566            .resolveSibling("D:foo", "D:foo")
567            .resolveSibling("", "C:\\");
568        test("C:\\foo\\bar")
569            .resolveSibling("gus", "C:\\foo\\gus")
570            .resolveSibling("D:\\bar", "D:\\bar")
571            .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
572            .resolveSibling("C:bar", "C:\\foo\\bar")
573            .resolveSibling("D:foo", "D:foo")
574            .resolveSibling("", "C:\\foo");
575        test("\\\\server\\share\\foo")
576            .resolveSibling("bar", "\\\\server\\share\\bar")
577            .resolveSibling("\\bar", "\\\\server\\share\\bar")
578            .resolveSibling("D:\\bar", "D:\\bar")
579            .resolveSibling("\\\\other\\share\\bar", "\\\\other\\share\\bar")
580            .resolveSibling("D:bar", "D:bar")
581            .resolveSibling("", "\\\\server\\share\\");
582        test("")
583            .resolveSibling("", "")
584            .resolveSibling("foo", "foo")
585            .resolveSibling("C:\\", "C:\\");
586
587        // relativize
588        test("C:\\a")
589            .relativize("C:\\a", "")
590            .relativize("C:\\", "..")
591            .relativize("C:\\.", "..")
592            .relativize("C:\\..", "..")
593            .relativize("C:\\..\\..", "..")
594            .relativize("C:\\a\\b", "b")
595            .relativize("C:\\a\\b\\c", "b\\c")
596            .relativize("C:\\a\\.", "")        // "." also valid
597            .relativize("C:\\a\\..", "..")
598            .relativize("C:\\x", "..\\x")
599            .relativizeFail("C:x")
600            .relativizeFail("x")
601            .relativizeFail("\\")
602            .relativizeFail("")
603            .relativizeFail(".")
604            .relativizeFail("..");
605        test("C:\\a\\b")
606            .relativize("C:\\a\\b", "")
607            .relativize("C:\\a", "..")
608            .relativize("C:\\", "..\\..")
609            .relativize("C:\\.", "..\\..")
610            .relativize("C:\\..", "..\\..")
611            .relativize("C:\\..\\..", "..\\..")
612            .relativize("C:\\a\\b\\c", "c")
613            .relativize("C:\\a\\.", "..")
614            .relativize("C:\\a\\..", "..\\..")
615            .relativize("C:\\x", "..\\..\\x")
616            .relativizeFail("C:x")
617            .relativizeFail("x")
618            .relativizeFail("\\")
619            .relativizeFail("")
620            .relativizeFail(".")
621            .relativizeFail("..");
622        test("C:\\a\\b\\c")
623            .relativize("C:\\a\\b\\c", "")
624            .relativize("C:\\a\\b", "..")
625            .relativize("C:\\a", "..\\..")
626            .relativize("C:\\", "..\\..\\..")
627            .relativize("C:\\.", "..\\..\\..")
628            .relativize("C:\\..", "..\\..\\..")
629            .relativize("C:\\..\\..", "..\\..\\..")
630            .relativize("C:\\..\\..\\..", "..\\..\\..")
631            .relativize("C:\\..\\..\\..\\..", "..\\..\\..")
632            .relativize("C:\\a\\b\\c\\d", "d")
633            .relativize("C:\\a\\b\\c\\d\\e", "d\\e")
634            .relativize("C:\\a\\b\\c\\.", "")        // "." also valid
635            .relativize("C:\\a\\b\\c\\..", "..")
636            .relativize("C:\\a\\x", "..\\..\\x")
637            .relativize("C:\\x", "..\\..\\..\\x")
638            .relativizeFail("C:x")
639            .relativizeFail("x")
640            .relativizeFail("\\")
641            .relativizeFail("")
642            .relativizeFail(".")
643            .relativizeFail("..");
644        test("C:\\..\\a")
645            .relativize("C:\\a", "")
646            .relativize("C:\\", "..")
647            .relativize("C:\\.", "..")
648            .relativize("C:\\..", "..")
649            .relativize("C:\\..\\..", "..")
650            .relativize("C:\\a\\b", "b")
651            .relativize("C:\\a\\b\\c", "b\\c")
652            .relativize("C:\\a\\.", "")        // "." also valid
653            .relativize("C:\\a\\..", "..")
654            .relativize("C:\\x", "..\\x")
655            .relativizeFail("C:x")
656            .relativizeFail("x")
657            .relativizeFail("\\")
658            .relativizeFail("")
659            .relativizeFail(".")
660            .relativizeFail("..");
661        test("C:\\..\\a\\b")
662            .relativize("C:\\a\\b", "")
663            .relativize("C:\\a", "..")
664            .relativize("C:\\", "..\\..")
665            .relativize("C:\\.", "..\\..")
666            .relativize("C:\\..", "..\\..")
667            .relativize("C:\\..\\..", "..\\..")
668            .relativize("C:\\..\\..\\..", "..\\..")
669            .relativize("C:\\..\\..\\..\\..", "..\\..")
670            .relativize("C:\\a\\b\\c", "c")
671            .relativize("C:\\a\\b\\.", "")        // "." also valid
672            .relativize("C:\\a\\b\\..", "..")
673            .relativize("C:\\a\\x", "..\\x")
674            .relativize("C:\\x", "..\\..\\x")
675            .relativizeFail("C:x")
676            .relativizeFail("x")
677            .relativizeFail("\\")
678            .relativizeFail("")
679            .relativizeFail(".")
680            .relativizeFail("..");
681        test("C:\\..\\..\\a\\b")
682            .relativize("C:\\a\\b", "")
683            .relativize("C:\\a", "..")
684            .relativize("C:\\", "..\\..")
685            .relativize("C:\\.", "..\\..")
686            .relativize("C:\\..", "..\\..")
687            .relativize("C:\\..\\..", "..\\..")
688            .relativize("C:\\..\\..\\..", "..\\..")
689            .relativize("C:\\..\\..\\..\\..", "..\\..")
690            .relativize("C:\\a\\b\\c", "c")
691            .relativize("C:\\a\\b\\.", "")        // "." also valid
692            .relativize("C:\\a\\b\\..", "..")
693            .relativize("C:\\a\\x", "..\\x")
694            .relativize("C:\\x", "..\\..\\x")
695            .relativizeFail("C:x")
696            .relativizeFail("x")
697            .relativizeFail("\\")
698            .relativizeFail("")
699            .relativizeFail(".")
700            .relativizeFail("..");
701        test("C:\\..\\a\\b\\c")
702            .relativize("C:\\a\\b\\c", "")
703            .relativize("C:\\a\\b", "..")
704            .relativize("C:\\a", "..\\..")
705            .relativize("C:\\", "..\\..\\..")
706            .relativize("C:\\.", "..\\..\\..")
707            .relativize("C:\\..", "..\\..\\..")
708            .relativize("C:\\..\\..", "..\\..\\..")
709            .relativize("C:\\..\\..\\..", "..\\..\\..")
710            .relativize("C:\\..\\..\\..\\..", "..\\..\\..")
711            .relativize("C:\\a\\b\\c\\d", "d")
712            .relativize("C:\\a\\b\\c\\d\\e", "d\\e")
713            .relativize("C:\\a\\b\\c\\.", "")        // "." also valid
714            .relativize("C:\\a\\b\\c\\..", "..")
715            .relativize("C:\\a\\x", "..\\..\\x")
716            .relativize("C:\\x", "..\\..\\..\\x")
717            .relativizeFail("C:x")
718            .relativizeFail("x")
719            .relativizeFail("\\")
720            .relativizeFail("")
721            .relativizeFail(".")
722            .relativizeFail("..");
723        test("C:\\..\\..\\a\\b\\c")
724            .relativize("C:\\a\\b\\c", "")
725            .relativize("C:\\a\\b", "..")
726            .relativize("C:\\a", "..\\..")
727            .relativize("C:\\", "..\\..\\..")
728            .relativize("C:\\.", "..\\..\\..")
729            .relativize("C:\\..", "..\\..\\..")
730            .relativize("C:\\..\\..", "..\\..\\..")
731            .relativize("C:\\..\\..\\..", "..\\..\\..")
732            .relativize("C:\\..\\..\\..\\..", "..\\..\\..")
733            .relativize("C:\\a\\b\\c\\d", "d")
734            .relativize("C:\\a\\b\\c\\d\\e", "d\\e")
735            .relativize("C:\\a\\b\\c\\.", "")        // "." also valid
736            .relativize("C:\\a\\b\\c\\..", "..")
737            .relativize("C:\\a\\x", "..\\..\\x")
738            .relativize("C:\\x", "..\\..\\..\\x")
739            .relativizeFail("C:x")
740            .relativizeFail("x")
741            .relativizeFail("\\")
742            .relativizeFail("")
743            .relativizeFail(".")
744            .relativizeFail("..");
745        test("C:\\..\\..\\..\\a\\b\\c")
746            .relativize("C:\\a\\b\\c", "")
747            .relativize("C:\\a\\b", "..")
748            .relativize("C:\\a", "..\\..")
749            .relativize("C:\\", "..\\..\\..")
750            .relativize("C:\\.", "..\\..\\..")
751            .relativize("C:\\..", "..\\..\\..")
752            .relativize("C:\\..\\..", "..\\..\\..")
753            .relativize("C:\\..\\..\\..", "..\\..\\..")
754            .relativize("C:\\..\\..\\..\\..", "..\\..\\..")
755            .relativize("C:\\a\\b\\c\\d", "d")
756            .relativize("C:\\a\\b\\c\\d\\e", "d\\e")
757            .relativize("C:\\a\\b\\c\\.", "")        // "." also valid
758            .relativize("C:\\a\\b\\c\\..", "..")
759            .relativize("C:\\a\\x", "..\\..\\x")
760            .relativize("C:\\x", "..\\..\\..\\x")
761            .relativizeFail("C:x")
762            .relativizeFail("x")
763            .relativizeFail("\\")
764            .relativizeFail("")
765            .relativizeFail(".")
766            .relativizeFail("..");
767        test("C:\\.\\a")
768            .relativize("C:\\a", "")
769            .relativize("C:\\", "..")
770            .relativize("C:\\.", "..")
771            .relativize("C:\\..", "..")
772            .relativize("C:\\..\\..", "..")
773            .relativize("C:\\a\\b", "b")
774            .relativize("C:\\a\\b\\c", "b\\c")
775            .relativize("C:\\a\\.", "")        // "." also valid
776            .relativize("C:\\a\\..", "..")
777            .relativize("C:\\x", "..\\x")
778            .relativizeFail("C:x")
779            .relativizeFail("x")
780            .relativizeFail("\\")
781            .relativizeFail("")
782            .relativizeFail(".")
783            .relativizeFail("..");
784        test("C:\\..\\a")
785            .relativize("C:\\a", "")
786            .relativize("C:\\", "..")
787            .relativize("C:\\.", "..")
788            .relativize("C:\\..", "..")
789            .relativize("C:\\..\\..", "..")
790            .relativize("C:\\a\\b", "b")
791            .relativize("C:\\a\\b\\c", "b\\c")
792            .relativize("C:\\a\\.", "")        // "." also valid
793            .relativize("C:\\a\\..", "..")
794            .relativize("C:\\x", "..\\x")
795            .relativizeFail("C:x")
796            .relativizeFail("x")
797            .relativizeFail("\\")
798            .relativizeFail("")
799            .relativizeFail(".")
800            .relativizeFail("..");
801        test("C:\\a\\..")
802            .relativize("C:\\a", "a")
803            .relativize("C:\\", "")          // "." is also valid
804            .relativize("C:\\.", "")
805            .relativize("C:\\..", "")
806            .relativize("C:\\..\\..", "")
807            .relativize("C:\\a\\.", "a")
808            .relativize("C:\\a\\..", "")
809            .relativize("C:\\x", "x")
810            .relativizeFail("C:x")
811            .relativizeFail("x")
812            .relativizeFail("\\")
813            .relativizeFail("")
814            .relativizeFail(".")
815            .relativizeFail("..");
816        test("C:a")
817            .relativize("C:a", "")
818            .relativize("C:", "..")
819            .relativize("C:.", "..")
820            .relativize("C:..", "..\\..")
821            .relativize("C:..\\..", "..\\..\\..")
822            .relativize("C:.\\..", "..\\..")
823            .relativize("C:a\\b", "b")
824            .relativize("C:a\\b\\c", "b\\c")
825            .relativize("C:..\\x", "..\\..\\x")
826            .relativizeFail("C:\\x")
827            .relativizeFail("x")
828            .relativizeFail("\\")
829            .relativizeFail("\\x");
830        test("C:a\\b")
831            .relativize("C:a\\b", "")
832            .relativize("C:a", "..")
833            .relativize("C:", "..\\..")
834            .relativize("C:.", "..\\..")
835            .relativize("C:..", "..\\..\\..")
836            .relativize("C:..\\..", "..\\..\\..\\..")
837            .relativize("C:.\\..", "..\\..\\..")
838            .relativize("C:a\\b\\c", "c")
839            .relativize("C:..\\x", "..\\..\\..\\x")
840            .relativizeFail("C:\\x")
841            .relativizeFail("x")
842            .relativizeFail("\\")
843            .relativizeFail("\\x");
844        test("C:a\\b\\c")
845            .relativize("C:a\\b\\c", "")
846            .relativize("C:a\\b", "..")
847            .relativize("C:a", "..\\..")
848            .relativize("C:", "..\\..\\..")
849            .relativize("C:.", "..\\..\\..")
850            .relativize("C:..", "..\\..\\..\\..")
851            .relativize("C:..\\..", "..\\..\\..\\..\\..")
852            .relativize("C:.\\..", "..\\..\\..\\..")
853            .relativize("C:a\\b\\c\\d", "d")
854            .relativize("C:a\\b\\c\\d\\e", "d\\e")
855            .relativize("C:a\\x", "..\\..\\x")
856            .relativize("C:..\\x", "..\\..\\..\\..\\x")
857            .relativizeFail("C:\\x")
858            .relativizeFail("x")
859            .relativizeFail("\\")
860            .relativizeFail("\\x");
861        test("C:")
862            .relativize("C:a", "a")
863            .relativize("C:a\\b\\c", "a\\b\\c")
864            .relativize("C:", "")
865            .relativize("C:.", "")              // "" also valid
866            .relativize("C:..", "..")
867            .relativize("C:..\\..", "..\\..")
868            .relativize("C:.\\..", "..")
869            .relativizeFail("C:\\x")
870            .relativizeFail("\\")
871            .relativizeFail("\\x");
872        test("C:..")
873            .relativize("C:..\\a", "a")
874            .relativize("C:..", "")
875            .relativize("C:.\\..", "")
876            .relativizeFail("C:\\x")
877            .relativizeFail("\\")
878            .relativizeFail("\\x")
879            .relativizeFail("")
880            .relativizeFail(".")
881            .relativizeFail("x");
882        test("C:..\\a")
883            .relativize("C:..\\a\\b", "b")
884            .relativize("C:..\\a", "")
885            .relativize("C:..", "..")
886            .relativize("C:.\\..", "..")
887            .relativizeFail("C:\\x")
888            .relativizeFail("\\")
889            .relativizeFail("\\x")
890            .relativizeFail("")
891            .relativizeFail(".")
892            .relativizeFail("x");
893        test("C:..\\a\\b")
894            .relativize("C:..\\a\\b\\c", "c")
895            .relativize("C:..\\a\\b", "")
896            .relativize("C:..\\a", "..")
897            .relativize("C:..", "..\\..")
898            .relativize("C:.\\..", "..\\..")
899            .relativizeFail("C:\\x")
900            .relativizeFail("\\")
901            .relativizeFail("\\x")
902            .relativizeFail("")
903            .relativizeFail("x");
904        test("C:a\\..")
905            .relativize("C:b", "b")
906            .relativize("C:", "")
907            .relativize("C:.", "")       // "." also valid
908            .relativize("C:..", "..")
909            .relativize("C:a\\..\\b", "b")
910            .relativize("C:a\\..", "")
911            .relativize("C:..\\b", "..\\b")
912            .relativize("C:b\\..", "")
913            .relativizeFail("C:\\x")
914            .relativizeFail("\\")
915            .relativizeFail("\\x")
916            .relativizeFail("x");
917        test("C:a\\..\\b")
918            .relativize("C:a\\..\\b", "")
919            .relativize("C:a\\..", "..")
920            .relativize("C:", "..")
921            .relativize("C:.", "..")
922            .relativize("C:..", "..\\..")
923            .relativize("C:b", "")
924            .relativize("C:c", "..\\c")
925            .relativize("C:..\\c", "..\\..\\c")
926            .relativize("C:a\\..\\b\\c", "c")
927            .relativizeFail("C:\\x")
928            .relativizeFail("\\")
929            .relativizeFail("\\x")
930            .relativizeFail("x");
931        test("\\a")
932            .relativize("\\a", "")
933            .relativize("\\", "..")
934            .relativize("\\.", "..")
935            .relativize("\\..", "..")
936            .relativize("\\..\\..", "..")
937            .relativize("\\a\\b", "b")
938            .relativize("\\a\\b\\c", "b\\c")
939            .relativize("\\a\\.", "")        // "." also valid
940            .relativize("\\a\\..", "..")
941            .relativize("\\x", "..\\x")
942            .relativizeFail("C:\\x")
943            .relativizeFail("C:x")
944            .relativizeFail("x")
945            .relativizeFail("")
946            .relativizeFail(".")
947            .relativizeFail("..");
948        test("\\a\\b")
949            .relativize("\\a\\b", "")
950            .relativize("\\a", "..")
951            .relativize("\\", "..\\..")
952            .relativize("\\.", "..\\..")
953            .relativize("\\..", "..\\..")
954            .relativize("\\..\\..", "..\\..")
955            .relativize("\\a\\b\\c", "c")
956            .relativize("\\a\\.", "..")
957            .relativize("\\a\\..", "..\\..")
958            .relativize("\\x", "..\\..\\x")
959            .relativizeFail("C:\\x")
960            .relativizeFail("C:x")
961            .relativizeFail("x")
962            .relativizeFail("")
963            .relativizeFail(".")
964            .relativizeFail("..");
965        test("\\a\\b\\c")
966            .relativize("\\a\\b\\c", "")
967            .relativize("\\a\\b", "..")
968            .relativize("\\a", "..\\..")
969            .relativize("\\", "..\\..\\..")
970            .relativize("\\.", "..\\..\\..")
971            .relativize("\\..", "..\\..\\..")
972            .relativize("\\..\\..", "..\\..\\..")
973            .relativize("\\..\\..\\..", "..\\..\\..")
974            .relativize("\\..\\..\\..\\..", "..\\..\\..")
975            .relativize("\\a\\b\\c\\d", "d")
976            .relativize("\\a\\b\\c\\d\\e", "d\\e")
977            .relativize("\\a\\b\\c\\.", "")        // "." also valid
978            .relativize("\\a\\b\\c\\..", "..")
979            .relativize("\\a\\x", "..\\..\\x")
980            .relativize("\\x", "..\\..\\..\\x")
981            .relativizeFail("C:\\x")
982            .relativizeFail("C:x")
983            .relativizeFail("x")
984            .relativizeFail("")
985            .relativizeFail(".")
986            .relativizeFail("..");
987        test("\\..\\a")
988            .relativize("\\a", "")
989            .relativize("\\", "..")
990            .relativize("\\.", "..")
991            .relativize("\\..", "..")
992            .relativize("\\..\\..", "..")
993            .relativize("\\a\\b", "b")
994            .relativize("\\a\\b\\c", "b\\c")
995            .relativize("\\a\\.", "")        // "." also valid
996            .relativize("\\a\\..", "..")
997            .relativize("\\x", "..\\x")
998            .relativizeFail("C:\\x")
999            .relativizeFail("C:x")
1000            .relativizeFail("x")
1001            .relativizeFail("")
1002            .relativizeFail(".")
1003            .relativizeFail("..");
1004        test("\\..\\a\\b")
1005            .relativize("\\a\\b", "")
1006            .relativize("\\a", "..")
1007            .relativize("\\", "..\\..")
1008            .relativize("\\.", "..\\..")
1009            .relativize("\\..", "..\\..")
1010            .relativize("\\..\\..", "..\\..")
1011            .relativize("\\..\\..\\..", "..\\..")
1012            .relativize("\\..\\..\\..\\..", "..\\..")
1013            .relativize("\\a\\b\\c", "c")
1014            .relativize("\\a\\b\\.", "")        // "." also valid
1015            .relativize("\\a\\b\\..", "..")
1016            .relativize("\\a\\x", "..\\x")
1017            .relativize("\\x", "..\\..\\x")
1018            .relativizeFail("C:\\x")
1019            .relativizeFail("C:x")
1020            .relativizeFail("x")
1021            .relativizeFail("")
1022            .relativizeFail(".")
1023            .relativizeFail("..");
1024        test("\\..\\..\\a\\b")
1025            .relativize("\\a\\b", "")
1026            .relativize("\\a", "..")
1027            .relativize("\\", "..\\..")
1028            .relativize("\\.", "..\\..")
1029            .relativize("\\..", "..\\..")
1030            .relativize("\\..\\..", "..\\..")
1031            .relativize("\\..\\..\\..", "..\\..")
1032            .relativize("\\..\\..\\..\\..", "..\\..")
1033            .relativize("\\a\\b\\c", "c")
1034            .relativize("\\a\\b\\.", "")        // "." also valid
1035            .relativize("\\a\\b\\..", "..")
1036            .relativize("\\a\\x", "..\\x")
1037            .relativize("\\x", "..\\..\\x")
1038            .relativizeFail("C:\\x")
1039            .relativizeFail("C:x")
1040            .relativizeFail("x")
1041            .relativizeFail("")
1042            .relativizeFail(".")
1043            .relativizeFail("..");
1044        test("\\..\\a\\b\\c")
1045            .relativize("\\a\\b\\c", "")
1046            .relativize("\\a\\b", "..")
1047            .relativize("\\a", "..\\..")
1048            .relativize("\\", "..\\..\\..")
1049            .relativize("\\.", "..\\..\\..")
1050            .relativize("\\..", "..\\..\\..")
1051            .relativize("\\..\\..", "..\\..\\..")
1052            .relativize("\\..\\..\\..", "..\\..\\..")
1053            .relativize("\\..\\..\\..\\..", "..\\..\\..")
1054            .relativize("\\a\\b\\c\\d", "d")
1055            .relativize("\\a\\b\\c\\d\\e", "d\\e")
1056            .relativize("\\a\\b\\c\\.", "")        // "." also valid
1057            .relativize("\\a\\b\\c\\..", "..")
1058            .relativize("\\a\\x", "..\\..\\x")
1059            .relativize("\\x", "..\\..\\..\\x")
1060            .relativizeFail("C:\\x")
1061            .relativizeFail("C:x")
1062            .relativizeFail("x")
1063            .relativizeFail("")
1064            .relativizeFail(".")
1065            .relativizeFail("..");
1066        test("\\..\\..\\a\\b\\c")
1067            .relativize("\\a\\b\\c", "")
1068            .relativize("\\a\\b", "..")
1069            .relativize("\\a", "..\\..")
1070            .relativize("\\", "..\\..\\..")
1071            .relativize("\\.", "..\\..\\..")
1072            .relativize("\\..", "..\\..\\..")
1073            .relativize("\\..\\..", "..\\..\\..")
1074            .relativize("\\..\\..\\..", "..\\..\\..")
1075            .relativize("\\..\\..\\..\\..", "..\\..\\..")
1076            .relativize("\\a\\b\\c\\d", "d")
1077            .relativize("\\a\\b\\c\\d\\e", "d\\e")
1078            .relativize("\\a\\b\\c\\.", "")        // "." also valid
1079            .relativize("\\a\\b\\c\\..", "..")
1080            .relativize("\\a\\x", "..\\..\\x")
1081            .relativize("\\x", "..\\..\\..\\x")
1082            .relativizeFail("C:\\x")
1083            .relativizeFail("C:x")
1084            .relativizeFail("x")
1085            .relativizeFail("")
1086            .relativizeFail(".")
1087            .relativizeFail("..");
1088        test("\\..\\..\\..\\a\\b\\c")
1089            .relativize("\\a\\b\\c", "")
1090            .relativize("\\a\\b", "..")
1091            .relativize("\\a", "..\\..")
1092            .relativize("\\", "..\\..\\..")
1093            .relativize("\\.", "..\\..\\..")
1094            .relativize("\\..", "..\\..\\..")
1095            .relativize("\\..\\..", "..\\..\\..")
1096            .relativize("\\..\\..\\..", "..\\..\\..")
1097            .relativize("\\..\\..\\..\\..", "..\\..\\..")
1098            .relativize("\\a\\b\\c\\d", "d")
1099            .relativize("\\a\\b\\c\\d\\e", "d\\e")
1100            .relativize("\\a\\b\\c\\.", "")        // "." also valid
1101            .relativize("\\a\\b\\c\\..", "..")
1102            .relativize("\\a\\x", "..\\..\\x")
1103            .relativize("\\x", "..\\..\\..\\x")
1104            .relativizeFail("C:\\x")
1105            .relativizeFail("C:x")
1106            .relativizeFail("x")
1107            .relativizeFail("")
1108            .relativizeFail(".")
1109            .relativizeFail("..");
1110        test("\\.\\a")
1111            .relativize("\\a", "")
1112            .relativize("\\", "..")
1113            .relativize("\\.", "..")
1114            .relativize("\\..", "..")
1115            .relativize("\\..\\..", "..")
1116            .relativize("\\a\\b", "b")
1117            .relativize("\\a\\b\\c", "b\\c")
1118            .relativize("\\a\\.", "")        // "." also valid
1119            .relativize("\\a\\..", "..")
1120            .relativize("\\x", "..\\x")
1121            .relativizeFail("C:\\x")
1122            .relativizeFail("C:x")
1123            .relativizeFail("x")
1124            .relativizeFail("")
1125            .relativizeFail(".")
1126            .relativizeFail("..");
1127        test("\\..\\a")
1128            .relativize("\\a", "")
1129            .relativize("\\", "..")
1130            .relativize("\\.", "..")
1131            .relativize("\\..", "..")
1132            .relativize("\\..\\..", "..")
1133            .relativize("\\a\\b", "b")
1134            .relativize("\\a\\b\\c", "b\\c")
1135            .relativize("\\a\\.", "")        // "." also valid
1136            .relativize("\\a\\..", "..")
1137            .relativize("\\x", "..\\x")
1138            .relativizeFail("C:\\x")
1139            .relativizeFail("C:x")
1140            .relativizeFail("x")
1141            .relativizeFail("")
1142            .relativizeFail(".")
1143            .relativizeFail("..");
1144        test("\\a\\..")
1145            .relativize("\\a", "a")
1146            .relativize("\\", "")          // "." is also valid
1147            .relativize("\\.", "")
1148            .relativize("\\..", "")
1149            .relativize("\\..\\..", "")
1150            .relativize("\\a\\.", "a")
1151            .relativize("\\a\\..", "")
1152            .relativize("\\x", "x")
1153            .relativizeFail("C:\\x")
1154            .relativizeFail("C:x")
1155            .relativizeFail("x")
1156            .relativizeFail("")
1157            .relativizeFail(".")
1158            .relativizeFail("..");
1159        test("\\")
1160            .relativize("\\a", "a")
1161            .relativize("\\", "")          // "." is also valid
1162            .relativize("\\.", "")
1163            .relativize("\\..", "")
1164            .relativize("\\..\\..", "")
1165            .relativize("\\a\\.", "a")
1166            .relativize("\\a\\..", "")
1167            .relativize("\\x", "x")
1168            .relativizeFail("C:\\x")
1169            .relativizeFail("C:x")
1170            .relativizeFail("x")
1171            .relativizeFail("")
1172            .relativizeFail(".")
1173            .relativizeFail("..");
1174        test("a")
1175            .relativize("a", "")
1176            .relativize("", "..")
1177            .relativize(".", "..")
1178            .relativize("..", "..\\..")
1179            .relativize("..\\..", "..\\..\\..")
1180            .relativize(".\\..", "..\\..")
1181            .relativize("a\\b", "b")
1182            .relativize("a\\b\\c", "b\\c")
1183            .relativize("..\\x", "..\\..\\x")
1184            .relativizeFail("C:\\x")
1185            .relativizeFail("C:x")
1186            .relativizeFail("\\")
1187            .relativizeFail("\\x");
1188        test("a\\b")
1189            .relativize("a\\b", "")
1190            .relativize("a", "..")
1191            .relativize("", "..\\..")
1192            .relativize(".", "..\\..")
1193            .relativize("..", "..\\..\\..")
1194            .relativize("..\\..", "..\\..\\..\\..")
1195            .relativize(".\\..", "..\\..\\..")
1196            .relativize("a\\b\\c", "c")
1197            .relativize("..\\x", "..\\..\\..\\x")
1198            .relativizeFail("C:\\x")
1199            .relativizeFail("C:x")
1200            .relativizeFail("\\")
1201            .relativizeFail("\\x");
1202        test("a\\b\\c")
1203            .relativize("a\\b\\c", "")
1204            .relativize("a\\b", "..")
1205            .relativize("a", "..\\..")
1206            .relativize("", "..\\..\\..")
1207            .relativize(".", "..\\..\\..")
1208            .relativize("..", "..\\..\\..\\..")
1209            .relativize("..\\..", "..\\..\\..\\..\\..")
1210            .relativize(".\\..", "..\\..\\..\\..")
1211            .relativize("a\\b\\c\\d", "d")
1212            .relativize("a\\b\\c\\d\\e", "d\\e")
1213            .relativize("a\\x", "..\\..\\x")
1214            .relativize("..\\x", "..\\..\\..\\..\\x")
1215            .relativizeFail("C:\\x")
1216            .relativizeFail("C:x")
1217            .relativizeFail("\\")
1218            .relativizeFail("\\x");
1219        test("")
1220            .relativize("a", "a")
1221            .relativize("a\\b\\c", "a\\b\\c")
1222            .relativize("", "")
1223            .relativize(".", ".")
1224            .relativize("..", "..")
1225            .relativize("..\\..", "..\\..")
1226            .relativize(".\\..", ".\\..")     // ".." also valid
1227            .relativizeFail("\\")
1228            .relativizeFail("\\x");
1229        test("..")
1230            .relativize("..\\a", "a")
1231            .relativize("..", "")
1232            .relativize(".\\..", "")
1233            .relativizeFail("C:\\x")
1234            .relativizeFail("C:x")
1235            .relativizeFail("\\")
1236            .relativizeFail("\\x")
1237            .relativizeFail("")
1238            .relativizeFail(".")
1239            .relativizeFail("x");
1240        test("..\\a")
1241            .relativize("..\\a\\b", "b")
1242            .relativize("..\\a", "")
1243            .relativize("..", "..")
1244            .relativize(".\\..", "..")
1245            .relativizeFail("C:\\x")
1246            .relativizeFail("C:x")
1247            .relativizeFail("\\")
1248            .relativizeFail("\\x")
1249            .relativizeFail("")
1250            .relativizeFail(".")
1251            .relativizeFail("x");
1252        test("..\\a\\b")
1253            .relativize("..\\a\\b\\c", "c")
1254            .relativize("..\\a\\b", "")
1255            .relativize("..\\a", "..")
1256            .relativize("..", "..\\..")
1257            .relativize(".\\..", "..\\..")
1258            .relativizeFail("C:\\x")
1259            .relativizeFail("C:x")
1260            .relativizeFail("\\")
1261            .relativizeFail("\\x")
1262            .relativizeFail("")
1263            .relativizeFail("x");
1264        test("a\\..")
1265            .relativize("b", "b")
1266            .relativize("", "")
1267            .relativize(".", "")       // "." also valid
1268            .relativize("..", "..")
1269            .relativize("a\\..\\b", "b")
1270            .relativize("a\\..", "")
1271            .relativize("..\\b", "..\\b")
1272            .relativize("b\\..", "")
1273            .relativizeFail("C:\\x")
1274            .relativizeFail("C:x")
1275            .relativizeFail("\\")
1276            .relativizeFail("\\x");
1277        test("a\\..\\b")
1278            .relativize("a\\..\\b", "")
1279            .relativize("a\\..", "..")
1280            .relativize("", "..")
1281            .relativize(".", "..")
1282            .relativize("..", "..\\..")
1283            .relativize("b", "")
1284            .relativize("c", "..\\c")
1285            .relativize("..\\c", "..\\..\\c")
1286            .relativize("a\\..\\b\\c", "c")
1287            .relativizeFail("C:\\x")
1288            .relativizeFail("C:x")
1289            .relativizeFail("\\")
1290            .relativizeFail("\\x");
1291
1292        // normalize
1293        test("C:\\")
1294            .normalize("C:\\");
1295        test("C:\\.")
1296            .normalize("C:\\");
1297        test("C:\\..")
1298            .normalize("C:\\");
1299        test("\\\\server\\share")
1300            .normalize("\\\\server\\share\\");
1301        test("\\\\server\\share\\.")
1302            .normalize("\\\\server\\share\\");
1303        test("\\\\server\\share\\..")
1304            .normalize("\\\\server\\share\\");
1305        test("C:")
1306            .normalize("C:");
1307        test("C:.")
1308            .normalize("C:");
1309        test("C:..")
1310            .normalize("C:..");
1311        test("\\")
1312            .normalize("\\");
1313        test("\\.")
1314            .normalize("\\");
1315        test("\\..")
1316            .normalize("\\");
1317        test("foo")
1318            .normalize("foo");
1319        test("foo\\.")
1320            .normalize("foo");
1321        test("foo\\..")
1322            .normalize("");
1323        test("C:\\foo")
1324            .normalize("C:\\foo");
1325        test("C:\\foo\\.")
1326            .normalize("C:\\foo");
1327        test("C:\\.\\foo")
1328            .normalize("C:\\foo");
1329        test("C:\\foo\\..")
1330            .normalize("C:\\");
1331        test("C:\\..\\foo")
1332            .normalize("C:\\foo");
1333        test("\\\\server\\share\\foo")
1334            .normalize("\\\\server\\share\\foo");
1335        test("\\\\server\\share\\foo\\.")
1336            .normalize("\\\\server\\share\\foo");
1337        test("\\\\server\\share\\.\\foo")
1338            .normalize("\\\\server\\share\\foo");
1339        test("\\\\server\\share\\foo\\..")
1340            .normalize("\\\\server\\share\\");
1341        test("\\\\server\\share\\..\\foo")
1342            .normalize("\\\\server\\share\\foo");
1343        test("C:foo")
1344            .normalize("C:foo");
1345        test("C:foo\\.")
1346            .normalize("C:foo");
1347        test("C:.\\foo")
1348            .normalize("C:foo");
1349        test("C:foo\\..")
1350            .normalize("C:");
1351        test("C:..\\foo")
1352            .normalize("C:..\\foo");
1353        test("\\foo")
1354            .normalize("\\foo");
1355        test("\\foo\\.")
1356            .normalize("\\foo");
1357        test("\\.\\foo")
1358            .normalize("\\foo");
1359        test("\\foo\\..")
1360            .normalize("\\");
1361        test("\\..\\foo")
1362            .normalize("\\foo");
1363        test(".")
1364            .normalize("");
1365        test("..")
1366            .normalize("..");
1367        test("\\..\\..")
1368            .normalize("\\");
1369        test("..\\..\\foo")
1370            .normalize("..\\..\\foo");
1371        test("foo\\bar\\..")
1372            .normalize("foo");
1373        test("foo\\bar\\.\\..")
1374            .normalize("foo");
1375        test("foo\\bar\\gus\\..\\..")
1376            .normalize("foo");
1377        test(".\\foo\\.\\bar\\.\\gus\\..\\.\\..")
1378            .normalize("foo");
1379        test("")
1380            .normalize("");
1381
1382        // UNC corner cases
1383        test("\\\\server\\share\\")
1384            .root("\\\\server\\share\\")
1385            .parent(null)
1386            .name(null);
1387        test("\\\\server")
1388            .invalid();
1389        test("\\\\server\\")
1390            .invalid();
1391        test("\\\\server\\share")
1392            .root("\\\\server\\share\\")
1393            .parent(null)
1394            .name(null);
1395
1396        // invalid
1397        test(":\\foo")
1398            .invalid();
1399        test("C::")
1400            .invalid();
1401        test("C:\\?")           // invalid character
1402            .invalid();
1403        test("C:\\*")           // invalid character
1404            .invalid();
1405        test("C:\\abc\u0001\\foo")
1406            .invalid();
1407        test("C:\\\u0019\\foo")
1408            .invalid();
1409        test("\\\\server\u0019\\share")
1410            .invalid();
1411        test("\\\\server\\share\u0019")
1412            .invalid();
1413        test("foo\u0000\bar")
1414            .invalid();
1415        test("C:\\foo ")                // trailing space
1416             .invalid();
1417        test("C:\\foo \\bar")
1418            .invalid();
1419        //test("C:\\foo.")              // trailing dot
1420            //.invalid();
1421        //test("C:\\foo...\\bar")
1422            //.invalid();
1423
1424        // normalization at construction time (remove redundant and replace slashes)
1425        test("C:/a/b/c")
1426            .string("C:\\a\\b\\c")
1427            .root("C:\\")
1428            .parent("C:\\a\\b");
1429        test("C://a//b//c")
1430            .string("C:\\a\\b\\c")
1431            .root("C:\\")
1432            .parent("C:\\a\\b");
1433
1434        // hashCode
1435        header("hashCode");
1436        int h1 = test("C:\\foo").path().hashCode();
1437        int h2 = test("c:\\FOO").path().hashCode();
1438        if (h1 != h2)
1439            throw new RuntimeException("PathOps failed");
1440    }
1441
1442    static void doUnixTests() {
1443        header("Unix specific tests");
1444        Path cwd = Paths.get("").toAbsolutePath();
1445
1446        // construction
1447        test("/")
1448            .string("/");
1449        test("/", "")
1450            .string("/");
1451        test("/", "foo")
1452            .string("/foo");
1453        test("/", "/foo")
1454            .string("/foo");
1455        test("/", "foo/")
1456            .string("/foo");
1457        test("foo", "bar", "gus")
1458            .string("foo/bar/gus");
1459        test("")
1460            .string("");
1461        test("", "/")
1462            .string("/");
1463        test("", "foo", "", "bar", "", "/gus")
1464            .string("foo/bar/gus");
1465
1466        // all components
1467        test("/a/b/c")
1468            .root("/")
1469            .parent("/a/b")
1470            .name("c");
1471
1472        // root component only
1473        test("/")
1474            .root("/")
1475            .parent(null)
1476            .name(null);
1477
1478        // no root component
1479        test("a/b")
1480            .root(null)
1481            .parent("a")
1482            .name("b");
1483
1484        // name component only
1485        test("foo")
1486            .root(null)
1487            .parent(null)
1488            .name("foo");
1489        test("")
1490             .root(null)
1491             .parent(null)
1492             .name("");
1493
1494        // startsWith
1495        test("/")
1496            .starts("/")
1497            .notStarts("")
1498            .notStarts("/foo");
1499        test("/foo")
1500            .starts("/")
1501            .starts("/foo")
1502            .notStarts("/f");
1503        test("/foo/bar")
1504            .starts("/")
1505            .starts("/foo")
1506            .starts("/foo/bar")
1507            .notStarts("/f")
1508            .notStarts("foo")
1509            .notStarts("foo/bar");
1510        test("foo")
1511            .starts("foo")
1512            .notStarts("")
1513            .notStarts("f");
1514        test("foo/bar")
1515            .starts("foo")
1516            .starts("foo/bar")
1517            .notStarts("f")
1518            .notStarts("/foo")
1519            .notStarts("/foo/bar");
1520        test("")
1521             .starts("")
1522             .notStarts("/");
1523
1524        // endsWith
1525        test("/")
1526            .ends("/")
1527            .notEnds("")
1528            .notEnds("foo")
1529            .notEnds("/foo");
1530        test("/foo")
1531            .ends("foo")
1532            .ends("/foo")
1533            .notEnds("fool");
1534        test("/foo/bar")
1535            .ends("bar")
1536            .ends("foo/bar")
1537            .ends("/foo/bar")
1538            .notEnds("ar")
1539            .notEnds("barack")
1540            .notEnds("/bar")
1541            .notEnds("o/bar");
1542        test("foo")
1543            .ends("foo")
1544            .notEnds("")
1545            .notEnds("oo")
1546            .notEnds("oola");
1547        test("foo/bar")
1548            .ends("bar")
1549            .ends("foo/bar")
1550            .notEnds("r")
1551            .notEnds("barmaid")
1552            .notEnds("/bar");
1553        test("foo/bar/gus")
1554            .ends("gus")
1555            .ends("bar/gus")
1556            .ends("foo/bar/gus")
1557            .notEnds("g")
1558            .notEnds("/gus")
1559            .notEnds("r/gus")
1560            .notEnds("barack/gus")
1561            .notEnds("bar/gust");
1562        test("")
1563            .ends("")
1564            .notEnds("/");
1565
1566        // elements
1567        test("a/b/c")
1568            .element(0, "a")
1569            .element(1, "b")
1570            .element(2, "c");
1571        test("")
1572            .element(0, "");
1573
1574        // subpath
1575        test("/foo")
1576            .subpath(0, 1, "foo");
1577        test("foo")
1578            .subpath(0, 1, "foo");
1579        test("/foo/bar")
1580            .subpath(0, 1, "foo")
1581            .subpath(1, 2, "bar")
1582            .subpath(0, 2, "foo/bar");
1583        test("foo/bar")
1584            .subpath(0, 1, "foo")
1585            .subpath(1, 2, "bar")
1586            .subpath(0, 2, "foo/bar");
1587        test("/foo/bar/gus")
1588            .subpath(0, 1, "foo")
1589            .subpath(1, 2, "bar")
1590            .subpath(2, 3, "gus")
1591            .subpath(0, 2, "foo/bar")
1592            .subpath(1, 3, "bar/gus")
1593            .subpath(0, 3, "foo/bar/gus");
1594        test("foo/bar/gus")
1595            .subpath(0, 1, "foo")
1596            .subpath(1, 2, "bar")
1597            .subpath(2, 3, "gus")
1598            .subpath(0, 2, "foo/bar")
1599            .subpath(1, 3, "bar/gus")
1600            .subpath(0, 3, "foo/bar/gus");
1601        test("")
1602            .subpath(0, 1, "");
1603
1604        // isAbsolute
1605        test("/")
1606            .absolute();
1607        test("/tmp")
1608            .absolute();
1609        test("tmp")
1610            .notAbsolute();
1611        test("")
1612            .notAbsolute();
1613        test(cwd)
1614            .absolute();
1615
1616        // toAbsolutePath
1617        test("/")
1618            .makeAbsolute()
1619            .absolute();
1620        test("/tmp")
1621            .makeAbsolute()
1622            .absolute();
1623        test("tmp")
1624            .makeAbsolute()
1625            .absolute();
1626        test("")
1627            .makeAbsolute()
1628            .absolute();
1629
1630        // resolve
1631        test("/tmp")
1632            .resolve("foo", "/tmp/foo")
1633            .resolve("/foo", "/foo")
1634            .resolve("", "/tmp");
1635        test("tmp")
1636            .resolve("foo", "tmp/foo")
1637            .resolve("/foo", "/foo")
1638            .resolve("", "tmp");
1639        test("")
1640            .resolve("", "")
1641            .resolve("foo", "foo")
1642            .resolve("/foo", "/foo");
1643
1644        // resolveSibling
1645        test("foo")
1646            .resolveSibling("bar", "bar")
1647            .resolveSibling("/bar", "/bar")
1648            .resolveSibling("", "");
1649        test("foo/bar")
1650            .resolveSibling("gus", "foo/gus")
1651            .resolveSibling("/gus", "/gus")
1652            .resolveSibling("", "foo");
1653        test("/foo")
1654            .resolveSibling("gus", "/gus")
1655            .resolveSibling("/gus", "/gus")
1656            .resolveSibling("", "/");
1657        test("/foo/bar")
1658            .resolveSibling("gus", "/foo/gus")
1659            .resolveSibling("/gus", "/gus")
1660            .resolveSibling("", "/foo");
1661        test("")
1662            .resolveSibling("foo", "foo")
1663            .resolveSibling("/foo", "/foo")
1664            .resolve("", "");
1665
1666        // relativize
1667        test("/a")
1668            .relativize("/a", "")
1669            .relativize("/", "..")
1670            .relativize("/.", "..")
1671            .relativize("/..", "..")
1672            .relativize("/../..", "..")
1673            .relativize("/a/b", "b")
1674            .relativize("/a/b/c", "b/c")
1675            .relativize("/a/.", "")        // "." also valid
1676            .relativize("/a/..", "..")
1677            .relativize("/x", "../x")
1678            .relativizeFail("x")
1679            .relativizeFail("")
1680            .relativizeFail(".")
1681            .relativizeFail("..");
1682        test("/a/b")
1683            .relativize("/a/b", "")
1684            .relativize("/a", "..")
1685            .relativize("/", "../..")
1686            .relativize("/.", "../..")
1687            .relativize("/..", "../..")
1688            .relativize("/../..", "../..")
1689            .relativize("/a/b/c", "c")
1690            .relativize("/a/.", "..")
1691            .relativize("/a/..", "../..")
1692            .relativize("/x", "../../x")
1693            .relativizeFail("x")
1694            .relativizeFail("")
1695            .relativizeFail(".")
1696            .relativizeFail("..");
1697        test("/a/b/c")
1698            .relativize("/a/b/c", "")
1699            .relativize("/a/b", "..")
1700            .relativize("/a", "../..")
1701            .relativize("/", "../../..")
1702            .relativize("/.", "../../..")
1703            .relativize("/..", "../../..")
1704            .relativize("/../..", "../../..")
1705            .relativize("/../../..", "../../..")
1706            .relativize("/../../../..", "../../..")
1707            .relativize("/a/b/c/d", "d")
1708            .relativize("/a/b/c/d/e", "d/e")
1709            .relativize("/a/b/c/.", "")        // "." also valid
1710            .relativize("/a/b/c/..", "..")
1711            .relativize("/a/x", "../../x")
1712            .relativize("/x", "../../../x")
1713            .relativizeFail("x")
1714            .relativizeFail("")
1715            .relativizeFail(".")
1716            .relativizeFail("..");
1717        test("/../a")
1718            .relativize("/a", "")
1719            .relativize("/", "..")
1720            .relativize("/.", "..")
1721            .relativize("/..", "..")
1722            .relativize("/../..", "..")
1723            .relativize("/a/b", "b")
1724            .relativize("/a/b/c", "b/c")
1725            .relativize("/a/.", "")        // "." also valid
1726            .relativize("/a/..", "..")
1727            .relativize("/x", "../x")
1728            .relativizeFail("x")
1729            .relativizeFail("")
1730            .relativizeFail(".")
1731            .relativizeFail("..");
1732        test("/../a/b")
1733            .relativize("/a/b", "")
1734            .relativize("/a", "..")
1735            .relativize("/", "../..")
1736            .relativize("/.", "../..")
1737            .relativize("/..", "../..")
1738            .relativize("/../..", "../..")
1739            .relativize("/../../..", "../..")
1740            .relativize("/../../../..", "../..")
1741            .relativize("/a/b/c", "c")
1742            .relativize("/a/b/.", "")        // "." also valid
1743            .relativize("/a/b/..", "..")
1744            .relativize("/a/x", "../x")
1745            .relativize("/x", "../../x")
1746            .relativizeFail("x")
1747            .relativizeFail("")
1748            .relativizeFail(".")
1749            .relativizeFail("..");
1750        test("/../../a/b")
1751            .relativize("/a/b", "")
1752            .relativize("/a", "..")
1753            .relativize("/", "../..")
1754            .relativize("/.", "../..")
1755            .relativize("/..", "../..")
1756            .relativize("/../..", "../..")
1757            .relativize("/../../..", "../..")
1758            .relativize("/../../../..", "../..")
1759            .relativize("/a/b/c", "c")
1760            .relativize("/a/b/.", "")        // "." also valid
1761            .relativize("/a/b/..", "..")
1762            .relativize("/a/x", "../x")
1763            .relativize("/x", "../../x")
1764            .relativizeFail("x")
1765            .relativizeFail("")
1766            .relativizeFail(".")
1767            .relativizeFail("..");
1768        test("/../a/b/c")
1769            .relativize("/a/b/c", "")
1770            .relativize("/a/b", "..")
1771            .relativize("/a", "../..")
1772            .relativize("/", "../../..")
1773            .relativize("/.", "../../..")
1774            .relativize("/..", "../../..")
1775            .relativize("/../..", "../../..")
1776            .relativize("/../../..", "../../..")
1777            .relativize("/../../../..", "../../..")
1778            .relativize("/a/b/c/d", "d")
1779            .relativize("/a/b/c/d/e", "d/e")
1780            .relativize("/a/b/c/.", "")        // "." also valid
1781            .relativize("/a/b/c/..", "..")
1782            .relativize("/a/x", "../../x")
1783            .relativize("/x", "../../../x")
1784            .relativizeFail("x")
1785            .relativizeFail("")
1786            .relativizeFail(".")
1787            .relativizeFail("..");
1788        test("/../../a/b/c")
1789            .relativize("/a/b/c", "")
1790            .relativize("/a/b", "..")
1791            .relativize("/a", "../..")
1792            .relativize("/", "../../..")
1793            .relativize("/.", "../../..")
1794            .relativize("/..", "../../..")
1795            .relativize("/../..", "../../..")
1796            .relativize("/../../..", "../../..")
1797            .relativize("/../../../..", "../../..")
1798            .relativize("/a/b/c/d", "d")
1799            .relativize("/a/b/c/d/e", "d/e")
1800            .relativize("/a/b/c/.", "")        // "." also valid
1801            .relativize("/a/b/c/..", "..")
1802            .relativize("/a/x", "../../x")
1803            .relativize("/x", "../../../x")
1804            .relativizeFail("x")
1805            .relativizeFail("")
1806            .relativizeFail(".")
1807            .relativizeFail("..");
1808        test("/../../../a/b/c")
1809            .relativize("/a/b/c", "")
1810            .relativize("/a/b", "..")
1811            .relativize("/a", "../..")
1812            .relativize("/", "../../..")
1813            .relativize("/.", "../../..")
1814            .relativize("/..", "../../..")
1815            .relativize("/../..", "../../..")
1816            .relativize("/../../..", "../../..")
1817            .relativize("/../../../..", "../../..")
1818            .relativize("/a/b/c/d", "d")
1819            .relativize("/a/b/c/d/e", "d/e")
1820            .relativize("/a/b/c/.", "")        // "." also valid
1821            .relativize("/a/b/c/..", "..")
1822            .relativize("/a/x", "../../x")
1823            .relativize("/x", "../../../x")
1824            .relativizeFail("x")
1825            .relativizeFail("")
1826            .relativizeFail(".")
1827            .relativizeFail("..");
1828        test("/./a")
1829            .relativize("/a", "")
1830            .relativize("/", "..")
1831            .relativize("/.", "..")
1832            .relativize("/..", "..")
1833            .relativize("/../..", "..")
1834            .relativize("/a/b", "b")
1835            .relativize("/a/b/c", "b/c")
1836            .relativize("/a/.", "")        // "." also valid
1837            .relativize("/a/..", "..")
1838            .relativize("/x", "../x")
1839            .relativizeFail("x")
1840            .relativizeFail("")
1841            .relativizeFail(".")
1842            .relativizeFail("..");
1843        test("/../a")
1844            .relativize("/a", "")
1845            .relativize("/", "..")
1846            .relativize("/.", "..")
1847            .relativize("/..", "..")
1848            .relativize("/../..", "..")
1849            .relativize("/a/b", "b")
1850            .relativize("/a/b/c", "b/c")
1851            .relativize("/a/.", "")        // "." also valid
1852            .relativize("/a/..", "..")
1853            .relativize("/x", "../x")
1854            .relativizeFail("x")
1855            .relativizeFail("")
1856            .relativizeFail(".")
1857            .relativizeFail("..");
1858        test("/a/..")
1859            .relativize("/a", "a")
1860            .relativize("/", "")          // "." is also valid
1861            .relativize("/.", "")
1862            .relativize("/..", "")
1863            .relativize("/../..", "")
1864            .relativize("/a/.", "a")
1865            .relativize("/a/..", "")
1866            .relativize("/x", "x")
1867            .relativizeFail("x")
1868            .relativizeFail("")
1869            .relativizeFail(".")
1870            .relativizeFail("..");
1871        test("/")
1872            .relativize("/a", "a")
1873            .relativize("/", "")          // "." is also valid
1874            .relativize("/.", "")
1875            .relativize("/..", "")
1876            .relativize("/../..", "")
1877            .relativize("/a/.", "a")
1878            .relativize("/a/..", "")
1879            .relativize("/x", "x")
1880            .relativizeFail("x")
1881            .relativizeFail("")
1882            .relativizeFail(".")
1883            .relativizeFail("..");
1884        test("a")
1885            .relativize("a", "")
1886            .relativize("", "..")
1887            .relativize(".", "..")
1888            .relativize("..", "../..")
1889            .relativize("../..", "../../..")
1890            .relativize("./..", "../..")
1891            .relativize("a/b", "b")
1892            .relativize("a/b/c", "b/c")
1893            .relativize("../x", "../../x")
1894            .relativizeFail("/")
1895            .relativizeFail("/x");
1896        test("a/b")
1897            .relativize("a/b", "")
1898            .relativize("a", "..")
1899            .relativize("", "../..")
1900            .relativize(".", "../..")
1901            .relativize("..", "../../..")
1902            .relativize("../..", "../../../..")
1903            .relativize("./..", "../../..")
1904            .relativize("a/b/c", "c")
1905            .relativize("../x", "../../../x")
1906            .relativizeFail("/")
1907            .relativizeFail("/x");
1908        test("a/b/c")
1909            .relativize("a/b/c", "")
1910            .relativize("a/b", "..")
1911            .relativize("a", "../..")
1912            .relativize("", "../../..")
1913            .relativize(".", "../../..")
1914            .relativize("..", "../../../..")
1915            .relativize("../..", "../../../../..")
1916            .relativize("./..", "../../../..")
1917            .relativize("a/b/c/d", "d")
1918            .relativize("a/b/c/d/e", "d/e")
1919            .relativize("a/x", "../../x")
1920            .relativize("../x", "../../../../x")
1921            .relativizeFail("/")
1922            .relativizeFail("/x");
1923        test("")
1924            .relativize("a", "a")
1925            .relativize("a/b/c", "a/b/c")
1926            .relativize("", "")
1927            .relativize(".", ".")
1928            .relativize("..", "..")
1929            .relativize("../..", "../..")
1930            .relativize("./..", "./..")     // ".." also valid
1931            .relativizeFail("/")
1932            .relativizeFail("/x");
1933        test("..")
1934            .relativize("../a", "a")
1935            .relativize("..", "")
1936            .relativize("./..", "")
1937            .relativizeFail("/")
1938            .relativizeFail("/x")
1939            .relativizeFail("")
1940            .relativizeFail(".")
1941            .relativizeFail("x");
1942        test("../a")
1943            .relativize("../a/b", "b")
1944            .relativize("../a", "")
1945            .relativize("..", "..")
1946            .relativize("./..", "..")
1947            .relativizeFail("/")
1948            .relativizeFail("/x")
1949            .relativizeFail("")
1950            .relativizeFail(".")
1951            .relativizeFail("x");
1952        test("../a/b")
1953            .relativize("../a/b/c", "c")
1954            .relativize("../a/b", "")
1955            .relativize("../a", "..")
1956            .relativize("..", "../..")
1957            .relativize("./..", "../..")
1958            .relativizeFail("/")
1959            .relativizeFail("/x")
1960            .relativizeFail("")
1961            .relativizeFail("x");
1962        test("a/..")
1963            .relativize("b", "b")
1964            .relativize("", "")
1965            .relativize(".", "")       // "." also valid
1966            .relativize("..", "..")
1967            .relativize("a/../b", "b")
1968            .relativize("a/..", "")
1969            .relativize("../b", "../b")
1970            .relativize("b/..", "")
1971            .relativizeFail("/")
1972            .relativizeFail("/x");
1973        test("a/../b")
1974            .relativize("a/../b", "")
1975            .relativize("a/..", "..")
1976            .relativize("", "..")
1977            .relativize(".", "..")
1978            .relativize("..", "../..")
1979            .relativize("b", "")
1980            .relativize("c", "../c")
1981            .relativize("../c", "../../c")
1982            .relativize("a/../b/c", "c")
1983            .relativizeFail("/")
1984            .relativizeFail("/x");
1985
1986        // normalize
1987        test("/")
1988            .normalize("/");
1989        test("foo")
1990            .normalize("foo");
1991        test("/foo")
1992            .normalize("/foo");
1993        test("")
1994            .normalize("");
1995        test(".")
1996            .normalize("");
1997        test("..")
1998            .normalize("..");
1999        test("/..")
2000            .normalize("/");
2001        test("/../..")
2002            .normalize("/");
2003        test("foo/.")
2004            .normalize("foo");
2005        test("./foo")
2006            .normalize("foo");
2007        test("foo/..")
2008            .normalize("");
2009        test("../foo")
2010            .normalize("../foo");
2011        test("../../foo")
2012            .normalize("../../foo");
2013        test("foo/bar/..")
2014            .normalize("foo");
2015        test("foo/bar/gus/../..")
2016            .normalize("foo");
2017        test("/foo/bar/gus/../..")
2018            .normalize("/foo");
2019
2020        // invalid
2021        test("foo\u0000bar")
2022            .invalid();
2023        test("\u0000foo")
2024            .invalid();
2025        test("bar\u0000")
2026            .invalid();
2027        test("//foo\u0000bar")
2028            .invalid();
2029        test("//\u0000foo")
2030            .invalid();
2031        test("//bar\u0000")
2032            .invalid();
2033
2034        // normalization of input
2035        test("//foo//bar")
2036            .string("/foo/bar")
2037            .root("/")
2038            .parent("/foo")
2039            .name("bar");
2040    }
2041
2042    static void npes() {
2043        header("NullPointerException");
2044
2045        Path path = FileSystems.getDefault().getPath("foo");
2046
2047        try {
2048            path.resolve((String)null);
2049            throw new RuntimeException("NullPointerException not thrown");
2050        } catch (NullPointerException npe) {
2051        }
2052
2053        try {
2054            path.relativize(null);
2055            throw new RuntimeException("NullPointerException not thrown");
2056        } catch (NullPointerException npe) {
2057        }
2058
2059        try {
2060            path.compareTo(null);
2061            throw new RuntimeException("NullPointerException not thrown");
2062        } catch (NullPointerException npe) {
2063        }
2064
2065        try {
2066            path.startsWith((Path)null);
2067            throw new RuntimeException("NullPointerException not thrown");
2068        } catch (NullPointerException npe) {
2069        }
2070
2071        try {
2072            path.endsWith((Path)null);
2073            throw new RuntimeException("NullPointerException not thrown");
2074        } catch (NullPointerException npe) {
2075        }
2076
2077    }
2078
2079    public static void main(String[] args) {
2080        // all platforms
2081        npes();
2082
2083        // operating system specific
2084        String osname = System.getProperty("os.name");
2085        if (osname.startsWith("Windows")) {
2086            doWindowsTests();
2087        } else {
2088            doUnixTests();
2089        }
2090
2091    }
2092}
2093