View Javadoc
1   /*
2    * SPDX-License-Identifier: Apache-2.0
3    * See LICENSE file for details.
4    *
5    * Copyright 2025-2026 Hazendaz
6    * Copyright 2011-2025 Acegi Technology Pty Limited.
7    */
8   package au.com.acegi.xmlformat;
9   
10  import static au.com.acegi.xmlformat.TestUtil.fileToString;
11  import static au.com.acegi.xmlformat.TestUtil.stringToFile;
12  import static org.hamcrest.CoreMatchers.is;
13  import static org.hamcrest.CoreMatchers.not;
14  import static org.hamcrest.MatcherAssert.assertThat;
15  import static org.junit.jupiter.api.Assertions.fail;
16  import static org.mockito.ArgumentMatchers.any;
17  import static org.mockito.ArgumentMatchers.anyString;
18  import static org.mockito.Mockito.atLeastOnce;
19  import static org.mockito.Mockito.mock;
20  import static org.mockito.Mockito.never;
21  import static org.mockito.Mockito.verify;
22  import static org.mockito.Mockito.when;
23  
24  import java.io.File;
25  import java.io.IOException;
26  
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugin.MojoFailureException;
29  import org.apache.maven.plugin.logging.Log;
30  import org.junit.jupiter.api.Assertions;
31  import org.junit.jupiter.api.BeforeEach;
32  import org.junit.jupiter.api.Test;
33  import org.junit.jupiter.api.io.TempDir;
34  
35  /**
36   * Tests {@link XmlFormatPlugin}.
37   */
38  public class XmlFormatPluginTest {
39  
40      private static final String EMPTY_FILE_NAME = "empty.xml";
41      private static final String EMPTY_TXT = "";
42      private static final String ERR_FILE_NAME = "error.xml";
43      private static final String ERR_TXT = "<xml> <hello> hello not closed! </xml>";
44      private static final String NO_CHG_TXT = "<xml> <leave-me-alone/> </xml>";
45      private static final String TO_CHG_TXT = "<xml> <hello/> </xml>";
46      private static final String INCLUDE_ALL_XML = "**/*.xml";
47  
48      @TempDir
49      private File tmp;
50      private File error;
51      @SuppressWarnings("PMD.ProperLogger")
52      private Log log;
53      private File noChange;
54      private File proj;
55      private File target;
56      private File toChange;
57  
58      @BeforeEach
59      void before() throws IOException {
60          proj = newFolder(tmp, "junit");
61          target = proj.toPath().resolve("target").toFile();
62          assertThat(target.mkdir(), is(true));
63  
64          toChange = proj.toPath().resolve("my.xml").toFile();
65          stringToFile(TO_CHG_TXT, toChange);
66  
67          noChange = target.toPath().resolve("exclude-me.xml").toFile();
68          stringToFile(NO_CHG_TXT, noChange);
69  
70          final File empty = proj.toPath().resolve(EMPTY_FILE_NAME).toFile();
71          stringToFile(EMPTY_TXT, empty);
72  
73          error = proj.toPath().resolve(ERR_FILE_NAME).toFile();
74          stringToFile(ERR_TXT, error);
75  
76          assertThat(fileToString(toChange), is(TO_CHG_TXT));
77          assertThat(fileToString(noChange), is(NO_CHG_TXT));
78          assertThat(fileToString(empty), is(EMPTY_TXT));
79          assertThat(fileToString(error), is(ERR_TXT));
80  
81          log = mock(Log.class);
82      }
83  
84      @Test
85      void pluginExcludesError() throws MojoExecutionException, MojoFailureException {
86          final XmlFormatPlugin plugin = new XmlFormatPlugin();
87          plugin.setLog(log);
88          when(log.isDebugEnabled()).thenReturn(true);
89          when(log.isErrorEnabled()).thenReturn(true);
90  
91          plugin.setBaseDirectory(proj);
92          plugin.setExcludes("**/" + ERR_FILE_NAME);
93          plugin.setIncludes(INCLUDE_ALL_XML);
94          plugin.setTargetDirectory(target);
95  
96          plugin.execute();
97  
98          verify(log, never()).isErrorEnabled();
99          verify(log, atLeastOnce()).isDebugEnabled();
100         verify(log, atLeastOnce()).debug(anyString());
101 
102         assertThat(fileToString(toChange), not(TO_CHG_TXT));
103         assertThat(fileToString(noChange), is(NO_CHG_TXT));
104         assertThat(fileToString(error), is(ERR_TXT));
105     }
106 
107     @Test
108     @SuppressWarnings("PMD.JUnitUseExpected")
109     void pluginReportsError() throws MojoExecutionException {
110         final XmlFormatPlugin plugin = new XmlFormatPlugin();
111         plugin.setLog(log);
112         when(log.isDebugEnabled()).thenReturn(false);
113         when(log.isErrorEnabled()).thenReturn(true);
114 
115         plugin.setBaseDirectory(proj);
116         plugin.setExcludes("");
117         plugin.setIncludes(INCLUDE_ALL_XML);
118         plugin.setTargetDirectory(target);
119 
120         Assertions.assertThrows(MojoFailureException.class, () -> {
121             plugin.execute();
122             fail("Should have raised exception when handling error");
123         });
124 
125         verify(log, atLeastOnce()).error(anyString(), any(Throwable.class));
126         verify(log, atLeastOnce()).isDebugEnabled();
127         verify(log, never()).debug(anyString());
128 
129         assertThat(fileToString(toChange), not(TO_CHG_TXT));
130         assertThat(fileToString(noChange), is(NO_CHG_TXT));
131         assertThat(fileToString(error), is(ERR_TXT));
132     }
133 
134     @Test
135     @SuppressWarnings("PMD.JUnitUseExpected")
136     void pluginSkipTargetFolder() throws MojoExecutionException, MojoFailureException {
137         final XmlFormatPlugin plugin = new XmlFormatPlugin();
138         plugin.setLog(log);
139 
140         plugin.setSkipTargetFolder(false);
141         when(log.isDebugEnabled()).thenReturn(true);
142         when(log.isErrorEnabled()).thenReturn(true);
143 
144         plugin.setBaseDirectory(proj);
145         plugin.setExcludes("**/" + ERR_FILE_NAME);
146         plugin.setIncludes(INCLUDE_ALL_XML);
147         plugin.setTargetDirectory(target);
148 
149         plugin.execute();
150 
151         assertThat(fileToString(toChange), not(TO_CHG_TXT));
152         assertThat(fileToString(noChange), not(NO_CHG_TXT));
153         assertThat(fileToString(error), is(ERR_TXT));
154     }
155 
156     @Test
157     void pluginSkip() throws MojoExecutionException, MojoFailureException {
158         final XmlFormatPlugin plugin = new XmlFormatPlugin();
159         plugin.setLog(log);
160         plugin.setSkip(true);
161         when(log.isDebugEnabled()).thenReturn(true);
162         when(log.isInfoEnabled()).thenReturn(true);
163         when(log.isErrorEnabled()).thenReturn(true);
164 
165         plugin.setBaseDirectory(proj);
166         plugin.setExcludes("**/" + ERR_FILE_NAME);
167         plugin.setIncludes(INCLUDE_ALL_XML);
168         plugin.setTargetDirectory(target);
169 
170         plugin.execute();
171 
172         verify(log, atLeastOnce()).info("[xml-format] Skipped");
173 
174         assertThat(fileToString(toChange), is(TO_CHG_TXT));
175     }
176 
177     private static File newFolder(final File root, final String... subDirs) throws IOException {
178         final String subFolder = String.join("/", subDirs);
179         final File result = root.toPath().resolve(subFolder).toFile();
180         if (!result.mkdirs()) {
181             throw new IOException("Couldn't create folders " + root);
182         }
183         return result;
184     }
185 }