1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle;
21
22 import static com.google.common.truth.Truth.assertThat;
23 import static com.google.common.truth.Truth.assertWithMessage;
24
25 import java.io.ByteArrayOutputStream;
26 import java.io.File;
27 import java.nio.charset.StandardCharsets;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.function.BiPredicate;
33
34 import javax.xml.parsers.ParserConfigurationException;
35
36 import org.w3c.dom.Document;
37 import org.w3c.dom.NamedNodeMap;
38 import org.w3c.dom.Node;
39
40 import com.puppycrawl.tools.checkstyle.bdd.InlineConfigParser;
41 import com.puppycrawl.tools.checkstyle.bdd.TestInputConfiguration;
42 import com.puppycrawl.tools.checkstyle.internal.utils.XmlUtil;
43
44 public abstract class AbstractXmlTestSupport extends AbstractModuleTestSupport {
45
46
47
48
49
50
51
52
53 protected static Document getOutputStreamXml(ByteArrayOutputStream outputStream)
54 throws ParserConfigurationException {
55 final String xml = outputStream.toString(StandardCharsets.UTF_8);
56
57 return XmlUtil.getRawXml("audit output", xml, xml);
58 }
59
60
61
62
63
64
65
66
67
68
69 protected static void verifyXml(String expectedOutputFile,
70 ByteArrayOutputStream actualOutputStream, String... messages) throws Exception {
71 verifyXml(expectedOutputFile, actualOutputStream, null, messages);
72 }
73
74
75
76
77
78
79
80
81
82
83
84 protected static void verifyXml(String expectedOutputFile,
85 ByteArrayOutputStream actualOutputStream,
86 BiPredicate<Node, Node> ordered, String... messages) throws Exception {
87 String expectedContents = readFile(expectedOutputFile);
88
89 for (int i = 0; i < messages.length; i++) {
90 expectedContents = expectedContents.replace("$" + i, messages[i]);
91 }
92
93 final Document expectedDocument = XmlUtil.getRawXml("audit output", expectedContents,
94 expectedContents);
95 final Document actualDocument = getOutputStreamXml(actualOutputStream);
96
97 assertWithMessage("xml encoding should be the same")
98 .that(actualDocument.getXmlEncoding())
99 .isEqualTo(expectedDocument.getXmlEncoding());
100
101 assertWithMessage("xml version should be the same")
102 .that(actualDocument.getXmlVersion())
103 .isEqualTo(expectedDocument.getXmlVersion());
104
105 verifyXmlNode(expectedDocument, actualDocument, "/", ordered);
106 }
107
108
109
110
111
112
113
114
115
116 private static void verifyXmlNodes(Node expected, Node actual, String path,
117 BiPredicate<Node, Node> ordered) {
118 final Node expectedFirstChild = expected.getFirstChild();
119 final Node actualFirstChild = actual.getFirstChild();
120
121 if (expectedFirstChild == null) {
122 assertWithMessage("no children nodes should exist: %s", path)
123 .that(actualFirstChild)
124 .isNull();
125 assertWithMessage("text should be the same: %s", path)
126 .that(actual.getNodeValue())
127 .isEqualTo(expected.getNodeValue());
128 }
129 else {
130 assertWithMessage("children nodes should exist: %s", path)
131 .that(actualFirstChild)
132 .isNotNull();
133
134 if (ordered == null) {
135 Node actualChild = actualFirstChild;
136
137 for (Node expectedChild = expectedFirstChild; expectedChild != null;
138 expectedChild = expectedChild.getNextSibling()) {
139 verifyXmlNode(expectedChild, actualChild, path, ordered);
140
141 actualChild = actualChild.getNextSibling();
142 }
143
144 assertWithMessage("node have same number of children: %s", path)
145 .that(actualChild)
146 .isNull();
147 }
148 else {
149 final Set<Node> expectedChildren = XmlUtil.getChildrenElements(expected);
150 final Set<Node> actualChildren = XmlUtil.getChildrenElements(actual);
151
152 assertWithMessage("node have same number of children: %s", path)
153 .that(actualChildren)
154 .hasSize(expectedChildren.size());
155
156 for (Node expectedChild : expectedChildren) {
157 Node foundChild = null;
158
159 for (Node actualChild : actualChildren) {
160 if (ordered.test(expectedChild, actualChild)) {
161 foundChild = actualChild;
162 break;
163 }
164 }
165
166 assertWithMessage("node should exist: %s%s/", path, expectedChild.getNodeName())
167 .that(foundChild)
168 .isNotNull();
169
170 verifyXmlNode(expectedChild, foundChild, path, ordered);
171 }
172 }
173 }
174 }
175
176
177
178
179
180
181
182
183
184
185 private static void verifyXmlNode(Node expected, Node actual, String path,
186 BiPredicate<Node, Node> ordered) {
187 if (expected == null) {
188 if (actual != null) {
189 assertWithMessage("no node should exist: %s%s/", path, actual.getNodeName())
190 .fail();
191 }
192 }
193 else {
194 final String newPath = path + expected.getNodeName() + "/";
195
196 assertWithMessage("node should exist: %s", newPath)
197 .that(actual)
198 .isNotNull();
199 assertWithMessage("node should have same name: %s", newPath)
200 .that(actual.getNodeName())
201 .isEqualTo(expected.getNodeName());
202 assertWithMessage("node should have same type: %s", newPath)
203 .that(actual.getNodeType())
204 .isEqualTo(expected.getNodeType());
205
206 verifyXmlAttributes(expected.getAttributes(), actual.getAttributes(), newPath);
207
208 verifyXmlNodes(expected, actual, newPath, ordered);
209 }
210 }
211
212
213
214
215
216
217
218
219
220 private static void verifyXmlAttributes(NamedNodeMap expected, NamedNodeMap actual,
221 String path) {
222 if (expected == null) {
223 assertWithMessage("no attributes should exist: %s", path)
224 .that(actual)
225 .isNull();
226 }
227 else {
228 assertWithMessage("attributes should exist: %s", path)
229 .that(actual)
230 .isNotNull();
231
232 for (int i = 0; i < expected.getLength(); i++) {
233 verifyXmlAttribute(expected.item(i), actual.item(i), path);
234 }
235
236 assertThat(actual.getLength())
237 .isEqualTo(expected.getLength());
238 assertWithMessage("node have same number of attributes: %s", path)
239 .that(actual.getLength())
240 .isEqualTo(expected.getLength());
241 }
242 }
243
244
245
246
247
248
249
250
251
252 private static void verifyXmlAttribute(Node expected, Node actual, String path) {
253 final String expectedName = expected.getNodeName();
254
255 assertWithMessage("attribute value for '%s' should not be null: %s", expectedName, path)
256 .that(actual)
257 .isNotNull();
258
259 assertWithMessage("attribute name should match: %s", path)
260 .that(actual.getNodeName())
261 .isEqualTo(expectedName);
262
263
264 if (!"/#document/checkstyle".equals(path) && !"version".equals(expectedName)) {
265 assertWithMessage("attribute value for '%s' should match: %s", expectedName, path)
266 .that(actual.getNodeValue())
267 .isEqualTo(expected.getNodeValue());
268 }
269 }
270
271
272
273
274
275
276
277
278 protected final void verifyWithInlineConfigParserAndXmlLogger(
279 String filePath, String expectedXmlReportPath) throws Exception {
280 final String configFilePath = getPath(filePath);
281 final TestInputConfiguration testInputConfiguration =
282 InlineConfigParser.parse(configFilePath);
283 final DefaultConfiguration parsedConfig = testInputConfiguration.createConfiguration();
284 final String basePath = new File(getPath("")).getAbsolutePath();
285
286 final Checker checker = createChecker(parsedConfig);
287 checker.setBasedir(basePath);
288
289 final ByteArrayOutputStream actualXmlOutput = new ByteArrayOutputStream();
290 final XMLLogger logger = new XMLLogger(actualXmlOutput,
291 AbstractAutomaticBean.OutputStreamOptions.CLOSE);
292 checker.addListener(logger);
293 final List<File> filesToCheck = Collections.singletonList(new File(configFilePath));
294 checker.process(filesToCheck);
295
296 verifyXml(getPath(expectedXmlReportPath), actualXmlOutput);
297 }
298
299
300
301
302
303
304
305
306
307
308
309 protected final void verifyWithInlineConfigParserAndXmlLogger(
310 String inputFileWithConfig, String expectedXmlReportPath,
311 List<String> targetFilePaths) throws Exception {
312 final String configFilePath = getPath(inputFileWithConfig);
313 final TestInputConfiguration testInputConfiguration =
314 InlineConfigParser.parse(configFilePath);
315 final DefaultConfiguration parsedConfig = testInputConfiguration.createConfiguration();
316 final String basePath = new File(getPath("")).getAbsolutePath();
317 final Checker checker = createChecker(parsedConfig);
318 checker.setBasedir(basePath);
319 final ByteArrayOutputStream actualXmlOutput = new ByteArrayOutputStream();
320 final XMLLogger logger = new XMLLogger(actualXmlOutput,
321 AbstractAutomaticBean.OutputStreamOptions.CLOSE);
322 checker.addListener(logger);
323
324 final List<File> filesToCheck = new ArrayList<>();
325 for (String path : targetFilePaths) {
326 filesToCheck.add(new File(getPath(path)));
327 }
328
329 checker.process(filesToCheck);
330 verifyXml(getPath(expectedXmlReportPath), actualXmlOutput);
331 }
332 }