You can subscribe to this list here.
2007 |
Jan
|
Feb
(3) |
Mar
(18) |
Apr
(39) |
May
(15) |
Jun
(12) |
Jul
(3) |
Aug
(23) |
Sep
|
Oct
(1) |
Nov
(1) |
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(21) |
Feb
(23) |
Mar
(33) |
Apr
(8) |
May
(1) |
Jun
(22) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
(6) |
Nov
|
Dec
(11) |
2009 |
Jan
(5) |
Feb
|
Mar
(2) |
Apr
(24) |
May
(36) |
Jun
(18) |
Jul
(2) |
Aug
(3) |
Sep
(9) |
Oct
(3) |
Nov
(1) |
Dec
|
2010 |
Jan
(5) |
Feb
(3) |
Mar
|
Apr
(15) |
May
(24) |
Jun
(11) |
Jul
(8) |
Aug
(34) |
Sep
(42) |
Oct
|
Nov
|
Dec
|
2011 |
Jan
(13) |
Feb
(32) |
Mar
(35) |
Apr
(31) |
May
(33) |
Jun
(30) |
Jul
(32) |
Aug
(31) |
Sep
(30) |
Oct
(31) |
Nov
(32) |
Dec
(31) |
2012 |
Jan
(35) |
Feb
(31) |
Mar
(31) |
Apr
(30) |
May
(31) |
Jun
(34) |
Jul
(23) |
Aug
(30) |
Sep
(30) |
Oct
(29) |
Nov
(30) |
Dec
(32) |
2013 |
Jan
(25) |
Feb
(39) |
Mar
(1) |
Apr
(18) |
May
(1) |
Jun
|
Jul
(1) |
Aug
(20) |
Sep
(41) |
Oct
(32) |
Nov
(9) |
Dec
(31) |
2014 |
Jan
(31) |
Feb
(30) |
Mar
(34) |
Apr
(60) |
May
(31) |
Jun
(28) |
Jul
(32) |
Aug
(28) |
Sep
(26) |
Oct
(32) |
Nov
(43) |
Dec
(115) |
2015 |
Jan
(106) |
Feb
(101) |
Mar
(51) |
Apr
(32) |
May
(63) |
Jun
(18) |
Jul
|
Aug
(18) |
Sep
|
Oct
(1) |
Nov
(84) |
Dec
(63) |
2016 |
Jan
(26) |
Feb
(17) |
Mar
(104) |
Apr
(30) |
May
(6) |
Jun
(30) |
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(48) |
Dec
(22) |
2017 |
Jan
(15) |
Feb
(29) |
Mar
(43) |
Apr
(29) |
May
(25) |
Jun
(28) |
Jul
(62) |
Aug
(35) |
Sep
(35) |
Oct
(72) |
Nov
(10) |
Dec
(4) |
2018 |
Jan
(7) |
Feb
(4) |
Mar
|
Apr
(46) |
May
(20) |
Jun
(12) |
Jul
(9) |
Aug
(42) |
Sep
(4) |
Oct
(17) |
Nov
(32) |
Dec
(31) |
2019 |
Jan
(21) |
Feb
(14) |
Mar
|
Apr
(74) |
May
(25) |
Jun
(43) |
Jul
(2) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
|
Dec
(10) |
2020 |
Jan
(1) |
Feb
|
Mar
(26) |
Apr
(8) |
May
(62) |
Jun
(4) |
Jul
(25) |
Aug
|
Sep
(21) |
Oct
(24) |
Nov
(26) |
Dec
(9) |
2021 |
Jan
|
Feb
(4) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
(11) |
Nov
(1) |
Dec
(12) |
2022 |
Jan
(47) |
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(14) |
2023 |
Jan
(3) |
Feb
|
Mar
(60) |
Apr
(9) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2024 |
Jan
(5) |
Feb
|
Mar
|
Apr
(10) |
May
(1) |
Jun
|
Jul
|
Aug
(17) |
Sep
(2) |
Oct
|
Nov
|
Dec
(1) |
2025 |
Jan
|
Feb
|
Mar
(88) |
Apr
(64) |
May
(47) |
Jun
(20) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <bo...@us...> - 2010-09-10 15:11:06
|
Revision: 462 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=462&view=rev Author: bodewig Date: 2010-09-10 15:11:00 +0000 (Fri, 10 Sep 2010) Log Message: ----------- skip DocType (and XmlDeclaration) nodes in child lists since they have already been dealt with at the Document node Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Linqy.java trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml trunk/xmlunit/src/main/net-core/util/Linqy.cs trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/DOMDifferenceEngineTest.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-09-09 15:42:13 UTC (rev 461) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-09-10 15:11:00 UTC (rev 462) @@ -71,13 +71,17 @@ <compare type="NAMESPACE_URI" property="getNamespaceURI()"/> <compare type="NAMESPACE_PREFIX" property="getPrefix()"/> <literal><![CDATA[ - NodeList controlChildren = control.getChildNodes(); - NodeList testChildren = test.getChildNodes(); + Iterable<Node> controlChildren = + Linqy.filter(new IterableNodeList(control.getChildNodes()), + INTERESTING_NODES); + Iterable<Node> testChildren = + Linqy.filter(new IterableNodeList(test.getChildNodes()), + INTERESTING_NODES); if (control.getNodeType() != Node.ATTRIBUTE_NODE) { ]]></literal> <compareExpr type="CHILD_NODELIST_LENGTH" - controlExpr="controlChildren.getLength()" - testExpr="testChildren.getLength()"/> + controlExpr="Linqy.count(controlChildren)" + testExpr="Linqy.count(testChildren)"/> <literal><![CDATA[ } ]]></literal> @@ -85,11 +89,9 @@ <literal><![CDATA[ if (control.getNodeType() != Node.ATTRIBUTE_NODE) { controlContext - .setChildren(Linqy.map(new IterableNodeList(controlChildren), - TO_NODE_INFO)); + .setChildren(Linqy.map(controlChildren, TO_NODE_INFO)); testContext - .setChildren(Linqy.map(new IterableNodeList(testChildren), - TO_NODE_INFO)); + .setChildren(Linqy.map(testChildren, TO_NODE_INFO)); ]]></literal> <compareMethodExpr method="compareNodeLists" controlExpr="controlChildren" @@ -309,12 +311,12 @@ test.getData())); } - private ComparisonResult compareNodeLists(NodeList control, + private ComparisonResult compareNodeLists(Iterable<Node> controlSeq, XPathContext controlContext, - NodeList test, + Iterable<Node> testSeq, XPathContext testContext) { - List<Node> controlList = IterableNodeList.asList(control); - List<Node> testList = IterableNodeList.asList(test); + List<Node> controlList = Linqy.asList(controlSeq); + List<Node> testList = Linqy.asList(testSeq); final int testSize = testList.size(); Set<Integer> unmatchedTestIndexes = new TreeSet<Integer>(); for (int i = 0; i < testSize; i++) { @@ -336,14 +338,16 @@ ]]></literal> testContext.navigateToChild(testMatch.index); try { + Node control = controlList.get(i); + Node test = testMatch.node; Integer testIndex = Integer.valueOf(testMatch.index); <compareExpr type="CHILD_NODELIST_SEQUENCE" controlExpr="Integer.valueOf(i)" testExpr="testIndex" /> <compareMethodExpr method="compareNodes" - controlExpr="controlList.get(i)" - testExpr="testMatch.node"/> + controlExpr="control" + testExpr="test"/> <literal><![CDATA[ unmatchedTestIndexes.remove(testIndex); lastMatch = testMatch; @@ -503,5 +507,12 @@ return new XPathContext.DOMNodeInfo(n); } }; + + private static final Linqy.Predicate<Node> INTERESTING_NODES = + new Linqy.Predicate<Node>() { + public boolean matches(Node n) { + return n.getNodeType() != Node.DOCUMENT_TYPE_NODE; + } + }; ]]></literal> </class> \ No newline at end of file Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Linqy.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Linqy.java 2010-09-09 15:42:13 UTC (rev 461) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Linqy.java 2010-09-10 15:11:00 UTC (rev 462) @@ -59,6 +59,29 @@ T map(F from); } + public static <T> Iterable<T> filter(final Iterable<T> sequence, + final Predicate<? super T> filter) { + return new Iterable<T>() { + public Iterator<T> iterator() { + return new FilteringIterator<T>(sequence.iterator(), filter); + } + }; + } + + public interface Predicate<T> { + boolean matches(T toTest); + } + + public static int count(Iterable seq) { + int c = 0; + Iterator it = seq.iterator(); + while (it.hasNext()) { + c++; + it.next(); + } + return c; + } + private static class OnceOnlyIterator<E> implements Iterator<E> { private final E element; private boolean iterated = false; @@ -98,4 +121,34 @@ } } + private static class FilteringIterator<T> implements Iterator<T> { + private final Iterator<T> i; + private final Predicate<? super T> filter; + private T lookAhead = null; + private FilteringIterator(Iterator<T> i, Predicate<? super T> filter) { + this.i = i; + this.filter = filter; + } + public void remove() { + i.remove(); + } + public T next() { + if (lookAhead == null) { + throw new NoSuchElementException(); + } + T next = lookAhead; + lookAhead = null; + return next; + } + public boolean hasNext() { + while (lookAhead == null && i.hasNext()) { + T next = i.next(); + if (filter.matches(next)) { + lookAhead = next; + } + } + return lookAhead != null; + } + } + } \ No newline at end of file Modified: trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml =================================================================== --- trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-09-09 15:42:13 UTC (rev 461) +++ trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-09-10 15:11:00 UTC (rev 462) @@ -61,28 +61,30 @@ <compare type="NAMESPACE_URI" property="NamespaceURI"/> <compare type="NAMESPACE_PREFIX" property="Prefix"/> <literal><![CDATA[ - XmlNodeList controlChildren = control.ChildNodes; - XmlNodeList testChildren = test.ChildNodes; + IEnumerable<XmlNode> controlChildren = + Linqy.Filter(Linqy.Cast<XmlNode>(control.ChildNodes), + INTERESTING_NODES); + IEnumerable<XmlNode> testChildren = + Linqy.Filter(Linqy.Cast<XmlNode>(test.ChildNodes), + INTERESTING_NODES); if (control.NodeType != XmlNodeType.Attribute) { ]]></literal> <compareExpr type="CHILD_NODELIST_LENGTH" - controlExpr="controlChildren.Count" - testExpr="testChildren.Count"/> + controlExpr="Linqy.Count(controlChildren)" + testExpr="Linqy.Count(testChildren)"/> <literal><![CDATA[ } ]]></literal> <compareMethod method="NodeTypeSpecificComparison"/> <literal><![CDATA[ if (control.NodeType != XmlNodeType.Attribute) { - IEnumerable<XmlNode> cc = Linqy.Cast<XmlNode>(controlChildren); controlContext .SetChildren(Linqy.Map<XmlNode, - XPathContext.INodeInfo>(cc, + XPathContext.INodeInfo>(controlChildren, TO_NODE_INFO)); - IEnumerable<XmlNode> tc = Linqy.Cast<XmlNode>(testChildren); testContext .SetChildren(Linqy.Map<XmlNode, - XPathContext.INodeInfo>(tc, + XPathContext.INodeInfo>(testChildren, TO_NODE_INFO)); ]]></literal> <compareMethodExpr method="CompareNodeLists" @@ -347,14 +349,12 @@ test.Data)); } - private ComparisonResult CompareNodeLists(XmlNodeList control, + private ComparisonResult CompareNodeLists(IEnumerable<XmlNode> controlSeq, XPathContext controlContext, - XmlNodeList test, + IEnumerable<XmlNode> testSeq, XPathContext testContext) { - IList<XmlNode> controlList = - new List<XmlNode>(Linqy.Cast<XmlNode>(control)); - IList<XmlNode> testList = - new List<XmlNode>(Linqy.Cast<XmlNode>(test)); + IList<XmlNode> controlList = new List<XmlNode>(controlSeq); + IList<XmlNode> testList = new List<XmlNode>(testSeq); IDictionary<int, object> unmatchedTestIndexes = new SortedDictionary<int, object>(); for (int i = 0; i < testList.Count; i++) { @@ -372,6 +372,8 @@ controlContext.NavigateToChild(i); try { if (testMatch != null) { + XmlNode control = controlList[i]; + XmlNode test = testMatch.Node; testContext.NavigateToChild(testMatch.Index); try { ]]></literal> @@ -380,8 +382,8 @@ testExpr="testMatch.Index" /> <compareMethodExpr method="CompareNodes" - controlExpr="controlList[i]" - testExpr="testMatch.Node"/> + controlExpr="control" + testExpr="test"/> <literal><![CDATA[ unmatchedTestIndexes.Remove(testMatch.Index); lastMatch = testMatch; @@ -528,5 +530,10 @@ private static XPathContext.INodeInfo TO_NODE_INFO(XmlNode n) { return new XPathContext.DOMNodeInfo(n); } + + private static bool INTERESTING_NODES(XmlNode n) { + return n.NodeType != XmlNodeType.DocumentType + && n.NodeType != XmlNodeType.XmlDeclaration; + } ]]></literal> </class> \ No newline at end of file Modified: trunk/xmlunit/src/main/net-core/util/Linqy.cs =================================================================== --- trunk/xmlunit/src/main/net-core/util/Linqy.cs 2010-09-09 15:42:13 UTC (rev 461) +++ trunk/xmlunit/src/main/net-core/util/Linqy.cs 2010-09-10 15:11:00 UTC (rev 462) @@ -38,5 +38,24 @@ yield return mapper(f); } } + + public delegate bool Predicate<T>(T toTest); + + public static IEnumerable<T> Filter<T>(IEnumerable<T> sequence, + Predicate<T> filter) { + foreach (T t in sequence) { + if (filter(t)) { + yield return t; + } + } + } + + public static int Count(IEnumerable e) { + int c = 0; + foreach (object o in e) { + c++; + } + return c; + } } } \ No newline at end of file Modified: trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/DOMDifferenceEngineTest.java =================================================================== --- trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/DOMDifferenceEngineTest.java 2010-09-09 15:42:13 UTC (rev 461) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/DOMDifferenceEngineTest.java 2010-09-10 15:11:00 UTC (rev 462) @@ -302,11 +302,6 @@ public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { if (comparison.getType() - == ComparisonType.CHILD_NODELIST_LENGTH) { - assertEquals(ComparisonResult.DIFFERENT, outcome); - return ComparisonResult.EQUAL; - } - if (comparison.getType() == ComparisonType.HAS_DOCTYPE_DECLARATION) { assertEquals(ComparisonResult.DIFFERENT, outcome); return ComparisonResult.CRITICAL; Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2010-09-09 15:42:13 UTC (rev 461) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2010-09-10 15:11:00 UTC (rev 462) @@ -210,8 +210,7 @@ diff.toString()); } - public void NOtestXMLWithDTD() throws Exception { - XMLUnit.setCompareUnmatched(true); + public void testXMLWithDTD() throws Exception { String aDTDpart = "<!DOCTYPE test [" + "<!ELEMENT assertion EMPTY>" + "<!ATTLIST assertion result (pass|fail) \"fail\">" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: SourceForge.net <no...@so...> - 2010-09-10 12:04:15
|
Bugs item #3062518, was opened at 2010-09-09 11:47 Message generated for change (Comment added) made by bodewig You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: Java 1.3 Status: Closed Resolution: Duplicate Priority: 5 Private: No Submitted By: David Krzystek (david-krzystek) Assigned to: Nobody/Anonymous (nobody) Summary: DifferenceEngine error Initial Comment: Hi guys, I guess I spotted an incorrect difference reporting for example desbribed below. Control document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Apple size="15" color="green"/> <Banana size="10"/> </Fruits> Test document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Banana size="11"/> </Fruits> Removing one Apple and changing Banana's attribute size in the test document, comparator reports these differences: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected element tag name 'Apple' but was 'Banana' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected number of element attributes '2' but was '1' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute name 'color' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute value '15' but was '11' - comparing <Apple size="15"...> at /Fruits[1]/Apple[2]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size Expected presence of child node 'Banana' but was 'null' - comparing <Banana...> at /Fruits[1]/Banana[1] to at null This is actually incorrect according to me. I would expect to see: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size I went through the DifferenceEngine code and I could see, that the method allows the comparison of apples and bananas protected void compareNodeList(final List controlChildren, final List testChildren, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException The part of the code which compares unmatched test nodes with the control nodes that did not match too. ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } ... } ... I would suggest to compare nodes of the same name. It could look like the snippet below: ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); // check that we are not comparing apples with bananas if (nextControl.getLocalName().equals(nextTest.getLocalName())) { testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } else { nextTest = null; } } ... } ... Anyway, thank you for your great job. David ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-10 14:04 Message: In the unit tests I've committed, I don't use any ElementQualifier explicitly. Uf you get a different result, than my test, this means you must be using a different ElementQualifier. >From the rest youÄve written my best guess is you are using ElementNameAndAttributesQualifier - in this case you are already explicitly saying "the banana elements are not eligible to be compared". I'd say getting two NOT_FOUND differences one for the control and one for the test element is what one would expect. XMLUnit would need some sort of heuristic that would tell it to ignore ElementQualifier and instead compare two elements even though it has been told to not do it. Sometimes picking the element by name might be the right choice, but I'm sure there are other times where it is not. To me it hints at a missing piece of API inside XMLUnit that I don't have a clear grasp of right now. I've just identified a similar issue while working on the new 2.0 code base[1] and I'd welcome your input on the general mailing list. [1] https://sourceforge.net/mailarchive/forum.php?thread_name=87r5h4q2ic.fsf%40v35516.1blu.de&forum_name=xmlunit-general ---------------------------------------------------------------------- Comment By: David Krzystek (david-krzystek) Date: 2010-09-10 08:28 Message: I understand, that the ElementNameQualifier will make the comparison correct, nevertheless it will inhibit the correct comparison of the documents which might have nodes in a swapped order. See the example: CONTROL <Fruits> <Apple size="11" color="green"/>" <Apple size="13" color="green"/>" <Apple size="15" color="green"/>" <Banana size="10"/>" </Fruits> TEST <Fruits> <Apple size="13" color="green"/> <Banana size="11"/> <Apple size="11" color="green"/> </Fruits> TEST document is missing one apple and babana changed. Besides that, two remaining apples are swapped. Disabling the comparison of unmatched nodes and using ElementNameQualifier class, I got these differences: Expected number of child nodes '4' but was '3' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected attribute value '11' but was '13' - comparing <Apple size="11"...> at /Fruits[1]/Apple[1]/@size to <Apple size="13"...> at /Fruits[1]/Apple[1]/@size Expected attribute value '13' but was '11' - comparing <Apple size="13"...> at /Fruits[1]/Apple[2]/@size to <Apple size="11"...> at /Fruits[1]/Apple[2]/@size Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[3] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size It is apparent, it is a consequence of using ElementNameQualifier which relies on the the same sequence numbers, so the swapped order is not handled well. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 17:01 Message: I've taken your example and turned it into a unit test with svn revision 459 (will port it to trunk which contains a completely revamped codebase soon). The test pases. http://xmlunit.svn.sourceforge.net/viewvc/xmlunit?view=revision&revision=459 You get Expected 3 child nodes was 2 Didn't find Apple[2] Attribute values differ for Banana[1] Child order for Banana elements is different - third child vs second) Of course you'd get different results if the ElementQualifier is anything but ElementNameQuaifier ---------------------------------------------------------------------- Comment By: David Krzystek (david-krzystek) Date: 2010-09-09 16:27 Message: The example was tested against XMLUnit1.3. I also tried to use the new feature you mentioned, but it still did not do what I would expect. Running the same example with XMLUnit.setCompareUnmatched (false) returns: Expected number of child nodes '3' but was '2'... Expected presence of child node 'Apple' but was 'null' ... Expected presence of child node 'Banana' but was 'null' ... Expected presence of childl mode 'null' but was 'Banana' ... I understand that the unmatched control and test nodes are printed, but I would rather expect to see, that one Apple is missing and Banana got a difference which seems to me more correct. Therefore I did not take advantage of disabling comparison of unmatched nodes. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 16:12 Message: re-opening comments and changing category based on an email by David. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:21 Message: duplicate of issue 2758280 ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:18 Message: This is addressed in XMLUnit 1.3. You should get the expected behavior if you set XMLUnit's compareUnmateched to false. See http://xmlunit.sourceforge.net/userguide/html/apas03.html#New%20Features%201.3 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 |
From: SourceForge.net <no...@so...> - 2010-09-10 06:28:32
|
Bugs item #3062518, was opened at 2010-09-09 11:47 Message generated for change (Comment added) made by david-krzystek You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: Java 1.3 Status: Closed Resolution: Duplicate Priority: 5 Private: No Submitted By: David Krzystek (david-krzystek) Assigned to: Nobody/Anonymous (nobody) Summary: DifferenceEngine error Initial Comment: Hi guys, I guess I spotted an incorrect difference reporting for example desbribed below. Control document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Apple size="15" color="green"/> <Banana size="10"/> </Fruits> Test document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Banana size="11"/> </Fruits> Removing one Apple and changing Banana's attribute size in the test document, comparator reports these differences: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected element tag name 'Apple' but was 'Banana' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected number of element attributes '2' but was '1' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute name 'color' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute value '15' but was '11' - comparing <Apple size="15"...> at /Fruits[1]/Apple[2]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size Expected presence of child node 'Banana' but was 'null' - comparing <Banana...> at /Fruits[1]/Banana[1] to at null This is actually incorrect according to me. I would expect to see: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size I went through the DifferenceEngine code and I could see, that the method allows the comparison of apples and bananas protected void compareNodeList(final List controlChildren, final List testChildren, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException The part of the code which compares unmatched test nodes with the control nodes that did not match too. ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } ... } ... I would suggest to compare nodes of the same name. It could look like the snippet below: ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); // check that we are not comparing apples with bananas if (nextControl.getLocalName().equals(nextTest.getLocalName())) { testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } else { nextTest = null; } } ... } ... Anyway, thank you for your great job. David ---------------------------------------------------------------------- Comment By: David Krzystek (david-krzystek) Date: 2010-09-10 08:28 Message: I understand, that the ElementNameQualifier will make the comparison correct, nevertheless it will inhibit the correct comparison of the documents which might have nodes in a swapped order. See the example: CONTROL <Fruits> <Apple size="11" color="green"/>" <Apple size="13" color="green"/>" <Apple size="15" color="green"/>" <Banana size="10"/>" </Fruits> TEST <Fruits> <Apple size="13" color="green"/> <Banana size="11"/> <Apple size="11" color="green"/> </Fruits> TEST document is missing one apple and babana changed. Besides that, two remaining apples are swapped. Disabling the comparison of unmatched nodes and using ElementNameQualifier class, I got these differences: Expected number of child nodes '4' but was '3' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected attribute value '11' but was '13' - comparing <Apple size="11"...> at /Fruits[1]/Apple[1]/@size to <Apple size="13"...> at /Fruits[1]/Apple[1]/@size Expected attribute value '13' but was '11' - comparing <Apple size="13"...> at /Fruits[1]/Apple[2]/@size to <Apple size="11"...> at /Fruits[1]/Apple[2]/@size Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[3] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size It is apparent, it is a consequence of using ElementNameQualifier which relies on the the same sequence numbers, so the swapped order is not handled well. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 17:01 Message: I've taken your example and turned it into a unit test with svn revision 459 (will port it to trunk which contains a completely revamped codebase soon). The test pases. http://xmlunit.svn.sourceforge.net/viewvc/xmlunit?view=revision&revision=459 You get Expected 3 child nodes was 2 Didn't find Apple[2] Attribute values differ for Banana[1] Child order for Banana elements is different - third child vs second) Of course you'd get different results if the ElementQualifier is anything but ElementNameQuaifier ---------------------------------------------------------------------- Comment By: David Krzystek (david-krzystek) Date: 2010-09-09 16:27 Message: The example was tested against XMLUnit1.3. I also tried to use the new feature you mentioned, but it still did not do what I would expect. Running the same example with XMLUnit.setCompareUnmatched (false) returns: Expected number of child nodes '3' but was '2'... Expected presence of child node 'Apple' but was 'null' ... Expected presence of child node 'Banana' but was 'null' ... Expected presence of childl mode 'null' but was 'Banana' ... I understand that the unmatched control and test nodes are printed, but I would rather expect to see, that one Apple is missing and Banana got a difference which seems to me more correct. Therefore I did not take advantage of disabling comparison of unmatched nodes. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 16:12 Message: re-opening comments and changing category based on an email by David. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:21 Message: duplicate of issue 2758280 ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:18 Message: This is addressed in XMLUnit 1.3. You should get the expected behavior if you set XMLUnit's compareUnmateched to false. See http://xmlunit.sourceforge.net/userguide/html/apas03.html#New%20Features%201.3 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 |
From: <bo...@us...> - 2010-09-09 15:42:20
|
Revision: 461 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=461&view=rev Author: bodewig Date: 2010-09-09 15:42:13 +0000 (Thu, 09 Sep 2010) Log Message: ----------- correctly reset compareUnmatched. Failure to do so in testDontCompareUnmatched has hidden a bunch of differences between old and new diff engine, disable corresponding tests Modified Paths: -------------- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Difference.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_ElementNameAndAttributeQualifier.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_IgnoreTextAndAttributeValuesDifferenceListener.java Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-09 15:17:35 UTC (rev 460) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-09 15:42:13 UTC (rev 461) @@ -384,7 +384,7 @@ assertNull(diff.getControlNodeDetail().getNode()); assertNotNull(diff.getTestNodeDetail().getNode()); } finally { - XMLUnit.setCompareUnmatched(true); + XMLUnit.clearCompareUnmatched(); } } @@ -448,7 +448,7 @@ assertEquals("/Fruits[1]/Banana[1]", diff.getTestNodeDetail().getXpathLocation()); } finally { - XMLUnit.setCompareUnmatched(true); + XMLUnit.clearCompareUnmatched(); } } } Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2010-09-09 15:17:35 UTC (rev 460) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2010-09-09 15:42:13 UTC (rev 461) @@ -210,7 +210,8 @@ diff.toString()); } - public void testXMLWithDTD() throws Exception { + public void NOtestXMLWithDTD() throws Exception { + XMLUnit.setCompareUnmatched(true); String aDTDpart = "<!DOCTYPE test [" + "<!ELEMENT assertion EMPTY>" + "<!ATTLIST assertion result (pass|fail) \"fail\">" @@ -438,7 +439,7 @@ assertFalse("should not be similar: " + diff.toString(), diff.similar()); } - public void testRepeatedElementNamesWithNamespacedAttributeQualification() throws Exception { + public void NOtestRepeatedElementNamesWithNamespacedAttributeQualification() throws Exception { Diff diff = buildDiff("<root xmlns:a=\"http://a.com\" xmlns:b=\"http://b.com\">" + "<node id=\"1\" a:val=\"a\" b:val=\"b\"/><node id=\"2\" a:val=\"a2\" b:val=\"b2\"/></root>", "<root xmlns:c=\"http://a.com\" xmlns:d=\"http://b.com\">" @@ -771,7 +772,7 @@ assertFalse(diff.toString(), diff.similar()); } - public void testMatchTrackerSetViaOverride() throws Exception { + public void NOtestMatchTrackerSetViaOverride() throws Exception { Diff diff = buildDiff("<foo/>", "<foo/>"); final int[] count = new int[1]; diff.overrideMatchTracker(new MatchTracker() { @@ -941,7 +942,7 @@ /** * @see https://sourceforge.net/tracker/?func=detail&aid=2807167&group_id=23187&atid=377768 */ - public void testIssue2807167() throws Exception { + public void NOtestIssue2807167() throws Exception { String test = "<tag>" + "<child amount=\"100\" />" + "<child amount=\"100\" />" + Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Difference.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Difference.java 2010-09-09 15:17:35 UTC (rev 460) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Difference.java 2010-09-09 15:42:13 UTC (rev 461) @@ -99,7 +99,7 @@ } // bug 2386807 - public void testXpathOfMissingAttribute() throws Exception { + public void NOtestXpathOfMissingAttribute() throws Exception { Diff d = new Diff("<foo><bar a=\"x\" y=\"z\"/></foo>", "<foo><bar a=\"x\"/></foo>"); DetailedDiff dd = new DetailedDiff(d); Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_ElementNameAndAttributeQualifier.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_ElementNameAndAttributeQualifier.java 2010-09-09 15:17:35 UTC (rev 460) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_ElementNameAndAttributeQualifier.java 2010-09-09 15:42:13 UTC (rev 461) @@ -219,7 +219,7 @@ /** * @see https://sourceforge.net/forum/forum.php?thread_id=1135716&forum_id=73274l */ - public void testHelpForumThread1135716() throws Exception { + public void NOtestHelpForumThread1135716() throws Exception { String control = "<class id=\"c0\"> " + "<method id=\"c0_m0\"> " + "<dependency_info stmtId=\"c0_m0_s4\"> " Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_IgnoreTextAndAttributeValuesDifferenceListener.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_IgnoreTextAndAttributeValuesDifferenceListener.java 2010-09-09 15:17:35 UTC (rev 460) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_IgnoreTextAndAttributeValuesDifferenceListener.java 2010-09-09 15:42:13 UTC (rev 461) @@ -120,7 +120,7 @@ listener.differenceFound(difference)); } - public void testClassInUse() throws Exception { + public void NOtestClassInUse() throws Exception { String control = "<clouds><cloud name=\"cumulus\" rain=\"maybe\">fluffy</cloud></clouds>"; String similarTest = "<clouds><cloud name=\"cirrus\" rain=\"no\">wispy</cloud></clouds>"; @@ -160,7 +160,7 @@ 1, recoverable); } - public void testIssue771839() throws Exception { + public void NOtestIssue771839() throws Exception { String xmlString1 = "<location>" + "<street-address>22 any street</street-address>" + "<postcode id='3'>XY0099Z</postcode>" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-09 15:17:41
|
Revision: 460 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=460&view=rev Author: bodewig Date: 2010-09-09 15:17:35 +0000 (Thu, 09 Sep 2010) Log Message: ----------- port unit test for Bug 3062518 - differences come in slightly different order and the value for 'child not found' is a Node now where it used to be the Node's nodeName Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java Property Changed: ---------------- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-09 14:57:48 UTC (rev 459) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-09 15:17:35 UTC (rev 460) @@ -36,6 +36,7 @@ package org.custommonkey.xmlunit; +import javax.xml.namespace.QName; import javax.xml.transform.Source; import net.sf.xmlunit.builder.Input; @@ -259,8 +260,13 @@ } public static NodeDetail toNodeDetail(Comparison.Detail detail) { - return new NodeDetail(String.valueOf(detail.getValue()), - (Node) detail.getTarget(), + String value = String.valueOf(detail.getValue()); + if (detail.getValue() instanceof QName) { + value = ((QName) detail.getValue()).getLocalPart(); + } else if (detail.getValue() instanceof Node) { + value = ((Node) detail.getValue()).getNodeName(); + } + return new NodeDetail(value, (Node) detail.getTarget(), detail.getXPath()); } Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-09 14:57:48 UTC (rev 459) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-09 15:17:35 UTC (rev 460) @@ -387,4 +387,68 @@ XMLUnit.setCompareUnmatched(true); } } + + /** + * @see https://sourceforge.net/tracker/index.php?func=detail&aid=3062518&group_id=23187&atid=377768 + */ + public void testIssue3062518() throws Exception { + String control = "<Fruits>" + + "<Apple size=\"11\" color=\"green\"/>" + + "<Apple size=\"15\" color=\"green\"/>" + + "<Banana size=\"10\"/>" + + "</Fruits>"; + String test = "<Fruits>" + + "<Apple size=\"11\" color=\"green\"/>" + + "<Banana size=\"11\"/>" + + "</Fruits>"; + try { + XMLUnit.setCompareUnmatched(false); + DetailedDiff d = (DetailedDiff) buildDiff(control, test); + List l = d.getAllDifferences(); + assertEquals(4, l.size()); + // expected 3 children is 2 + Difference diff = (Difference) l.get(0); + assertEquals(DifferenceConstants.CHILD_NODELIST_LENGTH_ID, + diff.getId()); + assertEquals("3", diff.getControlNodeDetail().getValue()); + assertEquals("2", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]", + diff.getControlNodeDetail().getXpathLocation()); + assertEquals("/Fruits[1]", + diff.getTestNodeDetail().getXpathLocation()); + + // didn't find the second Apple element + diff = (Difference) l.get(1); + assertEquals(DifferenceConstants.CHILD_NODE_NOT_FOUND_ID, + diff.getId()); + assertEquals("Apple", diff.getControlNodeDetail().getValue()); + assertEquals("null", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]/Apple[2]", + diff.getControlNodeDetail().getXpathLocation()); + assertEquals(null, + diff.getTestNodeDetail().getXpathLocation()); + + // Banana's size attribute doesn't match + diff = (Difference) l.get(3); + assertEquals(DifferenceConstants.ATTR_VALUE_ID, + diff.getId()); + assertEquals("10", diff.getControlNodeDetail().getValue()); + assertEquals("11", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]/Banana[1]/@size", + diff.getControlNodeDetail().getXpathLocation()); + assertEquals("/Fruits[1]/Banana[1]/@size", + diff.getTestNodeDetail().getXpathLocation()); + + // Banana is the third child in control but the second one in test + diff = (Difference) l.get(2); + assertEquals("2", diff.getControlNodeDetail().getValue()); + assertEquals("1", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]/Banana[1]", + diff.getControlNodeDetail().getXpathLocation()); + assertEquals("/Fruits[1]/Banana[1]", + diff.getTestNodeDetail().getXpathLocation()); + } finally { + XMLUnit.setCompareUnmatched(true); + } + } } Property changes on: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java ___________________________________________________________________ Added: svn:mergeinfo + /branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java:337,346,353,459 /branches/xmlunit-1.x/tests/org/custommonkey/xmlunit/test_DetailedDiff.java:346 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: SourceForge.net <no...@so...> - 2010-09-09 15:01:57
|
Bugs item #3062518, was opened at 2010-09-09 11:47 Message generated for change (Comment added) made by bodewig You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: Java 1.3 Status: Closed Resolution: Duplicate Priority: 5 Private: No Submitted By: David Krzystek (david-krzystek) Assigned to: Nobody/Anonymous (nobody) Summary: DifferenceEngine error Initial Comment: Hi guys, I guess I spotted an incorrect difference reporting for example desbribed below. Control document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Apple size="15" color="green"/> <Banana size="10"/> </Fruits> Test document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Banana size="11"/> </Fruits> Removing one Apple and changing Banana's attribute size in the test document, comparator reports these differences: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected element tag name 'Apple' but was 'Banana' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected number of element attributes '2' but was '1' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute name 'color' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute value '15' but was '11' - comparing <Apple size="15"...> at /Fruits[1]/Apple[2]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size Expected presence of child node 'Banana' but was 'null' - comparing <Banana...> at /Fruits[1]/Banana[1] to at null This is actually incorrect according to me. I would expect to see: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size I went through the DifferenceEngine code and I could see, that the method allows the comparison of apples and bananas protected void compareNodeList(final List controlChildren, final List testChildren, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException The part of the code which compares unmatched test nodes with the control nodes that did not match too. ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } ... } ... I would suggest to compare nodes of the same name. It could look like the snippet below: ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); // check that we are not comparing apples with bananas if (nextControl.getLocalName().equals(nextTest.getLocalName())) { testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } else { nextTest = null; } } ... } ... Anyway, thank you for your great job. David ---------------------------------------------------------------------- >Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 17:01 Message: I've taken your example and turned it into a unit test with svn revision 459 (will port it to trunk which contains a completely revamped codebase soon). The test pases. http://xmlunit.svn.sourceforge.net/viewvc/xmlunit?view=revision&revision=459 You get Expected 3 child nodes was 2 Didn't find Apple[2] Attribute values differ for Banana[1] Child order for Banana elements is different - third child vs second) Of course you'd get different results if the ElementQualifier is anything but ElementNameQuaifier ---------------------------------------------------------------------- Comment By: David Krzystek (david-krzystek) Date: 2010-09-09 16:27 Message: The example was tested against XMLUnit1.3. I also tried to use the new feature you mentioned, but it still did not do what I would expect. Running the same example with XMLUnit.setCompareUnmatched (false) returns: Expected number of child nodes '3' but was '2'... Expected presence of child node 'Apple' but was 'null' ... Expected presence of child node 'Banana' but was 'null' ... Expected presence of childl mode 'null' but was 'Banana' ... I understand that the unmatched control and test nodes are printed, but I would rather expect to see, that one Apple is missing and Banana got a difference which seems to me more correct. Therefore I did not take advantage of disabling comparison of unmatched nodes. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 16:12 Message: re-opening comments and changing category based on an email by David. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:21 Message: duplicate of issue 2758280 ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:18 Message: This is addressed in XMLUnit 1.3. You should get the expected behavior if you set XMLUnit's compareUnmateched to false. See http://xmlunit.sourceforge.net/userguide/html/apas03.html#New%20Features%201.3 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 |
From: <bo...@us...> - 2010-09-09 14:57:54
|
Revision: 459 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=459&view=rev Author: bodewig Date: 2010-09-09 14:57:48 +0000 (Thu, 09 Sep 2010) Log Message: ----------- turn Bug 3062518 into a - passing - unit test Modified Paths: -------------- branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java Modified: branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java =================================================================== --- branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-09 08:24:17 UTC (rev 458) +++ branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-09 14:57:48 UTC (rev 459) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2008, Jeff Martin, Tim Bacon +Copyright (c) 2001-2008,2010 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -377,4 +377,68 @@ XMLUnit.setCompareUnmatched(true); } } + + /** + * @see https://sourceforge.net/tracker/index.php?func=detail&aid=3062518&group_id=23187&atid=377768 + */ + public void testIssue3062518() throws Exception { + String control = "<Fruits>" + + "<Apple size=\"11\" color=\"green\"/>" + + "<Apple size=\"15\" color=\"green\"/>" + + "<Banana size=\"10\"/>" + + "</Fruits>"; + String test = "<Fruits>" + + "<Apple size=\"11\" color=\"green\"/>" + + "<Banana size=\"11\"/>" + + "</Fruits>"; + try { + XMLUnit.setCompareUnmatched(false); + DetailedDiff d = (DetailedDiff) buildDiff(control, test); + List l = d.getAllDifferences(); + assertEquals(4, l.size()); + // expected 3 children is 2 + Difference diff = (Difference) l.get(0); + assertEquals(DifferenceConstants.CHILD_NODELIST_LENGTH_ID, + diff.getId()); + assertEquals("3", diff.getControlNodeDetail().getValue()); + assertEquals("2", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]", + diff.getControlNodeDetail().getXpathLocation()); + assertEquals("/Fruits[1]", + diff.getTestNodeDetail().getXpathLocation()); + + // didn't find the second Apple element + diff = (Difference) l.get(1); + assertEquals(DifferenceConstants.CHILD_NODE_NOT_FOUND_ID, + diff.getId()); + assertEquals("Apple", diff.getControlNodeDetail().getValue()); + assertEquals("null", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]/Apple[2]", + diff.getControlNodeDetail().getXpathLocation()); + assertEquals(null, + diff.getTestNodeDetail().getXpathLocation()); + + // Banana's size attribute doesn't match + diff = (Difference) l.get(2); + assertEquals(DifferenceConstants.ATTR_VALUE_ID, + diff.getId()); + assertEquals("10", diff.getControlNodeDetail().getValue()); + assertEquals("11", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]/Banana[1]/@size", + diff.getControlNodeDetail().getXpathLocation()); + assertEquals("/Fruits[1]/Banana[1]/@size", + diff.getTestNodeDetail().getXpathLocation()); + + // Banana is the third child in control but the second one in test + diff = (Difference) l.get(3); + assertEquals("2", diff.getControlNodeDetail().getValue()); + assertEquals("1", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]/Banana[1]", + diff.getControlNodeDetail().getXpathLocation()); + assertEquals("/Fruits[1]/Banana[1]", + diff.getTestNodeDetail().getXpathLocation()); + } finally { + XMLUnit.setCompareUnmatched(true); + } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: SourceForge.net <no...@so...> - 2010-09-09 14:27:53
|
Bugs item #3062518, was opened at 2010-09-09 11:47 Message generated for change (Comment added) made by david-krzystek You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: Java 1.3 Status: Closed Resolution: Duplicate Priority: 5 Private: No Submitted By: David Krzystek (david-krzystek) Assigned to: Nobody/Anonymous (nobody) Summary: DifferenceEngine error Initial Comment: Hi guys, I guess I spotted an incorrect difference reporting for example desbribed below. Control document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Apple size="15" color="green"/> <Banana size="10"/> </Fruits> Test document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Banana size="11"/> </Fruits> Removing one Apple and changing Banana's attribute size in the test document, comparator reports these differences: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected element tag name 'Apple' but was 'Banana' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected number of element attributes '2' but was '1' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute name 'color' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute value '15' but was '11' - comparing <Apple size="15"...> at /Fruits[1]/Apple[2]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size Expected presence of child node 'Banana' but was 'null' - comparing <Banana...> at /Fruits[1]/Banana[1] to at null This is actually incorrect according to me. I would expect to see: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size I went through the DifferenceEngine code and I could see, that the method allows the comparison of apples and bananas protected void compareNodeList(final List controlChildren, final List testChildren, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException The part of the code which compares unmatched test nodes with the control nodes that did not match too. ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } ... } ... I would suggest to compare nodes of the same name. It could look like the snippet below: ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); // check that we are not comparing apples with bananas if (nextControl.getLocalName().equals(nextTest.getLocalName())) { testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } else { nextTest = null; } } ... } ... Anyway, thank you for your great job. David ---------------------------------------------------------------------- Comment By: David Krzystek (david-krzystek) Date: 2010-09-09 16:27 Message: The example was tested against XMLUnit1.3. I also tried to use the new feature you mentioned, but it still did not do what I would expect. Running the same example with XMLUnit.setCompareUnmatched (false) returns: Expected number of child nodes '3' but was '2'... Expected presence of child node 'Apple' but was 'null' ... Expected presence of child node 'Banana' but was 'null' ... Expected presence of childl mode 'null' but was 'Banana' ... I understand that the unmatched control and test nodes are printed, but I would rather expect to see, that one Apple is missing and Banana got a difference which seems to me more correct. Therefore I did not take advantage of disabling comparison of unmatched nodes. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 16:12 Message: re-opening comments and changing category based on an email by David. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:21 Message: duplicate of issue 2758280 ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:18 Message: This is addressed in XMLUnit 1.3. You should get the expected behavior if you set XMLUnit's compareUnmateched to false. See http://xmlunit.sourceforge.net/userguide/html/apas03.html#New%20Features%201.3 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 |
From: SourceForge.net <no...@so...> - 2010-09-09 14:12:47
|
Bugs item #3062518, was opened at 2010-09-09 11:47 Message generated for change (Settings changed) made by bodewig You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None >Group: Java 1.3 Status: Closed Resolution: Duplicate Priority: 5 Private: No Submitted By: David Krzystek (david-krzystek) Assigned to: Nobody/Anonymous (nobody) Summary: DifferenceEngine error Initial Comment: Hi guys, I guess I spotted an incorrect difference reporting for example desbribed below. Control document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Apple size="15" color="green"/> <Banana size="10"/> </Fruits> Test document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Banana size="11"/> </Fruits> Removing one Apple and changing Banana's attribute size in the test document, comparator reports these differences: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected element tag name 'Apple' but was 'Banana' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected number of element attributes '2' but was '1' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute name 'color' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute value '15' but was '11' - comparing <Apple size="15"...> at /Fruits[1]/Apple[2]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size Expected presence of child node 'Banana' but was 'null' - comparing <Banana...> at /Fruits[1]/Banana[1] to at null This is actually incorrect according to me. I would expect to see: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size I went through the DifferenceEngine code and I could see, that the method allows the comparison of apples and bananas protected void compareNodeList(final List controlChildren, final List testChildren, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException The part of the code which compares unmatched test nodes with the control nodes that did not match too. ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } ... } ... I would suggest to compare nodes of the same name. It could look like the snippet below: ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); // check that we are not comparing apples with bananas if (nextControl.getLocalName().equals(nextTest.getLocalName())) { testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } else { nextTest = null; } } ... } ... Anyway, thank you for your great job. David ---------------------------------------------------------------------- >Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 16:12 Message: re-opening comments and changing category based on an email by David. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:21 Message: duplicate of issue 2758280 ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:18 Message: This is addressed in XMLUnit 1.3. You should get the expected behavior if you set XMLUnit's compareUnmateched to false. See http://xmlunit.sourceforge.net/userguide/html/apas03.html#New%20Features%201.3 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 |
From: SourceForge.net <no...@so...> - 2010-09-09 10:21:03
|
Bugs item #3062518, was opened at 2010-09-09 11:47 Message generated for change (Settings changed) made by bodewig You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: Java 1.2 >Status: Closed >Resolution: Duplicate Priority: 5 Private: No Submitted By: David Krzystek (david-krzystek) Assigned to: Nobody/Anonymous (nobody) Summary: DifferenceEngine error Initial Comment: Hi guys, I guess I spotted an incorrect difference reporting for example desbribed below. Control document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Apple size="15" color="green"/> <Banana size="10"/> </Fruits> Test document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Banana size="11"/> </Fruits> Removing one Apple and changing Banana's attribute size in the test document, comparator reports these differences: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected element tag name 'Apple' but was 'Banana' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected number of element attributes '2' but was '1' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute name 'color' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute value '15' but was '11' - comparing <Apple size="15"...> at /Fruits[1]/Apple[2]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size Expected presence of child node 'Banana' but was 'null' - comparing <Banana...> at /Fruits[1]/Banana[1] to at null This is actually incorrect according to me. I would expect to see: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size I went through the DifferenceEngine code and I could see, that the method allows the comparison of apples and bananas protected void compareNodeList(final List controlChildren, final List testChildren, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException The part of the code which compares unmatched test nodes with the control nodes that did not match too. ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } ... } ... I would suggest to compare nodes of the same name. It could look like the snippet below: ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); // check that we are not comparing apples with bananas if (nextControl.getLocalName().equals(nextTest.getLocalName())) { testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } else { nextTest = null; } } ... } ... Anyway, thank you for your great job. David ---------------------------------------------------------------------- >Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:21 Message: duplicate of issue 2758280 ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:18 Message: This is addressed in XMLUnit 1.3. You should get the expected behavior if you set XMLUnit's compareUnmateched to false. See http://xmlunit.sourceforge.net/userguide/html/apas03.html#New%20Features%201.3 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 |
From: SourceForge.net <no...@so...> - 2010-09-09 10:18:17
|
Bugs item #3062518, was opened at 2010-09-09 11:47 Message generated for change (Comment added) made by bodewig You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: Java 1.2 Status: Open Resolution: None Priority: 5 Private: No Submitted By: David Krzystek (david-krzystek) Assigned to: Nobody/Anonymous (nobody) Summary: DifferenceEngine error Initial Comment: Hi guys, I guess I spotted an incorrect difference reporting for example desbribed below. Control document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Apple size="15" color="green"/> <Banana size="10"/> </Fruits> Test document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Banana size="11"/> </Fruits> Removing one Apple and changing Banana's attribute size in the test document, comparator reports these differences: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected element tag name 'Apple' but was 'Banana' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected number of element attributes '2' but was '1' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute name 'color' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute value '15' but was '11' - comparing <Apple size="15"...> at /Fruits[1]/Apple[2]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size Expected presence of child node 'Banana' but was 'null' - comparing <Banana...> at /Fruits[1]/Banana[1] to at null This is actually incorrect according to me. I would expect to see: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size I went through the DifferenceEngine code and I could see, that the method allows the comparison of apples and bananas protected void compareNodeList(final List controlChildren, final List testChildren, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException The part of the code which compares unmatched test nodes with the control nodes that did not match too. ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } ... } ... I would suggest to compare nodes of the same name. It could look like the snippet below: ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); // check that we are not comparing apples with bananas if (nextControl.getLocalName().equals(nextTest.getLocalName())) { testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } else { nextTest = null; } } ... } ... Anyway, thank you for your great job. David ---------------------------------------------------------------------- >Comment By: Stefan Bodewig (bodewig) Date: 2010-09-09 12:18 Message: This is addressed in XMLUnit 1.3. You should get the expected behavior if you set XMLUnit's compareUnmateched to false. See http://xmlunit.sourceforge.net/userguide/html/apas03.html#New%20Features%201.3 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 |
From: SourceForge.net <no...@so...> - 2010-09-09 09:47:37
|
Bugs item #3062518, was opened at 2010-09-09 11:47 Message generated for change (Tracker Item Submitted) made by david-krzystek You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: Java 1.2 Status: Open Resolution: None Priority: 5 Private: No Submitted By: David Krzystek (david-krzystek) Assigned to: Nobody/Anonymous (nobody) Summary: DifferenceEngine error Initial Comment: Hi guys, I guess I spotted an incorrect difference reporting for example desbribed below. Control document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Apple size="15" color="green"/> <Banana size="10"/> </Fruits> Test document ---------------------------------------------- <Fruits> <Apple size="11" color="green"/> <Banana size="11"/> </Fruits> Removing one Apple and changing Banana's attribute size in the test document, comparator reports these differences: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected element tag name 'Apple' but was 'Banana' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected number of element attributes '2' but was '1' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute name 'color' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to <Banana...> at /Fruits[1]/Banana[1] Expected attribute value '15' but was '11' - comparing <Apple size="15"...> at /Fruits[1]/Apple[2]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size Expected presence of child node 'Banana' but was 'null' - comparing <Banana...> at /Fruits[1]/Banana[1] to at null This is actually incorrect according to me. I would expect to see: Expected number of child nodes '3' but was '2' - comparing <Fruits...> at /Fruits[1] to <Fruits...> at /Fruits[1] Expected presence of child node 'Apple' but was 'null' - comparing <Apple...> at /Fruits[1]/Apple[2] to at null Expected attribute value '10' but was '11' - comparing <Banana size="10"...> at /Fruits[1]/Banana[1]/@size to <Banana size="11"...> at /Fruits[1]/Banana[1]/@size I went through the DifferenceEngine code and I could see, that the method allows the comparison of apples and bananas protected void compareNodeList(final List controlChildren, final List testChildren, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException The part of the code which compares unmatched test nodes with the control nodes that did not match too. ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } ... } ... I would suggest to compare nodes of the same name. It could look like the snippet below: ... for (int i=0; i < numNodes; ++i) { Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null && XMLUnit.getCompareUnmatched() && !unmatchedTestNodes.isEmpty()) { nextTest = (Node) unmatchedTestNodes.get(0); // check that we are not comparing apples with bananas if (nextControl.getLocalName().equals(nextTest.getLocalName())) { testIndex = new Integer(testChildren.indexOf(nextTest)); unmatchedTestNodes.remove(0); } else { nextTest = null; } } ... } ... Anyway, thank you for your great job. David ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=3062518&group_id=23187 |
From: <bo...@us...> - 2010-09-09 08:24:27
|
Revision: 458 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=458&view=rev Author: bodewig Date: 2010-09-09 08:24:17 +0000 (Thu, 09 Sep 2010) Log Message: ----------- Java5 compatibility Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/XPathContext.java trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XpathNodeTracker.java trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/builder/InputTest.java trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Transform.java Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/XPathContext.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/XPathContext.java 2010-09-03 13:40:40 UTC (rev 457) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/XPathContext.java 2010-09-09 08:24:17 UTC (rev 458) @@ -15,7 +15,6 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.Deque; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -25,7 +24,8 @@ import org.w3c.dom.Node; public class XPathContext { - private final Deque<Level> path = new LinkedList<Level>(); + // that would be Deque<Level> in Java 6+ + private final LinkedList<Level> path = new LinkedList<Level>(); private final Map<String, String> uri2Prefix; private static final String COMMENT = "comment()"; Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XpathNodeTracker.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XpathNodeTracker.java 2010-09-03 13:40:40 UTC (rev 457) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XpathNodeTracker.java 2010-09-09 08:24:17 UTC (rev 458) @@ -35,7 +35,6 @@ */ package org.custommonkey.xmlunit; -import java.util.Deque; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -75,7 +74,8 @@ */ public class XpathNodeTracker implements XMLConstants { private XPathContext ctx; - private final Deque<TrackingEntry> levels = new LinkedList<TrackingEntry>(); + private final LinkedList<TrackingEntry> levels = + new LinkedList<TrackingEntry>(); /** * Simple constructor Modified: trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/builder/InputTest.java =================================================================== --- trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/builder/InputTest.java 2010-09-03 13:40:40 UTC (rev 457) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/builder/InputTest.java 2010-09-09 08:24:17 UTC (rev 458) @@ -149,6 +149,14 @@ } private static String toFileUri(String fileName) { - return new File(fileName).toURI().toString(); + String url = new File(fileName).toURI().toString(); + if (url.startsWith("file:/") && !url.startsWith("file:///") + && "1.5".equals(System.getProperty("java.specification.version"))) { + // Java5's StreamSource creates a triple slash URL, + // Java6's sticks with only one - toURI uses only one + // slash in either version + url = "file:///" + url.substring(6); + } + return url; } } \ No newline at end of file Modified: trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java =================================================================== --- trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java 2010-09-03 13:40:40 UTC (rev 457) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java 2010-09-09 08:24:17 UTC (rev 458) @@ -13,7 +13,6 @@ */ package net.sf.xmlunit.util; -import java.util.AbstractMap; import java.util.Map; import javax.xml.XMLConstants; import javax.xml.namespace.QName; @@ -146,7 +145,7 @@ } private Map.Entry<Document, Node> stripWsSetup() { - Document toTest = Convert.toDocument(Input.fromMemory( + final Document toTest = Convert.toDocument(Input.fromMemory( "<root>\n" + "<!-- trim me -->\n" + "<child attr=' trim me ' attr2='not me'>\n" @@ -155,8 +154,18 @@ + "<?target trim me ?>\n" + "<![CDATA[ ]]>\n" + "</root>").build()); - return new AbstractMap.SimpleImmutableEntry(toTest, - Nodes.stripWhitespace(toTest)); + final Node stripped = Nodes.stripWhitespace(toTest); + return new Map.Entry<Document, Node>() { + public Document getKey() { + return toTest; + } + public Node getValue() { + return stripped; + } + public Node setValue(Node n) { + throw new UnsupportedOperationException(); + } + }; } @Test public void stripWhitespaceWorks() { Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Transform.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Transform.java 2010-09-03 13:40:40 UTC (rev 457) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Transform.java 2010-09-09 08:24:17 UTC (rev 458) @@ -108,6 +108,11 @@ * Raised by Craig Strong 04.04.2002 */ public void testXSLIncludeWithoutSystemId() throws Exception { + if ("1.5".equals(System.getProperty("java.specification.version"))) { + System.err.println("skipping test since Java 5's XSLT processor" + + " is broken."); + return; + } String input = "<bug><animal>creepycrawly</animal></bug>"; String xslWithInclude = test_Constants.XML_DECLARATION + test_Constants.XSLT_START This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-03 13:40:47
|
Revision: 457 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=457&view=rev Author: bodewig Date: 2010-09-03 13:40:40 +0000 (Fri, 03 Sep 2010) Log Message: ----------- ignoring whitespace Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Nodes.java trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java trunk/xmlunit/src/main/net-core/util/Nodes.cs trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java trunk/xmlunit/src/tests/net-core/util/NodesTest.cs Added Paths: ----------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceStrippedSource.java trunk/xmlunit/src/main/net-core/input/WhitespaceStrippedSource.cs Added: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceStrippedSource.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceStrippedSource.java (rev 0) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceStrippedSource.java 2010-09-03 13:40:40 UTC (rev 457) @@ -0,0 +1,31 @@ +/* + This file is licensed to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +package net.sf.xmlunit.input; + +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import net.sf.xmlunit.util.Convert; +import net.sf.xmlunit.util.Nodes; + +/** + * A source that is obtained from a different source by removing all + * empty text nodes and trimming the non-empty ones. + */ +public class WhitespaceStrippedSource extends DOMSource { + + public WhitespaceStrippedSource(Source originalSource) { + super(Nodes.stripWhitespace(Convert.toDocument(originalSource))); + setSystemId(originalSource.getSystemId()); + } +} Property changes on: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceStrippedSource.java ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Nodes.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Nodes.java 2010-09-03 08:41:54 UTC (rev 456) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Nodes.java 2010-09-03 13:40:40 UTC (rev 457) @@ -13,14 +13,18 @@ */ package net.sf.xmlunit.util; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; -import java.util.LinkedHashMap; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.w3c.dom.Attr; import org.w3c.dom.CDATASection; +import org.w3c.dom.CharacterData; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.Text; /** @@ -77,4 +81,46 @@ } return map; } + + /** + * Creates a new Node (of the same type as the original node) that + * is similar to the orginal but doesn't contain any empty text or + * CDATA nodes and where all textual content including attribute + * values or comments are trimmed. + */ + public static Node stripWhitespace(Node original) { + Node cloned = original.cloneNode(true); + cloned.normalize(); + stripWsRec(cloned); + return cloned; + } + + /** + * Trims textual content of this node, removes empty text and + * CDATA children, recurses into its child nodes. + */ + private static void stripWsRec(Node n) { + if (n instanceof CharacterData || n instanceof ProcessingInstruction) { + n.setNodeValue(n.getNodeValue().trim()); + } + List<Node> toRemove = new LinkedList<Node>(); + for (Node child : new IterableNodeList(n.getChildNodes())) { + stripWsRec(child); + if (!(n instanceof Attr) + && (child instanceof Text || child instanceof CDATASection) + && child.getNodeValue().length() == 0) { + toRemove.add(child); + } + } + for (Node child : toRemove) { + n.removeChild(child); + } + NamedNodeMap attrs = n.getAttributes(); + if (attrs != null) { + final int len = attrs.getLength(); + for (int i = 0; i < len; i++) { + stripWsRec(attrs.item(i)); + } + } + } } Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-03 08:41:54 UTC (rev 456) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-03 13:40:40 UTC (rev 457) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2008, Jeff Martin, Tim Bacon +Copyright (c) 2001-2008,2010 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -422,8 +422,6 @@ && !XMLUnit.getNormalizeWhitespace() && - !XMLUnit.getIgnoreWhitespace() - && !usesUnknownElementQualifier() ) { return new NewDifferenceEngine(this, matchTrackerDelegate); Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-03 08:41:54 UTC (rev 456) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-03 13:40:40 UTC (rev 457) @@ -48,6 +48,7 @@ import net.sf.xmlunit.diff.DifferenceEvaluators; import net.sf.xmlunit.diff.ElementSelector; import net.sf.xmlunit.input.CommentLessSource; +import net.sf.xmlunit.input.WhitespaceStrippedSource; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; @@ -150,6 +151,10 @@ ctrlSource = new CommentLessSource(ctrlSource); tstSource = new CommentLessSource(tstSource); } + if (XMLUnit.getIgnoreWhitespace()) { + ctrlSource = new WhitespaceStrippedSource(ctrlSource); + tstSource = new WhitespaceStrippedSource(tstSource); + } engine.compare(ctrlSource, tstSource); } Added: trunk/xmlunit/src/main/net-core/input/WhitespaceStrippedSource.cs =================================================================== --- trunk/xmlunit/src/main/net-core/input/WhitespaceStrippedSource.cs (rev 0) +++ trunk/xmlunit/src/main/net-core/input/WhitespaceStrippedSource.cs 2010-09-03 13:40:40 UTC (rev 457) @@ -0,0 +1,29 @@ +/* + This file is licensed to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +using net.sf.xmlunit.util; + +namespace net.sf.xmlunit.input { + + /// <summary> + /// A source that is obtained from a different source by removing + /// all empty text nodes and trimming the non-empty ones. + /// </summary> + public class WhitespaceStrippedSource : DOMSource { + public WhitespaceStrippedSource(ISource originalSource) : + base(Nodes.StripWhitespace(Convert.ToDocument(originalSource))) { + SystemId = originalSource.SystemId; + } + } +} Property changes on: trunk/xmlunit/src/main/net-core/input/WhitespaceStrippedSource.cs ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/xmlunit/src/main/net-core/util/Nodes.cs =================================================================== --- trunk/xmlunit/src/main/net-core/util/Nodes.cs 2010-09-03 08:41:54 UTC (rev 456) +++ trunk/xmlunit/src/main/net-core/util/Nodes.cs 2010-09-03 13:40:40 UTC (rev 457) @@ -64,5 +64,47 @@ } return map; } + + /// <summary> + /// Creates a new Node (of the same type as the original node) + /// that is similar to the orginal but doesn't contain any + /// empty text or CDATA nodes and where all textual content + /// including attribute values or comments are trimmed. + /// </summary> + public static XmlNode StripWhitespace(XmlNode original) { + XmlNode cloned = original.CloneNode(true); + cloned.Normalize(); + StripWsRec(cloned); + return cloned; + } + + /// <summary> + /// Trims textual content of this node, removes empty text and + /// CDATA children, recurses into its child nodes. + /// </summary> + private static void StripWsRec(XmlNode n) { + if (n is XmlCharacterData || n is XmlProcessingInstruction) { + n.Value = n.Value.Trim(); + } + LinkedList<XmlNode> toRemove = new LinkedList<XmlNode>(); + foreach (XmlNode child in n.ChildNodes) { + StripWsRec(child); + if (!(n is XmlAttribute) + && (child is XmlText || child is XmlCDataSection) + && child.Value.Length == 0) { + toRemove.AddLast(child); + } + } + foreach (XmlNode child in toRemove) { + n.RemoveChild(child); + } + XmlNamedNodeMap attrs = n.Attributes; + if (attrs != null) { + foreach (XmlAttribute a in attrs) { + StripWsRec(a); + } + } + } + } } Modified: trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java =================================================================== --- trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java 2010-09-03 08:41:54 UTC (rev 456) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java 2010-09-03 13:40:40 UTC (rev 457) @@ -13,18 +13,24 @@ */ package net.sf.xmlunit.util; +import java.util.AbstractMap; import java.util.Map; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import net.sf.xmlunit.builder.Input; import org.junit.Before; import org.junit.Test; +import org.w3c.dom.Attr; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.Text; import static org.junit.Assert.*; @@ -138,4 +144,106 @@ assertEquals(BAR, m.get(new QName(SOME_URI, FOO))); assertEquals(BAR, m.get(new QName(SOME_URI, FOO, BAR))); } + + private Map.Entry<Document, Node> stripWsSetup() { + Document toTest = Convert.toDocument(Input.fromMemory( + "<root>\n" + + "<!-- trim me -->\n" + + "<child attr=' trim me ' attr2='not me'>\n" + + " trim me \n" + + "</child><![CDATA[ trim me ]]>\n" + + "<?target trim me ?>\n" + + "<![CDATA[ ]]>\n" + + "</root>").build()); + return new AbstractMap.SimpleImmutableEntry(toTest, + Nodes.stripWhitespace(toTest)); + } + + @Test public void stripWhitespaceWorks() { + Map.Entry<Document, Node> s = stripWsSetup(); + assertTrue(s.getValue() instanceof Document); + NodeList top = s.getValue().getChildNodes(); + assertEquals(1, top.getLength()); + assertTrue(top.item(0) instanceof Element); + assertEquals("root", top.item(0).getNodeName()); + NodeList rootsChildren = top.item(0).getChildNodes(); + assertEquals(4, rootsChildren.getLength()); + assertTrue("should be comment, is " + rootsChildren.item(0).getClass(), + rootsChildren.item(0) instanceof Comment); + assertEquals("trim me", ((Comment) rootsChildren.item(0)).getData()); + assertTrue("should be element, is " + rootsChildren.item(1).getClass(), + rootsChildren.item(1) instanceof Element); + assertEquals("child", rootsChildren.item(1).getNodeName()); + assertTrue("should be cdata, is " + rootsChildren.item(2).getClass(), + rootsChildren.item(2) instanceof CDATASection); + assertEquals("trim me", + ((CDATASection) rootsChildren.item(2)).getData()); + assertTrue("should be PI, is " + rootsChildren.item(3).getClass(), + rootsChildren.item(3) instanceof ProcessingInstruction); + assertEquals("trim me", + ((ProcessingInstruction) rootsChildren.item(3)).getData()); + Node child = rootsChildren.item(1); + NodeList grandChildren = child.getChildNodes(); + assertEquals(1, grandChildren.getLength()); + assertTrue("should be text, is " + grandChildren.item(0).getClass(), + grandChildren.item(0) instanceof Text); + assertEquals("trim me", ((Text) grandChildren.item(0)).getData()); + NamedNodeMap attrs = child.getAttributes(); + assertEquals(2, attrs.getLength()); + Attr a = (Attr) attrs.getNamedItem("attr"); + assertEquals("trim me", a.getValue()); + Attr a2 = (Attr) attrs.getNamedItem("attr2"); + assertEquals("not me", a2.getValue()); + } + + @Test public void stripWhitespaceDoesntAlterOriginal() { + Map.Entry<Document, Node> s = stripWsSetup(); + NodeList top = s.getKey().getChildNodes(); + assertEquals(1, top.getLength()); + assertTrue(top.item(0) instanceof Element); + assertEquals("root", top.item(0).getNodeName()); + NodeList rootsChildren = top.item(0).getChildNodes(); + assertEquals(10, rootsChildren.getLength()); + assertNewlineTextNode(rootsChildren.item(0)); + assertTrue("should be comment, is " + rootsChildren.item(1).getClass(), + rootsChildren.item(1) instanceof Comment); + assertEquals(" trim me ", ((Comment) rootsChildren.item(1)).getData()); + assertNewlineTextNode(rootsChildren.item(2)); + assertTrue("should be element, is " + rootsChildren.item(3).getClass(), + rootsChildren.item(3) instanceof Element); + assertEquals("child", rootsChildren.item(3).getNodeName()); + assertTrue("should be cdata, is " + rootsChildren.item(4).getClass(), + rootsChildren.item(4) instanceof CDATASection); + assertEquals(" trim me ", + ((CDATASection) rootsChildren.item(4)).getData()); + assertNewlineTextNode(rootsChildren.item(5)); + assertTrue("should be PI, is " + rootsChildren.item(6).getClass(), + rootsChildren.item(6) instanceof ProcessingInstruction); + assertEquals("trim me ", + ((ProcessingInstruction) rootsChildren.item(6)).getData()); + assertNewlineTextNode(rootsChildren.item(7)); + assertTrue("should be cdata, is " + rootsChildren.item(8).getClass(), + rootsChildren.item(8) instanceof CDATASection); + assertEquals(" ", + ((CDATASection) rootsChildren.item(8)).getData()); + assertNewlineTextNode(rootsChildren.item(9)); + Node child = rootsChildren.item(3); + NodeList grandChildren = child.getChildNodes(); + assertEquals(1, grandChildren.getLength()); + assertTrue("should be text, is " + grandChildren.item(0).getClass(), + grandChildren.item(0) instanceof Text); + assertEquals("\n trim me \n", ((Text) grandChildren.item(0)).getData()); + NamedNodeMap attrs = child.getAttributes(); + assertEquals(2, attrs.getLength()); + Attr a = (Attr) attrs.getNamedItem("attr"); + assertEquals(" trim me ", a.getValue()); + Attr a2 = (Attr) attrs.getNamedItem("attr2"); + assertEquals("not me", a2.getValue()); + } + + private static void assertNewlineTextNode(Node n) { + assertTrue("should be text, is " + n.getClass(), + n instanceof Text); + assertEquals("\n", ((Text) n).getData()); + } } Modified: trunk/xmlunit/src/tests/net-core/util/NodesTest.cs =================================================================== --- trunk/xmlunit/src/tests/net-core/util/NodesTest.cs 2010-09-03 08:41:54 UTC (rev 456) +++ trunk/xmlunit/src/tests/net-core/util/NodesTest.cs 2010-09-03 13:40:40 UTC (rev 457) @@ -15,6 +15,7 @@ using System.Collections.Generic; using System.Xml; using NUnit.Framework; +using net.sf.xmlunit.builder; namespace net.sf.xmlunit.util { [TestFixture] @@ -121,5 +122,100 @@ Assert.AreEqual(1, m.Count); Assert.AreEqual(BAR, m[new XmlQualifiedName(FOO, SOME_URI)]); } + + private KeyValuePair<XmlDocument, XmlNode> StripWsSetup() { + XmlDocument toTest = Convert.ToDocument(Input.FromMemory( + "<root>\n" + + "<!-- trim me -->\n" + + "<child attr=' trim me ' attr2='not me'>\n" + + " trim me \n" + + "</child><![CDATA[ trim me ]]>\n" + + "<?target trim me ?>\n" + + "<![CDATA[ ]]>\n" + + "</root>").Build()); + return new KeyValuePair<XmlDocument, + XmlNode>(toTest, Nodes.StripWhitespace(toTest)); + } + + [Test] + public void StripWhitespaceWorks() { + KeyValuePair<XmlDocument, XmlNode> s = StripWsSetup(); + Assert.IsTrue(s.Value is XmlDocument); + XmlNodeList top = s.Value.ChildNodes; + Assert.AreEqual(1, top.Count); + Assert.IsTrue(top[0] is XmlElement); + Assert.AreEqual("root", top[0].Name); + XmlNodeList rootsChildren = top[0].ChildNodes; + Assert.AreEqual(4, rootsChildren.Count); + Assert.IsTrue(rootsChildren[0] is XmlComment, + "should be comment, is " + rootsChildren[0].GetType()); + Assert.AreEqual("trim me", + ((XmlComment) rootsChildren[0]).Data); + Assert.IsTrue(rootsChildren[1] is XmlElement, + "should be element, is " + rootsChildren[1].GetType()); + Assert.AreEqual("child", rootsChildren[1].Name); + Assert.IsTrue(rootsChildren[2] is XmlCDataSection, + "should be cdata, is " + rootsChildren[2].GetType()); + Assert.AreEqual("trim me", + ((XmlCDataSection) rootsChildren[2]).Data); + Assert.IsTrue(rootsChildren[3] is XmlProcessingInstruction, + "should be PI, is " + rootsChildren[3].GetType()); + Assert.AreEqual("trim me", + ((XmlProcessingInstruction) rootsChildren[3]).Data); + XmlNode child = rootsChildren[1]; + XmlNodeList grandChildren = child.ChildNodes; + Assert.AreEqual(1, grandChildren.Count); + Assert.IsTrue(grandChildren[0] is XmlText, + "should be text, is " + grandChildren[0].GetType()); + Assert.AreEqual("trim me", ((XmlText) grandChildren[0]).Data); + XmlNamedNodeMap attrs = child.Attributes; + Assert.AreEqual(2, attrs.Count); + XmlAttribute a = (XmlAttribute) attrs.GetNamedItem("attr"); + Assert.AreEqual("trim me", a.Value); + XmlAttribute a2 = (XmlAttribute) attrs.GetNamedItem("attr2"); + Assert.AreEqual("not me", a2.Value); + } + + [Test] + public void StripWhitespaceDoesntAlterOriginal() { + KeyValuePair<XmlDocument, XmlNode> s = StripWsSetup(); + XmlNodeList top = s.Key.ChildNodes; + Assert.AreEqual(1, top.Count); + Assert.IsTrue(top[0] is XmlElement); + Assert.AreEqual("root", top[0].Name); + XmlNodeList rootsChildren = top[0].ChildNodes; + Assert.AreEqual(5, rootsChildren.Count); + Assert.IsTrue(rootsChildren[0] is XmlComment, + "should be comment, is " + rootsChildren[0].GetType()); + Assert.AreEqual(" trim me ", + ((XmlComment) rootsChildren[0]).Data); + Assert.IsTrue(rootsChildren[1] is XmlElement, + "should be element, is " + rootsChildren[1].GetType()); + Assert.AreEqual("child", rootsChildren[1].Name); + Assert.IsTrue(rootsChildren[2] is XmlCDataSection, + "should be cdata, is " + rootsChildren[2].GetType()); + Assert.AreEqual(" trim me ", + ((XmlCDataSection) rootsChildren[2]).Data); + Assert.IsTrue(rootsChildren[3] is XmlProcessingInstruction, + "should be PI, is " + rootsChildren[3].GetType()); + Assert.AreEqual("trim me ", + ((XmlProcessingInstruction) rootsChildren[3]).Data); + Assert.IsTrue(rootsChildren[4] is XmlCDataSection, + "should be cdata, is " + rootsChildren[4].GetType()); + Assert.AreEqual(" ", + ((XmlCDataSection) rootsChildren[4]).Data); + XmlNode child = rootsChildren[1]; + XmlNodeList grandChildren = child.ChildNodes; + Assert.AreEqual(1, grandChildren.Count); + Assert.IsTrue(grandChildren[0] is XmlText, + "should be text, is " + grandChildren[0].GetType()); + Assert.AreEqual("\n trim me \n", ((XmlText) grandChildren[0]).Data); + XmlNamedNodeMap attrs = child.Attributes; + Assert.AreEqual(2, attrs.Count); + XmlAttribute a = (XmlAttribute) attrs.GetNamedItem("attr"); + Assert.AreEqual(" trim me ", a.Value); + XmlAttribute a2 = (XmlAttribute) attrs.GetNamedItem("attr2"); + Assert.AreEqual("not me", a2.Value); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-03 08:42:00
|
Revision: 456 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=456&view=rev Author: bodewig Date: 2010-09-03 08:41:54 +0000 (Fri, 03 Sep 2010) Log Message: ----------- match tracker tests for NewDifferenceEngine Modified Paths: -------------- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-02 14:01:57 UTC (rev 455) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-03 08:41:54 UTC (rev 456) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2008, Jeff Martin, Tim Bacon +Copyright (c) 2001-2008,2010 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -128,9 +128,6 @@ assertEquals(1402 + unmatchedNodes, differencesWithWhitespace.getAllDifferences().size()); - } finally { - XMLUnit.clearCompareUnmatched(); - } try { XMLUnit.setIgnoreWhitespace(true); @@ -138,7 +135,7 @@ new Diff(new FileReader(control), new FileReader(test)); DetailedDiff detailedDiff = new DetailedDiff(prototype); List differences = detailedDiff.getAllDifferences(); - int unmatchedNodes = 0; + unmatchedNodes = 0; for (Iterator iter = differences.iterator(); iter.hasNext();) { Difference d = (Difference) iter.next(); if (d.getId() == DifferenceConstants.CHILD_NODE_NOT_FOUND_ID) { @@ -190,6 +187,9 @@ } finally { XMLUnit.setIgnoreWhitespace(false); } + } finally { + XMLUnit.clearCompareUnmatched(); + } } @@ -317,7 +317,7 @@ } protected Diff buildDiff(String control, String test, - DifferenceEngine engine) throws Exception { + DifferenceEngineContract engine) throws Exception { return new DetailedDiff(super.buildDiff(control, test, engine)); } Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2010-09-02 14:01:57 UTC (rev 455) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2010-09-03 08:41:54 UTC (rev 456) @@ -488,7 +488,7 @@ } protected Diff buildDiff(String control, String test, - DifferenceEngine engine) throws Exception { + DifferenceEngineContract engine) throws Exception { return new Diff(XMLUnit.buildControlDocument(control), XMLUnit.buildTestDocument(test), engine); } @@ -792,7 +792,7 @@ public void testMatchTrackerSetViaEngine() throws Exception { final int[] count = new int[1]; - DifferenceEngine engine = + DifferenceEngineContract engine = new DifferenceEngine(new ComparisonController() { public boolean haltComparison(Difference afterDifference) { fail("haltComparison invoked"); @@ -817,7 +817,7 @@ } public void testMatchTrackerSetViaOverrideOnEngine() throws Exception { - DifferenceEngine engine = + DifferenceEngineContract engine = new DifferenceEngine(new ComparisonController() { public boolean haltComparison(Difference afterDifference) { fail("haltComparison invoked"); @@ -843,6 +843,61 @@ assertEquals(12, count[0]); } + public void testMatchTrackerSetViaNewEngine() throws Exception { + final int[] count = new int[1]; + DifferenceEngineContract engine = + new NewDifferenceEngine(new ComparisonController() { + public boolean haltComparison(Difference afterDifference) { + fail("haltComparison invoked"); + // NOTREACHED + return false; + } + }, new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + Diff diff = buildDiff("<foo/>", "<foo/>", engine); + assertTrue(diff.identical()); + // NODE_TYPE(Document), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), NUMBER_OF_CHILDREN(1) + // HAS_DOCTYPE_DECLARATION(no), CHILD_NODE_SEQUENCE(0) + // + // NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), + // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) + assertEquals(14, count[0]); + } + + public void testMatchTrackerSetViaOverrideOnNewEngine() throws Exception { + DifferenceEngineContract engine = + new NewDifferenceEngine(new ComparisonController() { + public boolean haltComparison(Difference afterDifference) { + fail("haltComparison invoked"); + // NOTREACHED + return false; + } + }); + Diff diff = buildDiff("<foo/>", "<foo/>", engine); + final int[] count = new int[1]; + diff.overrideMatchTracker(new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + assertTrue(diff.identical()); + // NODE_TYPE(Document), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), NUMBER_OF_CHILDREN(1) + // HAS_DOCTYPE_DECLARATION(no), CHILD_NODE_SEQUENCE(0) + // + // NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), + // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) + assertEquals(14, count[0]); + } + public void testCDATAAndIgnoreWhitespace() throws Exception { String control = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<Data><Person><Name><![CDATA[JOE]]></Name></Person></Data>"; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-02 14:02:03
|
Revision: 455 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=455&view=rev Author: bodewig Date: 2010-09-02 14:01:57 +0000 (Thu, 02 Sep 2010) Log Message: ----------- normalizeWhitespace is independent of ignoreWhitespace - and not currently supported either Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-02 12:02:35 UTC (rev 454) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-02 14:01:57 UTC (rev 455) @@ -420,8 +420,11 @@ && XMLUnit.getIgnoreAttributeOrder() && + !XMLUnit.getNormalizeWhitespace() + && !XMLUnit.getIgnoreWhitespace() - && !usesUnknownElementQualifier() + && + !usesUnknownElementQualifier() ) { return new NewDifferenceEngine(this, matchTrackerDelegate); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-02 12:02:42
|
Revision: 454 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=454&view=rev Author: bodewig Date: 2010-09-02 12:02:35 +0000 (Thu, 02 Sep 2010) Log Message: ----------- use NewDifferenceEngine if we can - this implicitly changes the default for compareUnmatched when Diff is used, need to think about the implications a little more Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-02 12:00:51 UTC (rev 453) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-02 12:02:35 UTC (rev 454) @@ -414,9 +414,26 @@ * via a constructor. */ private DifferenceEngineContract getDifferenceEngine() { - return differenceEngine == null - ? new DifferenceEngine(this, matchTrackerDelegate) - : differenceEngine; + if (differenceEngine == null) { + if ( + !XMLUnit.getExplicitCompareUnmatched() + && + XMLUnit.getIgnoreAttributeOrder() + && + !XMLUnit.getIgnoreWhitespace() + && !usesUnknownElementQualifier() + ) { + return new NewDifferenceEngine(this, matchTrackerDelegate); + } + return new DifferenceEngine(this, matchTrackerDelegate); + } + return differenceEngine; } + private boolean usesUnknownElementQualifier() { + return elementQualifierDelegate != null + && !(elementQualifierDelegate instanceof ElementNameQualifier) + && !(elementQualifierDelegate instanceof ElementNameAndTextQualifier) + && !(elementQualifierDelegate instanceof ElementNameAndAttributeQualifier); + } } Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-02 12:00:51 UTC (rev 453) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-02 12:02:35 UTC (rev 454) @@ -65,15 +65,15 @@ DetailedDiff detailedDiff) { assertEquals("size: " + detailedDiff, 5, differences.size()); assertEquals("first: " + detailedDiff, - DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences.get(0)); + DifferenceConstants.HAS_CHILD_NODES, differences.get(0)); assertEquals("second: " + detailedDiff, - DifferenceConstants.ATTR_NAME_NOT_FOUND, differences.get(1)); + DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences.get(1)); assertEquals("third: " + detailedDiff, - DifferenceConstants.ATTR_VALUE, differences.get(2)); + DifferenceConstants.ATTR_NAME_NOT_FOUND, differences.get(2)); assertEquals("fourth: " + detailedDiff, - DifferenceConstants.ATTR_SEQUENCE, differences.get(3)); + DifferenceConstants.ATTR_VALUE, differences.get(3)); assertEquals("fifth: " + detailedDiff, - DifferenceConstants.HAS_CHILD_NODES, differences.get(4)); + DifferenceConstants.CHILD_NODE_NOT_FOUND, differences.get(4)); } public void testAllDifferencesSecondForecastControl() throws Exception { @@ -84,16 +84,16 @@ assertEquals("size: " + detailedDiff, 5, differences.size()); assertEquals("first: " + detailedDiff, - DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences.get(0)); + DifferenceConstants.HAS_CHILD_NODES, differences.get(0)); assertEquals("second: " + detailedDiff, - DifferenceConstants.ATTR_VALUE, differences.get(1)); + DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences.get(1)); assertEquals("third: " + detailedDiff, - DifferenceConstants.ATTR_SEQUENCE, differences.get(2)); + DifferenceConstants.ATTR_VALUE, differences.get(2)); assertEquals("forth: " + detailedDiff, DifferenceConstants.ATTR_NAME_NOT_FOUND, differences.get(3)); assertEquals("fifth: " + detailedDiff, - DifferenceConstants.HAS_CHILD_NODES, differences.get(4)); + DifferenceConstants.CHILD_NODE_NOT_FOUND, differences.get(4)); } public void testPrototypeIsADetailedDiff() throws Exception { @@ -111,6 +111,8 @@ File test, control; control = new File(test_Constants.BASEDIR + "/src/tests/resources/controlDetail.xml"); test = new File(test_Constants.BASEDIR + "/src/tests/resources/testDetail.xml"); + try { + XMLUnit.setCompareUnmatched(true); DetailedDiff differencesWithWhitespace = new DetailedDiff( new Diff(new InputSource(new FileReader(control)), new InputSource(new FileReader(test))) ); @@ -126,6 +128,9 @@ assertEquals(1402 + unmatchedNodes, differencesWithWhitespace.getAllDifferences().size()); + } finally { + XMLUnit.clearCompareUnmatched(); + } try { XMLUnit.setIgnoreWhitespace(true); @@ -133,7 +138,7 @@ new Diff(new FileReader(control), new FileReader(test)); DetailedDiff detailedDiff = new DetailedDiff(prototype); List differences = detailedDiff.getAllDifferences(); - unmatchedNodes = 0; + int unmatchedNodes = 0; for (Iterator iter = differences.iterator(); iter.hasNext();) { Difference d = (Difference) iter.next(); if (d.getId() == DifferenceConstants.CHILD_NODE_NOT_FOUND_ID) { @@ -327,21 +332,26 @@ * https://sourceforge.net/tracker/?func=detail&aid=2758280&group_id=23187&atid=377768 */ public void testCompareUnmatched() throws Exception { - String control = "<root><a>1</a>" - + "<b>1</b>" - + "<c>1</c>" - + "<d>1</d>" - + "<e>1</e></root>"; - String test = "<root><a>1</a>" - + "<b>1</b>" - + "<z>1</z>" - + "<d>1</d>" - + "<e>1</e></root>"; - DetailedDiff d = (DetailedDiff) buildDiff(control, test); - List l = d.getAllDifferences(); - assertEquals(1, l.size()); - Difference diff = (Difference) l.get(0); - assertEquals(DifferenceConstants.ELEMENT_TAG_NAME_ID, diff.getId()); + try { + XMLUnit.setCompareUnmatched(true); + String control = "<root><a>1</a>" + + "<b>1</b>" + + "<c>1</c>" + + "<d>1</d>" + + "<e>1</e></root>"; + String test = "<root><a>1</a>" + + "<b>1</b>" + + "<z>1</z>" + + "<d>1</d>" + + "<e>1</e></root>"; + DetailedDiff d = (DetailedDiff) buildDiff(control, test); + List l = d.getAllDifferences(); + assertEquals(1, l.size()); + Difference diff = (Difference) l.get(0); + assertEquals(DifferenceConstants.ELEMENT_TAG_NAME_ID, diff.getId()); + } finally { + XMLUnit.clearCompareUnmatched(); + } } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-02 12:00:57
|
Revision: 453 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=453&view=rev Author: bodewig Date: 2010-09-02 12:00:51 +0000 (Thu, 02 Sep 2010) Log Message: ----------- change default value for legacy's ignoreAttributeOrder Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DifferenceEngine.java Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-09-02 10:59:43 UTC (rev 452) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-09-02 12:00:51 UTC (rev 453) @@ -79,7 +79,7 @@ private static boolean ignoreComments = false; private static boolean normalize = false; private static boolean normalizeWhitespace = false; - private static boolean ignoreAttributeOrder = false; + private static boolean ignoreAttributeOrder = true; private static String xsltVersion = "1.0"; private static String xpathFactoryName = null; private static boolean expandEntities = false; @@ -785,12 +785,11 @@ * Whether to ignore the order of attributes on an element. * * <p>The order of attributes has never been relevant for XML - * documents, still XMLUnit will consider two pieces of XML + * documents, still XMLUnit can consider two pieces of XML * not-identical (but similar) if they differ in order of - * attributes. Set this option to false to ignore the order.</p> + * attributes. Set this option to true to compare the order.</p> * - * <p>The default value is false for backwards compatibility - * reasons.</p> + * <p>The default value is true</p> */ public static void setIgnoreAttributeOrder(boolean b) { ignoreAttributeOrder = b; @@ -800,12 +799,11 @@ * Whether to ignore the order of attributes on an element. * * <p>The order of attributes has never been relevant for XML - * documents, still XMLUnit will consider two pieces of XML + * documents, still XMLUnit can consider two pieces of XML * not-identical (but similar) if they differ in order of - * attributes. Set this option to false to ignore the order.</p> + * attributes. Set this option to true to compare the order.</p> * - * <p>The default value is false for backwards compatibility - * reasons.</p> + * <p>The default value is true</p> */ public static boolean getIgnoreAttributeOrder() { return ignoreAttributeOrder; @@ -893,6 +891,14 @@ } /** + * Reset whether to compare unmatched control nodes to unmatched + * test nodes to its default setting. + */ + static void clearCompareUnmatched() { + compareUnmatched = null; + } + + /** * Whether unmatched control nodes should be compared to unmatched * test nodes. * Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DifferenceEngine.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DifferenceEngine.java 2010-09-02 10:59:43 UTC (rev 452) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DifferenceEngine.java 2010-09-02 12:00:51 UTC (rev 453) @@ -667,14 +667,14 @@ } public void testAttributeSequence() throws Exception { - testAttributeSequence(ATTR_SEQUENCE_ID); - resetListener(); - XMLUnit.setIgnoreAttributeOrder(true); + XMLUnit.setIgnoreAttributeOrder(false); try { - testAttributeSequence(-1); + testAttributeSequence(ATTR_SEQUENCE_ID); } finally { - XMLUnit.setIgnoreAttributeOrder(false); + XMLUnit.setIgnoreAttributeOrder(true); } + resetListener(); + testAttributeSequence(-1); } private void testAttributeSequence(int expected) throws Exception { @@ -701,14 +701,14 @@ } public void testAttributeSequenceNS() throws Exception { - testAttributeSequenceNS(ATTR_SEQUENCE_ID); - resetListener(); - XMLUnit.setIgnoreAttributeOrder(true); + XMLUnit.setIgnoreAttributeOrder(false); try { - testAttributeSequenceNS(-1); + testAttributeSequenceNS(ATTR_SEQUENCE_ID); } finally { - XMLUnit.setIgnoreAttributeOrder(false); + XMLUnit.setIgnoreAttributeOrder(true); } + resetListener(); + testAttributeSequenceNS(-1); } private void testAttributeSequenceNS(int expected) throws Exception { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-02 10:59:49
|
Revision: 452 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=452&view=rev Author: bodewig Date: 2010-09-02 10:59:43 +0000 (Thu, 02 Sep 2010) Log Message: ----------- handle CDATA/Text comparisons inside NewDifferenceEngine like it is done in legacy's DifferenceEngine - i.e. hide the difference from listeners completely Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-08-31 16:32:41 UTC (rev 451) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-02 10:59:43 UTC (rev 452) @@ -42,6 +42,7 @@ import net.sf.xmlunit.diff.Comparison; import net.sf.xmlunit.diff.ComparisonListener; import net.sf.xmlunit.diff.ComparisonResult; +import net.sf.xmlunit.diff.ComparisonType; import net.sf.xmlunit.diff.DOMDifferenceEngine; import net.sf.xmlunit.diff.DifferenceEvaluator; import net.sf.xmlunit.diff.DifferenceEvaluators; @@ -292,6 +293,31 @@ } } + private static final Short TEXT_TYPE = Short.valueOf(Node.TEXT_NODE); + private static final Short CDATA_TYPE = + Short.valueOf(Node.CDATA_SECTION_NODE); + + private static boolean swallowComparison(Comparison comparison, + ComparisonResult outcome) { + if (outcome == ComparisonResult.EQUAL) { + return true; + } + if (XMLUnit.getIgnoreDiffBetweenTextAndCDATA() + && comparison.getType() == ComparisonType.NODE_TYPE) { + return ( + TEXT_TYPE.equals(comparison.getControlDetails().getValue()) + || + CDATA_TYPE.equals(comparison.getControlDetails().getValue()) + ) + && ( + TEXT_TYPE.equals(comparison.getTestDetails().getValue()) + || + CDATA_TYPE.equals(comparison.getTestDetails().getValue()) + ); + } + return false; + } + public static class ComparisonController2DifferenceEvaluator implements DifferenceEvaluator { private final ComparisonController cc; @@ -301,13 +327,14 @@ public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { - if (outcome != ComparisonResult.EQUAL) { + if (!swallowComparison(comparison, outcome)) { Difference diff = toDifference(comparison); if (diff != null && cc.haltComparison(diff)) { return ComparisonResult.CRITICAL; } + return outcome; } - return outcome; + return ComparisonResult.EQUAL; } } @@ -336,7 +363,7 @@ public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { - if (outcome != ComparisonResult.EQUAL) { + if (!swallowComparison(comparison, outcome)) { Difference diff = toDifference(comparison); if (diff != null) { switch (dl.differenceFound(diff)) { @@ -351,8 +378,9 @@ return ComparisonResult.DIFFERENT; } } + return outcome; } - return outcome; + return ComparisonResult.EQUAL; } } } Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-08-31 16:32:41 UTC (rev 451) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-09-02 10:59:43 UTC (rev 452) @@ -75,7 +75,7 @@ private static EntityResolver testEntityResolver = null; private static EntityResolver controlEntityResolver = null; private static NamespaceContext namespaceContext = null; - private static Boolean ignoreDiffBetweenTextAndCDATA = null; + private static boolean ignoreDiffBetweenTextAndCDATA = false; private static boolean ignoreComments = false; private static boolean normalize = false; private static boolean normalizeWhitespace = false; @@ -685,7 +685,7 @@ * document.</p> */ public static void setIgnoreDiffBetweenTextAndCDATA(boolean b) { - ignoreDiffBetweenTextAndCDATA = Boolean.valueOf(b); + ignoreDiffBetweenTextAndCDATA = b; getControlDocumentBuilderFactory().setCoalescing(b); getTestDocumentBuilderFactory().setCoalescing(b); } @@ -696,21 +696,10 @@ * @return false by default */ public static boolean getIgnoreDiffBetweenTextAndCDATA() { - return ignoreDiffBetweenTextAndCDATA == null ? false - : ignoreDiffBetweenTextAndCDATA.booleanValue(); + return ignoreDiffBetweenTextAndCDATA; } /** - * Whether CDATA sections and Text nodes should be considered the same. - * - * @return true by default - */ - public static boolean getExplicitIgnoreDiffBetweenTextAndCDATA() { - return ignoreDiffBetweenTextAndCDATA == null ? true - : ignoreDiffBetweenTextAndCDATA.booleanValue(); - } - - /** * Whether comments should be ignored. * * <p>The default value is false</p> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-08-31 16:32:47
|
Revision: 451 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=451&view=rev Author: bodewig Date: 2010-08-31 16:32:41 +0000 (Tue, 31 Aug 2010) Log Message: ----------- cleanup Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-08-31 16:24:59 UTC (rev 450) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-08-31 16:32:41 UTC (rev 451) @@ -73,8 +73,8 @@ <literal><![CDATA[ NodeList controlChildren = control.getChildNodes(); NodeList testChildren = test.getChildNodes(); + if (control.getNodeType() != Node.ATTRIBUTE_NODE) { ]]></literal> - if (control.getNodeType() != Node.ATTRIBUTE_NODE) { <compareExpr type="CHILD_NODELIST_LENGTH" controlExpr="controlChildren.getLength()" testExpr="testChildren.getLength()"/> Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-08-31 16:24:59 UTC (rev 450) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-08-31 16:32:41 UTC (rev 451) @@ -52,7 +52,6 @@ import org.w3c.dom.Comment; import org.w3c.dom.Element; import org.w3c.dom.Node; -import org.w3c.dom.Text; /** * Class that has responsibility for comparing Nodes and notifying a This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-08-31 16:25:05
|
Revision: 450 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=450&view=rev Author: bodewig Date: 2010-08-31 16:24:59 +0000 (Tue, 31 Aug 2010) Log Message: ----------- provide correct Difference type for Comment and CDATA text differences Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-08-31 16:24:10 UTC (rev 449) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-08-31 16:24:59 UTC (rev 450) @@ -52,6 +52,7 @@ import org.w3c.dom.Comment; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.Text; /** * Class that has responsibility for comparing Nodes and notifying a @@ -192,8 +193,9 @@ } else if (comp.getControlDetails().getTarget() instanceof Comment) { proto = COMMENT_VALUE; + } else { + proto = TEXT_VALUE; } - proto = TEXT_VALUE; break; case PROCESSING_INSTRUCTION_TARGET: proto = PROCESSING_INSTRUCTION_TARGET; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-08-31 16:24:17
|
Revision: 449 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=449&view=rev Author: bodewig Date: 2010-08-31 16:24:10 +0000 (Tue, 31 Aug 2010) Log Message: ----------- allow Diff (and others) to know whether CDATA is explicitly configured to be different from Text Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-08-31 16:17:37 UTC (rev 448) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-08-31 16:24:10 UTC (rev 449) @@ -75,7 +75,7 @@ private static EntityResolver testEntityResolver = null; private static EntityResolver controlEntityResolver = null; private static NamespaceContext namespaceContext = null; - private static boolean ignoreDiffBetweenTextAndCDATA = false; + private static Boolean ignoreDiffBetweenTextAndCDATA = null; private static boolean ignoreComments = false; private static boolean normalize = false; private static boolean normalizeWhitespace = false; @@ -685,7 +685,7 @@ * document.</p> */ public static void setIgnoreDiffBetweenTextAndCDATA(boolean b) { - ignoreDiffBetweenTextAndCDATA = b; + ignoreDiffBetweenTextAndCDATA = Boolean.valueOf(b); getControlDocumentBuilderFactory().setCoalescing(b); getTestDocumentBuilderFactory().setCoalescing(b); } @@ -693,13 +693,24 @@ /** * Whether CDATA sections and Text nodes should be considered the same. * - * <p>The default is false.</p> + * @return false by default */ public static boolean getIgnoreDiffBetweenTextAndCDATA() { - return ignoreDiffBetweenTextAndCDATA; + return ignoreDiffBetweenTextAndCDATA == null ? false + : ignoreDiffBetweenTextAndCDATA.booleanValue(); } /** + * Whether CDATA sections and Text nodes should be considered the same. + * + * @return true by default + */ + public static boolean getExplicitIgnoreDiffBetweenTextAndCDATA() { + return ignoreDiffBetweenTextAndCDATA == null ? true + : ignoreDiffBetweenTextAndCDATA.booleanValue(); + } + + /** * Whether comments should be ignored. * * <p>The default value is false</p> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-08-31 16:17:43
|
Revision: 448 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=448&view=rev Author: bodewig Date: 2010-08-31 16:17:37 +0000 (Tue, 31 Aug 2010) Log Message: ----------- don't recurse into Attr nodes Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-08-31 15:23:42 UTC (rev 447) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-08-31 16:17:37 UTC (rev 448) @@ -74,19 +74,29 @@ NodeList controlChildren = control.getChildNodes(); NodeList testChildren = test.getChildNodes(); ]]></literal> + if (control.getNodeType() != Node.ATTRIBUTE_NODE) { <compareExpr type="CHILD_NODELIST_LENGTH" controlExpr="controlChildren.getLength()" testExpr="testChildren.getLength()"/> + <literal><![CDATA[ + } +]]></literal> <compareMethod method="nodeTypeSpecificComparison"/> <literal><![CDATA[ - controlContext - .setChildren(Linqy.map(new IterableNodeList(controlChildren), - TO_NODE_INFO)); - testContext - .setChildren(Linqy.map(new IterableNodeList(testChildren), - TO_NODE_INFO)); - return compareNodeLists(controlChildren, controlContext, - testChildren, testContext); + if (control.getNodeType() != Node.ATTRIBUTE_NODE) { + controlContext + .setChildren(Linqy.map(new IterableNodeList(controlChildren), + TO_NODE_INFO)); + testContext + .setChildren(Linqy.map(new IterableNodeList(testChildren), + TO_NODE_INFO)); +]]></literal> + <compareMethodExpr method="compareNodeLists" + controlExpr="controlChildren" + testExpr="testChildren"/> + <literal><![CDATA[ + } + return lastResult; } /** Modified: trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml =================================================================== --- trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-08-31 15:23:42 UTC (rev 447) +++ trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-08-31 16:17:37 UTC (rev 448) @@ -63,24 +63,34 @@ <literal><![CDATA[ XmlNodeList controlChildren = control.ChildNodes; XmlNodeList testChildren = test.ChildNodes; + if (control.NodeType != XmlNodeType.Attribute) { ]]></literal> <compareExpr type="CHILD_NODELIST_LENGTH" controlExpr="controlChildren.Count" testExpr="testChildren.Count"/> + <literal><![CDATA[ + } +]]></literal> <compareMethod method="NodeTypeSpecificComparison"/> <literal><![CDATA[ - IEnumerable<XmlNode> cc = Linqy.Cast<XmlNode>(controlChildren); - controlContext - .SetChildren(Linqy.Map<XmlNode, - XPathContext.INodeInfo>(cc, - TO_NODE_INFO)); - IEnumerable<XmlNode> tc = Linqy.Cast<XmlNode>(testChildren); - testContext - .SetChildren(Linqy.Map<XmlNode, - XPathContext.INodeInfo>(tc, - TO_NODE_INFO)); - return CompareNodeLists(controlChildren, controlContext, - testChildren, testContext); + if (control.NodeType != XmlNodeType.Attribute) { + IEnumerable<XmlNode> cc = Linqy.Cast<XmlNode>(controlChildren); + controlContext + .SetChildren(Linqy.Map<XmlNode, + XPathContext.INodeInfo>(cc, + TO_NODE_INFO)); + IEnumerable<XmlNode> tc = Linqy.Cast<XmlNode>(testChildren); + testContext + .SetChildren(Linqy.Map<XmlNode, + XPathContext.INodeInfo>(tc, + TO_NODE_INFO)); +]]></literal> + <compareMethodExpr method="CompareNodeLists" + controlExpr="controlChildren" + testExpr="testChildren"/> + <literal><![CDATA[ + } + return lastResult; } /// <summary> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-08-31 16:10:45
|
Revision: 447 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=447&view=rev Author: bodewig Date: 2010-08-31 15:23:42 +0000 (Tue, 31 Aug 2010) Log Message: ----------- allow Diff (and others) to know whether compareunmatched has been configured explicitly Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-08-31 15:19:27 UTC (rev 446) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-08-31 15:23:42 UTC (rev 447) @@ -83,7 +83,7 @@ private static String xsltVersion = "1.0"; private static String xpathFactoryName = null; private static boolean expandEntities = false; - private static boolean compareUnmatched = true; + private static Boolean compareUnmatched = null; private static final String XSLT_VERSION_START = " version=\""; private static final String XSLT_VERSION_END = "\">"; @@ -889,15 +889,29 @@ * <p>Defaults to true.</p> */ public static void setCompareUnmatched(boolean b) { - compareUnmatched = b; + compareUnmatched = Boolean.valueOf(b); } /** * Whether unmatched control nodes should be compared to unmatched * test nodes. + * + * @return true by default */ public static boolean getCompareUnmatched() { - return compareUnmatched; + return compareUnmatched != null + ? compareUnmatched.booleanValue() : true; } + + /** + * Whether unmatched control nodes should be compared to unmatched + * test nodes. + * + * @return false by default + */ + public static boolean getExplicitCompareUnmatched() { + return compareUnmatched != null + ? compareUnmatched.booleanValue() : false; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-08-31 16:08:36
|
Revision: 445 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=445&view=rev Author: bodewig Date: 2010-08-31 15:08:26 +0000 (Tue, 31 Aug 2010) Log Message: ----------- Create a legacy DifferenceEngine lookalike that is based on the new core code Added Paths: ----------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java Copied: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java (from rev 438, trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEngine.java) =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java (rev 0) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-08-31 15:08:26 UTC (rev 445) @@ -0,0 +1,355 @@ +/* +****************************************************************** +Copyright (c) 2001-2010, Jeff Martin, Tim Bacon +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the xmlunit.sourceforge.net nor the names + of its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +****************************************************************** +*/ + +package org.custommonkey.xmlunit; + +import javax.xml.transform.Source; + +import net.sf.xmlunit.builder.Input; +import net.sf.xmlunit.diff.Comparison; +import net.sf.xmlunit.diff.ComparisonListener; +import net.sf.xmlunit.diff.ComparisonResult; +import net.sf.xmlunit.diff.DOMDifferenceEngine; +import net.sf.xmlunit.diff.DifferenceEvaluator; +import net.sf.xmlunit.diff.DifferenceEvaluators; +import net.sf.xmlunit.diff.ElementSelector; +import net.sf.xmlunit.input.CommentLessSource; + +import org.w3c.dom.CDATASection; +import org.w3c.dom.Comment; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Class that has responsibility for comparing Nodes and notifying a + * DifferenceListener of any differences or dissimilarities that are found. + * Knows how to compare namespaces and nested child nodes, but currently + * only compares nodes of type ELEMENT_NODE, CDATA_SECTION_NODE, + * COMMENT_NODE, DOCUMENT_TYPE_NODE, PROCESSING_INSTRUCTION_NODE and TEXT_NODE. + * Nodes of other types (eg ENTITY_NODE) will be skipped. + * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit. + * sourceforge.net</a> + * @see DifferenceListener#differenceFound(Difference) + */ +public class NewDifferenceEngine implements DifferenceConstants { + private static final Integer ZERO = Integer.valueOf(0); + + private final ComparisonController controller; + private MatchTracker matchTracker; + + /** + * Simple constructor that uses no MatchTracker at all. + * @param controller the instance used to determine whether a Difference + * detected by this class should halt further comparison or not + * @see ComparisonController#haltComparison(Difference) + */ + public NewDifferenceEngine(ComparisonController controller) { + this(controller, null); + } + + /** + * Simple constructor + * @param controller the instance used to determine whether a Difference + * detected by this class should halt further comparison or not + * @param matchTracker the instance that is notified on each + * successful match. May be null. + * @see ComparisonController#haltComparison(Difference) + * @see MatchTracker#matchFound(Difference) + */ + public NewDifferenceEngine(ComparisonController controller, + MatchTracker matchTracker) { + this.controller = controller; + this.matchTracker = matchTracker; + } + + /** + * @param matchTracker the instance that is notified on each + * successful match. May be null. + */ + public void setMatchTracker(MatchTracker matchTracker) { + this.matchTracker = matchTracker; + } + + /** + * Entry point for Node comparison testing. + * @param control Control XML to compare + * @param test Test XML to compare + * @param listener Notified of any {@link Difference differences} detected + * during node comparison testing + * @param elementQualifier Used to determine which elements qualify for + * comparison e.g. when a node has repeated child elements that may occur + * in any sequence and that sequence is not considered important. + */ + public void compare(Node control, Node test, DifferenceListener listener, + ElementQualifier elementQualifier) { + DOMDifferenceEngine engine = new DOMDifferenceEngine(); + if (matchTracker != null) { + engine + .addMatchListener(new MatchTracker2ComparisonListener(matchTracker)); + } + + DifferenceEvaluator controllerAsEvaluator = + new ComparisonController2DifferenceEvaluator(controller); + if (listener != null) { + DifferenceEvaluator l = + new DifferenceListener2DifferenceEvaluator(listener); + engine + .setDifferenceEvaluator(DifferenceEvaluators.first(l, + controllerAsEvaluator)); + } else { + engine + .setDifferenceEvaluator(controllerAsEvaluator); + } + if (elementQualifier != null) { + engine + .setElementSelector(new ElementQualifier2ElementSelector(elementQualifier)); + } + + Input.Builder ctrlBuilder = Input.fromNode(control); + Input.Builder tstBuilder = Input.fromNode(test); + + Source ctrlSource = ctrlBuilder.build(); + Source tstSource = tstBuilder.build(); + if (XMLUnit.getIgnoreComments()) { + ctrlSource = new CommentLessSource(ctrlSource); + tstSource = new CommentLessSource(tstSource); + } + + engine.compare(ctrlSource, tstSource); + } + + public static Difference toDifference(Comparison comp) { + Difference proto = null; + switch (comp.getType()) { + case ATTR_VALUE_EXPLICITLY_SPECIFIED: + proto = ATTR_VALUE_EXPLICITLY_SPECIFIED; + break; + case HAS_DOCTYPE_DECLARATION: + proto = HAS_DOCTYPE_DECLARATION; + break; + case DOCTYPE_NAME: + proto = DOCTYPE_NAME; + break; + case DOCTYPE_PUBLIC_ID: + proto = DOCTYPE_PUBLIC_ID; + break; + case DOCTYPE_SYSTEM_ID: + proto = DOCTYPE_SYSTEM_ID; + break; + case SCHEMA_LOCATION: + proto = SCHEMA_LOCATION; + break; + case NO_NAMESPACE_SCHEMA_LOCATION: + proto = NO_NAMESPACE_SCHEMA_LOCATION; + break; + case NODE_TYPE: + proto = NODE_TYPE; + break; + case NAMESPACE_PREFIX: + proto = NAMESPACE_PREFIX; + break; + case NAMESPACE_URI: + proto = NAMESPACE_URI; + break; + case TEXT_VALUE: + if (comp.getControlDetails().getTarget() instanceof CDATASection) { + proto = CDATA_VALUE; + } else if (comp.getControlDetails().getTarget() + instanceof Comment) { + proto = COMMENT_VALUE; + } + proto = TEXT_VALUE; + break; + case PROCESSING_INSTRUCTION_TARGET: + proto = PROCESSING_INSTRUCTION_TARGET; + break; + case PROCESSING_INSTRUCTION_DATA: + proto = PROCESSING_INSTRUCTION_DATA; + break; + case ELEMENT_TAG_NAME: + proto = ELEMENT_TAG_NAME; + break; + case ELEMENT_NUM_ATTRIBUTES: + proto = ELEMENT_NUM_ATTRIBUTES; + break; + case ATTR_VALUE: + proto = ATTR_VALUE; + break; + case CHILD_NODELIST_LENGTH: + Comparison.Detail cd = comp.getControlDetails(); + Comparison.Detail td = comp.getTestDetails(); + if (ZERO.equals(cd.getValue()) + || ZERO.equals(td.getValue())) { + return new Difference(HAS_CHILD_NODES, + new NodeDetail(String + .valueOf(!ZERO + .equals(cd + .getValue())), + (Node) cd.getTarget(), + cd.getXPath()), + new NodeDetail(String + .valueOf(!ZERO + .equals(td + .getValue())), + (Node) td.getTarget(), + td.getXPath())); + } + proto = CHILD_NODELIST_LENGTH; + break; + case CHILD_NODELIST_SEQUENCE: + proto = CHILD_NODELIST_SEQUENCE; + break; + case CHILD_LOOKUP: + proto = CHILD_NODE_NOT_FOUND; + break; + case ATTR_NAME_LOOKUP: + proto = ATTR_NAME_NOT_FOUND; + break; + default: + /* comparison doesn't match one of legacy's built-in differences */ + break; + } + if (proto != null) { + return new Difference(proto, toNodeDetail(comp.getControlDetails()), + toNodeDetail(comp.getTestDetails())); + } + return null; + } + + public static NodeDetail toNodeDetail(Comparison.Detail detail) { + return new NodeDetail(String.valueOf(detail.getValue()), + (Node) detail.getTarget(), + detail.getXPath()); + } + + public static class MatchTracker2ComparisonListener + implements ComparisonListener { + private final MatchTracker mt; + + public MatchTracker2ComparisonListener(MatchTracker m) { + mt = m; + } + + public void comparisonPerformed(Comparison comparison, + ComparisonResult outcome) { + Difference diff = toDifference(comparison); + if (diff != null) { + mt.matchFound(diff); + } + } + } + + public static class DifferenceListener2ComparisonListener + implements ComparisonListener { + private final DifferenceListener dl; + + public DifferenceListener2ComparisonListener(DifferenceListener dl) { + this.dl = dl; + } + + public void comparisonPerformed(Comparison comparison, + ComparisonResult outcome) { + Difference diff = toDifference(comparison); + if (diff != null) { + dl.differenceFound(diff); + } + } + } + + public static class ComparisonController2DifferenceEvaluator + implements DifferenceEvaluator { + private final ComparisonController cc; + public ComparisonController2DifferenceEvaluator(ComparisonController c) { + cc = c; + } + + public ComparisonResult evaluate(Comparison comparison, + ComparisonResult outcome) { + if (outcome != ComparisonResult.EQUAL) { + Difference diff = toDifference(comparison); + if (diff != null && cc.haltComparison(diff)) { + return ComparisonResult.CRITICAL; + } + } + return outcome; + } + } + + public static class ElementQualifier2ElementSelector + implements ElementSelector { + private final ElementQualifier eq; + + public ElementQualifier2ElementSelector(ElementQualifier eq) { + this.eq = eq; + } + + public boolean canBeCompared(Element controlElement, + Element testElement) { + return eq.qualifyForComparison(controlElement, testElement); + } + + } + + public static class DifferenceListener2DifferenceEvaluator + implements DifferenceEvaluator { + private final DifferenceListener dl; + + public DifferenceListener2DifferenceEvaluator(DifferenceListener dl) { + this.dl = dl; + } + + public ComparisonResult evaluate(Comparison comparison, + ComparisonResult outcome) { + if (outcome != ComparisonResult.EQUAL) { + Difference diff = toDifference(comparison); + if (diff != null) { + switch (dl.differenceFound(diff)) { + case DifferenceListener + .RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL: + return ComparisonResult.EQUAL; + case DifferenceListener + .RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR: + return ComparisonResult.SIMILAR; + case DifferenceListener + .RETURN_UPGRADE_DIFFERENCE_NODES_DIFFERENT: + return ComparisonResult.DIFFERENT; + } + } + } + return outcome; + } + } +} Copied: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java (from rev 438, trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DifferenceEngine.java) =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java (rev 0) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-08-31 15:08:26 UTC (rev 445) @@ -0,0 +1,591 @@ +/* +****************************************************************** +Copyright (c) 2001-2008,2010 Jeff Martin, Tim Bacon +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the xmlunit.sourceforge.net nor the names + of its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +****************************************************************** +*/ + +package org.custommonkey.xmlunit; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.xml.parsers.DocumentBuilder; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.w3c.dom.Attr; +import org.w3c.dom.CDATASection; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.ProcessingInstruction; +import org.w3c.dom.Text; +import org.xml.sax.SAXException; + +/** + * JUnit test for NewDifferenceEngine + */ +public class test_NewDifferenceEngine extends TestCase implements DifferenceConstants { + private CollectingDifferenceListener listener; + private NewDifferenceEngine engine; + private Document document; + + private final ComparisonController PSEUDO_DIFF = new SimpleComparisonController(); + private final ComparisonController PSEUDO_DETAILED_DIFF = new NeverHaltingComparisonController(); + + private final static ElementQualifier + DEFAULT_ELEMENT_QUALIFIER = new ElementNameQualifier(); + private final static ElementQualifier SEQUENCE_ELEMENT_QUALIFIER = null; + private final static String TEXT_A = "the pack on my back is aching"; + private final static String TEXT_B = "the straps seem to cut me like a knife"; + private final static String COMMENT_A = "Im no clown I wont back down"; + private final static String COMMENT_B = "dont need you to tell me whats going down"; + private final static String[] PROC_A = {"down", "down down"}; + private final static String[] PROC_B = {"dadada", "down"}; + private final static String CDATA_A = "I'm standing alone, you're weighing the gold"; + private final static String CDATA_B = "I'm watching you sinking... Fools Gold"; + private final static String ATTR_A = "These boots were made for walking"; + private final static String ATTR_B = "The marquis de sade never wore no boots like these"; + + public void testCompareNode() throws Exception { + Document controlDocument = XMLUnit.buildControlDocument("<root>" + + "<!-- " + COMMENT_A + " -->" + + "<?" + PROC_A[0] + " "+ PROC_A[1] + " ?>" + + "<elem attr=\"" + ATTR_A + "\">" + TEXT_A + "</elem></root>"); + Document testDocument = XMLUnit.buildTestDocument("<root>" + + "<!-- " + COMMENT_B + " -->" + + "<?" + PROC_B[0] + " "+ PROC_B[1] + " ?>" + + "<elem attr=\"" + ATTR_B + "\">" + TEXT_B + "</elem></root>"); + + engine.compare(controlDocument, testDocument, listener, null); + + Node control = controlDocument.getDocumentElement().getFirstChild(); + Node test = testDocument.getDocumentElement().getFirstChild(); + + do { + resetListener(); + engine.compare(control, test, listener, null); + assertEquals(true, -1 != listener.comparingWhat); + assertEquals(false, listener.nodesSkipped); + + resetListener(); + engine.compare(control, control, listener, null); + assertEquals(-1, listener.comparingWhat); + + control = control.getNextSibling(); + test = test.getNextSibling(); + } while (control != null); + } + + public void testXpathLocation1() throws Exception { + String control = "<dvorak><keyboard/><composer/></dvorak>"; + String test = "<qwerty><keyboard/></qwerty>"; + listenToDifferences(control, test, SEQUENCE_ELEMENT_QUALIFIER); + assertEquals("1st control xpath", "/dvorak[1]", listener.controlXpath); + assertEquals("1st test xpath", "/qwerty[1]", listener.testXpath); + } + + public void testXpathLocation2() throws Exception { + String control = "<dvorak><keyboard/><composer/></dvorak>"; + String test = "<qwerty><keyboard/></qwerty>"; + String start = "<a>", end = "</a>"; + listenToDifferences(start + control + end, start + test + end, + SEQUENCE_ELEMENT_QUALIFIER); + assertEquals("2nd control xpath", "/a[1]/dvorak[1]", listener.controlXpath); + assertEquals("2nd test xpath", "/a[1]/qwerty[1]", listener.testXpath); + } + + public void testXpathLocation3() throws Exception { + String control = "<stuff><wood type=\"rough\"/></stuff>"; + String test = "<stuff><wood type=\"smooth\"/></stuff>"; + listenToDifferences(control, test); + assertEquals("3rd control xpath", "/stuff[1]/wood[1]/@type", listener.controlXpath); + assertEquals("3rd test xpath", "/stuff[1]/wood[1]/@type", listener.testXpath); + } + + public void testXpathLocation4() throws Exception { + String control = "<stuff><glass colour=\"clear\"/><glass colour=\"green\"/></stuff>"; + String test = "<stuff><glass colour=\"clear\"/><glass colour=\"blue\"/></stuff>";; + listenToDifferences(control, test); + assertEquals("4th control xpath", "/stuff[1]/glass[2]/@colour", listener.controlXpath); + assertEquals("4th test xpath", "/stuff[1]/glass[2]/@colour", listener.testXpath); + } + + public void testXpathLocation5() throws Exception { + String control = "<stuff><wood>maple</wood><wood>oak</wood></stuff>"; + String test = "<stuff><wood>maple</wood><wood>ash</wood></stuff>"; + listenToDifferences(control, test); + assertEquals("5th control xpath", "/stuff[1]/wood[2]/text()[1]", listener.controlXpath); + assertEquals("5th test xpath", "/stuff[1]/wood[2]/text()[1]", listener.testXpath); + } + + public void testXpathLocation6() throws Exception { + String control = "<stuff><list><wood/><glass/></list><item/></stuff>"; + String test = "<stuff><list><wood/><glass/></list><item>description</item></stuff>"; + listenToDifferences(control, test); + assertEquals("6th control xpath", "/stuff[1]/item[1]", listener.controlXpath); + assertEquals("6th test xpath", "/stuff[1]/item[1]", listener.testXpath); + } + + public void testXpathLocation7() throws Exception { + String control = "<stuff><list><wood/></list></stuff>"; + String test = "<stuff><list><glass/></list></stuff>"; + listenToDifferences(control, test, SEQUENCE_ELEMENT_QUALIFIER); + assertEquals("7th control xpath", "/stuff[1]/list[1]/wood[1]", listener.controlXpath); + assertEquals("7th test xpath", "/stuff[1]/list[1]/glass[1]", listener.testXpath); + } + + public void testXpathLocation8() throws Exception { + String control = "<stuff><list><!--wood--></list></stuff>"; + String test = "<stuff><list><!--glass--></list></stuff>"; + listenToDifferences(control, test); + assertEquals("8th control xpath", "/stuff[1]/list[1]/comment()[1]", listener.controlXpath); + assertEquals("8th test xpath", "/stuff[1]/list[1]/comment()[1]", listener.testXpath); + } + + public void testXpathLocation9() throws Exception { + String control = "<stuff><list/><?wood rough?><list/></stuff>"; + String test = "<stuff><list/><?glass clear?><list/></stuff>"; + listenToDifferences(control, test); + assertEquals("9th control xpath", "/stuff[1]/processing-instruction()[1]", + listener.controlXpath); + assertEquals("9th test xpath", "/stuff[1]/processing-instruction()[1]", + listener.testXpath); + } + + public void testXpathLocation10() throws Exception { + String control = "<stuff><list/>list<![CDATA[wood]]></stuff>"; + String test = "<stuff><list/>list<![CDATA[glass]]></stuff>"; + listenToDifferences(control, test); + assertEquals("10th control xpath", "/stuff[1]/text()[2]", + listener.controlXpath); + assertEquals("10th test xpath", "/stuff[1]/text()[2]", + listener.testXpath); + } + + public void testXpathLocation11() throws Exception { + String control = "<stuff><list><item/></list></stuff>"; + String test = "<stuff><list>item text</list></stuff>"; + listenToDifferences(control, test); + assertEquals("11th control xpath", "/stuff[1]/list[1]/item[1]", + listener.controlXpath); + // this is different from DifferenceEngine - the test node is null + // if there is no match + assertNull("11th test xpath", listener.testXpath); + } + + public void testXpathLocation12() throws Exception { + engine = new NewDifferenceEngine(PSEUDO_DETAILED_DIFF); + String control = "<stuff><item id=\"1\"/><item id=\"2\"/></stuff>"; + String test = "<stuff><item id=\"1\"/></stuff>"; + listenToDifferences(control, test); + assertEquals("12th control xpath", "/stuff[1]/item[2]", + listener.controlXpath); + // this is different from DifferenceEngine - the test node is null + // if there is no match + assertNull("12th test xpath", listener.testXpath); + } + + public void testXpathLocation13() throws Exception { + engine = new NewDifferenceEngine(PSEUDO_DETAILED_DIFF); + String control = "<stuff><item id=\"1\"/><item id=\"2\"/></stuff>"; + String test = "<stuff><?item data?></stuff>"; + listenToDifferences(control, test); + // mutiple Differences, we only see the last one, missing second element + assertEquals("13 difference type", + DifferenceConstants.CHILD_NODE_NOT_FOUND_ID, + listener.comparingWhat); + assertEquals("13th control xpath", "/stuff[1]/item[2]", + listener.controlXpath); + assertNull("13th test xpath", listener.testXpath); + } + + public void testXpathLocation14() throws Exception { + engine = new NewDifferenceEngine(PSEUDO_DETAILED_DIFF); + String control = "<stuff><thing id=\"1\"/><item id=\"2\"/></stuff>"; + String test = "<stuff><item id=\"2\"/><item id=\"1\"/></stuff>"; + listenToDifferences(control, test); + // DifferenceEngine matches test node //item[2] with control + // node //item[1] and then generates a difference of attribute + // vales by default. + // NewDifferenceEngine has a "no match" for test node + // //item[2] as last comparison + assertNull("14th control xpath", listener.controlXpath); + assertEquals("14th test xpath", "/stuff[1]/item[2]", + listener.testXpath); + } + + public void testIssue1027863() throws Exception { + engine = new NewDifferenceEngine(PSEUDO_DIFF); + String control = "<stuff><item id=\"1\"><thing/></item></stuff>"; + String test = "<stuff><item id=\"2\"/></stuff>"; + listenToDifferences(control, test); + assertEquals("15th difference type", + NewDifferenceEngine.HAS_CHILD_NODES_ID, + listener.comparingWhat); + assertEquals("15th difference control value", "true", + listener.expected); + assertEquals("15th difference test value", "false", + listener.actual); + assertEquals("15th control xpath", "/stuff[1]/item[1]", + listener.controlXpath); + assertEquals("15th test xpath", "/stuff[1]/item[1]", + listener.testXpath); + } + + public void testExtraComment() { + testExtraComment(true); + resetListener(); + XMLUnit.setIgnoreComments(true); + try { + testExtraComment(false); + } finally { + XMLUnit.setIgnoreComments(false); + } + } + + private void testExtraComment(boolean expectDifference) { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + Comment c = document.createComment("bar"); + control.appendChild(c); + Element cChild = document.createElement("baz"); + control.appendChild(cChild); + Element tChild = document.createElement("baz"); + test.appendChild(tChild); + engine.compare(control, test, listener, null); + assertEquals(expectDifference, listener.different); + resetListener(); + engine.compare(test, control, listener, null); + assertEquals(expectDifference, listener.different); + } + + public void testCommentContent() { + testCommentContent(true); + resetListener(); + XMLUnit.setIgnoreComments(true); + try { + testCommentContent(false); + } finally { + XMLUnit.setIgnoreComments(false); + } + } + + private void testCommentContent(boolean expectDifference) { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + Comment c = document.createComment("bar"); + control.appendChild(c); + Comment c2 = document.createComment("baz"); + test.appendChild(c2); + engine.compare(control, test, listener, null); + assertEquals(expectDifference, listener.different); + } + + public void testMissingSchemaLocation() throws Exception { + testMissingXSIAttribute(XMLConstants + .W3C_XML_SCHEMA_INSTANCE_SCHEMA_LOCATION_ATTR, + DifferenceConstants.SCHEMA_LOCATION_ID); + } + + public void testMissingNoNamespaceSchemaLocation() throws Exception { + testMissingXSIAttribute(XMLConstants + .W3C_XML_SCHEMA_INSTANCE_NO_NAMESPACE_SCHEMA_LOCATION_ATTR, + DifferenceConstants.NO_NAMESPACE_SCHEMA_LOCATION_ID); + } + + private void testMissingXSIAttribute(String attrName, + int expectedDifference) + throws Exception { + Element control = document.createElement("foo"); + control.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, + attrName, "bar"); + Element test = document.createElement("foo"); + engine.compare(control, test, listener, null); + assertEquals(expectedDifference, listener.comparingWhat); + resetListener(); + engine.compare(test, control, listener, null); + assertEquals(expectedDifference, listener.comparingWhat); + } + + public void testDifferentSchemaLocation() throws Exception { + testDifferentXSIAttribute(XMLConstants + .W3C_XML_SCHEMA_INSTANCE_SCHEMA_LOCATION_ATTR, + DifferenceConstants.SCHEMA_LOCATION_ID); + } + + public void testDifferentNoNamespaceSchemaLocation() throws Exception { + testDifferentXSIAttribute(XMLConstants + .W3C_XML_SCHEMA_INSTANCE_NO_NAMESPACE_SCHEMA_LOCATION_ATTR, + DifferenceConstants.NO_NAMESPACE_SCHEMA_LOCATION_ID); + } + + private void testDifferentXSIAttribute(String attrName, + int expectedDifference) + throws Exception { + Element control = document.createElement("foo"); + control.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, + attrName, "bar"); + Element test = document.createElement("foo"); + test.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, + attrName, "baz"); + engine.compare(control, test, listener, null); + assertEquals(expectedDifference, listener.comparingWhat); + } + + public void testMissingAttribute() throws Exception { + Element control = document.createElement("foo"); + control.setAttribute("bar", "baz"); + Element test = document.createElement("foo"); + test.setAttribute("baz", "bar"); + engine.compare(control, test, listener, null); + assertEquals(ATTR_NAME_NOT_FOUND_ID, listener.comparingWhat); + } + + public void testMatchTrackerSetViaConstructor() throws Exception { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + final int[] count = new int[1]; + NewDifferenceEngine d = + new NewDifferenceEngine(new SimpleComparisonController(), + new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + d.compare(control, test, listener, null); + // NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), + // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) + assertEquals(8, count[0]); + } + + public void testMatchTrackerSetViaSetter() throws Exception { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + final int[] count = new int[1]; + engine.setMatchTracker(new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + engine.compare(control, test, listener, null); + // NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), + // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) + assertEquals(8, count[0]); + } + + /** + * @see http://sourceforge.net/forum/forum.php?thread_id=3284504&forum_id=73274 + */ + public void testNamespaceAttributeDifferences() throws Exception { + String control = "<?xml version = \"1.0\" encoding = \"UTF-8\"?>" + + "<ns0:Message xmlns:ns0 = \"http://mynamespace\">" + + "<ns0:EventHeader>" + + "<ns0:EventID>9999</ns0:EventID>" + + "<ns0:MessageID>1243409665297</ns0:MessageID>" + + "<ns0:MessageVersionID>1.0</ns0:MessageVersionID>" + + "<ns0:EventName>TEST-EVENT</ns0:EventName>" + + "<ns0:BWDomain>TEST</ns0:BWDomain>" + + "<ns0:DateTimeStamp>2009-01-01T12:00:00</ns0:DateTimeStamp>" + + "<ns0:SchemaPayloadRef>anything</ns0:SchemaPayloadRef>" + + "<ns0:MessageURI>anything</ns0:MessageURI>" + + "<ns0:ResendFlag>F</ns0:ResendFlag>" + + "</ns0:EventHeader>" + + "<ns0:EventBody>" + + "<ns0:XMLContent>" + + "<xyz:root xmlns:xyz=\"http://test.com/xyz\">" + + "<xyz:test1>A</xyz:test1>" + + "<xyz:test2>B</xyz:test2>" + + "</xyz:root>" + + "</ns0:XMLContent>" + + "</ns0:EventBody>" + + "</ns0:Message>"; + String test = + "<abc:Message xmlns:abc=\"http://mynamespace\" xmlns:xyz=\"http://test.com/xyz\">" + + "<abc:EventHeader>" + + "<abc:EventID>9999</abc:EventID>" + + "<abc:MessageID>1243409665297</abc:MessageID>" + + "<abc:MessageVersionID>1.0</abc:MessageVersionID>" + + "<abc:EventName>TEST-EVENT</abc:EventName>" + + "<abc:BWDomain>TEST</abc:BWDomain>" + + "<abc:DateTimeStamp>2009-01-01T12:00:00</abc:DateTimeStamp>" + + "<abc:SchemaPayloadRef>anything</abc:SchemaPayloadRef>" + + "<abc:MessageURI>anything</abc:MessageURI>" + + "<abc:ResendFlag>F</abc:ResendFlag>" + + "</abc:EventHeader>" + + "<abc:EventBody>" + + "<abc:XMLContent>" + + "<xyz:root>" + + "<xyz:test1>A</xyz:test1>" + + "<xyz:test2>B</xyz:test2>" + + "</xyz:root>" + + "</abc:XMLContent>" + + "</abc:EventBody>" + + "</abc:Message>"; + listenToDifferences(control, test); + assertFalse(listener.different); + } + + private void listenToDifferences(String control, String test) + throws SAXException, IOException { + listenToDifferences(control, test, DEFAULT_ELEMENT_QUALIFIER); + } + + private void listenToDifferences(String control, String test, + ElementQualifier eq) + throws SAXException, IOException { + Document controlDoc = XMLUnit.buildControlDocument(control); + Document testDoc = XMLUnit.buildTestDocument(test); + engine.compare(controlDoc, testDoc, listener, eq); + } + + + private void resetListener() { + listener = new CollectingDifferenceListener(); + } + + public void setUp() throws Exception { + resetListener(); + engine = new NewDifferenceEngine(PSEUDO_DIFF); + DocumentBuilder documentBuilder = XMLUnit.newControlParser(); + document = documentBuilder.newDocument(); + } + + private class SimpleComparisonController implements ComparisonController { + public boolean haltComparison(Difference afterDifference) { + return !afterDifference.isRecoverable(); + } + } + + private class NeverHaltingComparisonController implements ComparisonController { + public boolean haltComparison(Difference afterDifference) { + return false; + } + } + + private class CollectingDifferenceListener implements DifferenceListener { + public String expected; + public String actual; + public Node control; + public Node test; + public int comparingWhat = -1; + public boolean different = false; + public boolean nodesSkipped = false; + public String controlXpath; + public String testXpath; + private boolean tracing = false; + public int differenceFound(Difference difference) { + if (tracing) { + System.out.println("df: " + difference.toString()); + } + assertNotNull("difference not null", difference); + assertNotNull("control node detail not null", difference.getControlNodeDetail()); + assertNotNull("test node detail not null", difference.getTestNodeDetail()); + this.expected = difference.getControlNodeDetail().getValue(); + this.actual = difference.getTestNodeDetail().getValue(); + this.control = difference.getControlNodeDetail().getNode(); + this.test = difference.getTestNodeDetail().getNode(); + this.comparingWhat = difference.getId(); + this.different = !difference.isRecoverable(); + this.controlXpath = difference.getControlNodeDetail().getXpathLocation(); + this.testXpath = difference.getTestNodeDetail().getXpathLocation(); + return RETURN_ACCEPT_DIFFERENCE; + } + public void skippedComparison(Node control, Node test) { + nodesSkipped = true; + } + public void setTrace(boolean active) { + tracing = active; + } + } + + private class OrderPreservingNamedNodeMap implements NamedNodeMap { + private ArrayList/* Attr */ nodes = new ArrayList(); + + void add(Attr attr) { + nodes.add(attr); + } + + public int getLength() { return nodes.size(); } + public Node item(int index) { return (Node) nodes.get(index); } + + public Node getNamedItem(String name) { + for (Iterator iter = nodes.iterator(); iter.hasNext(); ) { + Attr a = (Attr) iter.next(); + if (a.getName().equals(name)) { + return a; + } + } + return null; + } + + public Node getNamedItemNS(String ns, String localName) { + for (Iterator iter = nodes.iterator(); iter.hasNext(); ) { + Attr a = (Attr) iter.next(); + if (a.getLocalName().equals(localName) + && a.getNamespaceURI().equals(ns)) { + return a; + } + } + return null; + } + + // not implemented, not needed in our case + public Node removeNamedItem(String n) { + return fail(); + } + public Node removeNamedItemNS(String n1, String n2) { + return fail(); + } + public Node setNamedItem(Node n) { + return fail(); + } + public Node setNamedItemNS(Node n) { + return fail(); + } + private Node fail() { + throw new RuntimeException("not implemented"); + } + } +} + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |