View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle;
21  
22  import java.io.ByteArrayOutputStream;
23  import java.nio.charset.StandardCharsets;
24  import java.util.Set;
25  import java.util.function.BiPredicate;
26  
27  import javax.xml.parsers.ParserConfigurationException;
28  
29  import org.junit.Assert;
30  import org.w3c.dom.Document;
31  import org.w3c.dom.NamedNodeMap;
32  import org.w3c.dom.Node;
33  
34  import com.puppycrawl.tools.checkstyle.internal.utils.XmlUtil;
35  
36  public abstract class AbstractXmlTestSupport extends AbstractModuleTestSupport {
37  
38      protected static Document getOutputStreamXml(ByteArrayOutputStream outputStream)
39              throws ParserConfigurationException {
40          final String xml = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
41  
42          return XmlUtil.getRawXml("audit output", xml, xml);
43      }
44  
45      protected static void verifyXml(String expectedOutputFile,
46              ByteArrayOutputStream actualOutputStream, String... messages) throws Exception {
47          verifyXml(expectedOutputFile, actualOutputStream, null, messages);
48      }
49  
50      protected static void verifyXml(String expectedOutputFile,
51              ByteArrayOutputStream actualOutputStream,
52              BiPredicate<Node, Node> ordered, String... messages) throws Exception {
53          String expectedContents = readFile(expectedOutputFile);
54  
55          for (int i = 0; i < messages.length; i++) {
56              expectedContents = expectedContents.replace("$" + i, messages[i]);
57          }
58  
59          final Document expectedDocument = XmlUtil.getRawXml("audit output", expectedContents,
60                  expectedContents);
61          final Document actualDocument = getOutputStreamXml(actualOutputStream);
62  
63          verifyXmlNode(expectedDocument, actualDocument, "/", ordered);
64      }
65  
66      private static void verifyXmlNodes(Node expected, Node actual, String path,
67              BiPredicate<Node, Node> ordered) {
68          final Node expectedFirstChild = expected.getFirstChild();
69          final Node actualFirstChild = actual.getFirstChild();
70  
71          if (expectedFirstChild == null) {
72              Assert.assertNull("no children nodes should exist: " + path, actualFirstChild);
73              Assert.assertEquals("text should be the same: " + path, expected.getNodeValue(),
74                      actual.getNodeValue());
75          }
76          else {
77              Assert.assertNotNull("children nodes should exist: " + path, actualFirstChild);
78  
79              if (ordered == null) {
80                  Node actualChild = actualFirstChild;
81  
82                  for (Node expectedChild = expectedFirstChild; expectedChild != null;
83                          expectedChild = expectedChild.getNextSibling()) {
84                      verifyXmlNode(expectedChild, actualChild, path, ordered);
85  
86                      actualChild = actualChild.getNextSibling();
87                  }
88  
89                  Assert.assertNull("node have same number of children: " + path, actualChild);
90              }
91              else {
92                  final Set<Node> expectedChildren = XmlUtil.getChildrenElements(expected);
93                  final Set<Node> actualChildren = XmlUtil.getChildrenElements(actual);
94  
95                  Assert.assertEquals("node have same number of children: " + path,
96                          expectedChildren.size(), actualChildren.size());
97  
98                  for (Node expectedChild : expectedChildren) {
99                      Node foundChild = null;
100 
101                     for (Node actualChild : actualChildren) {
102                         if (ordered.test(expectedChild, actualChild)) {
103                             foundChild = actualChild;
104                             break;
105                         }
106                     }
107 
108                     Assert.assertNotNull("node should exist: " + path + expectedChild.getNodeName()
109                             + "/", foundChild);
110 
111                     verifyXmlNode(expectedChild, foundChild, path, ordered);
112                 }
113             }
114         }
115     }
116 
117     private static void verifyXmlNode(Node expected, Node actual, String path,
118             BiPredicate<Node, Node> ordered) {
119         if (expected == null) {
120             if (actual != null) {
121                 Assert.fail("no node should exist: " + path + actual.getNodeName() + "/");
122             }
123         }
124         else {
125             final String newPath = path + expected.getNodeName() + "/";
126 
127             Assert.assertNotNull("node should exist: " + newPath, actual);
128             Assert.assertEquals("node should have same name: " + newPath, expected.getNodeName(),
129                     actual.getNodeName());
130             Assert.assertEquals("node should have same type: " + newPath, expected.getNodeType(),
131                     actual.getNodeType());
132 
133             verifyXmlAttributes(expected.getAttributes(), actual.getAttributes(), newPath);
134 
135             verifyXmlNodes(expected, actual, newPath, ordered);
136         }
137     }
138 
139     private static void verifyXmlAttributes(NamedNodeMap expected, NamedNodeMap actual,
140             String path) {
141         if (expected == null) {
142             Assert.assertNull("no attributes should exist: " + path, actual);
143         }
144         else {
145             Assert.assertNotNull("attributes should exist: " + path, actual);
146 
147             for (int i = 0; i < expected.getLength(); i++) {
148                 verifyXmlAttribute(expected.item(i), actual.item(i), path);
149             }
150 
151             Assert.assertEquals("node have same number of attributes: " + path,
152                     expected.getLength(), actual.getLength());
153         }
154     }
155 
156     private static void verifyXmlAttribute(Node expected, Node actual, String path) {
157         final String expectedName = expected.getNodeName();
158 
159         Assert.assertNotNull("attribute value for '" + expectedName + "' should not be null: "
160                 + path, actual);
161 
162         Assert.assertEquals("attribute name should match: " + path, expectedName,
163                 actual.getNodeName());
164 
165         // ignore checkstyle version in xml as it changes each release
166         if (!"/#document/checkstyle".equals(path) && !"version".equals(expectedName)) {
167             Assert.assertEquals("attribute value for '" + expectedName + "' should match: " + path,
168                     expected.getNodeValue(), actual.getNodeValue());
169         }
170     }
171 }