package org.smoothbuild.io.fs.base; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.smoothbuild.io.fs.base.Path.path; import static org.smoothbuild.io.fs.base.PathState.DIR; import static org.smoothbuild.io.fs.base.PathState.FILE; import static org.smoothbuild.io.fs.base.PathState.NOTHING; import static org.smoothbuild.testing.common.ExceptionMatcher.exception; import static org.smoothbuild.util.Streams.inputStreamToByteArray; import static org.smoothbuild.util.Streams.writeAndClose; import static org.testory.Testory.given; import static org.testory.Testory.thenEqual; import static org.testory.Testory.thenReturned; import static org.testory.Testory.thenThrown; import static org.testory.Testory.when; import java.io.IOException; import org.junit.Test; public abstract class GenericFileSystemTestCase { protected FileSystem fileSystem; protected byte[] bytes = new byte[] { 1, 2, 3 }; protected Path path = path("some/dir/myFile"); protected Path path2 = path("other/dir/otherFile"); private final Path dir = path("my/dir"); private final Path linkPath = path("my/link"); // pathKind() @Test public void rooth_path_is_a_dir() throws Exception { when(fileSystem.pathState(Path.root())); thenReturned(DIR); } @Test public void non_root_path_are_initially_nothing_state() throws Exception { when(fileSystem.pathState(path("abc"))); thenReturned(NOTHING); } @Test public void file_path_has_file_state() throws Exception { given(this).createEmptyFile(path); when(fileSystem).pathState(path); thenReturned(FILE); } @Test public void dir_path_has_dir_state() throws Exception { given(this).createEmptyFile(dir.append(path)); when(fileSystem).pathState(dir); thenReturned(DIR); } @Test public void path_state_is_nothing_even_when_its_first_part_is_a_file() throws Exception { given(this).createEmptyFile(path); when(fileSystem).pathState(path.append(path("something"))); thenReturned(NOTHING); } @Test public void creating_file_twice_is_possible() throws Exception { given(this).createEmptyFile(path); when(this).createEmptyFile(path); thenReturned(); } // filesFrom() @Test public void files_from_throws_exception_when_dir_does_not_exist() throws Exception { when(fileSystem).files(path("abc")); thenThrown(exception(new FileSystemException("Dir " + path("abc") + " doesn't exists."))); } public void files_from_throws_exception_when_path_is_a_file() throws Exception { given(this).createEmptyFile(path); when(fileSystem).files(path); thenThrown(exception(new FileSystemException("Dir " + path + " doesn't exist. It is a file."))); } @Test public void files_from_returns_all_children() throws Exception { given(this).createEmptyFile("abc/dir1/file1.txt"); given(this).createEmptyFile("abc/dir2/file2.txt"); given(this).createEmptyFile("abc/text.txt"); when(fileSystem).files(path("abc")); thenReturned(containsInAnyOrder(path("dir1"), path("dir2"), path("text.txt"))); } @Test public void files_from_throws_exception_when_path_does_not_exist() throws Exception { when(fileSystem).files(path("abc")); thenThrown(FileSystemException.class); } // openInputStream() @Test public void open_input_stream_reads_file_content() throws Exception { given(this).createFile(path, bytes); when(inputStreamToByteArray(fileSystem.openInputStream(path))); thenReturned(bytes); } @Test public void cannot_open_output_stream_when_path_is_dir() throws Exception { given(this).createEmptyFile(path); when(fileSystem).openOutputStream(path.parent()); thenThrown(exception(new FileSystemException("Cannot use " + path.parent() + " path. It is already taken by dir."))); } @Test public void cannot_open_output_stream_when_path_is_root_dir() throws Exception { when(fileSystem).openOutputStream(Path.root()); thenThrown(exception(new FileSystemException("Cannot use " + Path.root() + " path. It is already taken by dir."))); } // openOutputStream() @Test public void data_written_via_open_output_stream_can_be_read_by_open_input_stream() throws Exception { writeAndClose(fileSystem.openOutputStream(path), bytes); when(inputStreamToByteArray(fileSystem.openInputStream(path))); thenReturned(bytes); } @Test public void open_output_stream_overwrites_existing_file() throws Exception { given(bytes = new byte[] { 1, 2, 3 }); writeAndClose(fileSystem.openOutputStream(path), new byte[] { 4, 5, 6, 7, 8 }); writeAndClose(fileSystem.openOutputStream(path), bytes); when(inputStreamToByteArray(fileSystem.openInputStream(path))); thenReturned(bytes); } @Test public void open_output_stream_returns() throws Exception { given(this).createEmptyFile(dir.append(path)); when(fileSystem).openOutputStream(dir); thenThrown(FileSystemException.class); } public void create_input_stream_throws_exception_when_file_does_not_exist() throws Exception { when(fileSystem).openInputStream(path("dir/file")); thenThrown(exception(new FileSystemException("File " + path("dir/file") + " doesn't exist."))); } @Test public void cannot_open_input_stream_when_file_is_a_dir() throws Exception { given(this).createEmptyFile("abc/def/file.txt"); when(fileSystem).openInputStream(path("abc/def")); thenThrown(FileSystemException.class); } // move() @Test public void moving_nonexistent_file_fails() throws Exception { when(fileSystem).move(path("source"), path("target")); thenThrown(exception(new FileSystemException( "Cannot move " + path("source") + ". It doesn't exist."))); } @Test public void moving_directory_fails() throws Exception { given(this).createEmptyFile(path("source/file")); when(fileSystem).move(path("source"), path("target")); thenThrown(exception(new FileSystemException( "Cannot move " + path("source") + ". It is directory."))); } @Test public void moving_to_directory_fails() throws Exception { given(this).createEmptyFile(path("source")); given(this).createEmptyFile(path("target/file")); when(fileSystem).move(path("source"), path("target")); thenThrown(exception(new FileSystemException( "Cannot move to " + path("target") + ". It is directory."))); } @Test public void moved_file_is_deleted_from_source() throws Exception { given(this).createEmptyFile(path("source")); when(fileSystem).move(path("source"), path("target")); thenEqual(fileSystem.pathState(path("source")), NOTHING); } @Test public void moved_file_is_copied_to_target() throws Exception { given(this).createFile(path("source"), bytes); when(fileSystem).move(path("source"), path("target")); thenEqual(fileSystem.pathState(path("source")), NOTHING); when(inputStreamToByteArray(fileSystem.openInputStream(path("target")))); thenReturned(bytes); } @Test public void moved_file_overwrites_target_file() throws Exception { given(this).createFile(path("source"), bytes); given(this).createEmptyFile(path("target")); when(fileSystem).move(path("source"), path("target")); thenEqual(fileSystem.pathState(path("source")), NOTHING); when(inputStreamToByteArray(fileSystem.openInputStream(path("target")))); thenReturned(bytes); } @Test public void moving_creates_missing_parent_directories_in_target_path() throws Exception { given(this).createFile(path("source"), bytes); when(fileSystem).move(path("source"), path("dir/target")); when(inputStreamToByteArray(fileSystem.openInputStream(path("dir/target")))); thenReturned(bytes); } // delete() @Test public void deleting_dir_removes_its_files() throws Exception { given(this).createEmptyFile(path); when(fileSystem).delete(path.parent()); thenEqual(fileSystem.pathState(path), NOTHING); } @Test public void delete_file() throws Exception { given(this).createEmptyFile(path); given(fileSystem).delete(path); when(fileSystem).pathState(path); thenReturned(NOTHING); } @Test public void delete_does_nothing_for_nonexistet_path() throws Exception { when(fileSystem).delete(path); thenReturned(); } @Test public void deleting_root_path_removes_all_files() throws Exception { given(this).createEmptyFile(path); given(this).createEmptyFile(path2); when(fileSystem).delete(Path.root()); thenEqual(fileSystem.pathState(path), NOTHING); thenEqual(fileSystem.pathState(path2), NOTHING); } // links @Test public void link_contains_data_from_target() throws Exception { given(this).createFile(path, bytes); when(fileSystem).createLink(linkPath, path); thenEqual(inputStreamToByteArray(fileSystem.openInputStream(linkPath)), bytes); } @Test public void creating_links_creates_missing_dirs() throws Exception { given(this).createFile(path, bytes); when(fileSystem).createLink(linkPath, path); thenEqual(fileSystem.pathState(linkPath), FILE); } @Test public void deleted_link_is_removed() throws Exception { given(this).createFile(path, bytes); given(fileSystem).createLink(linkPath, path); when(fileSystem).delete(linkPath); thenEqual(fileSystem.pathState(linkPath), NOTHING); } @Test public void deleting_link_to_file_does_not_delete_target() throws Exception { given(this).createFile(path, bytes); given(fileSystem).createLink(linkPath, path); when(fileSystem).delete(linkPath); thenEqual(fileSystem.pathState(path), FILE); } @Test public void link_to_dir_can_be_used_to_access_its_file() throws Exception { given(this).createFile(path, bytes); when(fileSystem).createLink(linkPath, path.parent()); thenEqual(inputStreamToByteArray(fileSystem.openInputStream(linkPath.append(path.lastPart()))), bytes); } @Test public void deleting_link_to_dir_does_not_delete_target() throws Exception { given(this).createEmptyFile(dir.append(path("ignore"))); given(fileSystem).createLink(path, dir); when(fileSystem).delete(path); thenEqual(fileSystem.pathState(path), NOTHING); thenEqual(fileSystem.pathState(dir), DIR); } @Test public void cannot_create_link_when_path_is_taken_by_file() throws Exception { given(this).createEmptyFile(path); given(this).createEmptyFile(linkPath); when(fileSystem).createLink(linkPath, path); thenThrown(exception(new FileSystemException("Cannot use " + linkPath + " path. It is already taken."))); } @Test public void cannot_create_link_when_path_is_taken_by_dir() throws Exception { given(this).createEmptyFile(path); given(this).createEmptyFile(linkPath); when(fileSystem).createLink(linkPath.parent(), path); thenThrown(exception(new FileSystemException("Cannot use " + linkPath.parent() + " path. It is already taken."))); } // createDir() @Test public void created_dir_exists() throws Exception { given(fileSystem).createDir(path); when(fileSystem).pathState(path); thenReturned(DIR); } @Test public void creating_existing_dir_does_not_cause_errors() throws Exception { given(fileSystem).createDir(path); when(fileSystem).createDir(path); thenReturned(); } @Test public void cannot_create_dir_if_such_file_already_exists() throws Exception { given(this).createEmptyFile(path); when(fileSystem).createDir(path); thenThrown(exception(new FileSystemException("Cannot use " + path + " path. It is already taken by file."))); } // helpers protected abstract void createEmptyFile(String path) throws IOException; protected abstract void createEmptyFile(Path path) throws IOException; protected abstract void createFile(Path path, byte[] content) throws IOException; }