Create a tmp directory recursive and touch an empty file in that directory. Delete all that were created after - krickert/search-api GitHub Wiki
package example;
import java.io.IOException;
import java.nio.file.*;
import java.util.Objects;
public class DirectoryProcessor {
/**
* Processes a directory and file as follows:
* <ol>
* <li>Ensures the directory path and prefix are not null.</li>
* <li>If the directory exists, verifies it is writable; if not, throws an exception.</li>
* <li>If the directory does not exist, creates it recursively; if creation fails, throws an exception.</li>
* <li>Writes a file named {@code prefix + "01.txt"} in that directory.</li>
* <li>Deletes that file and, if the directory was created by this method, deletes it along with any empty parent directories.</li>
* <li>Finally, ensures the directory exists and creates an empty file with the name exactly equal to {@code prefix}.</li>
* </ol>
*
* @param dirPath the directory path
* @param prefix the file prefix
* @throws IOException if any file operation fails
*/
public static void process(Path dirPath, String prefix) throws IOException {
// Validate inputs
Objects.requireNonNull(dirPath, "Directory path must not be null");
Objects.requireNonNull(prefix, "Prefix must not be null");
boolean created = false;
if (Files.exists(dirPath)) {
if (!Files.isDirectory(dirPath)) {
throw new IllegalArgumentException("The given path is not a directory: " + dirPath);
}
if (!Files.isWritable(dirPath)) {
throw new IOException("Directory is not writable: " + dirPath);
}
} else {
// Attempt to create the directory recursively
Files.createDirectories(dirPath);
created = true;
}
// Write a file named "<prefix>01.txt" with sample content
Path file01 = dirPath.resolve(prefix + "01.txt");
Files.writeString(file01, "Sample content");
// Delete the file
Files.delete(file01);
// If we created the directory, delete it and any empty parent directories
if (created) {
deleteRecursivelyIfEmpty(dirPath);
}
// Ensure the directory exists again
if (!Files.exists(dirPath)) {
Files.createDirectories(dirPath);
}
// Create an empty file with the exact name provided as prefix
Path finalFile = dirPath.resolve(prefix);
Files.createFile(finalFile);
}
/**
* Deletes the given directory and then climbs up the parent chain, deleting
* directories that are empty.
*
* @param dir the starting directory
* @throws IOException if deletion fails
*/
private static void deleteRecursivelyIfEmpty(Path dir) throws IOException {
Path current = dir;
while (current != null && Files.isDirectory(current) && isEmptyDirectory(current)) {
Files.delete(current);
current = current.getParent();
}
}
/**
* Checks whether the given directory is empty.
*
* @param dir the directory to check
* @return true if the directory is empty; false otherwise
* @throws IOException if an I/O error occurs
*/
private static boolean isEmptyDirectory(Path dir) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
return !stream.iterator().hasNext();
}
}
// Main method for demonstration purposes
public static void main(String[] args) {
try {
Path directory = Paths.get("testDir/subDir");
String prefix = "myFile";
process(directory, prefix);
System.out.println("Process completed successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Below is a complete JUnit 5 test class using AssertJ and the JUnit‑Jupiter @TempDir annotation. This test class covers the following scenarios for our directory processing code:
-
Non‑existent directory:
When the directory does not exist, the method creates it recursively, writes and deletes a temporary file, and finally creates an empty file using the prefix. -
Existing directory:
When the directory exists, the method verifies it’s writable and creates the final empty file. -
Null inputs:
The method throws a NullPointerException if the directory path or prefix is null. -
Invalid directory type:
If the provided path is a file (not a directory), an IllegalArgumentException is thrown.
Below is the test code:
package example;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.*;
class DirectoryProcessorTest {
@Test
void testProcessCreatesDirectoryAndFinalFileWhenDirectoryDoesNotExist(@TempDir Path tempDir) throws IOException {
// Create a subdirectory path that does not exist
Path nonExistentDir = tempDir.resolve("nonexistent/subdir");
String prefix = "testPrefix";
// Execute the process method
DirectoryProcessor.process(nonExistentDir, prefix);
// Verify the directory now exists
assertThat(Files.exists(nonExistentDir)).isTrue();
// Verify that the final file (with name equal to prefix) exists and is empty
Path finalFile = nonExistentDir.resolve(prefix);
assertThat(Files.exists(finalFile)).isTrue();
assertThat(Files.size(finalFile)).isEqualTo(0);
}
@Test
void testProcessWorksWhenDirectoryAlreadyExists(@TempDir Path tempDir) throws IOException {
// Create an existing directory
Path existingDir = tempDir.resolve("existingDir");
Files.createDirectories(existingDir);
String prefix = "existingPrefix";
// Execute the process method
DirectoryProcessor.process(existingDir, prefix);
// Verify the directory still exists and the final file is created
assertThat(Files.exists(existingDir)).isTrue();
Path finalFile = existingDir.resolve(prefix);
assertThat(Files.exists(finalFile)).isTrue();
assertThat(Files.size(finalFile)).isEqualTo(0);
}
@Test
void testProcessThrowsExceptionForNullDirectory() {
String prefix = "prefix";
assertThatThrownBy(() -> DirectoryProcessor.process(null, prefix))
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("Directory path must not be null");
}
@Test
void testProcessThrowsExceptionForNullPrefix(@TempDir Path tempDir) {
Path anyDir = tempDir.resolve("anyDir");
assertThatThrownBy(() -> DirectoryProcessor.process(anyDir, null))
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("Prefix must not be null");
}
@Test
void testProcessThrowsExceptionWhenPathIsNotDirectory(@TempDir Path tempDir) throws IOException {
// Create a file instead of a directory
Path filePath = tempDir.resolve("notADir.txt");
Files.createFile(filePath);
String prefix = "prefix";
assertThatThrownBy(() -> DirectoryProcessor.process(filePath, prefix))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("is not a directory");
}
}
-
@TempDir:
Provides a temporary directory that is automatically cleaned up by JUnit 5. -
AssertJ Assertions:
We useassertThat
,assertThatThrownBy
, and other AssertJ methods for fluent assertions. -
Test Scenarios:
Each test method validates one aspect of theDirectoryProcessor.process
method:- When the target directory doesn’t exist, the method creates it, processes the file, and creates the final empty file.
- When the directory exists, the method leaves it intact and creates the final file.
- Null inputs and invalid directory types throw the expected exceptions.
This test class, together with the earlier provided DirectoryProcessor
implementation, should give you a good starting point for testing your file/directory handling logic using JUnit 5 and AssertJ.