Browse Source

Added tests for NioFolder

* Completed testcases
* Implemented most of them (2 missing)
* Added OptionalMatcher
Markus Kreusch 9 years ago
parent
commit
1bf0c76918

+ 40 - 0
main/commons-test/src/main/java/org/cryptomator/common/test/matcher/OptionalMatcher.java

@@ -0,0 +1,40 @@
+package org.cryptomator.common.test.matcher;
+
+import java.util.Optional;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+
+public class OptionalMatcher {
+
+	public static <T> Matcher<Optional<T>> presentOptionalWithValueThat(Matcher<? super T> valueMatcher) {
+		return new TypeSafeDiagnosingMatcher<Optional<T>>(Optional.class) {
+			@Override
+			public void describeTo(Description description) {
+				description //
+						.appendText("a present Optional with a value that") //
+						.appendDescriptionOf(valueMatcher);
+			}
+
+			@Override
+			protected boolean matchesSafely(Optional<T> item, Description mismatchDescription) {
+				if (item.isPresent()) {
+					if (valueMatcher.matches(item.get())) {
+						return true;
+					} else {
+						mismatchDescription.appendText("a present Optional with value that");
+						valueMatcher.describeMismatch(item, mismatchDescription);
+						return false;
+					}
+				} else {
+					mismatchDescription.appendText("an empty Optional");
+					return false;
+				}
+
+			}
+
+		};
+	}
+
+}

+ 7 - 0
main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFile.java

@@ -2,8 +2,10 @@ package org.cryptomator.filesystem.nio;
 
 import static java.lang.String.format;
 
+import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.nio.ByteBuffer;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.time.Instant;
 import java.util.Optional;
@@ -91,6 +93,11 @@ class NioFile extends NioNode implements File {
 
 		@Override
 		public void delete() throws UncheckedIOException {
+			try {
+				Files.delete(path);
+			} catch (IOException e) {
+				throw new UncheckedIOException(e);
+			}
 		}
 
 		@Override

+ 17 - 0
main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFolder.java

@@ -7,6 +7,7 @@ import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.time.Instant;
 import java.util.Optional;
 import java.util.stream.Stream;
 
@@ -68,6 +69,19 @@ class NioFolder extends NioNode implements Folder {
 		}
 	}
 
