blob: 71e6aba2fd00da3c55f3d02c3230e2993114ad57 [file] [log] [blame]
/*
* 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 org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.IOException;
import java.nio.file.InvalidPathException;
import java.nio.file.LinkOption;
import java.nio.file.Path;
/**
* 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);
}
}