diff --git a/.github/workflows/dev_build.yml b/.github/workflows/dev_build.yml index dfc187c..e514591 100644 --- a/.github/workflows/dev_build.yml +++ b/.github/workflows/dev_build.yml @@ -11,8 +11,6 @@ name: Util Development Build on: push: branches: [ "dev" ] - pull_request: - branches-ignore: ["main"] jobs: dev-build: diff --git a/.github/workflows/dev_pr_build.yml b/.github/workflows/dev_pr_build.yml new file mode 100644 index 0000000..083b448 --- /dev/null +++ b/.github/workflows/dev_pr_build.yml @@ -0,0 +1,34 @@ +# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Util Development PR Build + +on: + pull_request: + branches-ignore: ["main"] + +jobs: + dev-build: + runs-on: ubuntu-latest + steps: + - name: Checkout Util + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build Util + run: mvn clean install --file pom.xml + + # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive + # - name: Update dependency graph + # uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 diff --git a/pom.xml b/pom.xml index 483fd27..75c618a 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ gov.hhs.aspr.ms util - 4.1.3 + 4.2.0 jar Modeling Utils @@ -60,8 +60,8 @@ 1.6.0 3.2.5 3.3.1 - 3.6.3 - 3.2.2 + 3.7.0 + 3.2.4 0.4.0 @@ -173,6 +173,8 @@ central true ASPR MS Util + true + published diff --git a/src/main/java/gov/hhs/aspr/ms/util/meta/unittestcoverage/MetaInfoGenerator.java b/src/main/java/gov/hhs/aspr/ms/util/meta/unittestcoverage/MetaInfoGenerator.java index 0ee2292..05a8ce6 100644 --- a/src/main/java/gov/hhs/aspr/ms/util/meta/unittestcoverage/MetaInfoGenerator.java +++ b/src/main/java/gov/hhs/aspr/ms/util/meta/unittestcoverage/MetaInfoGenerator.java @@ -228,7 +228,10 @@ private void probeTestClass(Class c) { final UnitTestForCoverage unitTestForCoverage = testMethod.getAnnotation(UnitTestForCoverage.class); int caseIndex = 0; - if (test != null && unitTestForCoverage == null) { + if (test != null ) { + caseIndex += 16; + } + if (unitTestForCoverage == null) { caseIndex += 8; } if (unitTestConstructor != null) { @@ -242,8 +245,34 @@ private void probeTestClass(Class c) { } switch (caseIndex) { - case 0: - // ignore the method + case 16: + warningContainerBuilder.addMethodWarning( + new MethodWarning(testMethod, WarningType.TEST_ANNOTATION_WITHOUT_UNIT_ANNOTATION)); + break; + case 3://fall through + case 5://fall through + case 6://fall through + case 7://fall through + case 9://fall through + case 10://fall through + case 11://fall through + case 12://fall through + case 13://fall through + case 14://fall through + case 15://fall through + case 19://fall through + case 21://fall through + case 22://fall through + case 23://fall through + case 25://fall through + case 26://fall through + case 27://fall through + case 28://fall through + case 29://fall through + case 30://fall through + case 31: + warningContainerBuilder.addMethodWarning( + new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); break; case 1: warningContainerBuilder.addMethodWarning( @@ -253,55 +282,30 @@ private void probeTestClass(Class c) { warningContainerBuilder.addMethodWarning( new MethodWarning(testMethod, WarningType.UNIT_METHOD_ANNOTATION_WITHOUT_TEST_ANNOTATION)); break; - case 3: - warningContainerBuilder - .addMethodWarning(new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); - break; + case 4: warningContainerBuilder.addMethodWarning( new MethodWarning(testMethod, WarningType.UNIT_CONSTRUCTOR_ANNOTATION_WITHOUT_TEST_ANNOTATION)); break; - case 5: - warningContainerBuilder - .addMethodWarning(new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); - break; - case 6: - warningContainerBuilder - .addMethodWarning(new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); - break; - case 7: - warningContainerBuilder - .addMethodWarning(new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); - break; + case 8: warningContainerBuilder.addMethodWarning( - new MethodWarning(testMethod, WarningType.TEST_ANNOTATION_WITHOUT_UNIT_ANNOTATION)); + new MethodWarning(testMethod, WarningType.UNIT_COVERAGE_ANNOTATION_WITHOUT_TEST_ANNOTATION)); + break; + + case 0://fall through + case 24: + //ignore break; - case 9: + case 17: probeFieldTest(testMethod, unitTestField); break; - case 10: + case 18: probeMethodTest(testMethod, unitTestMethod); break; - case 11: - warningContainerBuilder - .addMethodWarning(new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); - break; - case 12: + case 20: probeConstructorTest(testMethod, unitTestConstructor); break; - case 13: - warningContainerBuilder - .addMethodWarning(new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); - break; - case 14: - warningContainerBuilder - .addMethodWarning(new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); - break; - case 15: - warningContainerBuilder - .addMethodWarning(new MethodWarning(testMethod, WarningType.MULTIPLE_UNIT_ANNOTATIONS_PRESENT)); - break; default: throw new RuntimeException("unhandled case index " + caseIndex); diff --git a/src/main/java/gov/hhs/aspr/ms/util/meta/unittestcoverage/warnings/WarningType.java b/src/main/java/gov/hhs/aspr/ms/util/meta/unittestcoverage/warnings/WarningType.java index 162d020..7fa9ba4 100644 --- a/src/main/java/gov/hhs/aspr/ms/util/meta/unittestcoverage/warnings/WarningType.java +++ b/src/main/java/gov/hhs/aspr/ms/util/meta/unittestcoverage/warnings/WarningType.java @@ -21,6 +21,10 @@ public enum WarningType { SOURCE_CONSTRUCTOR_REQUIRES_TEST("Source constructor requires a test method but does not have one"), + UNIT_COVERAGE_ANNOTATION_WITHOUT_TEST_ANNOTATION( + "Test method is marked with @UnitTestForCoverage but does not have a corresponding @Test annotation"), + + UNIT_CONSTRUCTOR_ANNOTATION_WITHOUT_TEST_ANNOTATION( "Test method is marked with @UnitTestConstructor but does not have a corresponding @Test annotation"), diff --git a/src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceError.java b/src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceError.java index 686d170..f81caa8 100644 --- a/src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceError.java +++ b/src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceError.java @@ -3,7 +3,9 @@ import gov.hhs.aspr.ms.util.errors.ContractError; public enum ResourceError implements ContractError { - UNKNOWN_FILE("Provided file does not exist"); + UNKNOWN_FILE("Provided file does not exist"), + FILE_PATH_IS_DIRECTORY("The provided file path points to a directory and not a file"), + DIRECTORY_PATH_IS_FILE("The provided directory path points to a file and not a directory"); private final String description; diff --git a/src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceHelper.java b/src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceHelper.java index 1757f7b..fbb395f 100644 --- a/src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceHelper.java +++ b/src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceHelper.java @@ -5,78 +5,272 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.nio.file.Files; import java.nio.file.Path; import gov.hhs.aspr.ms.util.errors.ContractException; +/** + * ResourceHelper is a class designed to solve the issue that sometimes arises + * when running UnitTests and using files from the resources directory within + * the src/test folder. + *

+ * The issue is that the relative path to the resource folder is dependant on + * what folder you are executing the test from. This can vary from IDE to IDE + * and even from where you run the maven command if using maven to run the unit + * tests. + *

+ * This solves the issues by obtaining an absolute reference to the resource + * directory by using the class loader and an empty resource. + *

+ * In addition to the above, this class also provides convience methods to + * validate file paths and directory paths, and create directories and files. + */ public class ResourceHelper { - private ResourceHelper() { - } - + /** + * Given a class ref, uses the class loader from the classref and an empty + * resource name to obtain a URI and then creates and returns a Path from that + * URI. This path will be an absolute path and not a relative path. Because it + * uses the classloader, it no longer matters from where this method gets called + * with respect to the java command used to call it. + *

+ * This solves the problem of unit tests that use files from the + * src/test/resources sometimes failing because of the directory from which the + * test was executed. + * + * @throws RuntimeException if the url provided by the classloader cannot be + * converted to a valid URI. Note that the + * RuntimeException wraps the thrown + * {@link URISyntaxException} + */ public static Path getResourceDir(Class classRef) { return Path.of(getURI(classRef.getClassLoader().getResource(""))); } - protected static URI getURI(URL url) { - try { - return url.toURI(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); + /** + * Given a path, creates the directory. This internally calls + * dirPath.toFile().mkdirs(). + */ + public static Path createDirectory(Path dirPath) { + if (dirPath.toFile().exists()) { + return dirPath; } - } - public static Path makeOutputDir(Path dirPath) { dirPath.toFile().mkdirs(); return dirPath; } - public static Path makeOutputDir(Path basepath, String subDir) { - Path dirPath = basepath.resolve(subDir); + /** + * Given a string that is a valid path, creates the directory. + *

+ * calls {@link ResourceHelper#createDirectory(Path)} + */ + public static Path createDirectory(String directory) { + Path dirPath = Path.of(directory); + + return createDirectory(dirPath); + } + + /** + * Given a base directory path and a sub directory, resolves the sub directory + * against the base path and calls {@link ResourceHelper#createDirectory(Path)} + *

+ * returns the resolved path + */ + public static Path createDirectory(Path baseDirPath, String subDir) { + Path dirPath = baseDirPath.resolve(subDir); + + return createDirectory(dirPath); + } + + /** + * Given a base directory and a sub directory, resolves the sub directory + * against the base path and calls {@link ResourceHelper#createDirectory(Path)} + *

+ * returns the resolved path + */ + public static Path createDirectory(String baseDir, String subDir) { + Path dirPath = Path.of(baseDir, subDir); + + return createDirectory(dirPath); + } + + /** + * Given a directory path and a file name, creates a file with the given name in + * the given directory. + * + * @throws RuntimeException if the file cannot be created. Note that the + * RuntimeException wraps the thrown + * {@link IOException} + */ + public static void createFile(Path directory, String fileName) { + + File file = directory.resolve(fileName).toFile(); + + if (file.exists()) { + return; + } + + _createFile(file); + } + + /** + * Given a directory path and a file name, creates a file with the given name in + * the given directory. + *

+ * Deletes the file if it exists before creating the file. + * + * @throws RuntimeException if the file cannot be created. Note that the + * RuntimeException wraps the thrown + * {@link IOException} + */ + public static void createNewFile(Path directory, String fileName) { + + File file = directory.resolve(fileName).toFile(); + + if (file.exists()) { + file.delete(); + } + + _createFile(file); + } + + /** + * Given a file path, validates that the file exists. + *

+ * calls {@link ResourceHelper#validateFilePath(Path)} + * + * @throws ContractException + *

+ */ + public static Path validateFile(String file) { + Path filePath = Path.of(file); - return makeOutputDir(dirPath); + validateFile(filePath); + + return filePath; } - public static void createOutputFile(Path filePath, String fileName) { + /** + * Given a file path, validates that the file exists. + * + * @throws ContractException + * + */ + public static Path validateFile(Path filePath) { + File file = filePath.toFile(); - File isAfile = filePath.resolve(fileName).toFile(); + if (file.isDirectory()) { + throw new ContractException(ResourceError.FILE_PATH_IS_DIRECTORY); + } - if (isAfile.exists()) { - isAfile.delete(); + if (!file.exists()) { + throw new ContractException(ResourceError.UNKNOWN_FILE); } - createFile(isAfile); + return filePath; + } + + /** + * Given a file path, validates that the file path exists. + *

+ * calls {@link ResourceHelper#validateFilePath(Path)} + * + * @throws ContractException {@link ResourceError#FILE_PATH_IS_DIRECTORY} if the + * file path refers to a directory + */ + public static Path validateFilePath(String file) { + Path filePath = Path.of(file); + + validateFilePath(filePath); + + return filePath; } - public static Path validatePath(String path, boolean isOutput) { - Path maybePath = Path.of(path); - File maybeFile = maybePath.toFile(); + /** + * Given a file path, validates that the file path exists. + * + * @throws ContractException {@link ResourceError#FILE_PATH_IS_DIRECTORY} if the + * file path refers to a directory + */ + public static Path validateFilePath(Path filePath) { + File file = filePath.toFile(); - boolean isDirectory = maybeFile.isDirectory(); - boolean isFile = maybeFile.isFile(); + if (file.isDirectory()) { + throw new ContractException(ResourceError.FILE_PATH_IS_DIRECTORY); + } - // if the given string corresponds to a file that exists, return path - if (isFile) { - return maybePath; + if (!file.exists()) { + validateDirectoryPath(filePath.getParent()); } - // if file does not exist, ensure the path is not a directory and that the - // parent directory of the outputFile exists. - if (isOutput && !isDirectory) { - Path parentPath = maybePath.getParent(); + return filePath; + } + + /** + * Given a directory path, validates that the directory path exists. + *

+ * calls {@link ResourceHelper#validateDirectoryPath(Path)} + * + * @throws ContractException {@link ResourceError#DIRECTORY_PATH_IS_FILE} if the + * directory path refers to a file + */ + public static Path validateDirectoryPath(String directory) { + Path maybePath = Path.of(directory); + + validateDirectoryPath(maybePath); + + return maybePath; + } + + /** + * Given a directory path, validates that the directory path exists. + *

+ * If it does not exists, attempts to create it + * + * @throws ContractException {@link ResourceError#DIRECTORY_PATH_IS_FILE} if the + * directory path refers to a file + */ + public static Path validateDirectoryPath(Path directoryPath) { + File maybeFile = directoryPath.toFile(); + + if (maybeFile.isFile()) { + throw new ContractException(ResourceError.DIRECTORY_PATH_IS_FILE); + } - if (Files.exists(parentPath)) { - return maybePath; - } + if (!maybeFile.exists()) { + createDirectory(directoryPath); } - // otherwise throw an exception - throw new ContractException(ResourceError.UNKNOWN_FILE, path); + return directoryPath; + } + + /** + * Given a url, converts it to a URI + */ + protected static URI getURI(URL url) { + try { + return url.toURI(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } } - protected static void createFile(File file) { + /** + * Given a file, attempts to create the file package access for testing + */ + static void _createFile(File file) { try { file.createNewFile(); } catch (IOException e) { @@ -84,4 +278,7 @@ protected static void createFile(File file) { } } + private ResourceHelper() { + } + } diff --git a/src/test/java/gov/hhs/aspr/ms/util/resourcehelper/AT_ResourceHelper.java b/src/test/java/gov/hhs/aspr/ms/util/resourcehelper/AT_ResourceHelper.java index 5354b7f..88899bd 100644 --- a/src/test/java/gov/hhs/aspr/ms/util/resourcehelper/AT_ResourceHelper.java +++ b/src/test/java/gov/hhs/aspr/ms/util/resourcehelper/AT_ResourceHelper.java @@ -1,6 +1,7 @@ package gov.hhs.aspr.ms.util.resourcehelper; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -19,6 +20,29 @@ public class AT_ResourceHelper { + private class IOExceptionFile extends File { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public IOExceptionFile(String pathname) { + super(pathname); + } + + public IOExceptionFile(File file) { + super(file, pathSeparator); + } + + @Override + public boolean createNewFile() throws IOException { + + throw new IOException(); + } + + } + @Test @UnitTestMethod(target = ResourceHelper.class, name = "getResourceDir", args = { Class.class }) public void testGetResourceDir() throws MalformedURLException { @@ -40,105 +64,296 @@ public void testGetResourceDir() throws MalformedURLException { } @Test - @UnitTestMethod(target = ResourceHelper.class, name = "makeOutputDir", args = { Path.class }) - public void testMakeTestOutputDir() { + @UnitTestMethod(target = ResourceHelper.class, name = "createDirectory", args = { Path.class }) + public void testCreateDirectory() { Path path = ResourceHelper.getResourceDir(this.getClass()).resolve("additional-folder"); - Path newPath = ResourceHelper.makeOutputDir(path); + Path newPath = ResourceHelper.createDirectory(path); - assertNotNull(newPath); assertTrue(newPath.toFile().exists()); } @Test - @UnitTestMethod(target = ResourceHelper.class, name = "makeOutputDir", args = { Path.class, String.class }) - public void testMakeTestOutputDir_SubDir() { + @UnitTestMethod(target = ResourceHelper.class, name = "createDirectory", args = { String.class }) + public void testCreateDirectory_String() { Path path = ResourceHelper.getResourceDir(this.getClass()).resolve("additional-folder"); - Path newPath = ResourceHelper.makeOutputDir(path, "subFolder"); + Path newPath = ResourceHelper.createDirectory(path.toString()); - assertNotNull(newPath); assertTrue(newPath.toFile().exists()); } - private class IOExceptionFile extends File { - - /** - * - */ - private static final long serialVersionUID = 1L; + @Test + @UnitTestMethod(target = ResourceHelper.class, name = "createDirectory", args = { Path.class, String.class }) + public void testCreateDirectory_Path_String() { + Path path = ResourceHelper.getResourceDir(this.getClass()); - public IOExceptionFile(String pathname) { - super(pathname); - } + Path newPath = ResourceHelper.createDirectory(path, "additional-folder"); - public IOExceptionFile(File file) { - super(file, pathSeparator); - } + assertTrue(newPath.toFile().exists()); + } - @Override - public boolean createNewFile() throws IOException { + @Test + @UnitTestMethod(target = ResourceHelper.class, name = "createDirectory", args = { String.class, String.class }) + public void testCreateDirectory_String_String() { + Path path = ResourceHelper.getResourceDir(this.getClass()); - throw new IOException(); - } + Path newPath = ResourceHelper.createDirectory(path.toString(), "additional-folder"); + assertTrue(newPath.toFile().exists()); } @Test - @UnitTestMethod(target = ResourceHelper.class, name = "createOutputFile", args = { Path.class, - String.class }) - public void testCreateTestOutputFile() throws IOException { + @UnitTestMethod(target = ResourceHelper.class, name = "createFile", args = { Path.class, String.class }) + public void testCreateFile() throws IOException { Path path = ResourceHelper.getResourceDir(this.getClass()); - Path newPath = ResourceHelper.makeOutputDir(path); + Path newPath = ResourceHelper.createDirectory(path); String fileName = "foo.txt"; - ResourceHelper.createOutputFile(newPath, fileName); + ResourceHelper.createFile(newPath, fileName); assertTrue(newPath.resolve(fileName).toFile().exists()); - // test for delete/recreat file if it exists - ResourceHelper.createOutputFile(newPath, fileName); + // preconditions + // the file cannot be created + // force an IOException + RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { + IOExceptionFile testFile = new IOExceptionFile(newPath.resolve(fileName).toFile()); + ResourceHelper._createFile(testFile); + }); + + assertTrue(runtimeException.getCause() instanceof IOException); + + newPath.resolve(fileName).toFile().delete(); + } + + @Test + @UnitTestMethod(target = ResourceHelper.class, name = "createNewFile", args = { Path.class, String.class }) + public void testCreateNewFile() throws IOException { + Path path = ResourceHelper.getResourceDir(this.getClass()); + + Path newPath = ResourceHelper.createDirectory(path); + + String fileName = "foo.txt"; + ResourceHelper.createNewFile(newPath, fileName); + + assertTrue(newPath.resolve(fileName).toFile().exists()); // preconditions + // the file cannot be created // force an IOException RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { IOExceptionFile testFile = new IOExceptionFile(newPath.resolve(fileName).toFile()); - ResourceHelper.createFile(testFile); + ResourceHelper._createFile(testFile); }); assertTrue(runtimeException.getCause() instanceof IOException); + + newPath.resolve(fileName).toFile().delete(); } @Test - @UnitTestMethod(target = ResourceHelper.class, name = "validatePath", args = { String.class, boolean.class }) - public void testValidatePath() { + @UnitTestMethod(target = ResourceHelper.class, name = "validateFile", args = { String.class }) + public void testValidateFile() { Path resourceDir = ResourceHelper.getResourceDir(getClass()); - // path is a file that is not output and exists - String path = resourceDir.resolve("resourceHelper.json").toAbsolutePath().toString(); - Path expectedPath = resourceDir.resolve("resourceHelper.json").toAbsolutePath(); - assertEquals(expectedPath, ResourceHelper.validatePath(path, false)); - - // file is an output file that does not exist, but the directory the file - // resides in exists - ResourceHelper.makeOutputDir(resourceDir, "testOutput"); - path = resourceDir.resolve("testOutput").resolve("resourceHelper.json").toAbsolutePath().toString(); - expectedPath = resourceDir.resolve("testOutput").resolve("resourceHelper.json").toAbsolutePath(); - assertEquals(expectedPath, ResourceHelper.validatePath(path, true)); + Path dirPath = resourceDir; + String fileName = "validateFile.json"; + + ResourceHelper.createFile(dirPath, fileName); + + String filePath = dirPath.resolve(fileName).toAbsolutePath().toString(); + assertTrue(ResourceHelper.validateFile(filePath).toFile().exists()); // preconditions - // File does not exist and it is not an outputFile + // file path points to a directory ContractException contractException = assertThrows(ContractException.class, () -> { - ResourceHelper.validatePath("testOutput", false); + ResourceHelper.validateFile(resourceDir.toString()); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + // file does not exist + contractException = assertThrows(ContractException.class, () -> { + ResourceHelper.validateFile(dirPath.resolve("unknwonfile.txt")); }); assertEquals(ResourceError.UNKNOWN_FILE, contractException.getErrorType()); - // is output but parent directory does not exist + dirPath.resolve(fileName).toFile().delete(); + } + + @Test + @UnitTestMethod(target = ResourceHelper.class, name = "validateFile", args = { Path.class }) + public void testValidateFile_Path() { + Path resourceDir = ResourceHelper.getResourceDir(getClass()); + Path dirPath = resourceDir; + String fileName = "validateFile.json"; + + ResourceHelper.createFile(dirPath, fileName); + + Path filePath = dirPath.resolve(fileName).toAbsolutePath(); + assertTrue(ResourceHelper.validateFile(filePath).toFile().exists()); + + // preconditions + // file path points to a directory + ContractException contractException = assertThrows(ContractException.class, () -> { + ResourceHelper.validateFile(resourceDir.toString()); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + // file does not exist contractException = assertThrows(ContractException.class, () -> { - ResourceHelper.validatePath(resourceDir.resolve("nonExistantDir").resolve("file.json").toString(), true); + ResourceHelper.validateFile(dirPath.resolve("unknwonfile.txt")); }); assertEquals(ResourceError.UNKNOWN_FILE, contractException.getErrorType()); + + dirPath.resolve(fileName).toFile().delete(); + } + + @Test + @UnitTestMethod(target = ResourceHelper.class, name = "validateFilePath", args = { String.class }) + public void testValidateFilePath() { + Path resourceDir = ResourceHelper.getResourceDir(getClass()); + Path dirPath = resourceDir; + String fileName = "validateFilePath.json"; + String subDirName = "temp"; + + // delete any old test files + dirPath.resolve(fileName).toFile().delete(); + + // path is a file that does not exist but directory exists + String filePath = dirPath.resolve(fileName).toAbsolutePath().toString(); + Path path = ResourceHelper.validateFilePath(filePath); + assertFalse(path.toFile().exists()); + + // create file + ResourceHelper.createFile(dirPath, fileName); + + // path is a file that does exist + path = ResourceHelper.validateFilePath(filePath); + assertTrue(path.toFile().exists()); + + // path is a file that does not exist and the directory does not exist + dirPath = resourceDir.resolve(subDirName); + filePath = dirPath.resolve(fileName).toAbsolutePath().toString(); + path = ResourceHelper.validateFilePath(filePath); + // file does not exist + assertFalse(path.toFile().exists()); + // directory exists because it was created + assertTrue(dirPath.toFile().exists()); + + // preconditions + // File path points to a directory + ContractException contractException = assertThrows(ContractException.class, () -> { + ResourceHelper.validateFilePath(resourceDir); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + resourceDir.resolve(fileName).toFile().delete(); + dirPath.resolve(fileName).toFile().delete(); + } + + @Test + @UnitTestMethod(target = ResourceHelper.class, name = "validateFilePath", args = { Path.class }) + public void testValidateFilePath_Path() { + Path resourceDir = ResourceHelper.getResourceDir(getClass()); + Path dirPath = resourceDir; + String fileName = "validateFilePath.json"; + String subDirName = "temp"; + + // delete any old test files + dirPath.resolve(fileName).toFile().delete(); + + // path is a file that does not exist but directory exists + Path filePath = dirPath.resolve(fileName).toAbsolutePath(); + Path path = ResourceHelper.validateFilePath(filePath); + assertFalse(path.toFile().exists()); + + // create file + ResourceHelper.createFile(dirPath, fileName); + + // path is a file that does exist + path = ResourceHelper.validateFilePath(filePath); + assertTrue(path.toFile().exists()); + + // path is a file that does not exist and the directory does not exist + dirPath = resourceDir.resolve(subDirName); + filePath = dirPath.resolve(fileName).toAbsolutePath(); + path = ResourceHelper.validateFilePath(filePath); + // file does not exist + assertFalse(path.toFile().exists()); + // directory exists because it was created + assertTrue(dirPath.toFile().exists()); + + // preconditions + // File path points to a directory + ContractException contractException = assertThrows(ContractException.class, () -> { + ResourceHelper.validateFilePath(resourceDir); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + resourceDir.resolve(fileName).toFile().delete(); + dirPath.resolve(fileName).toFile().delete(); + } + + @Test + @UnitTestMethod(target = ResourceHelper.class, name = "validateDirectoryPath", args = { String.class }) + public void testValidateDirectoryPath() { + Path resourceDir = ResourceHelper.getResourceDir(getClass()); + Path dirPath = resourceDir; + String subDirName = "temp"; + + // delete any old test files + dirPath.resolve(subDirName).toFile().delete(); + + // path is a file that does not exist but directory exists + String filePath = dirPath.resolve(subDirName).toAbsolutePath().toString(); + Path path = ResourceHelper.validateDirectoryPath(filePath); + assertTrue(path.toFile().exists()); + + // preconditions + // directory path points to a file + String fileName = "validateDirectoryPath.json"; + ContractException contractException = assertThrows(ContractException.class, () -> { + ResourceHelper.createFile(dirPath, fileName); + ResourceHelper.validateDirectoryPath(dirPath.resolve(fileName).toString()); + }); + + assertEquals(ResourceError.DIRECTORY_PATH_IS_FILE, contractException.getErrorType()); + + dirPath.resolve(fileName).toFile().delete(); + } + + @Test + @UnitTestMethod(target = ResourceHelper.class, name = "validateDirectoryPath", args = { Path.class }) + public void testValidateDirectoryPath_Path() { + Path resourceDir = ResourceHelper.getResourceDir(getClass()); + Path dirPath = resourceDir; + String subDirName = "temp"; + + // delete any old test files + dirPath.resolve(subDirName).toFile().delete(); + + // path is a file that does not exist but directory exists + Path filePath = dirPath.resolve(subDirName).toAbsolutePath(); + Path path = ResourceHelper.validateDirectoryPath(filePath); + assertTrue(path.toFile().exists()); + + // preconditions + // directory path points to a file + String fileName = "validateDirectoryPath.json"; + ContractException contractException = assertThrows(ContractException.class, () -> { + ResourceHelper.createFile(dirPath, fileName); + ResourceHelper.validateDirectoryPath(dirPath.resolve(fileName)); + }); + + assertEquals(ResourceError.DIRECTORY_PATH_IS_FILE, contractException.getErrorType()); + + dirPath.resolve(fileName).toFile().delete(); } }