+	@Override
+	public Instant lastModified() throws UncheckedIOException {
+		if (Files.exists(path) && !Files.isDirectory(path)) {
+			throw new UncheckedIOException(new IOException(format("%s is a file", path)));
+		}
+		return super.lastModified();
+	}
+
+	@Override
+	public boolean exists() throws UncheckedIOException {
+		return Files.isDirectory(path);
+	}
+
 	@Override
 	public void moveTo(Folder target) {
 		if (belongsToSameFilesystem(target)) {
@@ -94,6 +108,9 @@ class NioFolder extends NioNode implements Folder {
 
 	@Override
 	public void delete() {
+		if (!exists()) {
+			return;
+		}
 		fileSystemVisitor() //
 				.forEachFile(NioFolder::deleteFile) //
 				.afterFolder(NioFolder::deleteEmptyFolder) //

+ 13 - 1
main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/FilesystemSetupUtils.java

@@ -6,6 +6,8 @@ import java.io.UncheckedIOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.nio.file.attribute.FileTime;
+import java.time.Instant;
 
 import org.apache.commons.io.IOUtils;
 
@@ -75,14 +77,24 @@ class FilesystemSetupUtils {
 
 	public static class FolderEntry implements Entry {
 		private Path relativePath;
+		private Instant lastModified;
 
 		public FolderEntry(Path relativePath) {
 			this.relativePath = relativePath;
 		}
 
+		public FolderEntry withLastModified(Instant lastModified) {
+			this.lastModified = lastModified;
+			return this;
+		}
+
 		@Override
 		public void create(Path root) throws IOException {
-			Files.createDirectories(root.resolve(relativePath));
+			Path path = root.resolve(relativePath);
+			Files.createDirectories(path);
+			if (lastModified != null) {
+				Files.setLastModifiedTime(path, FileTime.from(lastModified));
+			}
 		}
 	}
 

+ 285 - 7
main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFolderTest.java

@@ -2,13 +2,18 @@ package org.cryptomator.filesystem.nio;
 
 import static java.util.stream.Collectors.toList;
 import static org.cryptomator.common.test.matcher.ContainsMatcher.containsInAnyOrder;
+import static org.cryptomator.common.test.matcher.OptionalMatcher.presentOptionalWithValueThat;
 import static org.cryptomator.filesystem.nio.FilesystemSetupUtils.emptyFilesystem;
 import static org.cryptomator.filesystem.nio.FilesystemSetupUtils.file;
 import static org.cryptomator.filesystem.nio.FilesystemSetupUtils.folder;
 import static org.cryptomator.filesystem.nio.FilesystemSetupUtils.testFilesystem;
 import static org.cryptomator.filesystem.nio.NioNodeMatcher.fileWithName;
 import static org.cryptomator.filesystem.nio.NioNodeMatcher.folderWithName;
+import static org.cryptomator.filesystem.nio.PathMatcher.doesNotExist;
+import static org.cryptomator.filesystem.nio.PathMatcher.isDirectory;
+import static org.cryptomator.filesystem.nio.PathMatcher.isFile;
 import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.sameInstance;
 import static org.hamcrest.Matchers.empty;
 import static org.junit.Assert.assertThat;
 
@@ -16,7 +21,10 @@ import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.time.Instant;
 
+import org.cryptomator.filesystem.File;
+import org.cryptomator.filesystem.FileSystem;
 import org.cryptomator.filesystem.Folder;
 import org.junit.Rule;
 import org.junit.Test;
@@ -28,22 +36,62 @@ public class NioFolderTest {
 
 	@Test
 	public void testNameIsNameOfFolder() throws IOException {
-		final String folderName = "folderNameABC";
+		final String folderName = "nameOfFolder";
 		NioFileSystem fileSystem = NioFileSystem.rootedAt(emptyFilesystem());
 		Folder folder = fileSystem.folder(folderName);
 
 		assertThat(folder, folderWithName(folderName));
 	}
 
+	@Test
+	public void testCreateSucceedsIfFolderExists() throws IOException {
+		String folderName = "nameOfFolder";
+		Path testFilesystemPath = testFilesystem( //
+				folder(folderName));
+		NioFileSystem fileSystem = NioFileSystem.rootedAt(testFilesystemPath);
+		Folder existingFolder = fileSystem.folder(folderName);
+
+		existingFolder.create();
+
+		assertThat(Files.isDirectory(testFilesystemPath.resolve(folderName)), is(true));
+	}
+
+	@Test
+	public void testCreateSucceedsIfFolderDoesNotExist() throws IOException {
+		String folderName = "nameOfFolder";
+		Path testFilesystemPath = emptyFilesystem();
+		NioFileSystem fileSystem = NioFileSystem.rootedAt(testFilesystemPath);
+		Folder nonExistingFolder = fileSystem.folder(folderName);
+
+		nonExistingFolder.create();
+
+		assertThat(Files.isDirectory(testFilesystemPath.resolve(folderName)), is(true));
+	}
+
 	@Test
 	public void testCreateSucceedsIfParentIsMissing() throws IOException {
+		String parentFolderName = "nameOfParentFolder";
+		String folderName = "nameOfFolder";
 		Path emptyFilesystemPath = emptyFilesystem();
 		NioFileSystem fileSystem = NioFileSystem.rootedAt(emptyFilesystemPath);
-		Folder folderWithNonExistingParent = fileSystem.folder("a").folder("b");
+		Folder folderWithNonExistingParent = fileSystem.folder(parentFolderName).folder(folderName);
 
 		folderWithNonExistingParent.create();
 
-		assertThat(Files.isDirectory(emptyFilesystemPath.resolve("a/b")), is(true));
+		assertThat(Files.isDirectory(emptyFilesystemPath.resolve(parentFolderName).resolve(folderName)), is(true));
+	}
+
+	@Test
+	public void testCreateWithFolderWhichIsAFileThrowsUncheckedIOExceptionWithAbsolutePathOfFolderInMessage() throws IOException {
+		String folderName = "nameOfFolder";
+		Path testFilesystemPath = testFilesystem(file(folderName));
+		NioFileSystem fileSystem = NioFileSystem.rootedAt(testFilesystemPath);
+		Folder folderWhichIsAFile = fileSystem.folder(folderName);
+
+		thrown.expect(UncheckedIOException.class);
+		thrown.expectMessage(testFilesystemPath.resolve(folderName).toString());
+
+		folderWhichIsAFile.create();
 	}
 
 	@Test
@@ -55,12 +103,24 @@ public class NioFolderTest {
 
 	@Test
 	public void testChildrenOfNonExistingFolderThrowsUncheckedIOExceptionWithAbolutePathOfFolderInMessage() throws IOException {
-		Path emptyFolderPath = emptyFilesystem();
-		NioFolder folder = NioFileSystem.rootedAt(emptyFolderPath);
-		Files.delete(emptyFolderPath);
+		String nameOfNonExistingFolder = "nameOfFolder";
+		Path filesystemPath = emptyFilesystem();
+		Folder folder = NioFileSystem.rootedAt(filesystemPath).folder(nameOfNonExistingFolder);
 
 		thrown.expect(UncheckedIOException.class);
-		thrown.expectMessage(emptyFolderPath.toString());
+		thrown.expectMessage(filesystemPath.resolve(nameOfNonExistingFolder).toString());
+
+		folder.children();
+	}
+
+	@Test
+	public void testChildrenOfFolderWhichIsAFileThrowsUncheckedIOExceptionWithAbsolutePathOfFolderInMessage() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = testFilesystem(file(folderName));
+		Folder folder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		thrown.expect(UncheckedIOException.class);
+		thrown.expectMessage(filesystemPath.resolve(folderName).toString());
 
 		folder.children();
 	}
@@ -147,4 +207,222 @@ public class NioFolderTest {
 
 		folder.folders();
 	}
+
+	@Test
+	public void testDeleteOfEmptyFolderDeletesIt() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = testFilesystem( //
+				folder(folderName));
+		Folder folder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		folder.delete();
+
+		assertThat(filesystemPath.resolve(folderName), doesNotExist());
+	}
+
+	@Test
+	public void testDeleteOfFolderWithChildrenDeletesItAndAllChildrenRecursive() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = testFilesystem( //
+				folder(folderName), //
+				folder(folderName + "/subfolder1"), //
+				file(folderName + "/subfolder1/fileName1"), //
+				folder(folderName + "/subfolder2"), //
+				file(folderName + "/fileName1"), //
+				file(folderName + "/fileName2"));
+		Folder folder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		folder.delete();
+
+		assertThat(filesystemPath.resolve(folderName), doesNotExist());
+	}
+
+	@Test
+	public void testDeleteOfNonExistingFolderDoesNothing() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = emptyFilesystem();
+		Folder nonExistingFolder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		nonExistingFolder.delete();
+
+		assertThat(filesystemPath.resolve(folderName), doesNotExist());
+	}
+
+	@Test
+	public void testDeleteOfFolderWhichIsAFileDoesNothing() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = testFilesystem( //
+				file(folderName));
+		Folder folder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		folder.delete();
+
+		assertThat(filesystemPath.resolve(folderName), isFile());
+	}
+
+	@Test
+	public void testExistsReturnsTrueForExistingDirectory() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = testFilesystem( //
+				folder(folderName));
+		Folder folder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		assertThat(folder.exists(), is(true));
+	}
+
+	@Test
+	public void testExistsReturnsFalseForNonExistingDirectory() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = emptyFilesystem();
+		Folder nonExistingFolder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		assertThat(nonExistingFolder.exists(), is(false));
+	}
+
+	@Test
+	public void testExistsReturnsFalseForDirectoryWhichIsAFile() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = testFilesystem( //
+				file(folderName));
+		Folder folder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		assertThat(folder.exists(), is(false));
+	}
+
+	@Test
+	public void testIsAncestorOfWithChildReturnsTrue() throws IOException {
+		Folder folder = NioFileSystem.rootedAt(emptyFilesystem()).folder("a");
+		Folder child = folder.folder("b");
+
+		assertThat(folder.isAncestorOf(child), is(true));
+	}
+
+	@Test
+	public void testIsAncestorOfWithChildOfChildReturnsTrue() throws IOException {
+		Folder folder = NioFileSystem.rootedAt(emptyFilesystem()).folder("a");
+		Folder child = folder.folder("b");
+		File childOfChild = child.file("c");
+
+		assertThat(folder.isAncestorOf(childOfChild), is(true));
+	}
+
+	@Test
+	public void testIsAncestorOfWithSiblingReturnsFalse() throws IOException {
+		FileSystem fileSystem = NioFileSystem.rootedAt(emptyFilesystem());
+		Folder folder = fileSystem.folder("a");
+		Folder sibling = fileSystem.folder("b");
+
+		assertThat(folder.isAncestorOf(sibling), is(false));
+	}
+
+	@Test
+	public void testIsAncestorOfWithParentReturnsFalse() throws IOException {
+		Folder parent = NioFileSystem.rootedAt(emptyFilesystem()).folder("a");
+		Folder folder = parent.folder("b");
+
+		assertThat(folder.isAncestorOf(parent), is(false));
+	}
+
+	@Test
+	public void testLastModifiedOfExistingFolderReturnsLastModifiedDate() throws IOException {
+		String folderName = "nameOfFolder";
+		Instant lastModified = Instant.parse("2015-12-29T15:36:10.00Z");
+		Folder folder = NioFileSystem
+				.rootedAt(testFilesystem( //
+						folder(folderName).withLastModified(lastModified))) //
+				.folder(folderName);
+
+		assertThat(folder.lastModified(), is(lastModified));
+	}
+
+	@Test
+	public void testLastModifiedOfNonExistingFolderThrowsUncheckedIOExceptionWithAbsolutePathOfFolder() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = emptyFilesystem();
+		Folder folder = NioFileSystem.rootedAt(filesystemPath).folder(folderName);
+
+		thrown.expect(UncheckedIOException.class);
+		thrown.expectMessage(filesystemPath.resolve(folderName).toString());
+
+		folder.lastModified();
+	}
+
+	@Test
+	public void testLastModifiedOfFolderWhichIsAFileThrowsUncheckedIOExceptionWithAbsolutePathOfFolder() throws IOException {
+		String folderName = "nameOfFolder";
+		Path filesystemPath = testFilesystem(file(folderName));
+		Folder folder = NioFileSystem //
+				.rootedAt(filesystemPath) //
+				.folder(folderName);
+
+		thrown.expect(UncheckedIOException.class);
+		thrown.expectMessage(filesystemPath.resolve(folderName).toString());
+
+		folder.lastModified();
+	}
+
+	@Test
+	public void testParentOfDirectChildOfFilesystemReturnsFilesystem() throws IOException {
+		FileSystem fileSystem = NioFileSystem.rootedAt(emptyFilesystem());
+		Folder folder = fileSystem.folder("aName");
+
+		assertThat(folder.parent(), presentOptionalWithValueThat(is(sameInstance(fileSystem))));
+	}
+
+	@Test
+	public void testParentOfChildOfFolderReturnsFolder() throws IOException {
+		Folder folder = NioFileSystem.rootedAt(emptyFilesystem()).folder("aName");
+		Folder child = folder.folder("anotherName");
+
+		assertThat(child.parent(), presentOptionalWithValueThat(is(sameInstance(folder))));
+	}
+
+	@Test
+	public void testMoveToOfFolderToNonExistingFolderMovesFolder() throws IOException {
+		Path filesystemPath = testFilesystem( //
+				folder("folderToMove"));
+		NioFileSystem fileSystem = NioFileSystem.rootedAt(filesystemPath);
+		Folder folderToMove = fileSystem.folder("folderToMove");
+		Folder folderToMoveTo = fileSystem.folder("folderToMoveTo");
+
+		folderToMove.moveTo(folderToMoveTo);
+
+		assertThat(filesystemPath.resolve("folderToMove"), doesNotExist());
+		assertThat(filesystemPath.resolve("folderToMoveTo"), isDirectory());
+	}
+
+	@Test
+	public void testMoveToOfFolderWithChildrenMovesFolderAndChildren() throws IOException {
+		Path filesystemPath = testFilesystem( //
+				folder("folderToMove"), //
+				folder("folderToMove/subfolder1"), //
+				folder("folderToMove/subfolder2"), //
+				file("folderToMove/subfolder1/file1"), //
+				file("folderToMove/file2"), //
+				file("folderToMove/file3"));
+		NioFileSystem fileSystem = NioFileSystem.rootedAt(filesystemPath);
+		Folder folderToMove = fileSystem.folder("folderToMove");
+		Folder folderToMoveTo = fileSystem.folder("folderToMoveTo");
+
+		folderToMove.moveTo(folderToMoveTo);
+
+		assertThat(filesystemPath.resolve("folderToMove"), doesNotExist());
+		assertThat(filesystemPath.resolve("folderToMoveTo"), isDirectory());
+		assertThat(filesystemPath.resolve("folderToMoveTo/subfolder1"), isDirectory());
+		assertThat(filesystemPath.resolve("folderToMoveTo/subfolder2"), isDirectory());
+		assertThat(filesystemPath.resolve("folderToMoveTo/subfolder1/file1"), isFile());
+		assertThat(filesystemPath.resolve("folderToMoveTo/file2"), isFile());
+		assertThat(filesystemPath.resolve("folderToMoveTo/file3"), isFile());
+	}
+
+	@Test
+	public void testMoveToOfFolderToExistingFolderReplacesTargetFolder() throws IOException {
+		// TODO Markus Kreusch implement test
+	}
+
+	@Test
+	public void testMoveToOfFolderToExistingFileThrowsUncheckedIOExceptionWithAbsolutePathOfTarget() throws IOException {
+		// TODO Markus Kreusch implement test
+	}
+
 }

+ 27 - 0
main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/PathMatcher.java

@@ -19,4 +19,31 @@ class PathMatcher {
 		};
 	}
 
+	public static Matcher<Path> isFile() {
+		return new FeatureMatcher<Path, Boolean>(is(true), "a path for which Files.isRegularFile", "Files.isRegularFile") {
+			@Override
+			protected Boolean featureValueOf(Path actual) {
+				return Files.isRegularFile(actual);
+			}
+		};
+	}
+
+	public static Matcher<Path> doesNotExist() {
+		return new FeatureMatcher<Path, Boolean>(is(false), "a path for which Files.exists", "Files.exists") {
+			@Override
+			protected Boolean featureValueOf(Path actual) {
+				return Files.exists(actual);
+			}
+		};
+	}
+
+	public static Matcher<Path> doesExist() {
+		return new FeatureMatcher<Path, Boolean>(is(true), "a path for which Files.exists", "Files.exists") {
+			@Override
+			protected Boolean featureValueOf(Path actual) {
+				return Files.exists(actual);
+			}
+		};
+	}
+
 }