package usecases; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; import com.beijunyi.parallelgit.filesystem.AbstractGitFileSystemTest; import com.beijunyi.parallelgit.filesystem.io.GfsTreeIterator; import com.beijunyi.parallelgit.utils.TreeUtils; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.junit.Before; import org.junit.Test; import static org.eclipse.jgit.lib.FileMode.*; import static org.junit.Assert.*; public class GfsTreeWalkTest extends AbstractGitFileSystemTest { @Before public void setUp() throws IOException { initRepository(); } @Test public void walkGfsWhenThereAreOnlyRootLevelFiles_theFilesShouldBeIteratedInAlphabeticalOrder() throws IOException { String[] files = { "/a.txt", "/b.txt" }; initGitFileSystem(files); assertWalk(false, files); } @Test public void walkGfsWhenThereAreFilesInRootLevelDirectory_theDirectoryShouldBeInTheResult() throws IOException { String[] files = { "/dir/a.txt", "/dir/b.txt" }; initGitFileSystem(files); assertWalk(false, "/dir"); } @Test public void walkGfsRecursivelyWhenThereAreFilesInDirectories_allTheFilesShouldBeIteratedInAlphabeticalOrder() throws IOException { String[] files = { "/dir1/a.txt", "/dir1/b.txt", "/dir2/c.txt", "/some_other_file.txt" }; initGitFileSystem(files); assertWalk(true, files); } @Test public void getFileModeFromFileNode_shouldEqualRegularFile() throws IOException { initGitFileSystem("/test_file.txt"); TreeWalk tw = forPath("/test_file.txt"); assertEquals(REGULAR_FILE, tw.getFileMode(0)); } @Test public void getFileModeFromDirectoryNode_shouldEqualTree() throws IOException { initGitFileSystem("/dir/some_file.txt"); TreeWalk tw = forPath("/dir"); assertEquals(TREE, tw.getFileMode(0)); assertTrue(TreeUtils.isDirectory(tw)); } @Test public void getObjectIdFromFileNode_shouldReturnTheBlobIdOfTheFile() throws IOException { initRepository(); byte[] data = someBytes(); writeToCache("/test_file.txt", data); commitToMaster(); initGitFileSystem(); TreeWalk tw = forPath("/test_file.txt"); assertEquals(calculateBlobId(data), TreeUtils.getObjectId(tw)); } @Nonnull private TreeWalk prepareTreeWalk(boolean recursive) throws IOException { GfsTreeIterator iterator = GfsTreeIterator.iterateRoot(gfs); TreeWalk ret = new TreeWalk(repo); ret.setRecursive(recursive); ret.addTree(iterator); return ret; } private void assertWalk(boolean recursive, String... expected) throws IOException { try(TreeWalk tw = prepareTreeWalk(recursive)) { assertWalk(tw, expected); } } private void assertWalk(TreeWalk tw, String... expected) throws IOException { assertArrayEquals(expected, toArrayWithLeadingSlash(tw)); } @Nonnull private String[] toArrayWithLeadingSlash(TreeWalk tw) throws IOException { List<String> list = new ArrayList<>(); while(tw.next()) list.add("/" + tw.getPathString()); String[] ret = new String[list.size()]; return list.toArray(ret); } @Nonnull private TreeWalk forPath(String path) throws IOException { TreeWalk tw = prepareTreeWalk(false); PathFilter filter = PathFilter.create(path.charAt(0) == '/' ? path.substring(1) : path); tw.setFilter(filter); tw.setRecursive(false); while(tw.next()) { if(filter.isDone(tw)) return tw; if(tw.isSubtree()) tw.enterSubtree(); } throw new IllegalStateException(); } }