1 /*
2 * $Header: /home/cvs/jakarta-commons/betwixt/src/test/org/apache/commons/betwixt/xmlunit/XmlTestCase.java,v 1.3 2002/12/30 18:16:48 mvdb Exp $
3 * $Revision: 1.3 $
4 * $Date: 2002/12/30 18:16:48 $
5 *
6 * ====================================================================
7 *
8 * The Apache Software License, Version 1.1
9 *
10 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
11 * reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in
22 * the documentation and/or other materials provided with the
23 * distribution.
24 *
25 * 3. The end-user documentation included with the redistribution, if
26 * any, must include the following acknowlegement:
27 * "This product includes software developed by the
28 * Apache Software Foundation (http://www.apache.org/)."
29 * Alternately, this acknowlegement may appear in the software itself,
30 * if and wherever such third-party acknowlegements normally appear.
31 *
32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
33 * Foundation" must not be used to endorse or promote products derived
34 * from this software without prior written permission. For written
35 * permission, please contact apache@apache.org.
36 *
37 * 5. Products derived from this software may not be called "Apache"
38 * nor may "Apache" appear in their names without prior written
39 * permission of the Apache Group.
40 *
41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 * SUCH DAMAGE.
53 * ====================================================================
54 *
55 * This software consists of voluntary contributions made by many
56 * individuals on behalf of the Apache Software Foundation. For more
57 * information on the Apache Software Foundation, please see
58 * <http://www.apache.org/>.
59 *
60 * $Id: XmlTestCase.java,v 1.3 2002/12/30 18:16:48 mvdb Exp $
61 */
62 package org.apache.commons.betwixt.xmlunit;
63
64 import java.io.File;
65 import java.io.IOException;
66 import java.io.StringReader;
67
68 import javax.xml.parsers.DocumentBuilder;
69 import javax.xml.parsers.DocumentBuilderFactory;
70 import javax.xml.parsers.ParserConfigurationException;
71 import junit.framework.AssertionFailedError;
72 import junit.framework.TestCase;
73
74 import org.w3c.dom.Attr;
75 import org.w3c.dom.DOMException;
76 import org.w3c.dom.Document;
77 import org.w3c.dom.NamedNodeMap;
78 import org.w3c.dom.NodeList;
79 import org.xml.sax.InputSource;
80 import org.xml.sax.SAXException;
81
82 /***
83 * Provides xml test utilities.
84 * Hopefully, these might be moved into [xmlunit] sometime.
85 *
86 * @author Robert Burrell Donkin
87 */
88 public class XmlTestCase extends TestCase {
89
90 private static final boolean debug = false;
91
92 DocumentBuilderFactory domFactory;
93
94
95 public XmlTestCase(String testName) {
96 super(testName);
97 }
98
99 public void testXMLUnit() throws Exception {
100 xmlAssertIsomorphicContent(
101 parseFile("src/test/org/apache/commons/betwixt/xmlunit/rss-example.xml"),
102 parseFile("src/test/org/apache/commons/betwixt/xmlunit/rss-example.xml"));
103 }
104
105
106 public void xmlAssertIsomorphicContent(
107 org.w3c.dom.Document documentOne,
108 org.w3c.dom.Document documentTwo)
109 throws
110 AssertionFailedError
111 {
112 xmlAssertIsomorphicContent(null, documentOne, documentTwo);
113 }
114
115 public void xmlAssertIsomorphicContent(
116 String message,
117 org.w3c.dom.Document documentOne,
118 org.w3c.dom.Document documentTwo)
119 throws
120 AssertionFailedError
121 {
122 // two documents have isomorphic content iff their root elements
123 // are isomophic
124 xmlAssertIsomorphic(
125 message,
126 documentOne.getDocumentElement(),
127 documentTwo.getDocumentElement());
128 }
129
130 public void xmlAssertIsomorphic(
131 org.w3c.dom.Node rootOne,
132 org.w3c.dom.Node rootTwo)
133 throws
134 AssertionFailedError
135 {
136 xmlAssertIsomorphic(null, rootOne, rootTwo);
137 }
138
139 public void xmlAssertIsomorphic(
140 String message,
141 org.w3c.dom.Node rootOne,
142 org.w3c.dom.Node rootTwo)
143 throws
144 AssertionFailedError
145 {
146 // first normalize the xml
147 rootOne.normalize();
148 rootTwo.normalize();
149 // going to use recursion so avoid normalizing each time
150 testIsomorphic(message, rootOne, rootTwo);
151 }
152
153
154 private void testIsomorphic(
155 String message,
156 org.w3c.dom.Node nodeOne,
157 org.w3c.dom.Node nodeTwo)
158 throws
159 AssertionFailedError
160 {
161 try {
162 if (debug) {
163 log(
164 "node 1 name=" + nodeOne.getNodeName()
165 + " qname=" + nodeOne.getLocalName());
166 log(
167 "node 2 name=" + nodeTwo.getNodeName()
168 + " qname=" + nodeTwo.getLocalName());
169 }
170
171 // compare node properties
172 log("Comparing node properties");
173 assertEquals(
174 (null == message ? "(Unequal node types)" : message + "(Unequal node types)"),
175 nodeOne.getNodeType(),
176 nodeTwo.getNodeType());
177 assertEquals(
178 (null == message ? "(Unequal node names)" : message + "(Unequal node names)"),
179 nodeOne.getNodeName(),
180 nodeTwo.getNodeName());
181 assertEquals(
182 (null == message ? "(Unequal node values)" : message + "(Unequal node values)"),
183 trim(nodeOne.getNodeValue()),
184 trim(nodeTwo.getNodeValue()));
185 assertEquals(
186 (null == message ? "(Unequal local names)" : message + "(Unequal local names)"),
187 nodeOne.getLocalName(),
188 nodeTwo.getLocalName());
189 assertEquals(
190 (null == message ? "(Unequal namespace)" : message + "(Unequal namespace)"),
191 nodeOne.getNamespaceURI(),
192 nodeTwo.getNamespaceURI());
193
194
195 // compare attributes
196 log("Comparing attributes");
197 // make sure both have them first
198 assertEquals(
199 (null == message ? "(Unequal attributes)" : message + "(Unequal attributes)"),
200 nodeOne.hasAttributes(),
201 nodeTwo.hasAttributes());
202 if (nodeOne.hasAttributes()) {
203 // do the actual comparison
204 // first we check the number of attributes are equal
205 // we then check that for every attribute of node one,
206 // a corresponding attribute exists in node two
207 // (this should be sufficient to prove equality)
208 NamedNodeMap attributesOne = nodeOne.getAttributes();
209 NamedNodeMap attributesTwo = nodeTwo.getAttributes();
210
211 assertEquals(
212 (null == message ? "(Unequal attributes)" : message + "(Unequal attributes)"),
213 attributesOne.getLength(),
214 attributesTwo.getLength());
215
216 for (int i=0, size=attributesOne.getLength(); i<size; i++) {
217 Attr attributeOne = (Attr) attributesOne.item(i);
218 Attr attributeTwo = (Attr) attributesTwo.getNamedItemNS(
219 attributeOne.getNamespaceURI(),
220 attributeOne.getLocalName());
221 if (attributeTwo == null) {
222 attributeTwo = (Attr) attributesTwo.getNamedItem(attributeOne.getName());
223 }
224
225 // check attribute two exists
226 if (attributeTwo == null) {
227 String diagnosis = "[Missing attribute (" + attributeOne.getName() + ")]";
228 fail((null == message ? diagnosis : message + diagnosis));
229 }
230
231 // now check attribute values
232 assertEquals(
233 (null == message ? "(Unequal attribute values)" : message + "(Unequal attribute values)"),
234 attributeOne.getValue(),
235 attributeTwo.getValue());
236 }
237 }
238
239
240 // compare children
241 log("Comparing children");
242 // this time order is important
243 // so we can just go down the list and compare node-wise using recursion
244 NodeList childrenOne = nodeOne.getChildNodes();
245 NodeList childrenTwo = nodeTwo.getChildNodes();
246
247 assertEquals(
248 (null == message ? "(Unequal child nodes)" : message + "(Unequal child nodes)"),
249 childrenOne.getLength(),
250 childrenTwo.getLength());
251
252 for (int i=0, size=childrenOne.getLength(); i<size; i++) {
253 testIsomorphic(message, childrenOne.item(i), childrenTwo.item(i));
254
255 }
256
257 } catch (DOMException ex) {
258 fail((null == message ? "" : message + " ") + "DOM exception" + ex.toString());
259 }
260 }
261
262
263 protected DocumentBuilder createDocumentBuilder() {
264 try {
265
266 return getDomFactory().newDocumentBuilder();
267
268 } catch (ParserConfigurationException e) {
269 fail("Cannot create DOM builder: " + e.toString());
270
271 }
272 // just to keep the compiler happy
273 return null;
274 }
275
276 protected DocumentBuilderFactory getDomFactory() {
277 // lazy creation
278 if (domFactory == null) {
279 domFactory = DocumentBuilderFactory.newInstance();
280 }
281
282 return domFactory;
283 }
284
285 protected Document parseString(String string) {
286 try {
287
288 return createDocumentBuilder().parse(new InputSource(new StringReader(string)));
289
290 } catch (SAXException e) {
291 fail("Cannot create parse string: " + e.toString());
292
293 } catch (IOException e) {
294 fail("Cannot create parse string: " + e.toString());
295
296 }
297 // just to keep the compiler happy
298 return null;
299 }
300
301
302 protected Document parseFile(String path) {
303 try {
304
305 return createDocumentBuilder().parse(new File(path));
306
307 } catch (SAXException e) {
308 fail("Cannot create parse file: " + e.toString());
309
310 } catch (IOException e) {
311 fail("Cannot create parse file: " + e.toString());
312
313 }
314 // just to keep the compiler happy
315 return null;
316 }
317
318 private void log(String message)
319 {
320 if (debug) {
321 System.out.println("[XmlTestCase]" + message);
322 }
323 }
324
325 private String trim(String trimThis)
326 {
327 if (trimThis == null) {
328 return trimThis;
329 }
330
331 return trimThis.trim();
332 }
333 }
334
This page was automatically generated by Maven