From 861b37087f00c82cd1b48605457b5f278577c931 Mon Sep 17 00:00:00 2001 From: Gerd Aschemann Date: Wed, 29 Oct 2025 14:35:14 +0100 Subject: [PATCH 1/5] #429 Make sourceDocuments optional in Maven plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-populate sourceDocuments from sourceDir when not explicitly configured, matching the behavior of Gradle plugin and CLI. - Add findHtmlFiles() method to recursively scan for .html files - Modify setupConfiguration() to auto-populate when sourceDocuments is null - Add integration test executeWithOnlySourceDir_ShouldSucceed() - All existing tests pass without regression 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../maven/HtmlSanityCheckMojo.java | 36 ++++++++++- .../maven/HtmlSanityCheckMojoTest.java | 63 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/htmlSanityCheck-maven-plugin/src/main/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java b/htmlSanityCheck-maven-plugin/src/main/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java index 4461d283..593a8ff4 100644 --- a/htmlSanityCheck-maven-plugin/src/main/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java +++ b/htmlSanityCheck-maven-plugin/src/main/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java @@ -270,9 +270,16 @@ void logBuildParameter(Configuration myConfig) { } protected Configuration setupConfiguration() { + // Auto-populate sourceDocuments from sourceDir if not specified + // (same pattern as Gradle plugin and CLI) + Set documentsToCheck = sourceDocuments; + if (documentsToCheck == null && sourceDir != null) { + documentsToCheck = findHtmlFiles(sourceDir); + } + Configuration result = Configuration.builder() .excludes(excludes.stream().map(Pattern::compile).collect(Collectors.toSet())) - .sourceDocuments(sourceDocuments) + .sourceDocuments(documentsToCheck) .sourceDir(sourceDir) .checkingResultsDir(checkingResultsDir) .junitResultsDir(junitResultsDir) @@ -301,6 +308,33 @@ protected Configuration setupConfiguration() { return result; } + + /** + * Recursively finds all HTML files in the given directory. + * Mirrors the behavior of the Gradle plugin's fileTree(sourceDir).include('**/*.html') + * + * @param directory the directory to search + * @return set of HTML files found + */ + private Set findHtmlFiles(File directory) { + Set htmlFiles = new HashSet<>(); + if (directory == null || !directory.exists() || !directory.isDirectory()) { + return htmlFiles; + } + + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + // Recursively search subdirectories + htmlFiles.addAll(findHtmlFiles(file)); + } else if (file.isFile() && file.getName().endsWith(".html")) { + htmlFiles.add(file); + } + } + } + return htmlFiles; + } } /*======================================================================== diff --git a/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java b/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java index c708755a..5423d4fa 100644 --- a/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java +++ b/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java @@ -190,6 +190,69 @@ void execuuserte() throws IOException, MojoExecutionException { deleteDirectory(resultDir.toFile()); } + @Test + void executeWithOnlySourceDir_ShouldSucceed() throws IOException, MojoExecutionException { + // Setup: Create temp directories + Path junitDir = Files.createTempDirectory("MojoJunit"); + Path resultDir = Files.createTempDirectory("MojoResult"); + Path sourceDir = Files.createTempDirectory("MojoSource"); + + // Create HTML file in root of sourceDir + File rootHtmlFile = new File(sourceDir.toFile(), "root.html"); + Files.write(rootHtmlFile.toPath(), VALID_HTML.getBytes(StandardCharsets.UTF_8)); + + // Create subdirectory with another HTML file + File subDir = new File(sourceDir.toFile(), "subdir"); + boolean mkdirSuccess = subDir.mkdirs(); + Assertions.assertThat(mkdirSuccess).isTrue(); + File subHtmlFile = new File(subDir, "nested.html"); + Files.write(subHtmlFile.toPath(), VALID_HTML.getBytes(StandardCharsets.UTF_8)); + + // Create Mojo and set only sourceDir field (NOT sourceDocuments) + // This simulates a Maven pom.xml with only configured + HtmlSanityCheckMojo mojo = new TestableHtmlSanityCheckMojo( + sourceDir.toFile(), + null, // sourceDocuments explicitly NOT set + resultDir.toFile(), + junitDir.toFile() + ); + + // This should succeed - setupConfiguration() will auto-populate sourceDocuments + mojo.execute(); + + // Clean up + deleteDirectory(sourceDir.toFile()); + deleteDirectory(junitDir.toFile()); + deleteDirectory(resultDir.toFile()); + } + + /** + * Helper class to allow setting private fields for testing + */ + static class TestableHtmlSanityCheckMojo extends HtmlSanityCheckMojo { + TestableHtmlSanityCheckMojo(File sourceDir, Set sourceDocuments, + File checkingResultsDir, File junitResultsDir) { + // Use reflection to set private fields + try { + setField(this, "sourceDir", sourceDir); + setField(this, "sourceDocuments", sourceDocuments); + setField(this, "checkingResultsDir", checkingResultsDir); + setField(this, "junitResultsDir", junitResultsDir); + setField(this, "checkerClasses", AllCheckers.CHECKER_CLASSES); + setField(this, "excludes", new HashSet()); + } catch (Exception e) { + throw new RuntimeException("Failed to set fields", e); + } + } + + private void setField(Object target, String fieldName, Object value) + throws NoSuchFieldException, IllegalAccessException { + java.lang.reflect.Field field = HtmlSanityCheckMojo.class.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(target, value); + } + } + // Helper functions From 77883b0d74fd440e0fbcaf2838c20362915c4778 Mon Sep 17 00:00:00 2001 From: Gerd Aschemann Date: Wed, 29 Oct 2025 14:36:25 +0100 Subject: [PATCH 2/5] Fix typo in Configuration method name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename defaultIndeFilenames to defaultIndexFilenames 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../main/java/org/aim42/htmlsanitycheck/Configuration.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htmlSanityCheck-core/src/main/java/org/aim42/htmlsanitycheck/Configuration.java b/htmlSanityCheck-core/src/main/java/org/aim42/htmlsanitycheck/Configuration.java index f9d4a627..9de94a7a 100644 --- a/htmlSanityCheck-core/src/main/java/org/aim42/htmlsanitycheck/Configuration.java +++ b/htmlSanityCheck-core/src/main/java/org/aim42/htmlsanitycheck/Configuration.java @@ -51,7 +51,7 @@ public class Configuration { @Builder.Default Set excludes = new HashSet<>(); @Builder.Default - Set indexFilenames = defaultIndeFilenames(); + Set indexFilenames = defaultIndexFilenames(); /* * Explanation for configuring http status codes: @@ -77,13 +77,13 @@ public Configuration() { this.ignoreIPAddresses = false;// warning if numerical IP addresses this.ignoreLocalhost = false;// warning if localhost-URLs this.indexFilenames - = defaultIndeFilenames(); + = defaultIndexFilenames(); this.prefixOnlyHrefExtensions = Web.POSSIBLE_EXTENSIONS; this.checksToExecute = AllCheckers.CHECKER_CLASSES; } - private static Set defaultIndeFilenames() { + private static Set defaultIndexFilenames() { return Arrays.stream("index.html,index.htm".split(",")).collect(Collectors.toSet()); } From 34f94f1a8153f9e7f8ab91db8249c02fd3b7ba62 Mon Sep 17 00:00:00 2001 From: Gerd Aschemann Date: Wed, 29 Oct 2025 14:40:31 +0100 Subject: [PATCH 3/5] Add support for .htm files in both plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Gradle and Maven plugins to automatically search for both .html and .htm files when sourceDocuments is not specified. - Gradle plugin: Add .htm pattern to fileTree includes - Maven plugin: Update findHtmlFiles() to check for .htm extension - Update README.adoc in both plugins to document default behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- htmlSanityCheck-gradle-plugin/README.adoc | 2 +- .../aim42/htmlsanitycheck/gradle/HtmlSanityCheckTask.groovy | 1 + htmlSanityCheck-maven-plugin/README.adoc | 2 +- .../org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/htmlSanityCheck-gradle-plugin/README.adoc b/htmlSanityCheck-gradle-plugin/README.adoc index 66873cd8..3ac67528 100644 --- a/htmlSanityCheck-gradle-plugin/README.adoc +++ b/htmlSanityCheck-gradle-plugin/README.adoc @@ -92,7 +92,7 @@ Type: Directory. + Type: `org.gradle.api.file.FileCollection`. + -Default: All files in `+{sourceDir}+` whose names end with `.html`. +Default: All files in `+{sourceDir}+` whose names end with `.html` or `.htm`. `checkingResultsDir` (optional):: Directory where the checking results are written to. + diff --git a/htmlSanityCheck-gradle-plugin/src/main/groovy/org/aim42/htmlsanitycheck/gradle/HtmlSanityCheckTask.groovy b/htmlSanityCheck-gradle-plugin/src/main/groovy/org/aim42/htmlsanitycheck/gradle/HtmlSanityCheckTask.groovy index bdead7ac..5088bb31 100644 --- a/htmlSanityCheck-gradle-plugin/src/main/groovy/org/aim42/htmlsanitycheck/gradle/HtmlSanityCheckTask.groovy +++ b/htmlSanityCheck-gradle-plugin/src/main/groovy/org/aim42/htmlsanitycheck/gradle/HtmlSanityCheckTask.groovy @@ -117,6 +117,7 @@ class HtmlSanityCheckTask extends DefaultTask { if (sourceDocuments == null) { sourceDocuments = project.fileTree(sourceDir) sourceDocuments.include('**/*.html') + sourceDocuments.include('**/*.htm') } } diff --git a/htmlSanityCheck-maven-plugin/README.adoc b/htmlSanityCheck-maven-plugin/README.adoc index 15ce403e..db04d92e 100644 --- a/htmlSanityCheck-maven-plugin/README.adoc +++ b/htmlSanityCheck-maven-plugin/README.adoc @@ -79,7 +79,7 @@ Type: Directory. + Type: `org.maven.api.file.FileCollection`. + -Default: All files in `+{sourceDir}+` whose names end with `.html`. +Default: All files in `+{sourceDir}+` whose names end with `.html` or `.htm`. `checkingResultsDir` (optional):: Directory where the checking results are written to. + diff --git a/htmlSanityCheck-maven-plugin/src/main/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java b/htmlSanityCheck-maven-plugin/src/main/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java index 593a8ff4..d884b2f1 100644 --- a/htmlSanityCheck-maven-plugin/src/main/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java +++ b/htmlSanityCheck-maven-plugin/src/main/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojo.java @@ -311,7 +311,7 @@ protected Configuration setupConfiguration() { /** * Recursively finds all HTML files in the given directory. - * Mirrors the behavior of the Gradle plugin's fileTree(sourceDir).include('**/*.html') + * Searches for files with .html and .htm extensions. * * @param directory the directory to search * @return set of HTML files found @@ -328,7 +328,7 @@ private Set findHtmlFiles(File directory) { if (file.isDirectory()) { // Recursively search subdirectories htmlFiles.addAll(findHtmlFiles(file)); - } else if (file.isFile() && file.getName().endsWith(".html")) { + } else if (file.isFile() && (file.getName().endsWith(".html") || file.getName().endsWith(".htm"))) { htmlFiles.add(file); } } From 55fbf5d3826e50af78409b32ec54e309825094a6 Mon Sep 17 00:00:00 2001 From: Gerd Aschemann Date: Wed, 29 Oct 2025 15:11:45 +0100 Subject: [PATCH 4/5] Add test coverage for .htm files and fix README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tests to verify both .html and .htm files are discovered when sourceDocuments is auto-populated from sourceDir. - Maven plugin: Test verifies 3 files (.htm, .html, nested .htm) - Gradle plugin: Test verifies same file discovery pattern - Both tests confirm recursive directory scanning works for .htm - Fix Maven README: Use correct element name - All tests pass with no regressions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../gradle/HtmlSanityCheckTaskSpec.groovy | 28 +++++++++++ htmlSanityCheck-maven-plugin/README.adoc | 2 +- .../maven/HtmlSanityCheckMojoTest.java | 49 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/htmlSanityCheck-gradle-plugin/src/test/groovy/org/aim42/htmlsanitycheck/gradle/HtmlSanityCheckTaskSpec.groovy b/htmlSanityCheck-gradle-plugin/src/test/groovy/org/aim42/htmlsanitycheck/gradle/HtmlSanityCheckTaskSpec.groovy index 82c569ec..84baa903 100644 --- a/htmlSanityCheck-gradle-plugin/src/test/groovy/org/aim42/htmlsanitycheck/gradle/HtmlSanityCheckTaskSpec.groovy +++ b/htmlSanityCheck-gradle-plugin/src/test/groovy/org/aim42/htmlsanitycheck/gradle/HtmlSanityCheckTaskSpec.groovy @@ -62,4 +62,32 @@ class HtmlSanityCheckTaskSpec extends HtmlSanityCheckBaseSpec { e.message.contains("Your build configuration included 'failOnErrors=true', and 1 error(s) were found on all checked pages.") } + def "should include .htm files when auto-populating sourceDocuments"() { + given: + // Create .htm file + def htmFile = new File(sourceDir, "document.htm") + htmFile << VALID_HTML + + // Create .html file + htmlFile << VALID_HTML + + // Create subdirectory with .htm file + def subDir = new File(sourceDir, "docs") + subDir.mkdirs() + def nestedHtmFile = new File(subDir, "nested.htm") + nestedHtmFile << VALID_HTML + + when: + task.setSourceDir(testProjectDir.root) + + then: + task.sourceDocuments != null + // Verify that sourceDocuments includes both .html and .htm files + def fileNames = task.sourceDocuments.files.collect { it.name } + fileNames.contains("test.html") + fileNames.contains("document.htm") + fileNames.contains("nested.htm") + task.sourceDocuments.files.size() == 3 + } + } \ No newline at end of file diff --git a/htmlSanityCheck-maven-plugin/README.adoc b/htmlSanityCheck-maven-plugin/README.adoc index db04d92e..058d3336 100644 --- a/htmlSanityCheck-maven-plugin/README.adoc +++ b/htmlSanityCheck-maven-plugin/README.adoc @@ -41,7 +41,7 @@ Use the following snippet inside a Maven build file: - src/file-to-test.html <2> + src/file-to-test.html <2> src <3> diff --git a/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java b/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java index 5423d4fa..3aff30d0 100644 --- a/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java +++ b/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java @@ -226,6 +226,55 @@ void executeWithOnlySourceDir_ShouldSucceed() throws IOException, MojoExecutionE deleteDirectory(resultDir.toFile()); } + @Test + void executeWithOnlySourceDir_ShouldIncludeHtmFiles() throws IOException, MojoExecutionException { + // Setup: Create temp directories + Path junitDir = Files.createTempDirectory("MojoJunit"); + Path resultDir = Files.createTempDirectory("MojoResult"); + Path sourceDir = Files.createTempDirectory("MojoSource"); + + // Create .htm file in root + File rootHtmFile = new File(sourceDir.toFile(), "document.htm"); + Files.write(rootHtmFile.toPath(), VALID_HTML.getBytes(StandardCharsets.UTF_8)); + + // Create .html file for comparison + File rootHtmlFile = new File(sourceDir.toFile(), "page.html"); + Files.write(rootHtmlFile.toPath(), VALID_HTML.getBytes(StandardCharsets.UTF_8)); + + // Create subdirectory with .htm file + File subDir = new File(sourceDir.toFile(), "docs"); + boolean mkdirSuccess = subDir.mkdirs(); + Assertions.assertThat(mkdirSuccess).isTrue(); + File nestedHtmFile = new File(subDir, "nested.htm"); + Files.write(nestedHtmFile.toPath(), VALID_HTML.getBytes(StandardCharsets.UTF_8)); + + // Create Mojo and set only sourceDir field + HtmlSanityCheckMojo mojo = new TestableHtmlSanityCheckMojo( + sourceDir.toFile(), + null, // sourceDocuments explicitly NOT set + resultDir.toFile(), + junitDir.toFile() + ); + + // Get the configuration to verify sourceDocuments includes .htm files + Configuration config = mojo.setupConfiguration(); + + // Verify that both .html and .htm files are discovered + Assertions.assertThat(config.getSourceDocuments()).isNotNull(); + Assertions.assertThat(config.getSourceDocuments()).hasSize(3); + Assertions.assertThat(config.getSourceDocuments()) + .extracting(File::getName) + .containsExactlyInAnyOrder("document.htm", "page.html", "nested.htm"); + + // Execute should succeed with both file types + mojo.execute(); + + // Clean up + deleteDirectory(sourceDir.toFile()); + deleteDirectory(junitDir.toFile()); + deleteDirectory(resultDir.toFile()); + } + /** * Helper class to allow setting private fields for testing */ From 2d1b66cce7e4ee67c0a5e70429a97ee44bfc471e Mon Sep 17 00:00:00 2001 From: Gerd Aschemann Date: Wed, 29 Oct 2025 15:46:02 +0100 Subject: [PATCH 5/5] #429 Add test coverage for Maven plugin Increases test count from 10 to 18 tests to improve SonarCloud coverage for HtmlSanityCheckMojo. - Add tests for HTTP status code overrides (success/error/warning) - Add tests for findHtmlFiles() edge cases (null, non-existent, empty) - Verify non-HTML files are properly ignored - Refactor setField() helper to shared static method --- .../maven/HtmlSanityCheckMojoTest.java | 168 ++++++++++++++++-- 1 file changed, 155 insertions(+), 13 deletions(-) diff --git a/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java b/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java index 3aff30d0..e2af2944 100644 --- a/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java +++ b/htmlSanityCheck-maven-plugin/src/test/java/org/aim42/htmlsanitycheck/maven/HtmlSanityCheckMojoTest.java @@ -36,6 +36,68 @@ void setupConfiguration() { Assertions.assertThat(config.getFailOnErrors()).isFalse(); } + @Test + void setupConfigurationWithHttpSuccessCodes() throws Exception { + // Create mojo with custom HTTP success codes + Set customSuccessCodes = new HashSet<>(); + customSuccessCodes.add(299); + + HtmlSanityCheckMojo mojo = new HtmlSanityCheckMojo(); + setField(mojo, "httpSuccessCodes", customSuccessCodes); + + Configuration config = mojo.setupConfiguration(); + + Assertions.assertThat(config).isNotNull(); + Assertions.assertThat(config.getHttpSuccessCodes()).contains(299); + } + + @Test + void setupConfigurationWithHttpErrorCodes() throws Exception { + // Create mojo with custom HTTP error codes + Set customErrorCodes = new HashSet<>(); + customErrorCodes.add(599); + + HtmlSanityCheckMojo mojo = new HtmlSanityCheckMojo(); + setField(mojo, "httpErrorCodes", customErrorCodes); + + Configuration config = mojo.setupConfiguration(); + + Assertions.assertThat(config).isNotNull(); + Assertions.assertThat(config.getHttpErrorCodes()).contains(599); + } + + @Test + void setupConfigurationWithHttpWarningCodes() throws Exception { + // Create mojo with custom HTTP warning codes + Set customWarningCodes = new HashSet<>(); + customWarningCodes.add(199); + + HtmlSanityCheckMojo mojo = new HtmlSanityCheckMojo(); + setField(mojo, "httpWarningCodes", customWarningCodes); + + Configuration config = mojo.setupConfiguration(); + + Assertions.assertThat(config).isNotNull(); + Assertions.assertThat(config.getHttpWarningCodes()).contains(199); + } + + @Test + void setupConfigurationWithEmptyHttpStatusCodesShouldNotOverride() throws Exception { + // Create mojo with empty HTTP status code sets (should not override defaults) + HtmlSanityCheckMojo mojo = new HtmlSanityCheckMojo(); + setField(mojo, "httpSuccessCodes", new HashSet()); + setField(mojo, "httpErrorCodes", new HashSet()); + setField(mojo, "httpWarningCodes", new HashSet()); + + Configuration config = mojo.setupConfiguration(); + + // Verify that default codes are still present (not overridden by empty sets) + Assertions.assertThat(config).isNotNull(); + Assertions.assertThat(config.getHttpSuccessCodes()).contains(200); // Default success code + Assertions.assertThat(config.getHttpErrorCodes()).contains(404); // Default error code + Assertions.assertThat(config.getHttpWarningCodes()).contains(301); // Default warning code (redirect) + } + @Test void logBuildParameter() { @@ -226,6 +288,83 @@ void executeWithOnlySourceDir_ShouldSucceed() throws IOException, MojoExecutionE deleteDirectory(resultDir.toFile()); } + @Test + void findHtmlFilesWithNullDirectory() throws Exception { + HtmlSanityCheckMojo mojo = new HtmlSanityCheckMojo(); + setField(mojo, "sourceDir", null); + setField(mojo, "sourceDocuments", null); + + Configuration config = mojo.setupConfiguration(); + + // When both sourceDir and sourceDocuments are null, the config should have null sourceDocuments + // (This will be caught by validation) + Assertions.assertThat(config.getSourceDocuments()).isNull(); + } + + @Test + void findHtmlFilesWithNonExistentDirectory() throws Exception { + Path nonExistentDir = java.nio.file.Paths.get("/tmp/this-directory-does-not-exist-" + System.currentTimeMillis()); + HtmlSanityCheckMojo mojo = new HtmlSanityCheckMojo(); + setField(mojo, "sourceDir", nonExistentDir.toFile()); + setField(mojo, "sourceDocuments", null); + + Configuration config = mojo.setupConfiguration(); + + // Should return empty set when directory doesn't exist + Assertions.assertThat(config.getSourceDocuments()).isEmpty(); + } + + @Test + void findHtmlFilesWithEmptyDirectory() throws Exception { + Path emptyDir = Files.createTempDirectory("MojoEmpty"); + + HtmlSanityCheckMojo mojo = new HtmlSanityCheckMojo(); + setField(mojo, "sourceDir", emptyDir.toFile()); + setField(mojo, "sourceDocuments", null); + + Configuration config = mojo.setupConfiguration(); + + // Should return empty set when directory is empty + Assertions.assertThat(config.getSourceDocuments()).isEmpty(); + + // Clean up + Files.deleteIfExists(emptyDir); + } + + @Test + void findHtmlFilesIgnoresNonHtmlFiles() throws Exception { + Path sourceDir = Files.createTempDirectory("MojoSource"); + + // Create various non-HTML files + File txtFile = new File(sourceDir.toFile(), "readme.txt"); + Files.write(txtFile.toPath(), "Text content".getBytes(StandardCharsets.UTF_8)); + + File pdfFile = new File(sourceDir.toFile(), "document.pdf"); + Files.write(pdfFile.toPath(), "PDF content".getBytes(StandardCharsets.UTF_8)); + + File xmlFile = new File(sourceDir.toFile(), "config.xml"); + Files.write(xmlFile.toPath(), "".getBytes(StandardCharsets.UTF_8)); + + // Create one HTML file + File htmlFile = new File(sourceDir.toFile(), "page.html"); + Files.write(htmlFile.toPath(), VALID_HTML.getBytes(StandardCharsets.UTF_8)); + + HtmlSanityCheckMojo mojo = new HtmlSanityCheckMojo(); + setField(mojo, "sourceDir", sourceDir.toFile()); + setField(mojo, "sourceDocuments", null); + + Configuration config = mojo.setupConfiguration(); + + // Should only find the HTML file + Assertions.assertThat(config.getSourceDocuments()).hasSize(1); + Assertions.assertThat(config.getSourceDocuments()) + .extracting(File::getName) + .containsExactly("page.html"); + + // Clean up + deleteDirectory(sourceDir.toFile()); + } + @Test void executeWithOnlySourceDir_ShouldIncludeHtmFiles() throws IOException, MojoExecutionException { // Setup: Create temp directories @@ -283,23 +422,16 @@ static class TestableHtmlSanityCheckMojo extends HtmlSanityCheckMojo { File checkingResultsDir, File junitResultsDir) { // Use reflection to set private fields try { - setField(this, "sourceDir", sourceDir); - setField(this, "sourceDocuments", sourceDocuments); - setField(this, "checkingResultsDir", checkingResultsDir); - setField(this, "junitResultsDir", junitResultsDir); - setField(this, "checkerClasses", AllCheckers.CHECKER_CLASSES); - setField(this, "excludes", new HashSet()); + HtmlSanityCheckMojoTest.setField(this, "sourceDir", sourceDir); + HtmlSanityCheckMojoTest.setField(this, "sourceDocuments", sourceDocuments); + HtmlSanityCheckMojoTest.setField(this, "checkingResultsDir", checkingResultsDir); + HtmlSanityCheckMojoTest.setField(this, "junitResultsDir", junitResultsDir); + HtmlSanityCheckMojoTest.setField(this, "checkerClasses", AllCheckers.CHECKER_CLASSES); + HtmlSanityCheckMojoTest.setField(this, "excludes", new HashSet()); } catch (Exception e) { throw new RuntimeException("Failed to set fields", e); } } - - private void setField(Object target, String fieldName, Object value) - throws NoSuchFieldException, IllegalAccessException { - java.lang.reflect.Field field = HtmlSanityCheckMojo.class.getDeclaredField(fieldName); - field.setAccessible(true); - field.set(target, value); - } } @@ -315,5 +447,15 @@ void deleteDirectory(File directoryToBeDeleted) throws IOException { Files.deleteIfExists(directoryToBeDeleted.toPath()); } + /** + * Helper method to set private fields on HtmlSanityCheckMojo for testing + */ + private static void setField(Object target, String fieldName, Object value) + throws NoSuchFieldException, IllegalAccessException { + java.lang.reflect.Field field = HtmlSanityCheckMojo.class.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(target, value); + } + }