View Javadoc
1   /*
2    * SPDX-License-Identifier: Apache-2.0
3    * See LICENSE file for details.
4    *
5    * Copyright 2018-2026 Hazendaz
6    * Copyright 2011-2018 tunyk
7    */
8   package com.tunyk.mvn.plugins.htmlcompressor;
9   
10  import java.nio.charset.StandardCharsets;
11  import java.nio.file.Files;
12  import java.nio.file.Path;
13  
14  import org.junit.jupiter.api.AfterAll;
15  import org.junit.jupiter.api.Assertions;
16  import org.junit.jupiter.api.BeforeAll;
17  import org.junit.jupiter.api.BeforeEach;
18  import org.junit.jupiter.api.Test;
19  import org.junit.jupiter.api.io.TempDir;
20  import org.slf4j.Logger;
21  import org.slf4j.LoggerFactory;
22  
23  /**
24   * The Class HtmlCompressorTest.
25   */
26  class HtmlCompressorTest {
27  
28      /** The Constant LOG. */
29      private static final Logger LOG = LoggerFactory.getLogger(HtmlCompressorTest.class);
30  
31      /**
32       * Sets the up class.
33       */
34      @BeforeAll
35      static void setUpClass() {
36          LOG.info("Setting up class...");
37      }
38  
39      /**
40       * Tear down class.
41       */
42      @AfterAll
43      static void tearDownClass() {
44          LOG.info("Test finished.");
45      }
46  
47      /**
48       * Sets the up.
49       */
50      @BeforeEach
51      void setUp() {
52          LOG.info("Setting up data for testing...");
53      }
54  
55      /**
56       * Test compress with default settings produces output files.
57       *
58       * @throws Exception
59       *             the exception
60       */
61      @Test
62      void testCompress() throws Exception {
63          LOG.info("Testing compress method...");
64  
65          HtmlCompressor htmlCompressor = new HtmlCompressor("src/test/resources/html", "target/test/htmlcompressor/0");
66          htmlCompressor.compress();
67  
68          // Verify output files were created
69          Assertions.assertTrue(Files.exists(Path.of("target/test/htmlcompressor/0/templates/Template1.html")),
70                  "Template1.html should be created in output");
71          Assertions.assertTrue(Files.exists(Path.of("target/test/htmlcompressor/0/templates/Template2.html")),
72                  "Template2.html should be created in output");
73          Assertions.assertTrue(Files.exists(Path.of("target/test/htmlcompressor/0/templates/recursive/Template.html")),
74                  "Recursive Template.html should be created in output");
75  
76          // Verify content is compressed (comments removed by default)
77          String compressed = Files.readString(Path.of("target/test/htmlcompressor/0/templates/Template1.html"));
78          Assertions.assertFalse(compressed.contains("<!--"), "Compressed output should not contain HTML comments");
79          Assertions.assertTrue(compressed.contains("template #1"),
80                  "Compressed output should still contain main content");
81  
82          htmlCompressor = new HtmlCompressor("src/test/resources/html", "target/test/htmlcompressor/1", true,
83                  "target/test/htmlcompressor/1/integration.js", "src/test/resources/html/integration.js");
84          htmlCompressor.compress();
85  
86          // Verify JSON sprite file was created
87          Assertions.assertTrue(Files.exists(Path.of("target/test/htmlcompressor/1/integration.js")),
88                  "JSON integration file should be created");
89          String jsonContent = Files.readString(Path.of("target/test/htmlcompressor/1/integration.js"));
90          Assertions.assertTrue(jsonContent.contains("template"), "Integration JS should contain template references");
91  
92          htmlCompressor = new HtmlCompressor("src/test/resources/html", "target/test/htmlcompressor/2");
93          com.googlecode.htmlcompressor.compressor.HtmlCompressor htmlCompressorHandler = new com.googlecode.htmlcompressor.compressor.HtmlCompressor();
94          htmlCompressorHandler.setEnabled(false);
95          htmlCompressor.setHtmlCompressor(htmlCompressorHandler);
96          htmlCompressor.compress();
97  
98          // When compressor is disabled, output should match input (content not compressed)
99          String disabledOutput = Files.readString(Path.of("target/test/htmlcompressor/2/templates/Template1.html"));
100         Assertions.assertTrue(disabledOutput.contains("<!--"),
101                 "Output with disabled compressor should retain HTML comments");
102 
103         LOG.info("Passed");
104     }
105 
106     /**
107      * Test compress reduces file size compared to input.
108      *
109      * @param tempDir
110      *            the temp dir provided by JUnit
111      *
112      * @throws Exception
113      *             the exception
114      */
115     @Test
116     void testCompressReducesFileSize(@TempDir Path tempDir) throws Exception {
117         LOG.info("Testing that compress reduces file size...");
118 
119         HtmlCompressor htmlCompressor = new HtmlCompressor("src/test/resources/html", tempDir.toString());
120         htmlCompressor.compress();
121 
122         Path originalTemplate = Path.of("src/test/resources/html/templates/Template1.html");
123         Path compressedTemplate = tempDir.resolve("templates/Template1.html");
124 
125         long originalSize = Files.size(originalTemplate);
126         long compressedSize = Files.size(compressedTemplate);
127 
128         Assertions.assertTrue(compressedSize < originalSize,
129                 "Compressed file should be smaller than the original (original: " + originalSize + "B, compressed: "
130                         + compressedSize + "B)");
131 
132         LOG.info("Passed");
133     }
134 
135     /**
136      * Test compress with custom file extensions processes only specified types.
137      *
138      * @param tempDir
139      *            the temp dir provided by JUnit
140      *
141      * @throws Exception
142      *             the exception
143      */
144     @Test
145     void testCompressWithCustomFileExtensions(@TempDir Path tempDir) throws Exception {
146         LOG.info("Testing compress with custom file extensions...");
147 
148         // Create a test directory with mixed file types
149         Path srcDir = tempDir.resolve("src");
150         Files.createDirectories(srcDir);
151         Files.writeString(srcDir.resolve("page.html"), "<html><!-- comment --><body>Hello</body></html>");
152         Files.writeString(srcDir.resolve("page.htm"), "<html><!-- comment --><body>World</body></html>");
153         Files.writeString(srcDir.resolve("page.txt"), "this is text");
154 
155         Path targetDir = tempDir.resolve("target");
156         HtmlCompressor htmlCompressor = new HtmlCompressor(srcDir.toString(), targetDir.toString());
157         htmlCompressor.setFileExtensions(new String[] { "html" });
158         htmlCompressor.compress();
159 
160         // Only the .html file should be processed
161         Assertions.assertTrue(Files.exists(targetDir.resolve("page.html")), "HTML file should be in output");
162         Assertions.assertFalse(Files.exists(targetDir.resolve("page.htm")),
163                 "HTM file should not be in output with 'html'-only filter");
164         Assertions.assertFalse(Files.exists(targetDir.resolve("page.txt")), "TXT file should not be in output");
165 
166         LOG.info("Passed");
167     }
168 
169     /**
170      * Test compress with JSON file creation produces correct integration file.
171      *
172      * @param tempDir
173      *            the temp dir provided by JUnit
174      *
175      * @throws Exception
176      *             the exception
177      */
178     @Test
179     void testCompressWithJsonFileCreation(@TempDir Path tempDir) throws Exception {
180         LOG.info("Testing compress with JSON file creation...");
181 
182         Path targetDir = tempDir.resolve("output");
183         Path targetJsonFile = targetDir.resolve("sprite.js");
184 
185         HtmlCompressor htmlCompressor = new HtmlCompressor("src/test/resources/html", targetDir.toString(), true,
186                 targetJsonFile.toString(), "src/test/resources/html/integration.js");
187         htmlCompressor.compress();
188 
189         Assertions.assertTrue(Files.exists(targetJsonFile), "Integration JS file should be created");
190         String content = Files.readString(targetJsonFile);
191         // The integration.js template contains "htmlTemplates" and "%s" gets replaced
192         Assertions.assertTrue(content.contains("htmlTemplates"), "Integration file should use template structure");
193         // Verify it contains references to the compressed templates
194         Assertions.assertTrue(content.contains("Template1.html") || content.contains("template"),
195                 "Integration file should reference compressed templates");
196 
197         LOG.info("Passed");
198     }
199 
200     /**
201      * Test HtmlCompressor getters and setters.
202      */
203     @Test
204     void testHtmlCompressorGettersSetters() {
205         LOG.info("Testing HtmlCompressor getters and setters...");
206 
207         HtmlCompressor htmlCompressor = new HtmlCompressor("src/test/resources/html", "target/test");
208 
209         // Test srcDirPath getter/setter
210         Assertions.assertEquals("src/test/resources/html", htmlCompressor.getSrcDirPath());
211         htmlCompressor.setSrcDirPath("src/main/resources");
212         Assertions.assertEquals("src/main/resources", htmlCompressor.getSrcDirPath());
213 
214         // Test targetDirPath getter/setter
215         Assertions.assertEquals("target/test", htmlCompressor.getTargetDirPath());
216         htmlCompressor.setTargetDirPath("target/other");
217         Assertions.assertEquals("target/other", htmlCompressor.getTargetDirPath());
218 
219         // Test createJsonFile getter/setter
220         Assertions.assertFalse(htmlCompressor.isCreateJsonFile());
221         htmlCompressor.setCreateJsonFile(true);
222         Assertions.assertTrue(htmlCompressor.isCreateJsonFile());
223 
224         // Test targetJsonFilePath getter/setter
225         htmlCompressor.setTargetJsonFilePath("target/sprite.js");
226         Assertions.assertEquals("target/sprite.js", htmlCompressor.getTargetJsonFilePath());
227 
228         // Test jsonIntegrationFilePath getter/setter
229         htmlCompressor.setJsonIntegrationFilePath("src/integration.js");
230         Assertions.assertEquals("src/integration.js", htmlCompressor.getJsonIntegrationFilePath());
231 
232         // Test fileEncoding getter/setter
233         htmlCompressor.setFileEncoding(StandardCharsets.UTF_8);
234         Assertions.assertEquals(StandardCharsets.UTF_8, htmlCompressor.getFileEncoding());
235 
236         // Test fileExtensions getter/setter
237         htmlCompressor.setFileExtensions(new String[] { "html", "htm" });
238         Assertions.assertArrayEquals(new String[] { "html", "htm" }, htmlCompressor.getFileExtensions());
239 
240         // Test htmlCompressor handler getter/setter
241         com.googlecode.htmlcompressor.compressor.HtmlCompressor handler = new com.googlecode.htmlcompressor.compressor.HtmlCompressor();
242         htmlCompressor.setHtmlCompressor(handler);
243         Assertions.assertSame(handler, htmlCompressor.getHtmlCompressor());
244 
245         LOG.info("Passed");
246     }
247 
248     /**
249      * Test second constructor initializes all JSON-related fields.
250      */
251     @Test
252     void testSecondConstructorInitializesJsonFields() {
253         LOG.info("Testing HtmlCompressor second constructor...");
254 
255         HtmlCompressor htmlCompressor = new HtmlCompressor("src", "target", true, "target/sprite.js",
256                 "src/integration.js");
257 
258         Assertions.assertEquals("src", htmlCompressor.getSrcDirPath());
259         Assertions.assertEquals("target", htmlCompressor.getTargetDirPath());
260         Assertions.assertTrue(htmlCompressor.isCreateJsonFile());
261         Assertions.assertEquals("target/sprite.js", htmlCompressor.getTargetJsonFilePath());
262         Assertions.assertEquals("src/integration.js", htmlCompressor.getJsonIntegrationFilePath());
263 
264         LOG.info("Passed");
265     }
266 }