View Javadoc
1   /*
2    * XML Format Maven Plugin (https://github.com/acegi/xml-format-maven-plugin)
3    *
4    * Copyright 2011-2025 Acegi Technology Pty Limited.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package au.com.acegi.xmlformat;
19  
20  import static java.nio.charset.StandardCharsets.UTF_8;
21  
22  import static au.com.acegi.xmlformat.FormatUtil.format;
23  import static au.com.acegi.xmlformat.FormatUtil.formatInPlace;
24  import static au.com.acegi.xmlformat.TestUtil.getResource;
25  import static au.com.acegi.xmlformat.TestUtil.streamToString;
26  import static au.com.acegi.xmlformat.TestUtil.stringToFile;
27  import static org.hamcrest.CoreMatchers.is;
28  import static org.hamcrest.MatcherAssert.assertThat;
29  import static org.junit.jupiter.api.Assertions.assertThrows;
30  
31  import java.io.ByteArrayOutputStream;
32  import java.io.File;
33  import java.io.IOException;
34  import java.io.InputStream;
35  
36  import org.dom4j.DocumentException;
37  import org.junit.jupiter.api.Test;
38  import org.junit.jupiter.api.io.TempDir;
39  
40  /** Tests {@link FormatUtil}. */
41  public class FormatUtilTest {
42  
43      private static final String FORMATTED_XML = "<xml><hello/></xml>";
44      private static final String UNFORMATTED_XML = "<xml>   <hello/> </xml>";
45  
46      @TempDir
47      private File tmp;
48  
49      @Test
50      void formattedWillNotChange() throws DocumentException, IOException {
51          inPlaceChange(FORMATTED_XML, false);
52      }
53  
54      @Test
55      void test1() throws DocumentException, IOException {
56          final XmlOutputFormat fmt = new XmlOutputFormat();
57          fmt.setIndentSize(4);
58          fmt.setNewLineAfterDeclaration(false);
59          fmt.setPadText(false);
60          testInOut(1, fmt);
61      }
62  
63      @Test
64      void test1KeepBlankLines() throws DocumentException, IOException {
65          final XmlOutputFormat fmt = new XmlOutputFormat();
66          fmt.setIndentSize(4);
67          fmt.setNewLineAfterDeclaration(false);
68          fmt.setPadText(false);
69          fmt.setKeepBlankLines(true);
70          testInOut(1, fmt);
71      }
72  
73      @Test
74      void test2() throws DocumentException, IOException {
75          final XmlOutputFormat fmt = new XmlOutputFormat();
76          fmt.setIndentSize(2);
77          fmt.setNewLineAfterDeclaration(false);
78          fmt.setPadText(false);
79          testInOut(2, fmt);
80      }
81  
82      @Test
83      void test2KeepBlankLines() throws DocumentException, IOException {
84          final XmlOutputFormat fmt = new XmlOutputFormat();
85          fmt.setIndentSize(2);
86          fmt.setNewLineAfterDeclaration(false);
87          fmt.setPadText(false);
88          fmt.setKeepBlankLines(true);
89          testInOut(2, fmt);
90      }
91  
92      @Test
93      void test3() throws DocumentException, IOException {
94          final XmlOutputFormat fmt = new XmlOutputFormat();
95          fmt.setIndentSize(2);
96          fmt.setNewLineAfterDeclaration(false);
97          fmt.setPadText(false);
98          testInOut(3, fmt);
99      }
100 
101     @Test
102     void test4() throws DocumentException, IOException {
103         final XmlOutputFormat fmt = new XmlOutputFormat();
104         fmt.setIndent("\t");
105         fmt.setNewLineAfterDeclaration(false);
106         fmt.setPadText(false);
107         testInOut(4, fmt);
108     }
109 
110     @Test
111     void test4KeepBlankLines() throws DocumentException, IOException {
112         final XmlOutputFormat fmt = new XmlOutputFormat();
113         fmt.setIndent("\t");
114         fmt.setNewLineAfterDeclaration(false);
115         fmt.setPadText(false);
116         fmt.setKeepBlankLines(true);
117         testInOut(4, fmt);
118     }
119 
120     @Test
121     void test5() throws DocumentException, IOException {
122         final XmlOutputFormat fmt = new XmlOutputFormat();
123         fmt.setIndent("    ");
124         fmt.setNewLineAfterDeclaration(false);
125         fmt.setPadText(false);
126         fmt.setTrimText(true);
127         testInOut(5, fmt);
128     }
129 
130     /**
131      * New lines between the XML declaration and the root elements are ignored at the parse level it seems, they don't
132      * reach the XMLWriter. Not ideal, but believe we can leave with this exception
133      */
134     @Test
135     void test5KeepBlankLines() throws DocumentException, IOException {
136         final XmlOutputFormat fmt = new XmlOutputFormat();
137         fmt.setIndent("    ");
138         // Set to true to keep the new line given keep blank lines will not
139         fmt.setNewLineAfterDeclaration(true);
140         fmt.setPadText(false);
141         fmt.setTrimText(true);
142         fmt.setKeepBlankLines(true);
143         testInOut(5, fmt);
144     }
145 
146     /**
147      * New lines between the XML declaration and the root elements are ignored at the parse level it seems, they don't
148      * reach the XMLWriter. Not ideal, but believe we can leave with this exception
149      */
150     @Test
151     void test6() throws DocumentException, IOException {
152         final XmlOutputFormat fmt = new XmlOutputFormat();
153         fmt.setIndent("    ");
154         // Set to true to keep the new line given keep blank lines will not
155         fmt.setNewLineAfterDeclaration(true);
156         fmt.setPadText(false);
157         fmt.setTrimText(true);
158         fmt.setKeepBlankLines(true);
159         testInOut(6, fmt);
160     }
161 
162     @Test
163     void testInvalid() throws DocumentException, IOException {
164         assertThrows(DocumentException.class, () -> {
165             try (InputStream in = getResource("/invalid.xml")) {
166                 final ByteArrayOutputStream out = new ByteArrayOutputStream();
167                 format(in, out, new XmlOutputFormat());
168             }
169         });
170     }
171 
172     @Test
173     void unformattedWillChange() throws DocumentException, IOException {
174         inPlaceChange(UNFORMATTED_XML, true);
175     }
176 
177     private void inPlaceChange(final String txt, final boolean shouldChange) throws DocumentException, IOException {
178         final File file = File.createTempFile("junit", null, tmp);
179         stringToFile(txt, file);
180 
181         final XmlOutputFormat fmt = new XmlOutputFormat();
182         fmt.setSuppressDeclaration(true);
183         fmt.setIndent("");
184         fmt.setNewlines(false);
185 
186         final boolean written = formatInPlace(file, fmt);
187         assertThat(written, is(shouldChange));
188     }
189 
190     private void testInOut(final int id, final XmlOutputFormat fmt) throws DocumentException, IOException {
191         try (InputStream in = getResource("/test" + id + "-in.xml")) {
192             final ByteArrayOutputStream out = new ByteArrayOutputStream();
193             format(in, out, fmt);
194 
195             final String received = new String(out.toByteArray(), UTF_8);
196             final String expected = streamToString(getResource(getOutputFileName(id, fmt)));
197             assertThat(received, is(expected));
198         }
199     }
200 
201     private String getOutputFileName(final int id, final XmlOutputFormat fmt) {
202         if (fmt.isKeepBlankLines()) {
203             return "/test" + id + "-out-kbl.xml";
204         }
205         return "/test" + id + "-out.xml";
206     }
207 }