| /* |
| * Copyright 2013 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.common.jimfs; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.fail; |
| |
| import com.google.common.testing.EqualsTester; |
| import com.google.common.testing.NullPointerTester; |
| import java.io.IOException; |
| import java.nio.file.InvalidPathException; |
| import java.nio.file.LinkOption; |
| import java.nio.file.Path; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** |
| * Tests for {@link JimfsPath}. |
| * |
| * @author Colin Decker |
| */ |
| @RunWith(JUnit4.class) |
| public class JimfsPathTest { |
| |
| private final PathService pathService = PathServiceTest.fakeUnixPathService(); |
| |
| @Test |
| public void testPathParsing() { |
| assertPathEquals("/", "/"); |
| assertPathEquals("/foo", "/foo"); |
| assertPathEquals("/foo", "/", "foo"); |
| assertPathEquals("/foo/bar", "/foo/bar"); |
| assertPathEquals("/foo/bar", "/", "foo", "bar"); |
| assertPathEquals("/foo/bar", "/foo", "bar"); |
| assertPathEquals("/foo/bar", "/", "foo/bar"); |
| assertPathEquals("foo/bar/baz", "foo/bar/baz"); |
| assertPathEquals("foo/bar/baz", "foo", "bar", "baz"); |
| assertPathEquals("foo/bar/baz", "foo/bar", "baz"); |
| assertPathEquals("foo/bar/baz", "foo", "bar/baz"); |
| } |
| |
| @Test |
| public void testPathParsing_withExtraSeparators() { |
| assertPathEquals("/foo/bar", "///foo/bar"); |
| assertPathEquals("/foo/bar", "/foo///bar//"); |
| assertPathEquals("/foo/bar/baz", "/foo", "/bar", "baz/"); |
| // assertPathEquals("/foo/bar/baz", "/foo\\/bar//\\\\/baz\\/"); |
| } |
| |
| @Test |
| public void testPathParsing_windowsStylePaths() throws IOException { |
| PathService windowsPathService = PathServiceTest.fakeWindowsPathService(); |
| assertEquals("C:\\", pathService.parsePath("C:\\").toString()); |
| assertEquals("C:\\foo", windowsPathService.parsePath("C:\\foo").toString()); |
| assertEquals("C:\\foo", windowsPathService.parsePath("C:\\", "foo").toString()); |
| assertEquals("C:\\foo", windowsPathService.parsePath("C:", "\\foo").toString()); |
| assertEquals("C:\\foo", windowsPathService.parsePath("C:", "foo").toString()); |
| assertEquals("C:\\foo\\bar", windowsPathService.parsePath("C:", "foo/bar").toString()); |
| } |
| |
| @Test |
| public void testParsing_windowsStylePaths_invalidPaths() { |
| PathService windowsPathService = PathServiceTest.fakeWindowsPathService(); |
| |
| try { |
| // The actual windows implementation seems to allow "C:" but treat it as a *name*, not a root |
| // despite the fact that a : is illegal except in a root... a : at any position other than |
| // index 1 in the string will produce an exception. |
| // Here, I choose to be more strict |
| windowsPathService.parsePath("C:"); |
| fail(); |
| } catch (InvalidPathException expected) { |
| } |
| |
| try { |
| // "1:\" isn't a root because 1 isn't a letter |
| windowsPathService.parsePath("1:\\foo"); |
| fail(); |
| } catch (InvalidPathException expected) { |
| } |
| |
| try { |
| // < and > are reserved characters |
| windowsPathService.parsePath("foo<bar>"); |
| fail(); |
| } catch (InvalidPathException expected) { |
| } |
| } |
| |
| @Test |
| public void testPathParsing_withAlternateSeparator() { |
| // windows recognizes / as an alternate separator |
| PathService windowsPathService = PathServiceTest.fakeWindowsPathService(); |
| assertEquals( |
| windowsPathService.parsePath("foo\\bar\\baz"), windowsPathService.parsePath("foo/bar/baz")); |
| assertEquals( |
| windowsPathService.parsePath("C:\\foo\\bar"), windowsPathService.parsePath("C:\\foo/bar")); |
| assertEquals( |
| windowsPathService.parsePath("c:\\foo\\bar\\baz"), |
| windowsPathService.parsePath("c:", "foo/", "bar/baz")); |
| } |
| |
| @Test |
| public void testRootPath() { |
| new PathTester(pathService, "/").root("/").test("/"); |
| } |
| |
| @Test |
| public void testRelativePath_singleName() { |
| new PathTester(pathService, "test").names("test").test("test"); |
| |
| Path path = pathService.parsePath("test"); |
| assertEquals(path, path.getFileName()); |
| } |
| |
| @Test |
| public void testRelativePath_twoNames() { |
| PathTester tester = new PathTester(pathService, "foo/bar").names("foo", "bar"); |
| |
| tester.test("foo/bar"); |
| } |
| |
| @Test |
| public void testRelativePath_fourNames() { |
| new PathTester(pathService, "foo/bar/baz/test") |
| .names("foo", "bar", "baz", "test") |
| .test("foo/bar/baz/test"); |
| } |
| |
| @Test |
| public void testAbsolutePath_singleName() { |
| new PathTester(pathService, "/foo").root("/").names("foo").test("/foo"); |
| } |
| |
| @Test |
| public void testAbsolutePath_twoNames() { |
| new PathTester(pathService, "/foo/bar").root("/").names("foo", "bar").test("/foo/bar"); |
| } |
| |
| @Test |
| public void testAbsoluteMultiNamePath_fourNames() { |
| new PathTester(pathService, "/foo/bar/baz/test") |
| .root("/") |
| .names("foo", "bar", "baz", "test") |
| .test("/foo/bar/baz/test"); |
| } |
| |
| @Test |
| public void testResolve_fromRoot() { |
| Path root = pathService.parsePath("/"); |
| |
| assertResolvedPathEquals("/foo", root, "foo"); |
| assertResolvedPathEquals("/foo/bar", root, "foo/bar"); |
| assertResolvedPathEquals("/foo/bar", root, "foo", "bar"); |
| assertResolvedPathEquals("/foo/bar/baz/test", root, "foo/bar/baz/test"); |
| assertResolvedPathEquals("/foo/bar/baz/test", root, "foo", "bar/baz", "test"); |
| } |
| |
| @Test |
| public void testResolve_fromAbsolute() { |
| Path path = pathService.parsePath("/foo"); |
| |
| assertResolvedPathEquals("/foo/bar", path, "bar"); |
| assertResolvedPathEquals("/foo/bar/baz/test", path, "bar/baz/test"); |
| assertResolvedPathEquals("/foo/bar/baz/test", path, "bar/baz", "test"); |
| assertResolvedPathEquals("/foo/bar/baz/test", path, "bar", "baz", "test"); |
| } |
| |
| @Test |
| public void testResolve_fromRelative() { |
| Path path = pathService.parsePath("foo"); |
| |
| assertResolvedPathEquals("foo/bar", path, "bar"); |
| assertResolvedPathEquals("foo/bar/baz/test", path, "bar/baz/test"); |
| assertResolvedPathEquals("foo/bar/baz/test", path, "bar", "baz", "test"); |
| assertResolvedPathEquals("foo/bar/baz/test", path, "bar/baz", "test"); |
| } |
| |
| @Test |
| public void testResolve_withThisAndParentDirNames() { |
| Path path = pathService.parsePath("/foo"); |
| |
| assertResolvedPathEquals("/foo/bar/../baz", path, "bar/../baz"); |
| assertResolvedPathEquals("/foo/bar/../baz", path, "bar", "..", "baz"); |
| assertResolvedPathEquals("/foo/./bar/baz", path, "./bar/baz"); |
| assertResolvedPathEquals("/foo/./bar/baz", path, ".", "bar/baz"); |
| } |
| |
| @Test |
| public void testResolve_givenAbsolutePath() { |
| assertResolvedPathEquals("/test", pathService.parsePath("/foo"), "/test"); |
| assertResolvedPathEquals("/test", pathService.parsePath("foo"), "/test"); |
| } |
| |
| @Test |
| public void testResolve_givenEmptyPath() { |
| assertResolvedPathEquals("/foo", pathService.parsePath("/foo"), ""); |
| assertResolvedPathEquals("foo", pathService.parsePath("foo"), ""); |
| } |
| |
| @Test |
| public void testResolve_againstEmptyPath() { |
| assertResolvedPathEquals("foo/bar", pathService.emptyPath(), "foo/bar"); |
| } |
| |
| @Test |
| public void testResolveSibling_givenEmptyPath() { |
| Path path = pathService.parsePath("foo/bar"); |
| Path resolved = path.resolveSibling(""); |
| assertPathEquals("foo", resolved); |
| |
| path = pathService.parsePath("foo"); |
| resolved = path.resolveSibling(""); |
| assertPathEquals("", resolved); |
| } |
| |
| @Test |
| public void testResolveSibling_againstEmptyPath() { |
| Path path = pathService.parsePath(""); |
| Path resolved = path.resolveSibling("foo"); |
| assertPathEquals("foo", resolved); |
| |
| path = pathService.parsePath(""); |
| resolved = path.resolveSibling(""); |
| assertPathEquals("", resolved); |
| } |
| |
| @Test |
| public void testRelativize_bothAbsolute() { |
| // TODO(cgdecker): When the paths have different roots, how should this work? |
| // Should it work at all? |
| assertRelativizedPathEquals("b/c", pathService.parsePath("/a"), "/a/b/c"); |
| assertRelativizedPathEquals("c/d", pathService.parsePath("/a/b"), "/a/b/c/d"); |
| } |
| |
| @Test |
| public void testRelativize_bothRelative() { |
| assertRelativizedPathEquals("b/c", pathService.parsePath("a"), "a/b/c"); |
| assertRelativizedPathEquals("d", pathService.parsePath("a/b/c"), "a/b/c/d"); |
| } |
| |
| @Test |
| public void testRelativize_againstEmptyPath() { |
| assertRelativizedPathEquals("foo/bar", pathService.emptyPath(), "foo/bar"); |
| } |
| |
| @Test |
| public void testRelativize_oneAbsoluteOneRelative() { |
| try { |
| pathService.parsePath("/foo/bar").relativize(pathService.parsePath("foo")); |
| fail(); |
| } catch (IllegalArgumentException expected) { |
| } |
| |
| try { |
| pathService.parsePath("foo").relativize(pathService.parsePath("/foo/bar")); |
| fail(); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testNormalize_withParentDirName() { |
| assertNormalizedPathEquals("/foo/baz", "/foo/bar/../baz"); |
| assertNormalizedPathEquals("/foo/baz", "/foo", "bar", "..", "baz"); |
| } |
| |
| @Test |
| public void testNormalize_withThisDirName() { |
| assertNormalizedPathEquals("/foo/bar/baz", "/foo/bar/./baz"); |
| assertNormalizedPathEquals("/foo/bar/baz", "/foo", "bar", ".", "baz"); |
| } |
| |
| @Test |
| public void testNormalize_withThisAndParentDirNames() { |
| assertNormalizedPathEquals("foo/test", "foo/./bar/../././baz/../test"); |
| } |
| |
| @Test |
| public void testNormalize_withLeadingParentDirNames() { |
| assertNormalizedPathEquals("../../foo/baz", "../../foo/bar/../baz"); |
| } |
| |
| @Test |
| public void testNormalize_withLeadingThisAndParentDirNames() { |
| assertNormalizedPathEquals("../../foo/baz", "./.././.././foo/bar/../baz"); |
| } |
| |
| @Test |
| public void testNormalize_withExtraParentDirNamesAtRoot() { |
| assertNormalizedPathEquals("/", "/.."); |
| assertNormalizedPathEquals("/", "/../../.."); |
| assertNormalizedPathEquals("/", "/foo/../../.."); |
| assertNormalizedPathEquals("/", "/../foo/../../bar/baz/../../../.."); |
| } |
| |
| @Test |
| public void testPathWithExtraSlashes() { |
| assertPathEquals("/foo/bar/baz", pathService.parsePath("/foo/bar/baz/")); |
| assertPathEquals("/foo/bar/baz", pathService.parsePath("/foo//bar///baz")); |
| assertPathEquals("/foo/bar/baz", pathService.parsePath("///foo/bar/baz")); |
| } |
| |
| @Test |
| public void testEqualityBasedOnStringNotName() { |
| Name a1 = Name.create("a", "a"); |
| Name a2 = Name.create("A", "a"); |
| Name a3 = Name.create("a", "A"); |
| |
| Path path1 = pathService.createFileName(a1); |
| Path path2 = pathService.createFileName(a2); |
| Path path3 = pathService.createFileName(a3); |
| |
| new EqualsTester().addEqualityGroup(path1, path3).addEqualityGroup(path2).testEquals(); |
| } |
| |
| @Test |
| public void testNullPointerExceptions() throws NoSuchMethodException { |
| NullPointerTester tester = |
| new NullPointerTester().ignore(JimfsPath.class.getMethod("toRealPath", LinkOption[].class)); |
| // ignore toRealPath because the pathService creates fake paths that do not have a |
| // JimfsFileSystem instance, causing it to fail since it needs to access the file system |
| |
| tester.testAllPublicInstanceMethods(pathService.parsePath("/")); |
| tester.testAllPublicInstanceMethods(pathService.parsePath("")); |
| tester.testAllPublicInstanceMethods(pathService.parsePath("/foo")); |
| tester.testAllPublicInstanceMethods(pathService.parsePath("/foo/bar/baz")); |
| tester.testAllPublicInstanceMethods(pathService.parsePath("foo")); |
| tester.testAllPublicInstanceMethods(pathService.parsePath("foo/bar")); |
| tester.testAllPublicInstanceMethods(pathService.parsePath("foo/bar/baz")); |
| tester.testAllPublicInstanceMethods(pathService.parsePath(".")); |
| tester.testAllPublicInstanceMethods(pathService.parsePath("..")); |
| } |
| |
| private void assertResolvedPathEquals( |
| String expected, Path path, String firstResolvePath, String... moreResolvePaths) { |
| Path resolved = path.resolve(firstResolvePath); |
| for (String additionalPath : moreResolvePaths) { |
| resolved = resolved.resolve(additionalPath); |
| } |
| assertPathEquals(expected, resolved); |
| |
| Path relative = pathService.parsePath(firstResolvePath, moreResolvePaths); |
| resolved = path.resolve(relative); |
| assertPathEquals(expected, resolved); |
| |
| // assert the invariant that p.relativize(p.resolve(q)).equals(q) when q does not have a root |
| // p = path, q = relative, p.resolve(q) = resolved |
| if (relative.getRoot() == null) { |
| assertEquals(relative, path.relativize(resolved)); |
| } |
| } |
| |
| private void assertRelativizedPathEquals(String expected, Path path, String relativizePath) { |
| Path relativized = path.relativize(pathService.parsePath(relativizePath)); |
| assertPathEquals(expected, relativized); |
| } |
| |
| private void assertNormalizedPathEquals(String expected, String first, String... more) { |
| assertPathEquals(expected, pathService.parsePath(first, more).normalize()); |
| } |
| |
| private void assertPathEquals(String expected, String first, String... more) { |
| assertPathEquals(expected, pathService.parsePath(first, more)); |
| } |
| |
| private void assertPathEquals(String expected, Path path) { |
| assertEquals(pathService.parsePath(expected), path); |
| } |
| } |