diff --git a/src/main/java/org/junit/rules/TemporaryFolder.java b/src/main/java/org/junit/rules/TemporaryFolder.java index c730a2e3cd34f..e8dfe0a0dc83d 100644 --- a/src/main/java/org/junit/rules/TemporaryFolder.java +++ b/src/main/java/org/junit/rules/TemporaryFolder.java @@ -171,59 +171,44 @@ public File newFile() throws IOException { * folder. */ public File newFolder(String path) throws IOException { - if (new File(path).isAbsolute()) { - throw new IOException("folder path must be a relative path"); - } - File file = new File(getRoot(), path); - if (!file.mkdirs()) { - if (file.isDirectory()) { - throw new IOException( - "a folder with the path \'" + path + "\' already exists"); - } - throw new IOException( - "could not create a folder with the path \'" + path + "\'"); - } - return file; + return newFolder(new String[]{path}); } /** - * Returns a new fresh folder with the given path under the temporary + * Returns a new fresh folder with the given paths under the temporary * folder. For example, if you pass in the strings {@code "parent"} and {@code "child"} * then a directory named {@code "parent"} will be created under the temporary folder * and a directory named {@code "child"} will be created under the newly-created * {@code "parent"} directory. */ public File newFolder(String... paths) throws IOException { - File file = getRoot(); + // Before checking the paths, check if create() was ever called, and if it wasn't, throw + File root = getRoot(); + + for (String path : paths) { + if (new File(path).isAbsolute()) { + throw new IOException("folder path \'" + path + "\' is not a relative path"); + } + } + + File relativePath = null; + File file = root; + boolean lastMkdirsCallSuccessful = true; for (int i = 0; i < paths.length; i++) { - String folderName = paths[i]; - validateFolderName(folderName); - file = new File(file, folderName); - if (!file.mkdir() && isLastElementInArray(i, paths)) { + relativePath = relativePath == null ? new File(paths[i]) : new File(relativePath, paths[i]); + file = new File(root, relativePath.getPath()); + + lastMkdirsCallSuccessful = file.mkdirs(); + if (!lastMkdirsCallSuccessful && !file.isDirectory()) { throw new IOException( - "a folder with the name \'" + folderName + "\' already exists"); + "could not create a folder with the path \'" + relativePath.getPath() + "\'"); } } - return file; - } - - /** - * Validates if multiple path components were used while creating a folder. - * - * @param folderName - * Name of the folder being created - */ - private void validateFolderName(String folderName) throws IOException { - File tempFile = new File(folderName); - if (tempFile.getParent() != null) { - String errorMsg = "Folder name cannot consist of multiple path components separated by a file separator." - + " Please use newFolder('MyParentFolder','MyFolder') to create hierarchies of folders"; - throw new IOException(errorMsg); + if (!lastMkdirsCallSuccessful) { + throw new IOException( + "a folder with the path \'" + relativePath.getPath() + "\' already exists"); } - } - - private boolean isLastElementInArray(int index, String[] array) { - return index == array.length - 1; + return file; } /** diff --git a/src/test/java/org/junit/rules/TemporaryFolderUsageTest.java b/src/test/java/org/junit/rules/TemporaryFolderUsageTest.java index d5c3702ac3f75..bbf843b7e2922 100644 --- a/src/test/java/org/junit/rules/TemporaryFolderUsageTest.java +++ b/src/test/java/org/junit/rules/TemporaryFolderUsageTest.java @@ -99,7 +99,7 @@ public void newFolderWithPathStartingWithFileSeparatorThrowsIOException() throws IOException { tempFolder.create(); thrown.expect(IOException.class); - thrown.expectMessage("folder path must be a relative path"); + thrown.expectMessage("folder path '/temp1' is not a relative path"); tempFolder.newFolder(File.separator + "temp1"); } @@ -124,22 +124,46 @@ public void newFolderWithPathContainingForwardSlashCreatesDirectories() } @Test - public void newFolderWithGivenPathThrowsIllegalArgumentExceptionIfPathExists() throws IOException { + public void newFolderWithGivenPathThrowsIllegalArgumentExceptionIfFolderExists() throws IOException { tempFolder.create(); tempFolder.newFolder("level1", "level2", "level3"); thrown.expect(IOException.class); - thrown.expectMessage("a folder with the name 'level3' already exists"); + String path = "level1" + File.separator + "level2" + File.separator + "level3"; + thrown.expectMessage("a folder with the path '" + path + "' already exists"); tempFolder.newFolder("level1", "level2", "level3"); } @Test - public void newFolderWithGivenPathThrowsIOExceptionIfFolderNamesConsistOfMultiplePathComponents() + public void newFolderWithPathsContainingForwardSlashCreatesFullPath() throws IOException { tempFolder.create(); - thrown.expect(IOException.class); - thrown.expectMessage("name cannot consist of multiple path components"); tempFolder.newFolder("temp1", "temp2", "temp3/temp4"); + + File directory = new File(tempFolder.getRoot(), "temp1"); + assertFileIsDirectory(directory); + directory = new File(directory, "temp2"); + assertFileIsDirectory(directory); + directory = new File(directory, "temp3"); + assertFileIsDirectory(directory); + directory = new File(directory, "temp4"); + assertFileIsDirectory(directory); + } + + @Test + public void newFolderWithPathsContainingFileSeparatorCreatesFullPath() + throws IOException { + tempFolder.create(); + tempFolder.newFolder("temp1", "temp2", "temp3" + File.separator + "temp4"); + + File directory = new File(tempFolder.getRoot(), "temp1"); + assertFileIsDirectory(directory); + directory = new File(directory, "temp2"); + assertFileIsDirectory(directory); + directory = new File(directory, "temp3"); + assertFileIsDirectory(directory); + directory = new File(directory, "temp4"); + assertFileIsDirectory(directory); } @Test