/*
* Copyright 2013-present Facebook, 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.facebook.buck.io;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import com.facebook.buck.testutil.integration.TemporaryPaths;
import com.facebook.buck.util.RichStream;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.Rule;
import org.junit.Test;
public class MorePathsTest {
@Rule public TemporaryPaths tmp = new TemporaryPaths();
@Test
public void testGetRelativePath() {
// Path on base directory.
assertEquals(Paths.get("file"), MorePaths.getRelativePath(Paths.get("file"), Paths.get("")));
// Path on base directory (using null).
assertEquals(Paths.get("file"), MorePaths.getRelativePath(Paths.get("file"), null));
// Path internal to base directory.
assertEquals(
Paths.get("dir/file"),
MorePaths.getRelativePath(Paths.get("base/dir/file"), Paths.get("base")));
// Path external to base directory.
assertEquals(
Paths.get("../dir1/file"),
MorePaths.getRelativePath(Paths.get("dir1/file"), Paths.get("base")));
}
@Test
public void testFilterForSubpaths() {
Path root = tmp.getRoot();
ImmutableSet<Path> paths =
RichStream.of(
".buckd",
"foo/bar",
root.toAbsolutePath() + "/buck-cache",
Paths.get("/root/not/in/test").toAbsolutePath().toString())
.map(Paths::get)
.toImmutableSet();
assertEquals(
"Set should have been filtered down to paths contained under root.",
ImmutableSet.of(Paths.get(".buckd"), Paths.get("foo/bar"), Paths.get("buck-cache")),
MorePaths.filterForSubpaths(paths, root));
}
@Test
public void testCreateRelativeSymlinkToFilesInRoot() throws InterruptedException, IOException {
ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmp.getRoot());
tmp.newFile("biz.txt");
Path pathToDesiredLinkUnderProjectRoot = Paths.get("gamma.txt");
Path pathToExistingFileUnderProjectRoot = Paths.get("biz.txt");
Path relativePath =
MoreProjectFilesystems.createRelativeSymlink(
pathToDesiredLinkUnderProjectRoot,
pathToExistingFileUnderProjectRoot,
projectFilesystem);
assertEquals("biz.txt", relativePath.toString());
Path absolutePathToDesiredLinkUnderProjectRoot =
projectFilesystem.resolve(pathToDesiredLinkUnderProjectRoot);
assertTrue(Files.isSymbolicLink(absolutePathToDesiredLinkUnderProjectRoot));
Path targetOfSymbolicLink = Files.readSymbolicLink(absolutePathToDesiredLinkUnderProjectRoot);
assertEquals(relativePath, targetOfSymbolicLink);
Path absolutePathToExistingFileUnderProjectRoot =
projectFilesystem.resolve(pathToExistingFileUnderProjectRoot);
Files.write(absolutePathToExistingFileUnderProjectRoot, "Hello, World!".getBytes());
String dataReadFromSymlink =
new String(Files.readAllBytes(absolutePathToDesiredLinkUnderProjectRoot));
assertEquals("Hello, World!", dataReadFromSymlink);
}
@Test
public void testCreateRelativeSymlinkToFileInRoot() throws InterruptedException, IOException {
ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmp.getRoot());
tmp.newFile("biz.txt");
tmp.newFolder("alpha", "beta");
Path pathToDesiredLinkUnderProjectRoot = Paths.get("alpha/beta/gamma.txt");
Path pathToExistingFileUnderProjectRoot = Paths.get("biz.txt");
Path relativePath =
MoreProjectFilesystems.createRelativeSymlink(
pathToDesiredLinkUnderProjectRoot,
pathToExistingFileUnderProjectRoot,
projectFilesystem);
assertEquals(Paths.get("../../biz.txt").toString(), relativePath.toString());
Path absolutePathToDesiredLinkUnderProjectRoot =
projectFilesystem.resolve(pathToDesiredLinkUnderProjectRoot);
assertTrue(Files.isSymbolicLink(absolutePathToDesiredLinkUnderProjectRoot));
Path targetOfSymbolicLink = Files.readSymbolicLink(absolutePathToDesiredLinkUnderProjectRoot);
assertEquals(relativePath, targetOfSymbolicLink);
Path absolutePathToExistingFileUnderProjectRoot =
projectFilesystem.resolve(pathToExistingFileUnderProjectRoot);
Files.write(absolutePathToExistingFileUnderProjectRoot, "Hello, World!".getBytes());
String dataReadFromSymlink =
new String(Files.readAllBytes(absolutePathToDesiredLinkUnderProjectRoot));
assertEquals("Hello, World!", dataReadFromSymlink);
}
@Test
public void testCreateRelativeSymlinkToFilesOfVaryingDepth()
throws InterruptedException, IOException {
ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmp.getRoot());
tmp.newFolder("foo", "bar", "baz");
tmp.newFile("foo/bar/baz/biz.txt");
tmp.newFolder("alpha", "beta");
Path pathToDesiredLinkUnderProjectRoot = Paths.get("alpha/beta/gamma.txt");
Path pathToExistingFileUnderProjectRoot = Paths.get("foo/bar/baz/biz.txt");
Path relativePath =
MoreProjectFilesystems.createRelativeSymlink(
pathToDesiredLinkUnderProjectRoot,
pathToExistingFileUnderProjectRoot,
projectFilesystem);
assertEquals(Paths.get("../../foo/bar/baz/biz.txt").toString(), relativePath.toString());
Path absolutePathToDesiredLinkUnderProjectRoot =
projectFilesystem.resolve(pathToDesiredLinkUnderProjectRoot);
assertTrue(Files.isSymbolicLink(absolutePathToDesiredLinkUnderProjectRoot));
Path targetOfSymbolicLink = Files.readSymbolicLink(absolutePathToDesiredLinkUnderProjectRoot);
assertEquals(relativePath, targetOfSymbolicLink);
Path absolutePathToExistingFileUnderProjectRoot =
projectFilesystem.resolve(pathToExistingFileUnderProjectRoot);
Files.write(absolutePathToExistingFileUnderProjectRoot, "Hello, World!".getBytes());
String dataReadFromSymlink =
new String(Files.readAllBytes(absolutePathToDesiredLinkUnderProjectRoot));
assertEquals("Hello, World!", dataReadFromSymlink);
}
@Test
public void testExpandHomeDir() {
Path homeDir = Paths.get(System.getProperty("user.home"));
assertEquals(
"Must expand home dir.",
homeDir.resolve("foo"),
MorePaths.expandHomeDir(Paths.get("~/foo")));
assertEquals(
"Must expand home dir by itself too.", homeDir, MorePaths.expandHomeDir(Paths.get("~")));
Path relativePath = Paths.get("foo/bar");
assertEquals(
"Must not expand relative paths.", relativePath, MorePaths.expandHomeDir(relativePath));
Path absolutePath = Paths.get("/foo/bar");
assertEquals(
"Must not expand absolute paths.", absolutePath, MorePaths.expandHomeDir(absolutePath));
Path funnyHomePath = Paths.get("~jacko/foo");
assertEquals(
"Must only expand home paths starting with ~/",
funnyHomePath,
MorePaths.expandHomeDir(funnyHomePath));
}
@Test
public void relativizeWithDotPathDoesNotAddExtraDotDotPath() {
// Ensure workaround for bug JDK-6925169 for "." case.
Path p1 = Paths.get("./a/b");
Path p2 = Paths.get("c/d/e");
assertThat(MorePaths.relativize(p1, p2), equalTo(Paths.get("../../c/d/e")));
}
@Test
public void relativizeWithDotDotPathDoesNotAddExtraDotDotPath() {
// Ensure workaround for bug JDK-6925169 for ".." case.
Path p1 = Paths.get("a/../b");
Path p2 = Paths.get("c/d/e");
assertThat(MorePaths.relativize(p1, p2), equalTo(Paths.get("../c/d/e")));
}
@Test
public void relativeWithEmptyPath() {
// Ensure workaround for Windows Path relativize bug
Path p1 = Paths.get("");
Path p2 = Paths.get("foo");
assertThat(MorePaths.relativize(p1, p2), equalTo(Paths.get("foo")));
}
@Test
public void normalizeWithEmptyPath() {
// Ensure workaround for Java Path normalize bug
Path emptyPath = Paths.get("");
assertThat(MorePaths.normalize(emptyPath), equalTo(emptyPath));
}
@Test
public void fixPathCommonTest() {
final Path inputPath = Paths.get("subdir/subdir2/foo/bar/x.file");
final Path expecting = Paths.get("subdir/subdir2/foo/bar/x.file");
assertEquals(expecting, MorePaths.fixPath(inputPath));
}
@Test
public void fixPathAbsoluteTest() {
final Path inputPath = Paths.get("/subdir/subdir2/foo/bar/x.file");
final Path expecting = Paths.get("/subdir/subdir2/foo/bar/x.file");
assertEquals(expecting, MorePaths.fixPath(inputPath));
}
@Test
public void fixPathEmptyPartTest() {
final Path inputPath = Paths.get("subdir/subdir2//foo///bar/////x.file");
final Path expecting = Paths.get("subdir/subdir2/foo/bar/x.file");
assertEquals(expecting, MorePaths.fixPath(inputPath));
}
@Test
public void fixPathDotPartTest() {
final Path inputPath = Paths.get("subdir/subdir2/./foo/././bar/./x.file");
final Path expecting = Paths.get("subdir/subdir2/foo/bar/x.file");
assertEquals(expecting, MorePaths.fixPath(inputPath));
}
@Test
public void fixPathDotDotPartTest() {
final Path inputPath = Paths.get("subdir/subdir2/foo/../bar/x.file");
final Path expecting = Paths.get("subdir/subdir2/foo/../bar/x.file");
// should be the same! Does not fully "normalize" path.
assertEquals(expecting, MorePaths.fixPath(inputPath));
}
@Test
public void getNameWithoutExtension() {
Path inputPath = Paths.get("subdir/subdir2/bar/x.file");
assertEquals("x", MorePaths.getNameWithoutExtension(inputPath));
}
}