package com.beijunyi.parallelgit.filesystem.io; import java.io.IOException; import java.nio.file.Files; import java.util.Collections; import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.beijunyi.parallelgit.filesystem.AbstractGitFileSystemTest; import com.beijunyi.parallelgit.filesystem.exceptions.IncompatibleFileModeException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.revwalk.RevCommit; import org.junit.Test; import static com.beijunyi.parallelgit.filesystem.io.GfsFileAttributeView.*; import static com.beijunyi.parallelgit.utils.TreeUtils.getObjectId; import static org.eclipse.jgit.lib.FileMode.*; import static org.eclipse.jgit.lib.ObjectId.zeroId; import static org.junit.Assert.*; public class GitFileAttributeViewTest extends AbstractGitFileSystemTest { @Test public void whenFileIsNotFreshlyAdded_isNewAttributeShouldBeFalse() throws IOException { initGitFileSystem("/some_file.txt"); assertFalse(isNew("/some_file.txt")); } @Test public void whenFileIsFreshlyAdded_isNewAttributeShouldBeTrue() throws IOException { initGitFileSystem(); Files.write(gfs.getPath("/some_file.txt"), someBytes()); assertTrue(isNew("/some_file.txt")); } @Test public void whenDirectoryIsFreshlyAdded_isNewAttributeShouldBeTrue() throws IOException { initGitFileSystem(); Files.createDirectory(gfs.getPath("/dir")); assertTrue(isNew("/dir")); } @Test public void whenFileIsFreshlyAddedAndThenModified_isNewAttributeShouldBeTrue() throws IOException { initGitFileSystem(); Files.write(gfs.getPath("/some_file.txt"), someBytes()); Files.write(gfs.getPath("/some_file.txt"), someBytes()); assertTrue(isNew("/some_file.txt")); } @Test public void whenFileIsDeletedAndThenAdded_isNewAttributeShouldBeFalse() throws IOException { initGitFileSystem("/some_file.txt"); Files.delete(gfs.getPath("/some_file.txt")); Files.write(gfs.getPath("/some_file.txt"), someBytes()); assertFalse(isNew("/some_file.txt")); } @Test public void whenFileIsNotModified_isModifiedAttributeShouldBeFalse() throws IOException { initGitFileSystem("/some_file.txt"); assertFalse(isModified("/some_file.txt")); } @Test public void whenFileContentIsModified_isModifiedAttributeShouldBeTrue() throws IOException { initGitFileSystem("/some_file.txt"); Files.write(gfs.getPath("/some_file.txt"), someBytes()); assertTrue(isModified("/some_file.txt")); } @Test public void whenFileModeIsModified_isModifiedAttributeShouldBeTrue() throws IOException { writeToCache("/some_file.txt", someBytes(), REGULAR_FILE); initGitFileSystem(); open("/some_file.txt").setFileMode(EXECUTABLE_FILE); assertTrue(isModified("/some_file.txt")); } @Test public void whenFileContentIsModified_isModifiedAttributeOfTheParentDirectoryShouldBeTrue() throws IOException { initGitFileSystem("/dir/some_file.txt"); Files.write(gfs.getPath("/dir/some_file.txt"), someBytes()); assertTrue(isModified("/dir")); } @Test public void whenFileModeIsModified_isModifiedAttributeOfTheParentDirectoryShouldBeTrue() throws IOException { writeToCache("/dir/some_file.txt", someBytes(), REGULAR_FILE); initGitFileSystem(); open("/dir/some_file.txt").setFileMode(EXECUTABLE_FILE); assertTrue(isModified("/dir")); } @Test public void whenFileIsFreshlyAddedAndThenModified_isModifiedAttributeShouldBeTrue() throws IOException { initGitFileSystem(); Files.write(gfs.getPath("/some_file.txt"), someBytes()); Files.write(gfs.getPath("/some_file.txt"), someBytes()); assertTrue(isModified("/some_file.txt")); } @Test public void whenNewChildIsAdded_isModifiedAttributeOfTheDirectoryShouldBeTrue() throws IOException { initGitFileSystem("/dir/some_file.txt"); Files.write(gfs.getPath("/dir/some_other_file.txt"), someBytes()); assertTrue(isModified("/dir")); } @Test public void whenNewChildIsDeleted_isModifiedAttributeOfTheDirectoryShouldBeTrue() throws IOException { initGitFileSystem("/dir/some_file.txt"); Files.delete(gfs.getPath("/dir/some_file.txt")); assertTrue(isModified("/dir")); } @Test public void whenEmptyChildrenDirectoriesAreCreated_isModifiedAttributeOfTheDirectoryShouldBeFalse() throws IOException { initGitFileSystem("/dir/some_file.txt"); Files.createDirectories(gfs.getPath("/dir/empty_dir1/empty_dir2")); assertFalse(isModified("/dir")); } @Test public void whenFileIsDeletedAndThenAddedWithTheSameContent_isModifiedAttributeShouldBeFalse() throws IOException { byte[] data = someBytes(); writeToCache("/some_file.txt", data); initGitFileSystem(); Files.delete(gfs.getPath("/some_file.txt")); Files.write(gfs.getPath("/some_file.txt"), data); assertFalse(isModified("/some_file.txt")); } @Test public void whenFileIsDeletedAndThenAddedWithTheSameContent_isModifiedAttributeOfTheParentDirectoryShouldBeFalse() throws IOException { byte[] data = someBytes(); writeToCache("/dir/some_file.txt", data); initGitFileSystem(); Files.delete(gfs.getPath("/dir/some_file.txt")); Files.write(gfs.getPath("/dir/some_file.txt"), data); assertFalse(isModified("/dir")); } @Test public void whenFileIsNotModified_getObjectIdShouldReturnItsOriginalBlobId() throws IOException { writeToCache("/some_file.txt", someBytes()); initGitFileSystem(); RevCommit head = gfs.getStatusProvider().commit(); assertEquals(getObjectId("/some_file.txt", head.getTree(), repo), objectId("/some_file.txt")); } @Test public void whenFileIsModified_getObjectIdShouldReturnItsNewBlobId() throws IOException { initGitFileSystem("/some_file.txt"); byte[] data = someBytes(); Files.write(gfs.getPath("/some_file.txt"), data); assertEquals(calculateBlobId(data), objectId("/some_file.txt")); } @Test public void whenDirectoryIsNotModified_getObjectIdShouldReturnItsOriginalBlobId() throws IOException { writeToCache("/dir/some_file.txt", someBytes()); initGitFileSystem(); RevCommit head = gfs.getStatusProvider().commit(); assertEquals(getObjectId("/dir", head.getTree(), repo), objectId("/dir")); } @Test public void whenEmptyChildrenDirectoriesIAreCreated_getObjectIdShouldReturnSameValue() throws IOException { initGitFileSystem("/dir/some_file.txt"); AnyObjectId original = objectId("/dir"); Files.createDirectories(gfs.getPath("/dir/empty_dir1/empty_dir2")); assertEquals(original, objectId("/dir")); } @Test public void whenDirectoryIsEmpty_getObjectIdShouldReturnZeroId() throws IOException { initGitFileSystem(); Files.createDirectory(gfs.getPath("/dir")); assertEquals(zeroId(), objectId("/dir")); } @Test public void whenDirectoryIsModified_getObjectIdShouldReturnDifferentValue() throws IOException { initGitFileSystem("/dir/some_file.txt"); AnyObjectId original = objectId("/dir"); Files.write(gfs.getPath("/dir/some_other_file.txt"), someBytes()); assertNotEquals(original, objectId("/dir")); } @Test public void whenFileIsNotModified_getFileModeShouldReturnItsOriginalFileMode() throws IOException { writeToCache("/some_file.txt", someBytes(), EXECUTABLE_FILE); initGitFileSystem(); assertEquals(EXECUTABLE_FILE, fileMode("/some_file.txt")); } @Test public void whenFileIsModified_getFileModeShouldReturnItsNewFileMode() throws IOException { writeToCache("/some_file.txt", someBytes(), REGULAR_FILE); initGitFileSystem(); open("/some_file.txt").setFileMode(EXECUTABLE_FILE); assertEquals(EXECUTABLE_FILE, fileMode("/some_file.txt")); } @Test(expected = IncompatibleFileModeException.class) public void setTheModeOfDirectoryToFile_shouldThrowIncompatibleFileModeException() throws IOException { initGitFileSystem("/dir/some_file.txt"); open("/dir").setFileMode(REGULAR_FILE); } @Test(expected = IncompatibleFileModeException.class) public void setTheModeOfFileToDirectory_shouldThrowIncompatibleFileModeException() throws IOException { initGitFileSystem("/some_file.txt"); open("/some_file.txt").setFileMode(TREE); } @Nonnull private GfsFileAttributeView.Git open(String path) { GfsFileAttributeView.Git view = (GfsFileAttributeView.Git) provider.getFileAttributeView(gfs.getPath(path), GitFileAttributeView.class); assert view != null; return view; } @Nullable private Object readAttribute(String path, String key) throws IOException { return open(path).readAttributes(Collections.singleton(key)).get(key); } private boolean isNew(String path) throws IOException { return (boolean) readAttribute(path, IS_NEW); } private boolean isModified(String path) throws IOException { return (boolean) readAttribute(path, IS_MODIFIED); } @Nullable private ObjectId objectId(String path) throws IOException { return (ObjectId) readAttribute(path, OBJECT_ID); } @Nullable private FileMode fileMode(String path) throws IOException { return (FileMode) readAttribute(path, FILE_MODE); } }