001: /*
002: ******************************************************************
003: Copyright (c) 2001-2007, Jeff Martin, Tim Bacon
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: * Redistributions of source code must retain the above copyright
011: notice, this list of conditions and the following disclaimer.
012: * Redistributions in binary form must reproduce the above
013: copyright notice, this list of conditions and the following
014: disclaimer in the documentation and/or other materials provided
015: with the distribution.
016: * Neither the name of the xmlunit.sourceforge.net nor the names
017: of its contributors may be used to endorse or promote products
018: derived from this software without specific prior written
019: permission.
020:
021: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
022: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
023: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
024: FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
025: COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
026: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
027: BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
028: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
029: CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
030: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
031: ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
032: POSSIBILITY OF SUCH DAMAGE.
033:
034: ******************************************************************
035: */
036:
037: package org.custommonkey.xmlunit;
038:
039: import java.io.File;
040: import java.io.FileReader;
041: import java.io.Reader;
042: import java.util.Iterator;
043: import java.util.List;
044:
045: import org.w3c.dom.Document;
046: import org.xml.sax.InputSource;
047:
048: /**
049: * Test a DetailedDiff. Extend the test case class for Diff so we can rerun those
050: * tests with a DetailedDiff and assert that behaviour has not changed.
051: */
052: public class test_DetailedDiff extends test_Diff {
053: private String firstForecast, secondForecast;
054:
055: public void testAllDifferencesFirstForecastControl()
056: throws Exception {
057: Diff multipleDifferences = new Diff(firstForecast,
058: secondForecast);
059: DetailedDiff detailedDiff = new DetailedDiff(
060: multipleDifferences);
061:
062: List differences = detailedDiff.getAllDifferences();
063: assertExpectedDifferencesFirstForecastControl(differences,
064: detailedDiff);
065: }
066:
067: private void assertExpectedDifferencesFirstForecastControl(
068: List differences, DetailedDiff detailedDiff) {
069: assertEquals("size: " + detailedDiff, 5, differences.size());
070: assertEquals("first: " + detailedDiff,
071: DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences
072: .get(0));
073: assertEquals("second: " + detailedDiff,
074: DifferenceConstants.ATTR_NAME_NOT_FOUND, differences
075: .get(1));
076: assertEquals("third: " + detailedDiff,
077: DifferenceConstants.ATTR_VALUE, differences.get(2));
078: assertEquals("fourth: " + detailedDiff,
079: DifferenceConstants.ATTR_SEQUENCE, differences.get(3));
080: assertEquals("fifth: " + detailedDiff,
081: DifferenceConstants.HAS_CHILD_NODES, differences.get(4));
082: }
083:
084: public void testAllDifferencesSecondForecastControl()
085: throws Exception {
086: Diff multipleDifferences = new Diff(secondForecast,
087: firstForecast);
088: DetailedDiff detailedDiff = new DetailedDiff(
089: multipleDifferences);
090:
091: List differences = detailedDiff.getAllDifferences();
092:
093: assertEquals("size: " + detailedDiff, 5, differences.size());
094: assertEquals("first: " + detailedDiff,
095: DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences
096: .get(0));
097: assertEquals("second: " + detailedDiff,
098: DifferenceConstants.ATTR_VALUE, differences.get(1));
099: assertEquals("third: " + detailedDiff,
100: DifferenceConstants.ATTR_SEQUENCE, differences.get(2));
101: assertEquals("forth: " + detailedDiff,
102: DifferenceConstants.ATTR_NAME_NOT_FOUND, differences
103: .get(3));
104: assertEquals("fifth: " + detailedDiff,
105: DifferenceConstants.HAS_CHILD_NODES, differences.get(4));
106: }
107:
108: public void testPrototypeIsADetailedDiff() throws Exception {
109: Diff multipleDifferences = new Diff(firstForecast,
110: secondForecast);
111: DetailedDiff detailedDiff = new DetailedDiff(new DetailedDiff(
112: multipleDifferences));
113:
114: List differences = detailedDiff.getAllDifferences();
115: assertExpectedDifferencesFirstForecastControl(differences,
116: detailedDiff);
117: }
118:
119: public void testLargeFiles() throws Exception {
120: int i = 0;
121: String expr = null;
122: File test, control;
123: control = new File(test_Constants.BASEDIR
124: + "/tests/etc/controlDetail.xml");
125: test = new File(test_Constants.BASEDIR
126: + "/tests/etc/testDetail.xml");
127: DetailedDiff differencesWithWhitespace = new DetailedDiff(
128: new Diff(new InputSource(new FileReader(control)),
129: new InputSource(new FileReader(test))));
130:
131: List l = differencesWithWhitespace.getAllDifferences();
132: int unmatchedNodes = 0;
133: for (Iterator iter = l.iterator(); iter.hasNext();) {
134: Difference d = (Difference) iter.next();
135: if (d.getId() == DifferenceConstants.CHILD_NODE_NOT_FOUND_ID) {
136: unmatchedNodes++;
137: }
138: }
139:
140: assertEquals(1402 + unmatchedNodes, differencesWithWhitespace
141: .getAllDifferences().size());
142:
143: try {
144: XMLUnit.setIgnoreWhitespace(true);
145: Diff prototype = new Diff(new FileReader(control),
146: new FileReader(test));
147: DetailedDiff detailedDiff = new DetailedDiff(prototype);
148: List differences = detailedDiff.getAllDifferences();
149: unmatchedNodes = 0;
150: for (Iterator iter = differences.iterator(); iter.hasNext();) {
151: Difference d = (Difference) iter.next();
152: if (d.getId() == DifferenceConstants.CHILD_NODE_NOT_FOUND_ID) {
153: unmatchedNodes++;
154: }
155: }
156: assertEquals(40 + unmatchedNodes, differences.size());
157:
158: SimpleXpathEngine xpathEngine = new SimpleXpathEngine();
159: Document controlDoc = XMLUnit
160: .buildControlDocument(new InputSource(
161: new FileReader(control)));
162: Document testDoc = XMLUnit
163: .buildTestDocument(new InputSource(new FileReader(
164: test)));
165:
166: Difference aDifference;
167: String value;
168: for (Iterator iter = differences.iterator(); iter.hasNext();) {
169: aDifference = (Difference) iter.next();
170: if (aDifference.equals(DifferenceConstants.ATTR_VALUE)
171: || aDifference
172: .equals(DifferenceConstants.CDATA_VALUE)
173: || aDifference
174: .equals(DifferenceConstants.COMMENT_VALUE)
175: || aDifference
176: .equals(DifferenceConstants.ELEMENT_TAG_NAME)
177: || aDifference
178: .equals(DifferenceConstants.TEXT_VALUE)) {
179: expr = aDifference.getControlNodeDetail()
180: .getXpathLocation();
181: if (expr == null || expr.length() == 0) {
182: System.out.println(aDifference);
183: } else {
184: value = xpathEngine.evaluate(expr, controlDoc);
185: assertEquals(i + " control "
186: + aDifference.toString(), value,
187: aDifference.getControlNodeDetail()
188: .getValue());
189: }
190:
191: expr = aDifference.getTestNodeDetail()
192: .getXpathLocation();
193: if (expr == null || expr.length() == 0) {
194: System.out.println(aDifference);
195: } else {
196: value = xpathEngine.evaluate(expr, testDoc);
197: assertEquals(i + " test "
198: + aDifference.toString(), value,
199: aDifference.getTestNodeDetail()
200: .getValue());
201: }
202: }
203: ++i;
204: }
205: } catch (Exception e) {
206: System.out.println("eek@" + i + ":" + expr);
207: throw e;
208: } finally {
209: XMLUnit.setIgnoreWhitespace(false);
210: }
211:
212: }
213:
214: public void testSeeAllDifferencesEvenIfDiffWouldSayHaltComparison()
215: throws Exception {
216: String control = "<a><b/><c/></a>";
217: String test = "<a><c/></a>";
218:
219: Diff d = new Diff(control, test);
220: DetailedDiff dd = new DetailedDiff(d);
221:
222: List l = dd.getAllDifferences();
223: // number of children is different, didn't find <b/>, wrong
224: // sequence of nodes
225: assertEquals(3, l.size());
226: }
227:
228: public void testSeeAllDifferencesEvenIfDiffSaysHaltComparison()
229: throws Exception {
230: String control = "<a><b/><c/></a>";
231: String test = "<a><c/></a>";
232:
233: Diff d = new Diff(control, test);
234: d.similar();
235: DetailedDiff dd = new DetailedDiff(d);
236:
237: List l = dd.getAllDifferences();
238: // number of children is different, didn't find <b/>, wrong
239: // sequence of nodes
240: assertEquals(3, l.size());
241: }
242:
243: /**
244: * @see http://sourceforge.net/forum/forum.php?thread_id=1691528&forum_id=73274
245: */
246: public void testHelpForumThread1691528() throws Exception {
247: String control = "<table border=\"1\">" + "<tr>"
248: + "<th>News</th>" + "</tr>" + "<tr>"
249: + "<td>Newsitem 1</td>" + "</tr>" + "</table>";
250: String test = "<table border=\"1\">" + "<tr>" + "<th>News</th>"
251: + "</tr>" + "<tr>" + "<td>Newsitem 2</td>"
252: + "<td>Newsitem 1</td>" + "</tr>" + "</table>";
253:
254: DetailedDiff diff = new DetailedDiff(new Diff(control, test));
255: List changes = diff.getAllDifferences();
256: // number of children, text of first child, unexpected second
257: // test child
258: assertEquals(3, changes.size());
259: }
260:
261: protected Diff buildDiff(Document control, Document test) {
262: return new DetailedDiff(super .buildDiff(control, test));
263: }
264:
265: protected Diff buildDiff(String control, String test)
266: throws Exception {
267: return new DetailedDiff(super .buildDiff(control, test));
268: }
269:
270: protected Diff buildDiff(Reader control, Reader test)
271: throws Exception {
272: return new DetailedDiff(super .buildDiff(control, test));
273: }
274:
275: public test_DetailedDiff(String name) {
276: super (name);
277: firstForecast = "<weather><today icon=\"clouds\" temp=\"17\">"
278: + "<outlook>unsettled</outlook></today></weather>";
279: secondForecast = "<weather><today temp=\"20\"/></weather>";
280: }
281:
282: }
|