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-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-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-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: <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: <bo...@us...> - 2010-09-12 06:07:35
|
Revision: 463 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=463&view=rev Author: bodewig Date: 2010-09-12 06:07:29 +0000 (Sun, 12 Sep 2010) Log Message: ----------- ignore anything between the document node and the root element in legacy layer Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DifferenceEngine.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_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-09-10 15:11:00 UTC (rev 462) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-12 06:07:29 UTC (rev 463) @@ -53,6 +53,7 @@ import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; +import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -121,16 +122,22 @@ public void compare(Node control, Node test, DifferenceListener listener, ElementQualifier elementQualifier) { DOMDifferenceEngine engine = new DOMDifferenceEngine(); + + IsBetweenDocumentNodeAndRootElement checkPrelude = + new IsBetweenDocumentNodeAndRootElement(); + engine.addComparisonListener(checkPrelude); + if (matchTracker != null) { engine .addMatchListener(new MatchTracker2ComparisonListener(matchTracker)); } DifferenceEvaluator controllerAsEvaluator = - new ComparisonController2DifferenceEvaluator(controller); + new ComparisonController2DifferenceEvaluator(controller, + checkPrelude); if (listener != null) { DifferenceEvaluator l = - new DifferenceListener2DifferenceEvaluator(listener); + new DifferenceListener2DifferenceEvaluator(listener, checkPrelude); engine .setDifferenceEvaluator(DifferenceEvaluators.first(l, controllerAsEvaluator)); @@ -309,10 +316,18 @@ Short.valueOf(Node.CDATA_SECTION_NODE); private static boolean swallowComparison(Comparison comparison, - ComparisonResult outcome) { + ComparisonResult outcome, + IsBetweenDocumentNodeAndRootElement + checkPrelude) { if (outcome == ComparisonResult.EQUAL) { return true; } + if ((comparison.getType() == ComparisonType.CHILD_NODELIST_LENGTH + && comparison.getControlDetails().getTarget() instanceof Document) + || checkPrelude.shouldSkip() + ) { + return true; + } if (XMLUnit.getIgnoreDiffBetweenTextAndCDATA() && comparison.getType() == ComparisonType.NODE_TYPE) { return ( @@ -332,13 +347,16 @@ public static class ComparisonController2DifferenceEvaluator implements DifferenceEvaluator { private final ComparisonController cc; - public ComparisonController2DifferenceEvaluator(ComparisonController c) { + private final IsBetweenDocumentNodeAndRootElement checkPrelude; + public ComparisonController2DifferenceEvaluator(ComparisonController c, + IsBetweenDocumentNodeAndRootElement checkPrelude) { cc = c; + this.checkPrelude = checkPrelude; } public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { - if (!swallowComparison(comparison, outcome)) { + if (!swallowComparison(comparison, outcome, checkPrelude)) { Difference diff = toDifference(comparison); if (diff != null && cc.haltComparison(diff)) { return ComparisonResult.CRITICAL; @@ -367,14 +385,17 @@ public static class DifferenceListener2DifferenceEvaluator implements DifferenceEvaluator { private final DifferenceListener dl; + private final IsBetweenDocumentNodeAndRootElement checkPrelude; - public DifferenceListener2DifferenceEvaluator(DifferenceListener dl) { + public DifferenceListener2DifferenceEvaluator(DifferenceListener dl, + IsBetweenDocumentNodeAndRootElement checkPrelude) { this.dl = dl; + this.checkPrelude = checkPrelude; } public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { - if (!swallowComparison(comparison, outcome)) { + if (!swallowComparison(comparison, outcome, checkPrelude)) { Difference diff = toDifference(comparison); if (diff != null) { switch (dl.differenceFound(diff)) { @@ -394,4 +415,50 @@ return ComparisonResult.EQUAL; } } + + /** + * Tests whether the DifferenceEngine is currently processing + * comparisons of "things" between the document node and the + * document's root element (comments or PIs, mostly) since these + * must be ignored for backwards compatibility reasons. + * + * <p>Relies on the following assumptions: + * <ul> + + * <li>the last comparison DOMDifferenceEngine performs on the + * document node is an XML_ENCODING comparison.</li> + * <li>the first comparison DOMDifferenceEngine performs on matching + * root elements is a NODE_TYPE comparison. The control Node + * is an Element Node.</li> + * <li>the first comparison DOMDifferenceEngine performs if the + * root elements don't match is a CHILD_LOOKUP comparison. + * The control Node is an Element Node.</li> + * </ul> + * </p> + */ + private static class IsBetweenDocumentNodeAndRootElement + implements ComparisonListener { + + private boolean haveSeenXmlEncoding = false; + private boolean haveSeenElementNodeComparison = false; + + public void comparisonPerformed(Comparison comparison, + ComparisonResult outcome) { + if (comparison.getType() == ComparisonType.XML_ENCODING) { + haveSeenXmlEncoding = true; + } else if (comparison.getControlDetails().getTarget() + instanceof Element + && + (comparison.getType() == ComparisonType.NODE_TYPE + || comparison.getType() == ComparisonType.CHILD_LOOKUP) + ) { + haveSeenElementNodeComparison = true; + } + } + + private boolean shouldSkip() { + return haveSeenXmlEncoding && !haveSeenElementNodeComparison; + } + } + } 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-10 15:11:00 UTC (rev 462) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DifferenceEngine.java 2010-09-12 06:07:29 UTC (rev 463) @@ -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 @@ -925,11 +925,46 @@ + "</abc:XMLContent>" + "</abc:EventBody>" + "</abc:Message>"; - listener.tracing = true; listenToDifferences(control, test); assertFalse(listener.different); } + /** + * XMLUnit 1.3 jumps from the document node straight to the root + * element, ignoring any other children the document might have. + * Some people consider this a bug (Issue 2770386) others rely on + * it. + * + * <p>XMLUnit 2.x doesn't ignore differences in the prelude but we + * want to keep the behavior for the legacy code base.</p> + */ + public void testIgnoresDifferencesBetweenDocAndRootElement() + throws Throwable { + String control = + "<?xml version = \"1.0\" encoding = \"UTF-8\"?>" + + "<!-- some comment -->" + + "<?foo some PI ?>" + + "<bar/>"; + String test = "<bar/>"; + listenToDifferences(control, test); + assertFalse("unexpected difference: " + listener.comparingWhat, + listener.different); + resetListener(); + control = + "<?xml version = \"1.0\" encoding = \"UTF-8\"?>" + + "<!-- some comment -->" + + "<?foo some PI ?>" + + "<bar/>"; + test = + "<?xml version = \"1.0\" encoding = \"UTF-8\"?>" + + "<?foo some other PI ?>" + + "<!-- some other comment -->" + + "<bar/>"; + listenToDifferences(control, test); + assertFalse("unexpected difference: " + listener.comparingWhat, + listener.different); + } + private void listenToDifferences(String control, String test) throws SAXException, IOException { Document controlDoc = XMLUnit.buildControlDocument(control); Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-10 15:11:00 UTC (rev 462) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-12 06:07:29 UTC (rev 463) @@ -466,6 +466,42 @@ assertFalse(listener.different); } + /** + * XMLUnit 1.3 jumps from the document node straight to the root + * element, ignoring any other children the document might have. + * Some people consider this a bug (Issue 2770386) others rely on + * it. + * + * <p>XMLUnit 2.x doesn't ignore differences in the prelude but we + * want to keep the behavior for the legacy code base.</p> + */ + public void testIgnoresDifferencesBetweenDocAndRootElement() + throws Throwable { + String control = + "<?xml version = \"1.0\" encoding = \"UTF-8\"?>" + + "<!-- some comment -->" + + "<?foo some PI ?>" + + "<bar/>"; + String test = "<bar/>"; + listenToDifferences(control, test); + assertFalse("unexpected difference: " + listener.comparingWhat, + listener.different); + resetListener(); + control = + "<?xml version = \"1.0\" encoding = \"UTF-8\"?>" + + "<!-- some comment -->" + + "<?foo some PI ?>" + + "<bar/>"; + test = + "<?xml version = \"1.0\" encoding = \"UTF-8\"?>" + + "<?foo some other PI ?>" + + "<!-- some other comment -->" + + "<bar/>"; + listenToDifferences(control, test); + assertFalse("unexpected difference: " + listener.comparingWhat, + listener.different); + } + private void listenToDifferences(String control, String test) throws SAXException, IOException { listenToDifferences(control, test, DEFAULT_ELEMENT_QUALIFIER); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-13 09:49:34
|
Revision: 466 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=466&view=rev Author: bodewig Date: 2010-09-13 09:49:28 +0000 (Mon, 13 Sep 2010) Log Message: ----------- DIFFERENT is different enough to make nodes not match Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_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-09-13 08:29:05 UTC (rev 465) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-09-13 09:49:28 UTC (rev 466) @@ -484,7 +484,7 @@ compareDontFire(new Comparison(ComparisonType.NODE_TYPE, n1, null, n1.getNodeType(), n2, null, n2.getNodeType())); - return r != ComparisonResult.CRITICAL; + return r != ComparisonResult.CRITICAL && r != ComparisonResult.DIFFERENT; } private class Match { Modified: trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml =================================================================== --- trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-09-13 08:29:05 UTC (rev 465) +++ trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-09-13 09:49:28 UTC (rev 466) @@ -515,7 +515,8 @@ CompareDontFire(new Comparison(ComparisonType.NODE_TYPE, n1, null, n1.NodeType, n2, null, n2.NodeType)); - return r != ComparisonResult.CRITICAL; + return r != ComparisonResult.CRITICAL + && r != ComparisonResult.DIFFERENT; } internal class Match { Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-13 08:29:05 UTC (rev 465) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-13 09:49:28 UTC (rev 466) @@ -227,13 +227,13 @@ 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 + // mutiple Differences, we only see the last one, missing PI in test 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); + assertNull("13th control xpath", listener.controlXpath); + assertEquals("13th test xpath", "/stuff[1]/processing-instruction()[1]", + listener.testXpath); } public void testXpathLocation14() 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-13 10:46:14
|
Revision: 468 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=468&view=rev Author: bodewig Date: 2010-09-13 10:46:07 +0000 (Mon, 13 Sep 2010) Log Message: ----------- a missing test child node could be signaled after the root element of the control document has been visited Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.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 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-13 10:41:11 UTC (rev 467) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-13 10:46:07 UTC (rev 468) @@ -348,6 +348,12 @@ } if ((comparison.getType() == ComparisonType.CHILD_NODELIST_LENGTH && comparison.getControlDetails().getTarget() instanceof Document) + || + (comparison.getType() == ComparisonType.CHILD_LOOKUP + && comparison.getTestDetails() != null + && comparison.getTestDetails().getTarget() instanceof Node + && ((Node) comparison.getTestDetails().getTarget()).getParentNode() + instanceof Document) || checkPrelude.shouldSkip() ) { return true; 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-13 10:41:11 UTC (rev 467) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2010-09-13 10:46:07 UTC (rev 468) @@ -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 @@ -963,5 +963,19 @@ ElementNameAndAttributeQualifier()); assertTrue(diff.toString(), diff.similar()); } + + public void testCocoonXmlTestCase() throws Exception { + Document control = + XMLUnit.buildTestDocument("<!DOCTYPE skinconfig []>" + + "<!--abcd--><root></root>"); + Document test = + XMLUnit.buildControlDocument("<!DOCTYPE skinconfig [<!--abcd-->]>" + + "<root></root>"); + Diff diff = new Diff(control, test); + assertTrue(diff.toString(), diff.identical()); + + diff = new Diff(test, control); + assertTrue(diff.toString(), diff.identical()); + } } 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-13 10:41:11 UTC (rev 467) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Difference.java 2010-09-13 10:46:07 UTC (rev 468) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2009, Jeff Martin, Tim Bacon +Copyright (c) 2001-2010, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-13 11:37:15
|
Revision: 470 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=470&view=rev Author: bodewig Date: 2010-09-13 11:37:08 +0000 (Mon, 13 Sep 2010) Log Message: ----------- don't match test nodes more than once Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 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-13 11:25:11 UTC (rev 469) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-09-13 11:37:08 UTC (rev 470) @@ -333,7 +333,8 @@ controlContext.navigateToChild(i); try { Match testMatch = findMatchingNode(controlList.get(i), testList, - lastMatch.index); + lastMatch.index, + unmatchedTestIndexes); if (testMatch != null) { ]]></literal> testContext.navigateToChild(testMatch.index); @@ -460,14 +461,21 @@ private Match findMatchingNode(final Node searchFor, final List<Node> searchIn, - final int indexOfLastMatch) { + final int indexOfLastMatch, + final Set<Integer> availableIndexes) { final int searchSize = searchIn.size(); for (int i = indexOfLastMatch + 1; i < searchSize; i++) { + if (!availableIndexes.contains(Integer.valueOf(i))) { + continue; + } if (nodesMatch(searchFor, searchIn.get(i))) { return new Match(searchIn.get(i), i); } } for (int i = 0; i < indexOfLastMatch; i++) { + if (!availableIndexes.contains(Integer.valueOf(i))) { + continue; + } if (nodesMatch(searchFor, searchIn.get(i))) { return new Match(searchIn.get(i), i); } Modified: trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml =================================================================== --- trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-09-13 11:25:11 UTC (rev 469) +++ trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-09-13 11:37:08 UTC (rev 470) @@ -368,7 +368,8 @@ Match lastMatch = new Match(null, -1); for (int i = 0; i < controlList.Count; i++) { Match testMatch = FindMatchingNode(controlList[i], testList, - lastMatch.Index); + lastMatch.Index, + unmatchedTestIndexes); controlContext.NavigateToChild(i); try { if (testMatch != null) { @@ -492,14 +493,22 @@ private Match FindMatchingNode(XmlNode searchFor, IList<XmlNode> searchIn, - int indexOfLastMatch) { + int indexOfLastMatch, + IDictionary<int, object> + availableIndexes) { int searchSize = searchIn.Count; for (int i = indexOfLastMatch + 1; i < searchSize; i++) { + if (!availableIndexes.ContainsKey(i)) { + continue; + } if (NodesMatch(searchFor, searchIn[i])) { return new Match(searchIn[i], i); } } for (int i = 0; i < indexOfLastMatch; i++) { + if (!availableIndexes.ContainsKey(i)) { + continue; + } if (NodesMatch(searchFor, searchIn[i])) { return new Match(searchIn[i], i); } 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-13 11:25:11 UTC (rev 469) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2010-09-13 11:37:08 UTC (rev 470) @@ -941,7 +941,7 @@ /** * @see https://sourceforge.net/tracker/?func=detail&aid=2807167&group_id=23187&atid=377768 */ - public void NOtestIssue2807167() throws Exception { + public void testIssue2807167() throws Exception { String test = "<tag>" + "<child amount=\"100\" />" + "<child amount=\"100\" />" + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-14 06:55:57
|
Revision: 473 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=473&view=rev Author: bodewig Date: 2010-09-14 06:55:50 +0000 (Tue, 14 Sep 2010) Log Message: ----------- make the whole process of selecting nodes to match pluggable via a strategy Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/AbstractDifferenceEngine.java trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DifferenceEngine.java trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java trunk/xmlunit/src/main/net-core/diff/AbstractDifferenceEngine.cs trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml trunk/xmlunit/src/main/net-core/diff/IDifferenceEngine.cs trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/DOMDifferenceEngineTest.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs Added Paths: ----------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DefaultNodeMatcher.java trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/NodeMatcher.java trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs trunk/xmlunit/src/main/net-core/diff/INodeMatcher.cs Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/AbstractDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/AbstractDifferenceEngine.java 2010-09-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/AbstractDifferenceEngine.java 2010-09-14 06:55:50 UTC (rev 473) @@ -23,7 +23,7 @@ public abstract class AbstractDifferenceEngine implements DifferenceEngine { private final ComparisonListenerSupport listeners = new ComparisonListenerSupport(); - private ElementSelector elementSelector = ElementSelectors.Default; + private NodeMatcher nodeMatcher = new DefaultNodeMatcher(); private DifferenceEvaluator diffEvaluator = DifferenceEvaluators.Default; private Map<String, String> uri2Prefix = Collections.emptyMap(); @@ -48,16 +48,16 @@ listeners.addDifferenceListener(l); } - public void setElementSelector(ElementSelector s) { - if (s == null) { - throw new IllegalArgumentException("element selector must" + public void setNodeMatcher(NodeMatcher n) { + if (n == null) { + throw new IllegalArgumentException("node matcher must" + " not be null"); } - elementSelector = s; + nodeMatcher = n; } - public ElementSelector getElementSelector() { - return elementSelector; + public NodeMatcher getNodeMatcher() { + return nodeMatcher; } public void setDifferenceEvaluator(DifferenceEvaluator e) { 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-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java.xml 2010-09-14 06:55:50 UTC (rev 473) @@ -20,6 +20,7 @@ <import reference="java.util.HashSet"/> <import reference="java.util.LinkedList"/> <import reference="java.util.List"/> + <import reference="java.util.Map"/> <import reference="java.util.Set"/> <import reference="java.util.TreeSet"/> <import reference="javax.xml.XMLConstants"/> @@ -315,47 +316,46 @@ XPathContext controlContext, Iterable<Node> testSeq, XPathContext testContext) { - 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++) { - unmatchedTestIndexes.add(Integer.valueOf(i)); - } ]]></literal> <lastResultDef/> <literal><![CDATA[ // if there are no children on either Node, the result is equal lastResult = ComparisonResult.EQUAL; - final int controlSize = controlList.size(); - Match lastMatch = new Match(null, -1); - for (int i = 0; i < controlSize; i++) { - controlContext.navigateToChild(i); + + Iterable<Map.Entry<Node, Node>> matches = + getNodeMatcher().match(controlSeq, testSeq); + List<Node> controlList = Linqy.asList(controlSeq); + List<Node> testList = Linqy.asList(testSeq); + Set<Node> seen = new HashSet<Node>(); + for (Map.Entry<Node, Node> pair : matches) { + Node control = pair.getKey(); + seen.add(control); + Node test = pair.getValue(); + seen.add(test); + int controlIndex = controlList.indexOf(control); + int testIndex = testList.indexOf(test); + controlContext.navigateToChild(controlIndex); + testContext.navigateToChild(testIndex); try { - Match testMatch = findMatchingNode(controlList.get(i), testList, - lastMatch.index, - unmatchedTestIndexes); - if (testMatch != null) { ]]></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" + controlExpr="Integer.valueOf(controlIndex)" + testExpr="Integer.valueOf(testIndex)" /> <compareMethodExpr method="compareNodes" controlExpr="control" testExpr="test"/> <literal><![CDATA[ - unmatchedTestIndexes.remove(testIndex); - lastMatch = testMatch; - } finally { - testContext.navigateToParent(); - } - } else { + } finally { + testContext.navigateToParent(); + controlContext.navigateToParent(); + } + } + final int controlSize = controlList.size(); + for (int i = 0; i < controlSize; i++) { + if (!seen.contains(controlList.get(i))) { + controlContext.navigateToChild(i); + try { lastResult = compare(new Comparison(ComparisonType.CHILD_LOOKUP, controlList.get(i), @@ -365,26 +365,28 @@ ]]></literal> <if-return-boilerplate/> <literal><![CDATA[ + } finally { + controlContext.navigateToParent(); } - } finally { - controlContext.navigateToParent(); } } - for (Integer I : unmatchedTestIndexes) { - int i = I.intValue(); - testContext.navigateToChild(i); - try { - lastResult = - compare(new Comparison(ComparisonType.CHILD_LOOKUP, - null, null, null, - testList.get(i), - getXPath(testContext), - testList.get(i))); + final int testSize = testList.size(); + for (int i = 0; i < testSize; i++) { + if (!seen.contains(testList.get(i))) { + testContext.navigateToChild(i); + try { + lastResult = + compare(new Comparison(ComparisonType.CHILD_LOOKUP, + null, null, null, + testList.get(i), + getXPath(testContext), + testList.get(i))); ]]></literal> <if-return-boilerplate/> <literal><![CDATA[ - } finally { - testContext.navigateToParent(); + } finally { + testContext.navigateToParent(); + } } } return lastResult; @@ -459,51 +461,6 @@ return null; } - private Match findMatchingNode(final Node searchFor, - final List<Node> searchIn, - final int indexOfLastMatch, - final Set<Integer> availableIndexes) { - final int searchSize = searchIn.size(); - for (int i = indexOfLastMatch + 1; i < searchSize; i++) { - if (!availableIndexes.contains(Integer.valueOf(i))) { - continue; - } - if (nodesMatch(searchFor, searchIn.get(i))) { - return new Match(searchIn.get(i), i); - } - } - for (int i = 0; i < indexOfLastMatch; i++) { - if (!availableIndexes.contains(Integer.valueOf(i))) { - continue; - } - if (nodesMatch(searchFor, searchIn.get(i))) { - return new Match(searchIn.get(i), i); - } - } - return null; - } - - private boolean nodesMatch(final Node n1, final Node n2) { - if (n1 instanceof Element && n2 instanceof Element) { - return getElementSelector() - .canBeCompared((Element) n1, (Element) n2); - } - ComparisonResult r = - compareDontFire(new Comparison(ComparisonType.NODE_TYPE, - n1, null, n1.getNodeType(), - n2, null, n2.getNodeType())); - return r != ComparisonResult.CRITICAL && r != ComparisonResult.DIFFERENT; - } - - private class Match { - private final Node node; - private final int index; - private Match(Node match, int index) { - this.node = match; - this.index = index; - } - } - private static final Linqy.Mapper<Node, QName> QNAME_MAPPER = new Linqy.Mapper<Node, QName>() { public QName map(Node n) { return Nodes.getQName(n); } Added: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DefaultNodeMatcher.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DefaultNodeMatcher.java (rev 0) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DefaultNodeMatcher.java 2010-09-14 06:55:50 UTC (rev 473) @@ -0,0 +1,125 @@ +/* + 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.diff; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import net.sf.xmlunit.util.Linqy; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Strategy that matches control and tests nodes for comparison. + */ +public class DefaultNodeMatcher implements NodeMatcher { + private final ElementSelector elementSelector; + private final NodeTypeMatcher nodeTypeMatcher; + + public DefaultNodeMatcher() { + this(ElementSelectors.Default); + } + + public DefaultNodeMatcher(ElementSelector es) { + this(es, new DefaultNodeTypeMatcher()); + } + + public DefaultNodeMatcher(ElementSelector es, NodeTypeMatcher ntm) { + elementSelector = es; + nodeTypeMatcher = ntm; + } + + public Iterable<Map.Entry<Node, Node>> match(Iterable<Node> controlNodes, + Iterable<Node> testNodes) { + Map<Node, Node> matches = new LinkedHashMap<Node, Node>(); + List<Node> controlList = Linqy.asList(controlNodes); + List<Node> testList = Linqy.asList(testNodes); + final int testSize = testList.size(); + Set<Integer> unmatchedTestIndexes = new TreeSet<Integer>(); + for (int i = 0; i < testSize; i++) { + unmatchedTestIndexes.add(Integer.valueOf(i)); + } + final int controlSize = controlList.size(); + Match lastMatch = new Match(null, -1); + for (int i = 0; i < controlSize; i++) { + Node control = controlList.get(i); + Match testMatch = findMatchingNode(control, testList, + lastMatch.index, + unmatchedTestIndexes); + if (testMatch != null) { + unmatchedTestIndexes.remove(testMatch.index); + matches.put(control, testMatch.node); + } + } + return matches.entrySet(); + } + + private Match findMatchingNode(final Node searchFor, + final List<Node> searchIn, + final int indexOfLastMatch, + final Set<Integer> availableIndexes) { + final int searchSize = searchIn.size(); + for (int i = indexOfLastMatch + 1; i < searchSize; i++) { + if (!availableIndexes.contains(Integer.valueOf(i))) { + continue; + } + if (nodesMatch(searchFor, searchIn.get(i))) { + return new Match(searchIn.get(i), i); + } + } + for (int i = 0; i < indexOfLastMatch; i++) { + if (!availableIndexes.contains(Integer.valueOf(i))) { + continue; + } + if (nodesMatch(searchFor, searchIn.get(i))) { + return new Match(searchIn.get(i), i); + } + } + return null; + } + + private boolean nodesMatch(final Node n1, final Node n2) { + if (n1 instanceof Element && n2 instanceof Element) { + return elementSelector.canBeCompared((Element) n1, (Element) n2); + } + return nodeTypeMatcher.canBeCompared(n1.getNodeType(), + n2.getNodeType()); + } + + private class Match { + private final Node node; + private final int index; + private Match(Node match, int index) { + this.node = match; + this.index = index; + } + } + + public interface NodeTypeMatcher { + boolean canBeCompared(short controlType, short testType); + } + + private static final short CDATA = Node.TEXT_NODE; + private static final short TEXT = Node.CDATA_SECTION_NODE; + + public static class DefaultNodeTypeMatcher implements NodeTypeMatcher { + public boolean canBeCompared(short controlType, short testType) { + return controlType == testType + || (controlType == CDATA && testType == TEXT) + || (controlType == TEXT && testType == CDATA); + } + } +} Property changes on: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DefaultNodeMatcher.java ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DifferenceEngine.java 2010-09-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DifferenceEngine.java 2010-09-14 06:55:50 UTC (rev 473) @@ -38,9 +38,9 @@ void addDifferenceListener(ComparisonListener l); /** - * Sets the strategy for selecting elements to compare. + * Sets the strategy for selecting nodes to compare. */ - void setElementSelector(ElementSelector s); + void setNodeMatcher(NodeMatcher n); /** * Determines whether the comparison should stop after given Added: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/NodeMatcher.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/NodeMatcher.java (rev 0) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/NodeMatcher.java 2010-09-14 06:55:50 UTC (rev 473) @@ -0,0 +1,30 @@ +/* + 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.diff; + +import java.util.Map; +import org.w3c.dom.Node; + +/** + * Strategy that matches control and tests nodes for comparison. + */ +public interface NodeMatcher { + + /** + * Matches control and test nodes against each other, returns the + * matching pairs. + */ + Iterable<Map.Entry<Node, Node>> match(Iterable<Node> controlNodes, + Iterable<Node> testNodes); +} Property changes on: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/NodeMatcher.java ___________________________________________________________________ Added: svn:eol-style + native 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-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-14 06:55:50 UTC (rev 473) @@ -45,6 +45,7 @@ import net.sf.xmlunit.diff.ComparisonResult; import net.sf.xmlunit.diff.ComparisonType; import net.sf.xmlunit.diff.DOMDifferenceEngine; +import net.sf.xmlunit.diff.DefaultNodeMatcher; import net.sf.xmlunit.diff.DifferenceEvaluators; import net.sf.xmlunit.diff.ElementSelector; import net.sf.xmlunit.input.CommentLessSource; @@ -170,8 +171,7 @@ }); if (elementQualifier != null) { - engine - .setElementSelector(new ElementQualifier2ElementSelector(elementQualifier)); + engine.setNodeMatcher(new DefaultNodeMatcher(new ElementQualifier2ElementSelector(elementQualifier))); } Input.Builder ctrlBuilder = Input.fromNode(control); @@ -349,11 +349,12 @@ if ((comparison.getType() == ComparisonType.CHILD_NODELIST_LENGTH && comparison.getControlDetails().getTarget() instanceof Document) || - (comparison.getType() == ComparisonType.CHILD_LOOKUP - && comparison.getTestDetails() != null - && comparison.getTestDetails().getTarget() instanceof Node - && ((Node) comparison.getTestDetails().getTarget()).getParentNode() - instanceof Document) + ( + comparison.getType() == ComparisonType.CHILD_LOOKUP + && + (isNonElementDocumentChild(comparison.getControlDetails()) + || isNonElementDocumentChild(comparison.getTestDetails())) + ) || checkPrelude.shouldSkip() ) { return true; @@ -374,6 +375,12 @@ return false; } + private static boolean isNonElementDocumentChild(Comparison.Detail detail) { + return detail != null && detail.getTarget() instanceof Node + && !(detail.getTarget() instanceof Element) + && ((Node) detail.getTarget()).getParentNode() instanceof Document; + } + public static class ComparisonController2DifferenceEvaluator implements net.sf.xmlunit.diff.DifferenceEvaluator { private final ComparisonController cc; Modified: trunk/xmlunit/src/main/net-core/diff/AbstractDifferenceEngine.cs =================================================================== --- trunk/xmlunit/src/main/net-core/diff/AbstractDifferenceEngine.cs 2010-09-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/main/net-core/diff/AbstractDifferenceEngine.cs 2010-09-14 06:55:50 UTC (rev 473) @@ -26,16 +26,17 @@ public event ComparisonListener MatchListener; public event ComparisonListener DifferenceListener; - private ElementSelector elementSelector = ElementSelectors.Default; - public virtual ElementSelector ElementSelector { + private INodeMatcher nodeMatcher = + new DefaultNodeMatcher(ElementSelectors.Default); + public virtual INodeMatcher NodeMatcher { set { if (value == null) { - throw new ArgumentNullException("element selector"); + throw new ArgumentNullException("node matcher"); } - elementSelector = value; + nodeMatcher = value; } get { - return elementSelector; + return nodeMatcher; } } Modified: trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml =================================================================== --- trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-09-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.xml 2010-09-14 06:55:50 UTC (rev 473) @@ -353,45 +353,48 @@ XPathContext controlContext, IEnumerable<XmlNode> testSeq, XPathContext testContext) { - 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++) { - unmatchedTestIndexes.Add(i, DUMMY); - } ]]></literal> <lastResultDef/> <literal><![CDATA[ // if there are no children on either Node, the result is equal lastResult = ComparisonResult.EQUAL; - Match lastMatch = new Match(null, -1); - for (int i = 0; i < controlList.Count; i++) { - Match testMatch = FindMatchingNode(controlList[i], testList, - lastMatch.Index, - unmatchedTestIndexes); - controlContext.NavigateToChild(i); + + IEnumerable<KeyValuePair<XmlNode, XmlNode>> matches = + NodeMatcher.Match(controlSeq, testSeq); + IList<XmlNode> controlList = new List<XmlNode>(controlSeq); + IList<XmlNode> testList = new List<XmlNode>(testSeq); + IDictionary<XmlNode, object> seen = + new Dictionary<XmlNode, object>(); + foreach (KeyValuePair<XmlNode, XmlNode> pair in matches) { + XmlNode control = pair.Key; + seen[control] = DUMMY; + XmlNode test = pair.Value; + seen[test] = DUMMY; + int controlIndex = controlList.IndexOf(control); + int testIndex = testList.IndexOf(test); + controlContext.NavigateToChild(controlIndex); + testContext.NavigateToChild(testIndex); try { - if (testMatch != null) { - XmlNode control = controlList[i]; - XmlNode test = testMatch.Node; - testContext.NavigateToChild(testMatch.Index); - try { ]]></literal> <compareExpr type="CHILD_NODELIST_SEQUENCE" - controlExpr="i" - testExpr="testMatch.Index" + controlExpr="controlIndex" + testExpr="testIndex" /> <compareMethodExpr method="CompareNodes" controlExpr="control" testExpr="test"/> <literal><![CDATA[ - unmatchedTestIndexes.Remove(testMatch.Index); - lastMatch = testMatch; - } finally { - testContext.NavigateToParent(); - } - } else { + } finally { + testContext.NavigateToParent(); + controlContext.NavigateToParent(); + } + } + + int controlSize = controlList.Count; + for (int i = 0; i < controlSize; i++) { + if (!seen.ContainsKey(controlList[i])) { + controlContext.NavigateToChild(i); + try { lastResult = Compare(new Comparison(ComparisonType.CHILD_LOOKUP, controlList[i], @@ -399,26 +402,30 @@ controlList[i], null, null, null)); ]]></literal> - <if-return-boilerplate/> - <literal><![CDATA[ + <if-return-boilerplate/> + <literal><![CDATA[ + } finally { + controlContext.NavigateToParent(); } - } finally { - controlContext.NavigateToParent(); } } - foreach (int i in unmatchedTestIndexes.Keys) { - testContext.NavigateToChild(i); - try { - lastResult = - Compare(new Comparison(ComparisonType.CHILD_LOOKUP, - null, null, null, - testList[i], GetXPath(testContext), - testList[i])); + int testSize = testList.Count; + for (int i = 0; i < testSize; i++) { + if (!seen.ContainsKey(testList[i])) { + testContext.NavigateToChild(i); + try { + lastResult = + Compare(new Comparison(ComparisonType.CHILD_LOOKUP, + null, null, null, + testList[i], + GetXPath(testContext), + testList[i])); ]]></literal> <if-return-boilerplate/> <literal><![CDATA[ - } finally { - testContext.NavigateToParent(); + } finally { + testContext.NavigateToParent(); + } } } return lastResult; @@ -491,52 +498,6 @@ return null; } - private Match FindMatchingNode(XmlNode searchFor, - IList<XmlNode> searchIn, - int indexOfLastMatch, - IDictionary<int, object> - availableIndexes) { - int searchSize = searchIn.Count; - for (int i = indexOfLastMatch + 1; i < searchSize; i++) { - if (!availableIndexes.ContainsKey(i)) { - continue; - } - if (NodesMatch(searchFor, searchIn[i])) { - return new Match(searchIn[i], i); - } - } - for (int i = 0; i < indexOfLastMatch; i++) { - if (!availableIndexes.ContainsKey(i)) { - continue; - } - if (NodesMatch(searchFor, searchIn[i])) { - return new Match(searchIn[i], i); - } - } - return null; - } - - private bool NodesMatch(XmlNode n1, XmlNode n2) { - if (n1 is XmlElement && n2 is XmlElement) { - return ElementSelector(n1 as XmlElement, n2 as XmlElement); - } - ComparisonResult r = - CompareDontFire(new Comparison(ComparisonType.NODE_TYPE, - n1, null, n1.NodeType, - n2, null, n2.NodeType)); - return r != ComparisonResult.CRITICAL - && r != ComparisonResult.DIFFERENT; - } - - internal class Match { - internal readonly XmlNode Node; - internal readonly int Index; - internal Match(XmlNode match, int index) { - Node = match; - Index = index; - } - } - private static XPathContext.INodeInfo TO_NODE_INFO(XmlNode n) { return new XPathContext.DOMNodeInfo(n); } Added: trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs =================================================================== --- trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs (rev 0) +++ trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs 2010-09-14 06:55:50 UTC (rev 473) @@ -0,0 +1,122 @@ +/* + 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 System.Collections.Generic; +using System.Xml; + +namespace net.sf.xmlunit.diff { + + /// <summary> + /// Strategy that matches control and tests nodes for comparison. + /// </summary> + public class DefaultNodeMatcher : INodeMatcher { + private static readonly object DUMMY = new object(); + + private readonly ElementSelector elementSelector; + private readonly NodeTypeMatcher nodeTypeMatcher; + + public DefaultNodeMatcher() : this(ElementSelectors.Default) { + } + + public DefaultNodeMatcher(ElementSelector es) : + this(es, DefaultNodeTypeMatcher) { + } + + public DefaultNodeMatcher(ElementSelector es, NodeTypeMatcher ntm) { + elementSelector = es; + nodeTypeMatcher = ntm; + } + + public IEnumerable<KeyValuePair<XmlNode, XmlNode>> + Match(IEnumerable<XmlNode> controlNodes, + IEnumerable<XmlNode> testNodes) { + LinkedList<KeyValuePair<XmlNode, XmlNode>> matches = + new LinkedList<KeyValuePair<XmlNode, XmlNode>>(); + IList<XmlNode> controlList = new List<XmlNode>(controlNodes); + IList<XmlNode> testList = new List<XmlNode>(testNodes); + IDictionary<int, object> unmatchedTestIndexes = + new Dictionary<int, object>(); + for (int i = 0; i < testList.Count; i++) { + unmatchedTestIndexes.Add(i, DUMMY); + } + int controlSize = controlList.Count; + MatchInfo lastMatch = new MatchInfo(null, -1); + for (int i = 0; i < controlSize; i++) { + XmlNode control = controlList[i]; + MatchInfo testMatch = FindMatchingNode(control, testList, + lastMatch.Index, + unmatchedTestIndexes); + if (testMatch != null) { + unmatchedTestIndexes.Remove(testMatch.Index); + matches.AddLast(new KeyValuePair<XmlNode, + XmlNode>(control, testMatch.Node)); + } + } + return matches; + } + + private MatchInfo FindMatchingNode(XmlNode searchFor, + IList<XmlNode> searchIn, + int indexOfLastMatch, + IDictionary<int, object> + availableIndexes) { + int searchSize = searchIn.Count; + for (int i = indexOfLastMatch + 1; i < searchSize; i++) { + if (!availableIndexes.ContainsKey(i)) { + continue; + } + if (NodesMatch(searchFor, searchIn[i])) { + return new MatchInfo(searchIn[i], i); + } + } + for (int i = 0; i < indexOfLastMatch; i++) { + if (!availableIndexes.ContainsKey(i)) { + continue; + } + if (NodesMatch(searchFor, searchIn[i])) { + return new MatchInfo(searchIn[i], i); + } + } + return null; + } + + private bool NodesMatch(XmlNode n1, XmlNode n2) { + if (n1 is XmlElement && n2 is XmlElement) { + return elementSelector(n1 as XmlElement, n2 as XmlElement); + } + return nodeTypeMatcher(n1.NodeType, n2.NodeType); + } + + internal class MatchInfo { + internal readonly XmlNode Node; + internal readonly int Index; + internal MatchInfo(XmlNode match, int index) { + Node = match; + Index = index; + } + } + + public delegate bool NodeTypeMatcher(XmlNodeType controlType, + XmlNodeType testType); + + public static bool DefaultNodeTypeMatcher(XmlNodeType controlType, + XmlNodeType testType) { + return controlType == testType + || (controlType == XmlNodeType.CDATA + && testType == XmlNodeType.Text) + || (controlType == XmlNodeType.Text + && testType == XmlNodeType.CDATA); + } + } +} \ No newline at end of file Property changes on: trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/xmlunit/src/main/net-core/diff/IDifferenceEngine.cs =================================================================== --- trunk/xmlunit/src/main/net-core/diff/IDifferenceEngine.cs 2010-09-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/main/net-core/diff/IDifferenceEngine.cs 2010-09-14 06:55:50 UTC (rev 473) @@ -38,9 +38,9 @@ event ComparisonListener DifferenceListener; /// <summary> - /// Sets the strategy for selecting elements to compare. + /// Sets the strategy for selecting nodes to compare. /// </summary> - ElementSelector ElementSelector { set; } + INodeMatcher NodeMatcher { set; } /// <summary> /// Determines whether the comparison should stop after given Added: trunk/xmlunit/src/main/net-core/diff/INodeMatcher.cs =================================================================== --- trunk/xmlunit/src/main/net-core/diff/INodeMatcher.cs (rev 0) +++ trunk/xmlunit/src/main/net-core/diff/INodeMatcher.cs 2010-09-14 06:55:50 UTC (rev 473) @@ -0,0 +1,32 @@ +/* + 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 System.Collections.Generic; +using System.Xml; + +namespace net.sf.xmlunit.diff { + + /// <summary> + /// Strategy that matches control and tests nodes for comparison. + /// </summary> + public interface INodeMatcher { + /// <summary> + /// Matches control and test nodes against each other, returns + /// the matching pairs. + /// </summary> + IEnumerable<KeyValuePair<XmlNode, XmlNode>> + Match(IEnumerable<XmlNode> controlNodes, + IEnumerable<XmlNode> testNodes); + } +} Property changes on: trunk/xmlunit/src/main/net-core/diff/INodeMatcher.cs ___________________________________________________________________ Added: svn:eol-style + native 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-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/DOMDifferenceEngineTest.java 2010-09-14 06:55:50 UTC (rev 473) @@ -634,7 +634,7 @@ assertEquals(1, ex.invoked); d = new DOMDifferenceEngine(); - d.setElementSelector(ElementSelectors.byName); + d.setNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)); ex = new DiffExpecter(ComparisonType.CHILD_LOOKUP, "/bar[1]", null); d.addDifferenceListener(ex); d.setDifferenceEvaluator(DifferenceEvaluators.DefaultStopWhenDifferent); @@ -751,7 +751,7 @@ } }; d.setDifferenceEvaluator(ev); - d.setElementSelector(ElementSelectors.byName); + d.setNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)); assertEquals(ComparisonResult.CRITICAL, d.compareNodes(e1, new XPathContext(), 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-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-14 06:55:50 UTC (rev 473) @@ -418,7 +418,7 @@ diff.getTestNodeDetail().getXpathLocation()); // didn't find the second Apple element - diff = (Difference) l.get(1); + diff = (Difference) l.get(3); assertEquals(DifferenceConstants.CHILD_NODE_NOT_FOUND_ID, diff.getId()); assertEquals("Apple", diff.getControlNodeDetail().getValue()); @@ -429,7 +429,7 @@ diff.getTestNodeDetail().getXpathLocation()); // Banana's size attribute doesn't match - diff = (Difference) l.get(3); + diff = (Difference) l.get(2); assertEquals(DifferenceConstants.ATTR_VALUE_ID, diff.getId()); assertEquals("10", diff.getControlNodeDetail().getValue()); @@ -440,7 +440,7 @@ diff.getTestNodeDetail().getXpathLocation()); // Banana is the third child in control but the second one in test - diff = (Difference) l.get(2); + diff = (Difference) l.get(1); assertEquals("2", diff.getControlNodeDetail().getValue()); assertEquals("1", diff.getTestNodeDetail().getValue()); assertEquals("/Fruits[1]/Banana[1]", Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-14 06:55:50 UTC (rev 473) @@ -487,6 +487,10 @@ assertFalse("unexpected difference: " + listener.comparingWhat, listener.different); resetListener(); + listenToDifferences(test, control); + assertFalse("unexpected difference: " + listener.comparingWhat, + listener.different); + resetListener(); control = "<?xml version = \"1.0\" encoding = \"UTF-8\"?>" + "<!-- some comment -->" @@ -500,6 +504,10 @@ listenToDifferences(control, test); assertFalse("unexpected difference: " + listener.comparingWhat, listener.different); + resetListener(); + listenToDifferences(test, control); + assertFalse("unexpected difference: " + listener.comparingWhat, + listener.different); } private void listenToDifferences(String control, String test) Modified: trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs =================================================================== --- trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs 2010-09-13 11:49:10 UTC (rev 472) +++ trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs 2010-09-14 06:55:50 UTC (rev 473) @@ -627,7 +627,7 @@ Assert.AreEqual(1, ex.invoked); d = new DOMDifferenceEngine(); - d.ElementSelector = ElementSelectors.ByName; + d.NodeMatcher = new DefaultNodeMatcher(ElementSelectors.ByName); ex = new DiffExpecter(ComparisonType.CHILD_LOOKUP); d.DifferenceListener += ex.ComparisonPerformed; d.DifferenceEvaluator = @@ -743,7 +743,7 @@ outcome); }; d.DifferenceEvaluator = ev; - d.ElementSelector = ElementSelectors.ByName; + d.NodeMatcher = new DefaultNodeMatcher(ElementSelectors.ByName); Assert.AreEqual(ComparisonResult.CRITICAL, d.CompareNodes(e1, new XPathContext(), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-14 07:26:58
|
Revision: 474 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=474&view=rev Author: bodewig Date: 2010-09-14 07:26:52 +0000 (Tue, 14 Sep 2010) Log Message: ----------- minor cleanup Modified Paths: -------------- trunk/xmlunit/src/main/net-core/diff/AbstractDifferenceEngine.cs trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java Modified: trunk/xmlunit/src/main/net-core/diff/AbstractDifferenceEngine.cs =================================================================== --- trunk/xmlunit/src/main/net-core/diff/AbstractDifferenceEngine.cs 2010-09-14 06:55:50 UTC (rev 473) +++ trunk/xmlunit/src/main/net-core/diff/AbstractDifferenceEngine.cs 2010-09-14 07:26:52 UTC (rev 474) @@ -26,8 +26,7 @@ public event ComparisonListener MatchListener; public event ComparisonListener DifferenceListener; - private INodeMatcher nodeMatcher = - new DefaultNodeMatcher(ElementSelectors.Default); + private INodeMatcher nodeMatcher = new DefaultNodeMatcher(); public virtual INodeMatcher NodeMatcher { set { if (value == null) { 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-14 06:55:50 UTC (rev 473) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-14 07:26:52 UTC (rev 474) @@ -417,15 +417,13 @@ assertEquals("/Fruits[1]", diff.getTestNodeDetail().getXpathLocation()); - // didn't find the second Apple element - diff = (Difference) l.get(3); - assertEquals(DifferenceConstants.CHILD_NODE_NOT_FOUND_ID, - diff.getId()); - assertEquals("Apple", diff.getControlNodeDetail().getValue()); - assertEquals("null", diff.getTestNodeDetail().getValue()); - assertEquals("/Fruits[1]/Apple[2]", + // Banana is the third child in control but the second one in test + diff = (Difference) l.get(1); + assertEquals("2", diff.getControlNodeDetail().getValue()); + assertEquals("1", diff.getTestNodeDetail().getValue()); + assertEquals("/Fruits[1]/Banana[1]", diff.getControlNodeDetail().getXpathLocation()); - assertEquals(null, + assertEquals("/Fruits[1]/Banana[1]", diff.getTestNodeDetail().getXpathLocation()); // Banana's size attribute doesn't match @@ -439,14 +437,17 @@ 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(1); - assertEquals("2", diff.getControlNodeDetail().getValue()); - assertEquals("1", diff.getTestNodeDetail().getValue()); - assertEquals("/Fruits[1]/Banana[1]", + // didn't find the second Apple element + diff = (Difference) l.get(3); + 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("/Fruits[1]/Banana[1]", + assertEquals(null, diff.getTestNodeDetail().getXpathLocation()); + } 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-14 07:28:56
|
Revision: 475 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=475&view=rev Author: bodewig Date: 2010-09-14 07:28:50 +0000 (Tue, 14 Sep 2010) Log Message: ----------- whitespace Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceConstants.java trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceConstants.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceConstants.java 2010-09-14 07:26:52 UTC (rev 474) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceConstants.java 2010-09-14 07:28:50 UTC (rev 475) @@ -97,7 +97,7 @@ * attribute at all. */ int NO_NAMESPACE_SCHEMA_LOCATION_ID = 24; - + /** Comparing an implied attribute value against an explicit value */ public static final Difference ATTR_VALUE_EXPLICITLY_SPECIFIED = new Difference(ATTR_VALUE_EXPLICITLY_SPECIFIED_ID, @@ -181,7 +181,7 @@ public static final Difference CHILD_NODELIST_SEQUENCE = new Difference(CHILD_NODELIST_SEQUENCE_ID, "sequence of child nodes", true); - + /** Comparing 2 Documents only one of which has a doctype */ public static final Difference HAS_DOCTYPE_DECLARATION = new Difference(HAS_DOCTYPE_DECLARATION_ID, Modified: trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs =================================================================== --- trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs 2010-09-14 07:26:52 UTC (rev 474) +++ trunk/xmlunit/src/main/net-core/diff/DefaultNodeMatcher.cs 2010-09-14 07:28:50 UTC (rev 475) @@ -16,7 +16,7 @@ using System.Xml; namespace net.sf.xmlunit.diff { - + /// <summary> /// Strategy that matches control and tests nodes for comparison. /// </summary> 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-14 07:26:52 UTC (rev 474) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-14 07:28:50 UTC (rev 475) @@ -125,7 +125,7 @@ unmatchedNodes++; } } - + assertEquals(1402 + unmatchedNodes, differencesWithWhitespace.getAllDifferences().size()); @@ -169,7 +169,7 @@ assertEquals(i + " control " + aDifference.toString(), value, aDifference.getControlNodeDetail().getValue()); } - + expr = aDifference.getTestNodeDetail().getXpathLocation(); if (expr == null || expr.length()==0) { System.out.println(aDifference); @@ -219,7 +219,7 @@ // sequence of nodes assertEquals(3, l.size()); } - + /** * @see http://sourceforge.net/forum/forum.php?thread_id=1691528&forum_id=73274 */ @@ -241,7 +241,7 @@ + "<td>Newsitem 1</td>" + "</tr>" + "</table>"; - + DetailedDiff diff = new DetailedDiff(new Diff(control, test)); List changes = diff.getAllDifferences(); // number of children, text of first child, unexpected second Modified: trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs =================================================================== --- trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs 2010-09-14 07:26:52 UTC (rev 474) +++ trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs 2010-09-14 07:28:50 UTC (rev 475) @@ -42,7 +42,7 @@ internal DiffExpecter(ComparisonType type, string controlXPath, string testXPath) : this(type, 1, true, controlXPath, testXPath) { } - + private DiffExpecter(ComparisonType type, int expected, bool withXPath, string controlXPath, string testXPath) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-14 10:10:37
|
Revision: 476 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=476&view=rev Author: bodewig Date: 2010-09-14 10:10:30 +0000 (Tue, 14 Sep 2010) Log Message: ----------- enable NewDifferenceEngine even for compareUnmatched = true Modified Paths: -------------- 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/java-legacy/org/custommonkey/xmlunit/XMLUnit.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.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-14 07:28:50 UTC (rev 475) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-14 10:10:30 UTC (rev 476) @@ -421,15 +421,14 @@ private DifferenceEngineContract getDifferenceEngine() { if (differenceEngine == null) { if ( - !XMLUnit.getExplicitCompareUnmatched() - && XMLUnit.getIgnoreAttributeOrder() && !XMLUnit.getNormalizeWhitespace() && differenceListenerDelegate == null && - !usesUnknownElementQualifier() + (!usesUnknownElementQualifier() + || XMLUnit.getCompareUnmatched()) ) { 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-14 07:28:50 UTC (rev 475) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-14 10:10:30 UTC (rev 476) @@ -36,6 +36,10 @@ package org.custommonkey.xmlunit; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; import javax.xml.namespace.QName; import javax.xml.transform.Source; @@ -48,8 +52,10 @@ import net.sf.xmlunit.diff.DefaultNodeMatcher; import net.sf.xmlunit.diff.DifferenceEvaluators; import net.sf.xmlunit.diff.ElementSelector; +import net.sf.xmlunit.diff.NodeMatcher; import net.sf.xmlunit.input.CommentLessSource; import net.sf.xmlunit.input.WhitespaceStrippedSource; +import net.sf.xmlunit.util.Linqy; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; @@ -170,9 +176,15 @@ } }); + NodeMatcher m = new DefaultNodeMatcher(); if (elementQualifier != null) { - engine.setNodeMatcher(new DefaultNodeMatcher(new ElementQualifier2ElementSelector(elementQualifier))); + m = new DefaultNodeMatcher(new ElementQualifier2ElementSelector(elementQualifier)); } + if (!XMLUnit.getCompareUnmatched()) { + engine.setNodeMatcher(m); + } else { + engine.setNodeMatcher(new CompareUnmatchedNodeMatcher(m)); + } Input.Builder ctrlBuilder = Input.fromNode(control); Input.Builder tstBuilder = Input.fromNode(test); @@ -513,4 +525,60 @@ } } + private static class CompareUnmatchedNodeMatcher + implements NodeMatcher { + private final NodeMatcher nestedMatcher; + private CompareUnmatchedNodeMatcher(NodeMatcher nested) { + nestedMatcher = nested; + } + + public Iterable<Map.Entry<Node, Node>> + match(Iterable<Node> controlNodes, + Iterable<Node> testNodes) { + final Map<Node, Node> map = new HashMap<Node, Node>(); + for (Map.Entry<Node, Node> e + : nestedMatcher.match(controlNodes, testNodes)) { + map.put(e.getKey(), e.getValue()); + } + + final LinkedList<Map.Entry<Node, Node>> result = + new LinkedList<Map.Entry<Node, Node>>(); + + for (Node n : controlNodes) { + if (map.containsKey(n)) { + result.add(new Entry(n, map.get(n))); + } else if (n instanceof Element) { + Iterable<Node> unmatchedTestElements = + Linqy.filter(testNodes, new Linqy.Predicate<Node>() { + public boolean matches(Node t) { + return t instanceof Element + && !map.containsValue(t); + } + }); + Iterator<Node> it = unmatchedTestElements.iterator(); + if (it.hasNext()) { + Node t = it.next(); + map.put(n, t); + result.add(new Entry(n, t)); + } + } + } + return result; + } + + private static class Entry implements Map.Entry<Node, Node> { + private final Node key; + private final Node value; + private Entry(Node k, Node v) { + key = k; + value = v; + } + public Node getKey() { return key; } + public Node getValue() { return value; } + public Node setValue(Node v) { + throw new UnsupportedOperationException(); + } + } + } + } 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-14 07:28:50 UTC (rev 475) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLUnit.java 2010-09-14 10:10:30 UTC (rev 476) @@ -83,7 +83,7 @@ private static String xsltVersion = "1.0"; private static String xpathFactoryName = null; private static boolean expandEntities = false; - private static Boolean compareUnmatched = null; + private static boolean compareUnmatched = true; private static final String XSLT_VERSION_START = " version=\""; private static final String XSLT_VERSION_END = "\">"; @@ -887,37 +887,18 @@ * <p>Defaults to true.</p> */ public static void setCompareUnmatched(boolean b) { - compareUnmatched = Boolean.valueOf(b); + compareUnmatched = b; } /** - * 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. * * @return true by default */ public static boolean getCompareUnmatched() { - return compareUnmatched != null - ? compareUnmatched.booleanValue() : true; + return compareUnmatched; } - /** - * 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; - } } 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-14 07:28:50 UTC (rev 475) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2010-09-14 10:10:30 UTC (rev 476) @@ -111,38 +111,13 @@ 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))) ); - List l = differencesWithWhitespace.getAllDifferences(); - int unmatchedNodes = 0; - for (Iterator iter = l.iterator(); iter.hasNext();) { - Difference d = (Difference) iter.next(); - if (d.getId() == DifferenceConstants.CHILD_NODE_NOT_FOUND_ID) { - unmatchedNodes++; - } - } - - assertEquals(1402 + unmatchedNodes, - differencesWithWhitespace.getAllDifferences().size()); - try { XMLUnit.setIgnoreWhitespace(true); Diff prototype = new Diff(new FileReader(control), new FileReader(test)); DetailedDiff detailedDiff = new DetailedDiff(prototype); List differences = detailedDiff.getAllDifferences(); - unmatchedNodes = 0; - for (Iterator iter = differences.iterator(); iter.hasNext();) { - Difference d = (Difference) iter.next(); - if (d.getId() == DifferenceConstants.CHILD_NODE_NOT_FOUND_ID) { - unmatchedNodes++; - } - } - assertEquals(40 + unmatchedNodes, differences.size()); SimpleXpathEngine xpathEngine = new SimpleXpathEngine(); Document controlDoc = @@ -187,10 +162,6 @@ } finally { XMLUnit.setIgnoreWhitespace(false); } - } finally { - XMLUnit.clearCompareUnmatched(); - } - } public void testSeeAllDifferencesEvenIfDiffWouldSayHaltComparison() throws Exception { @@ -276,8 +247,8 @@ DetailedDiff dd = new DetailedDiff(diff); List l = dd.getAllDifferences(); assertEquals(3, l.size()); - // (0) number of children, (1) node not found, (2) order different - Difference d = (Difference) l.get(1); + // (0) number of children, (1) order different, (2) node not found + Difference d = (Difference) l.get(2); assertEquals(DifferenceConstants.CHILD_NODE_NOT_FOUND_ID, d.getId()); assertEquals("/books[1]/book[1]", @@ -332,26 +303,21 @@ * https://sourceforge.net/tracker/?func=detail&aid=2758280&group_id=23187&atid=377768 */ public void testCompareUnmatched() throws Exception { - 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(); - } + 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()); } /** @@ -384,7 +350,7 @@ assertNull(diff.getControlNodeDetail().getNode()); assertNotNull(diff.getTestNodeDetail().getNode()); } finally { - XMLUnit.clearCompareUnmatched(); + XMLUnit.setCompareUnmatched(true); } } @@ -449,7 +415,7 @@ diff.getTestNodeDetail().getXpathLocation()); } finally { - XMLUnit.clearCompareUnmatched(); + XMLUnit.setCompareUnmatched(true); } } } Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-14 07:28:50 UTC (rev 475) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-14 10:10:30 UTC (rev 476) @@ -241,14 +241,13 @@ 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); + assertEquals("14th difference type", + NewDifferenceEngine.CHILD_NODELIST_SEQUENCE_ID, + listener.comparingWhat); + assertEquals("14th control xpath", "/stuff[1]/item[1]", + listener.controlXpath); + assertEquals("14th test xpath", "/stuff[1]/item[1]", + listener.testXpath); } public void testIssue1027863() 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-14 10:23:42
|
Revision: 477 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=477&view=rev Author: bodewig Date: 2010-09-14 10:23:36 +0000 (Tue, 14 Sep 2010) Log Message: ----------- the legacy DifferenceEngine doesn't only match Elements Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_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-09-14 10:10:30 UTC (rev 476) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-14 10:23:36 UTC (rev 477) @@ -547,12 +547,11 @@ for (Node n : controlNodes) { if (map.containsKey(n)) { result.add(new Entry(n, map.get(n))); - } else if (n instanceof Element) { + } else { Iterable<Node> unmatchedTestElements = Linqy.filter(testNodes, new Linqy.Predicate<Node>() { public boolean matches(Node t) { - return t instanceof Element - && !map.containsValue(t); + return !map.containsValue(t); } }); Iterator<Node> it = unmatchedTestElements.iterator(); Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-14 10:10:30 UTC (rev 476) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2010-09-14 10:23:36 UTC (rev 477) @@ -205,9 +205,8 @@ 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); + assertEquals("11th test xpath", "/stuff[1]/list[1]/text()[1]", + listener.testXpath); } public void testXpathLocation12() throws Exception { @@ -227,13 +226,13 @@ 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 PI in test + // mutiple Differences, we only see the last one, missing second element assertEquals("13 difference type", DifferenceConstants.CHILD_NODE_NOT_FOUND_ID, listener.comparingWhat); - assertNull("13th control xpath", listener.controlXpath); - assertEquals("13th test xpath", "/stuff[1]/processing-instruction()[1]", - listener.testXpath); + assertEquals("13th control xpath", "/stuff[1]/item[2]", + listener.controlXpath); + assertNull("13th test xpath", listener.testXpath); } public void testXpathLocation14() 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-14 11:30:51
|
Revision: 479 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=479&view=rev Author: bodewig Date: 2010-09-14 11:30:44 +0000 (Tue, 14 Sep 2010) Log Message: ----------- can also deal with custom DifferenceListener Modified Paths: -------------- 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/tests/java-legacy/org/custommonkey/xmlunit/test_IgnoreTextAndAttributeValuesDifferenceListener.java Removed Paths: ------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEvaluator.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-14 10:25:52 UTC (rev 478) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-14 11:30:44 UTC (rev 479) @@ -72,7 +72,7 @@ * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit.sourceforge.net</a> */ public class Diff - implements DifferenceEvaluator, DifferenceListener, ComparisonController { + implements DifferenceListener, ComparisonController { private final Document controlDoc; private final Document testDoc; private boolean similar = true; @@ -425,8 +425,6 @@ && !XMLUnit.getNormalizeWhitespace() && - differenceListenerDelegate == null - && (!usesUnknownElementQualifier() || XMLUnit.getCompareUnmatched()) ) { Deleted: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEvaluator.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEvaluator.java 2010-09-14 10:25:52 UTC (rev 478) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEvaluator.java 2010-09-14 11:30:44 UTC (rev 479) @@ -1,55 +0,0 @@ -/* -****************************************************************** -Copyright (c) 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; - -/** - * Contains the pure evaluation logic of DifferenceListener - */ -public interface DifferenceEvaluator { - /** - * Receive notification of a difference and decides whether 2 - * nodes are different. - * @param difference a Difference instance as defined in {@link - * DifferenceConstants DifferenceConstants} describing the cause - * of the difference and containing the detail of the nodes that - * differ - * @return int one of the RETURN_... constants of - * DifferenceListener describing how this difference was - * interpreted - */ - int evaluate(Difference difference); -} 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-14 10:25:52 UTC (rev 478) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-14 11:30:44 UTC (rev 479) @@ -50,6 +50,7 @@ import net.sf.xmlunit.diff.ComparisonType; import net.sf.xmlunit.diff.DOMDifferenceEngine; import net.sf.xmlunit.diff.DefaultNodeMatcher; +import net.sf.xmlunit.diff.DifferenceEvaluator; import net.sf.xmlunit.diff.DifferenceEvaluators; import net.sf.xmlunit.diff.ElementSelector; import net.sf.xmlunit.diff.NodeMatcher; @@ -138,34 +139,19 @@ .addMatchListener(new MatchTracker2ComparisonListener(matchTracker)); } - net.sf.xmlunit.diff.DifferenceEvaluator controllerAsEvaluator = + DifferenceEvaluator controllerAsEvaluator = new ComparisonController2DifferenceEvaluator(controller); - net.sf.xmlunit.diff.DifferenceEvaluator ev = null; + DifferenceEvaluator ev = null; if (listener != null) { - net.sf.xmlunit.diff.DifferenceEvaluator e = null; - if (listener instanceof org.custommonkey.xmlunit.DifferenceEvaluator) { - e = new DifferenceEvaluatorAdapter((DifferenceEvaluator) listener); - final ComparisonListener l = new DifferenceListener2ComparisonListener(listener); - engine - .addDifferenceListener(new ComparisonListener() { - public void comparisonPerformed(Comparison comparison, - ComparisonResult outcome) { - if (!swallowComparison(comparison, outcome, - checkPrelude)) { - l.comparisonPerformed(comparison, outcome); - } - } - }); - } else { - e = new DifferenceListener2DifferenceEvaluator(listener); - } - ev = DifferenceEvaluators.first(e, controllerAsEvaluator); + ev = DifferenceEvaluators + .first(new DifferenceListener2DifferenceEvaluator(listener), + controllerAsEvaluator); } else { ev = controllerAsEvaluator; } final net.sf.xmlunit.diff.DifferenceEvaluator evaluator = ev; engine - .setDifferenceEvaluator(new net.sf.xmlunit.diff.DifferenceEvaluator() { + .setDifferenceEvaluator(new DifferenceEvaluator() { public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { if (!swallowComparison(comparison, outcome, @@ -394,7 +380,7 @@ } public static class ComparisonController2DifferenceEvaluator - implements net.sf.xmlunit.diff.DifferenceEvaluator { + implements DifferenceEvaluator { private final ComparisonController cc; public ComparisonController2DifferenceEvaluator(ComparisonController c) { cc = c; @@ -410,33 +396,6 @@ } } - public static class DifferenceEvaluatorAdapter - implements net.sf.xmlunit.diff.DifferenceEvaluator { - private final DifferenceEvaluator de; - public DifferenceEvaluatorAdapter(DifferenceEvaluator d) { - de = d; - } - - public ComparisonResult evaluate(Comparison comparison, - ComparisonResult outcome) { - Difference diff = toDifference(comparison); - if (diff != null) { - switch (de.evaluate(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; - } - } - public static class ElementQualifier2ElementSelector implements ElementSelector { private final ElementQualifier eq; @@ -453,7 +412,7 @@ } public static class DifferenceListener2DifferenceEvaluator - implements net.sf.xmlunit.diff.DifferenceEvaluator { + implements DifferenceEvaluator { private final DifferenceListener dl; public DifferenceListener2DifferenceEvaluator(DifferenceListener dl) { 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-14 10:25:52 UTC (rev 478) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_IgnoreTextAndAttributeValuesDifferenceListener.java 2010-09-14 11:30:44 UTC (rev 479) @@ -146,9 +146,9 @@ new Diff(control, dissimilarTest)); dissimilarDetailedDiff.overrideDifferenceListener(listener); List differences = dissimilarDetailedDiff.getAllDifferences(); - assertEquals("wrong number of attributes, missing attribute, different attribute value, and missing text node. " + assertEquals("has children, wrong number of attributes, missing attribute, different attribute value, and missing text node. " + dissimilarDetailedDiff.toString(), - 4, differences.size()); + 5, differences.size()); int recoverable = 0; for (Iterator iter = differences.iterator(); iter.hasNext(); ) { Difference aDifference = (Difference) iter.next(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2010-09-17 11:50:37
|
Revision: 481 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=481&view=rev Author: bodewig Date: 2010-09-17 11:50:31 +0000 (Fri, 17 Sep 2010) Log Message: ----------- implement whitespace nomalization 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/WhitespaceNormalizedSource.java trunk/xmlunit/src/main/net-core/input/WhitespaceNormalizedSource.cs Copied: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceNormalizedSource.java (from rev 479, trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceStrippedSource.java) =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceNormalizedSource.java (rev 0) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/input/WhitespaceNormalizedSource.java 2010-09-17 11:50:31 UTC (rev 481) @@ -0,0 +1,35 @@ +/* + 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 normalizing the non-empty ones. + * + * <p>"normalized" in this context means all whitespace characters + * are replaced by space characters and consecutive whitespace + * characaters are collapsed.</p> + */ +public class WhitespaceNormalizedSource extends DOMSource { + + public WhitespaceNormalizedSource(Source originalSource) { + super(Nodes.normalizeWhitespace(Convert.toDocument(originalSource))); + setSystemId(originalSource.getSystemId()); + } +} 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-16 15:13:39 UTC (rev 480) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Nodes.java 2010-09-17 11:50:31 UTC (rev 481) @@ -91,21 +91,43 @@ public static Node stripWhitespace(Node original) { Node cloned = original.cloneNode(true); cloned.normalize(); - stripWsRec(cloned); + handleWsRec(cloned, false); return cloned; } /** + * 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 and normalized. + * + * <p>"normalized" in this context means all whitespace characters + * are replaced by space characters and consecutive whitespace + * characaters are collapsed.</p> + */ + public static Node normalizeWhitespace(Node original) { + Node cloned = original.cloneNode(true); + cloned.normalize(); + handleWsRec(cloned, true); + return cloned; + } + + /** * Trims textual content of this node, removes empty text and * CDATA children, recurses into its child nodes. + * @param normalize whether to normalize whitespace as well */ - private static void stripWsRec(Node n) { + private static void handleWsRec(Node n, boolean normalize) { if (n instanceof CharacterData || n instanceof ProcessingInstruction) { - n.setNodeValue(n.getNodeValue().trim()); + String s = n.getNodeValue().trim(); + if (normalize) { + s = normalize(s); + } + n.setNodeValue(s); } List<Node> toRemove = new LinkedList<Node>(); for (Node child : new IterableNodeList(n.getChildNodes())) { - stripWsRec(child); + handleWsRec(child, normalize); if (!(n instanceof Attr) && (child instanceof Text || child instanceof CDATASection) && child.getNodeValue().length() == 0) { @@ -119,8 +141,40 @@ if (attrs != null) { final int len = attrs.getLength(); for (int i = 0; i < len; i++) { - stripWsRec(attrs.item(i)); + handleWsRec(attrs.item(i), normalize); } } } + + private static final char SPACE = ' '; + + /** + * Normalize a string. + * + * <p>"normalized" in this context means all whitespace characters + * are replaced by space characters and consecutive whitespace + * characaters are collapsed.</p> + */ + static String normalize(String s) { + StringBuilder sb = new StringBuilder(); + boolean changed = false; + boolean lastCharWasWS = false; + final int len = s.length(); + for (int i = 0; i < len; i++) { + char c = s.charAt(i); + if (Character.isWhitespace(c)) { + if (!lastCharWasWS) { + sb.append(SPACE); + changed |= (c != SPACE); + } else { + changed = true; + } + lastCharWasWS = true; + } else { + sb.append(c); + lastCharWasWS = false; + } + } + return changed ? sb.toString() : s; + } } 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-16 15:13:39 UTC (rev 480) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/Diff.java 2010-09-17 11:50:31 UTC (rev 481) @@ -423,8 +423,6 @@ if ( XMLUnit.getIgnoreAttributeOrder() && - !XMLUnit.getNormalizeWhitespace() - && (!usesUnknownElementQualifier() || XMLUnit.getCompareUnmatched()) ) { 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-16 15:13:39 UTC (rev 480) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2010-09-17 11:50:31 UTC (rev 481) @@ -57,6 +57,7 @@ import net.sf.xmlunit.diff.ElementSelectors; import net.sf.xmlunit.diff.NodeMatcher; import net.sf.xmlunit.input.CommentLessSource; +import net.sf.xmlunit.input.WhitespaceNormalizedSource; import net.sf.xmlunit.input.WhitespaceStrippedSource; import net.sf.xmlunit.util.Linqy; import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier; @@ -200,7 +201,10 @@ ctrlSource = new CommentLessSource(ctrlSource); tstSource = new CommentLessSource(tstSource); } - if (XMLUnit.getIgnoreWhitespace()) { + if (XMLUnit.getNormalizeWhitespace()) { + ctrlSource = new WhitespaceNormalizedSource(ctrlSource); + tstSource = new WhitespaceNormalizedSource(tstSource); + } else if (XMLUnit.getIgnoreWhitespace()) { ctrlSource = new WhitespaceStrippedSource(ctrlSource); tstSource = new WhitespaceStrippedSource(tstSource); } Copied: trunk/xmlunit/src/main/net-core/input/WhitespaceNormalizedSource.cs (from rev 479, trunk/xmlunit/src/main/net-core/input/WhitespaceStrippedSource.cs) =================================================================== --- trunk/xmlunit/src/main/net-core/input/WhitespaceNormalizedSource.cs (rev 0) +++ trunk/xmlunit/src/main/net-core/input/WhitespaceNormalizedSource.cs 2010-09-17 11:50:31 UTC (rev 481) @@ -0,0 +1,35 @@ +/* + 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 normalizing the non-empty ones. + /// </summary> + /// <remarks> + /// "normalized" in this context means all whitespace characters + /// are replaced by space characters and consecutive whitespace + /// characaters are collapsed. + /// </remarks> + public class WhitespaceNormalizedSource : DOMSource { + public WhitespaceNormalizedSource(ISource originalSource) : + base(Nodes.NormalizeWhitespace(Convert.ToDocument(originalSource))) + { + SystemId = originalSource.SystemId; + } + } +} Modified: trunk/xmlunit/src/main/net-core/util/Nodes.cs =================================================================== --- trunk/xmlunit/src/main/net-core/util/Nodes.cs 2010-09-16 15:13:39 UTC (rev 480) +++ trunk/xmlunit/src/main/net-core/util/Nodes.cs 2010-09-17 11:50:31 UTC (rev 481) @@ -74,21 +74,45 @@ public static XmlNode StripWhitespace(XmlNode original) { XmlNode cloned = original.CloneNode(true); cloned.Normalize(); - StripWsRec(cloned); + HandleWsRec(cloned, false); return cloned; } /// <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 normalized. + /// </summary> + /// <remarks> + /// "normalized" in this context means all whitespace + /// characters are replaced by space characters and + /// consecutive whitespace characaters are collapsed. + /// </remarks> + public static XmlNode NormalizeWhitespace(XmlNode original) { + XmlNode cloned = original.CloneNode(true); + cloned.Normalize(); + HandleWsRec(cloned, true); + 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) { + /// <parameter name="normalize">whether to normalize + /// whitespace as well</parameter> + private static void HandleWsRec(XmlNode n, bool normalize) { if (n is XmlCharacterData || n is XmlProcessingInstruction) { - n.Value = n.Value.Trim(); + string s = n.Value.Trim(); + if (normalize) { + s = Normalize(s); + } + n.Value = s; } LinkedList<XmlNode> toRemove = new LinkedList<XmlNode>(); foreach (XmlNode child in n.ChildNodes) { - StripWsRec(child); + HandleWsRec(child, normalize); if (!(n is XmlAttribute) && (child is XmlText || child is XmlCDataSection) && child.Value.Length == 0) { @@ -101,10 +125,40 @@ XmlNamedNodeMap attrs = n.Attributes; if (attrs != null) { foreach (XmlAttribute a in attrs) { - StripWsRec(a); + HandleWsRec(a, normalize); } } } + private const char SPACE = ' '; + + /// <summary> + /// Normalize a string. + /// <summary> + /// <remarks> + /// "normalized" in this context means all whitespace + /// characters are replaced by space characters and + /// consecutive whitespace characaters are collapsed. + /// </remarks> + internal static string Normalize(string s) { + StringBuilder sb = new StringBuilder(); + bool changed = false; + bool lastCharWasWS = false; + foreach (char c in s) { + if (char.IsWhiteSpace(c)) { + if (!lastCharWasWS) { + sb.Append(SPACE); + changed |= (c != SPACE); + } else { + changed = true; + } + lastCharWasWS = true; + } else { + sb.Append(c); + lastCharWasWS = false; + } + } + return changed ? sb.ToString() : s; + } } } 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-16 15:13:39 UTC (rev 480) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/util/NodesTest.java 2010-09-17 11:50:31 UTC (rev 481) @@ -144,16 +144,20 @@ assertEquals(BAR, m.get(new QName(SOME_URI, FOO, BAR))); } - private Map.Entry<Document, Node> stripWsSetup() { - final Document toTest = Convert.toDocument(Input.fromMemory( + private Document handleWsSetup() { + return Convert.toDocument(Input.fromMemory( "<root>\n" - + "<!-- trim me -->\n" + + "<!-- trim\tme -->\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()); + } + + private Map.Entry<Document, Node> stripWsSetup() { + final Document toTest = handleWsSetup(); final Node stripped = Nodes.stripWhitespace(toTest); return new Map.Entry<Document, Node>() { public Document getKey() { @@ -168,8 +172,32 @@ }; } + private Map.Entry<Document, Node> normalizeWsSetup() { + final Document toTest = handleWsSetup(); + final Node stripped = Nodes.normalizeWhitespace(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() { - Map.Entry<Document, Node> s = stripWsSetup(); + handleWsWorks(stripWsSetup(), "trim\tme"); + } + + @Test public void normalizeWhitespaceWorks() { + handleWsWorks(normalizeWsSetup(), "trim me"); + } + + private void handleWsWorks(Map.Entry<Document, Node> s, + String commentContent) { assertTrue(s.getValue() instanceof Document); NodeList top = s.getValue().getChildNodes(); assertEquals(1, top.getLength()); @@ -179,7 +207,8 @@ 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()); + assertEquals(commentContent, + ((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()); @@ -206,7 +235,14 @@ } @Test public void stripWhitespaceDoesntAlterOriginal() { - Map.Entry<Document, Node> s = stripWsSetup(); + handleWsDoesntAlterOriginal(stripWsSetup()); + } + + @Test public void normalizeWhitespaceDoesntAlterOriginal() { + handleWsDoesntAlterOriginal(normalizeWsSetup()); + } + + private void handleWsDoesntAlterOriginal(Map.Entry<Document, Node> s) { NodeList top = s.getKey().getChildNodes(); assertEquals(1, top.getLength()); assertTrue(top.item(0) instanceof Element); @@ -216,7 +252,7 @@ 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()); + assertEquals(" trim\tme ", ((Comment) rootsChildren.item(1)).getData()); assertNewlineTextNode(rootsChildren.item(2)); assertTrue("should be element, is " + rootsChildren.item(3).getClass(), rootsChildren.item(3) instanceof Element); @@ -255,4 +291,11 @@ n instanceof Text); assertEquals("\n", ((Text) n).getData()); } + + @Test public void normalize() { + assertSame("foo", Nodes.normalize("foo")); + assertSame("foo bar", Nodes.normalize("foo bar")); + assertEquals("foo bar", Nodes.normalize("foo\nbar")); + assertEquals("foo bar", Nodes.normalize("foo \r\n\t bar")); + } } Modified: trunk/xmlunit/src/tests/net-core/util/NodesTest.cs =================================================================== --- trunk/xmlunit/src/tests/net-core/util/NodesTest.cs 2010-09-16 15:13:39 UTC (rev 480) +++ trunk/xmlunit/src/tests/net-core/util/NodesTest.cs 2010-09-17 11:50:31 UTC (rev 481) @@ -123,23 +123,42 @@ Assert.AreEqual(BAR, m[new XmlQualifiedName(FOO, SOME_URI)]); } - private KeyValuePair<XmlDocument, XmlNode> StripWsSetup() { - XmlDocument toTest = Convert.ToDocument(Input.FromMemory( + private XmlDocument HandleWsSetup() { + return Convert.ToDocument(Input.FromMemory( "<root>\n" - + "<!-- trim me -->\n" + + "<!-- trim\tme -->\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()); + } + + private KeyValuePair<XmlDocument, XmlNode> StripWsSetup() { + XmlDocument toTest = HandleWsSetup(); return new KeyValuePair<XmlDocument, XmlNode>(toTest, Nodes.StripWhitespace(toTest)); } + private KeyValuePair<XmlDocument, XmlNode> NormalizeWsSetup() { + XmlDocument toTest = HandleWsSetup(); + return new KeyValuePair<XmlDocument, + XmlNode>(toTest, Nodes.NormalizeWhitespace(toTest)); + } + [Test] public void StripWhitespaceWorks() { - KeyValuePair<XmlDocument, XmlNode> s = StripWsSetup(); + HandleWsWorks(StripWsSetup(), "trim\tme"); + } + + [Test] + public void NormalizeWhitespaceWorks() { + HandleWsWorks(NormalizeWsSetup(), "trim me"); + } + + private void HandleWsWorks(KeyValuePair<XmlDocument, XmlNode> s, + string commentContent) { Assert.IsTrue(s.Value is XmlDocument); XmlNodeList top = s.Value.ChildNodes; Assert.AreEqual(1, top.Count); @@ -149,7 +168,7 @@ Assert.AreEqual(4, rootsChildren.Count); Assert.IsTrue(rootsChildren[0] is XmlComment, "should be comment, is " + rootsChildren[0].GetType()); - Assert.AreEqual("trim me", + Assert.AreEqual(commentContent, ((XmlComment) rootsChildren[0]).Data); Assert.IsTrue(rootsChildren[1] is XmlElement, "should be element, is " + rootsChildren[1].GetType()); @@ -178,7 +197,16 @@ [Test] public void StripWhitespaceDoesntAlterOriginal() { - KeyValuePair<XmlDocument, XmlNode> s = StripWsSetup(); + HandleWsDoesntAlterOriginal(StripWsSetup()); + } + + [Test] + public void NormalizeWhitespaceDoesntAlterOriginal() { + HandleWsDoesntAlterOriginal(NormalizeWsSetup()); + } + + private void HandleWsDoesntAlterOriginal(KeyValuePair<XmlDocument, + XmlNode> s) { XmlNodeList top = s.Key.ChildNodes; Assert.AreEqual(1, top.Count); Assert.IsTrue(top[0] is XmlElement); @@ -187,7 +215,7 @@ Assert.AreEqual(5, rootsChildren.Count); Assert.IsTrue(rootsChildren[0] is XmlComment, "should be comment, is " + rootsChildren[0].GetType()); - Assert.AreEqual(" trim me ", + Assert.AreEqual(" trim\tme ", ((XmlComment) rootsChildren[0]).Data); Assert.IsTrue(rootsChildren[1] is XmlElement, "should be element, is " + rootsChildren[1].GetType()); @@ -217,5 +245,13 @@ XmlAttribute a2 = (XmlAttribute) attrs.GetNamedItem("attr2"); Assert.AreEqual("not me", a2.Value); } + + [Test] + public void Normalize() { + Assert.AreSame("foo", Nodes.Normalize("foo")); + Assert.AreSame("foo bar", Nodes.Normalize("foo bar")); + Assert.AreEqual("foo bar", Nodes.Normalize("foo\nbar")); + Assert.AreEqual("foo bar", Nodes.Normalize("foo \r\n\t bar")); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2011-04-20 12:38:32
|
Revision: 495 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=495&view=rev Author: bodewig Date: 2011-04-20 12:38:25 +0000 (Wed, 20 Apr 2011) Log Message: ----------- merge fix for issue 3290264 from 1.x branch Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLAssert.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_XMLTestCase.java trunk/xmlunit/src/user-guide/XMLUnit-Java.xml Property Changed: ---------------- trunk/xmlunit/src/main/java-legacy/ trunk/xmlunit/src/tests/java-legacy/ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/jaxp13/test_Validator.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java trunk/xmlunit/src/user-guide/ Property changes on: trunk/xmlunit/src/main/java-legacy ___________________________________________________________________ Modified: svn:mergeinfo - /branches/xmlunit-1.x/src/java:346,353 + /branches/xmlunit-1.x/src/java:346,353,494 Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLAssert.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLAssert.java 2011-04-20 12:31:11 UTC (rev 494) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/XMLAssert.java 2011-04-20 12:38:25 UTC (rev 495) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2007, Jeff Martin, Tim Bacon +Copyright (c) 2001-2007,2011 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -46,8 +46,10 @@ import javax.xml.parsers.DocumentBuilder; import junit.framework.Assert; +import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -1114,7 +1116,12 @@ d.appendChild(root); final int length = nodes.getLength(); for (int i = 0; i < length; i++) { - root.appendChild(d.importNode(nodes.item(i), true)); + Node n = d.importNode(nodes.item(i), true); + if (n instanceof Attr) { + root.setAttributeNodeNS((Attr) n); + } else { + root.appendChild(n); + } } return d; } Property changes on: trunk/xmlunit/src/tests/java-legacy ___________________________________________________________________ Modified: svn:mergeinfo - /branches/xmlunit-1.x/tests:346 /branches/xmlunit-1.x/tests/java:337,346,353 + /branches/xmlunit-1.x/tests:346 /branches/xmlunit-1.x/tests/java:337,346,353,494 Property changes on: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/jaxp13/test_Validator.java ___________________________________________________________________ Modified: svn:mergeinfo - /branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/jaxp13/test_Validator.java:337,346,353,491 /branches/xmlunit-1.x/tests/org/custommonkey/xmlunit/jaxp13/test_Validator.java:346 + /branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/jaxp13/test_Validator.java:337,346,353,491,494 /branches/xmlunit-1.x/tests/org/custommonkey/xmlunit/jaxp13/test_Validator.java:346 Property changes on: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java ___________________________________________________________________ Modified: 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 + /branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java:337,346,353,459,494 /branches/xmlunit-1.x/tests/org/custommonkey/xmlunit/test_DetailedDiff.java:346 Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_XMLTestCase.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_XMLTestCase.java 2011-04-20 12:31:11 UTC (rev 494) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_XMLTestCase.java 2011-04-20 12:38:25 UTC (rev 495) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 200, Jeff Martin, Tim Bacon +Copyright (c) 2001-2011, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ /** * Test case used to test the XMLTestCase */ -public class test_XMLTestCase extends XMLTestCase{ +public class test_XMLTestCase extends XMLTestCase { private static final String PREFIX = "foo"; private static final String TEST_NS = "urn:org.example"; private static final NamespaceContext NS_CONTEXT; @@ -572,6 +572,16 @@ assertXpathExists("/axrtable/schema", xmlDocument); } + // bug 3290264 + public void testAssertXpathEqualsAndAttributes() throws Exception { + assertXpathsNotEqual("/foo/Bar/@a", "/foo/Bar", + "<foo><Bar a=\"1\" /></foo>"); + assertXpathsNotEqual("/foo/Bar/@a", "/foo/Bar/@b", + "<foo><Bar a=\"1\" b=\"1\"/></foo>"); + assertXpathsEqual("/foo/Bar/@a", "/foo/Bar/@a", + "<foo><Bar a=\"1\" b=\"2\"/></foo>"); + } + public test_XMLTestCase(String name) { super(name); } Property changes on: trunk/xmlunit/src/user-guide ___________________________________________________________________ Modified: svn:mergeinfo - /branches/xmlunit-1.x/src/user-guide:346,355 + /branches/xmlunit-1.x/src/user-guide:346,355,494 Modified: trunk/xmlunit/src/user-guide/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/user-guide/XMLUnit-Java.xml 2011-04-20 12:31:11 UTC (rev 494) +++ trunk/xmlunit/src/user-guide/XMLUnit-Java.xml 2011-04-20 12:38:25 UTC (rev 495) @@ -3615,6 +3615,37 @@ </section> </section> + <section id="Changes 1.4"> + <title>Changes from XMLUnit 1.3 to 1.4</title> + + <section id="Breaking Changes 1.3"> + <title>Breaking Changes</title> + + <!--itemizedlist> + </itemizedlist--> + </section> + + <section id="New Features 1.4"> + <title>New Features</title> + + <!--itemizedlist> + </itemizedlist--> + </section> + + <section id="Bugfixes 1.4"> + <title>Important Bug Fixes</title> + + <itemizedlist> + <listitem> + <literal>XMLTestCase</literal>'s and <literal>XMLAssert</literal>'s + <literal>assertXpathsEqual</literal> methods threw an + exception at least one XPath matched an attribute. <ulink + url="https://sourceforge.net/tracker/?func=detail&aid=3290264&group_id=23187&atid=377768">Issue 377768</ulink>. + </listitem> + </itemizedlist> + </section> + </section> + </appendix> </article> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2013-02-03 06:37:45
|
Revision: 503 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=503&view=rev Author: bodewig Date: 2013-02-03 06:37:37 +0000 (Sun, 03 Feb 2013) Log Message: ----------- port xsi:type special handling from 1.x branch Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/XPathContext.java trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Nodes.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java Property Changed: ---------------- 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 =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java 2013-02-02 14:35:56 UTC (rev 502) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java 2013-02-03 06:37:37 UTC (rev 503) @@ -328,7 +328,6 @@ testContext .addAttributes(Linqy.map(testAttributes.remainingAttributes, QNAME_MAPPER)); - Set<Attr> foundTestAttributes = new HashSet<Attr>(); lastResult = compare(new Comparison(ComparisonType.ELEMENT_NUM_ATTRIBUTES, @@ -340,6 +339,7 @@ return lastResult; } + Set<Attr> foundTestAttributes = new HashSet<Attr>(); for (Attr controlAttr : controlAttributes.remainingAttributes) { final Attr testAttr = findMatchingAttr(testAttributes.remainingAttributes, @@ -393,6 +393,12 @@ } } + lastResult = compareXsiType(controlAttributes.type, controlContext, + testAttributes.type, testContext); + if (lastResult == ComparisonResult.CRITICAL) { + return lastResult; + } + lastResult = compare(new Comparison(ComparisonType.SCHEMA_LOCATION, control, getXPath(controlContext), @@ -537,6 +543,68 @@ } /** + * Compares xsi:type attribute values + */ + private ComparisonResult compareXsiType(Attr controlAttr, + XPathContext controlContext, + Attr testAttr, + XPathContext testContext) { + boolean mustChangeControlContext = controlAttr != null; + boolean mustChangeTestContext = testAttr != null; + if (!mustChangeControlContext && !mustChangeTestContext) { + return ComparisonResult.EQUAL; + } + + try { + if (mustChangeControlContext) { + QName q = Nodes.getQName(controlAttr); + controlContext.addAttribute(q); + controlContext.navigateToAttribute(q); + } + if (mustChangeTestContext) { + QName q = Nodes.getQName(testAttr); + testContext.addAttribute(q); + testContext.navigateToAttribute(q); + } + ComparisonResult lastResult = + compare(new Comparison(ComparisonType.ATTR_NAME_LOOKUP, + controlAttr, getXPath(controlContext), + mustChangeControlContext, + testAttr, getXPath(testContext), + mustChangeTestContext)); + if (lastResult == ComparisonResult.CRITICAL) { + return lastResult; + } + if (mustChangeControlContext && mustChangeTestContext) { + lastResult = + compareAttributeExplicitness(controlAttr, controlContext, + testAttr, testContext); + if (lastResult == ComparisonResult.CRITICAL) { + return lastResult; + } + QName controlQName = valueAsQName(controlAttr); + QName testQName = valueAsQName(testAttr); + lastResult = + compare(new Comparison(ComparisonType.ATTR_VALUE, + controlAttr, + getXPath(controlContext), + controlQName.toString(), + testAttr, + getXPath(testContext), + testQName.toString())); + } + return lastResult; + } finally { + if (mustChangeControlContext) { + controlContext.navigateToParent(); + } + if (mustChangeTestContext) { + testContext.navigateToParent(); + } + } + } + + /** * Compares properties of an attribute. */ private ComparisonResult compareAttributes(Attr control, @@ -544,11 +612,8 @@ Attr test, XPathContext testContext) { ComparisonResult lastResult = - compare(new Comparison(ComparisonType.ATTR_VALUE_EXPLICITLY_SPECIFIED, - control, getXPath(controlContext), - control.getSpecified(), - test, getXPath(testContext), - test.getSpecified())); + compareAttributeExplicitness(control, controlContext, test, + testContext); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } @@ -561,6 +626,20 @@ } /** + * Compares whether two attributes are specified explicitly. + */ + private ComparisonResult + compareAttributeExplicitness(Attr control, XPathContext controlContext, + Attr test, XPathContext testContext) { + return + compare(new Comparison(ComparisonType.ATTR_VALUE_EXPLICITLY_SPECIFIED, + control, getXPath(controlContext), + control.getSpecified(), + test, getXPath(testContext), + test.getSpecified())); + } + + /** * Separates XML namespace related attributes from "normal" attributes.xb */ private static Attributes splitAttributes(final NamedNodeMap map) { @@ -570,28 +649,45 @@ Attr nNsLoc = (Attr) map.getNamedItemNS(XMLConstants .W3C_XML_SCHEMA_INSTANCE_NS_URI, "noNamespaceSchemaLocation"); + Attr type = (Attr) map.getNamedItemNS(XMLConstants + .W3C_XML_SCHEMA_INSTANCE_NS_URI, + "type"); List<Attr> rest = new LinkedList<Attr>(); final int len = map.getLength(); for (int i = 0; i < len; i++) { Attr a = (Attr) map.item(i); if (!XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(a.getNamespaceURI()) - && - !XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI - .equals(a.getNamespaceURI())) { + && a != sLoc && a != nNsLoc && a != type) { rest.add(a); } } - return new Attributes(sLoc, nNsLoc, rest); + return new Attributes(sLoc, nNsLoc, type, rest); } + private static QName valueAsQName(Attr attribute) { + String[] pieces = attribute.getValue().split(":"); + if (pieces.length < 2) { + pieces = new String[] { "", pieces[0] }; + } else if (pieces.length > 2) { + pieces = new String[] { + pieces[0], + attribute.getValue().substring(pieces[0].length() + 1) + }; + } + return new QName(Nodes.findNamespaceURIForPrefix(attribute, pieces[0]), + pieces[1], pieces[0]); + } + private static class Attributes { private final Attr schemaLocation; private final Attr noNamespaceSchemaLocation; + private final Attr type; private final List<Attr> remainingAttributes; private Attributes(Attr schemaLocation, Attr noNamespaceSchemaLocation, - List<Attr> remainingAttributes) { + Attr type, List<Attr> remainingAttributes) { this.schemaLocation = schemaLocation; this.noNamespaceSchemaLocation = noNamespaceSchemaLocation; + this.type = type; this.remainingAttributes = remainingAttributes; } } 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 2013-02-02 14:35:56 UTC (rev 502) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/XPathContext.java 2013-02-03 06:37:37 UTC (rev 503) @@ -70,6 +70,12 @@ } } + public void addAttribute(QName attribute) { + Level current = path.getLast(); + current.attributes.put(attribute, + new Level(ATTR + getName(attribute))); + } + public void setChildren(Iterable<? extends NodeInfo> children) { Level current = path.getLast(); current.children.clear(); 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 2013-02-02 14:35:56 UTC (rev 502) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/util/Nodes.java 2013-02-03 06:37:37 UTC (rev 503) @@ -113,6 +113,35 @@ } /** + * Looks up the namespace URI associated with a given prefix on a given node. + * @param onNode the reference node + * @param prefix the prefix to look for + * @return the URI or null of it cannot be found + */ + public static String findNamespaceURIForPrefix(Node onNode, String prefix) { + if (onNode != null && onNode instanceof Attr) { + onNode = ((Attr) onNode).getOwnerElement(); + } + while (onNode != null && onNode.getNodeType() != Node.ELEMENT_NODE) { + onNode = onNode.getParentNode(); + } + if (onNode == null) { + return null; + } + + if (prefix == null || "".equals(prefix)) { + prefix = XMLConstants.XMLNS_ATTRIBUTE; + } + Map<QName, String> attrs = getAttributes(onNode); + String uri = attrs.get(new QName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, + prefix)); + if (uri != null) { + return uri; + } + return findNamespaceURIForPrefix(onNode.getParentNode(), prefix); + } + + /** * Trims textual content of this node, removes empty text and * CDATA children, recurses into its child nodes. * @param normalize whether to normalize whitespace as well 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 2013-02-02 14:35:56 UTC (rev 502) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2013-02-03 06:37:37 UTC (rev 503) @@ -997,7 +997,45 @@ assertTrue(diff.toString(), diff.similar()); } - public void XtestXsiTypeSpecialCaseDoesntIgnorePrefix() throws Exception { + public void testXsiTypeSpecialCaseShortLocalName() throws Exception { + String test = "<ns1:Square xsi:type=\"ns1:a\" " + + "xmlns:ns1=\"http://example.com/\" " + + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>"; + + String control = "<ns2:Square xsi:type=\"ns2:a\" " + + "xmlns:ns2=\"http://example.com/\" " + + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>"; + Diff diff = new Diff(control, test); + assertTrue(diff.toString(), diff.similar()); + } + + public void testXsiTypeSpecialCaseWorksWithDefaultNs() throws Exception { + String test = "<Square xsi:type=\"Shape\" " + + "xmlns=\"http://example.com/\" " + + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>"; + + String control = "<ns2:Square xsi:type=\"ns2:Shape\" " + + "xmlns:ns2=\"http://example.com/\" " + + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>"; + Diff diff = new Diff(control, test); + assertTrue(diff.toString(), diff.similar()); + } + + public void testXsiTypeSpecialCaseInheritsParentNs() throws Exception { + String test = "<ns1:Shapes xmlns:ns1=\"http://example.com/\">" + + "<ns1:Square xsi:type=\"ns1:Shape\" " + + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>" + + "</ns1:Shapes>"; + + String control = "<ns2:Shapes xmlns:ns2=\"http://example.com/\">" + + "<ns2:Square xsi:type=\"ns2:Shape\" " + + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>" + + "</ns2:Shapes>"; + Diff diff = new Diff(control, test); + assertTrue(diff.toString(), diff.similar()); + } + + public void testXsiTypeSpecialCaseDoesntIgnorePrefix() throws Exception { String test = "<ns1:Square xsi:type=\"ns1:Shape\" " + "xmlns:ns1=\"http://example.com/\" " + "xmlns:ns2=\"http://example.com/another-uri/\" " Property changes on: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java ___________________________________________________________________ Modified: svn:mergeinfo - /branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/test_Diff.java:337,346,353,494,499 /branches/xmlunit-1.x/tests/org/custommonkey/xmlunit/test_Diff.java:346 + /branches/xmlunit-1.x/tests/java/org/custommonkey/xmlunit/test_Diff.java:337,346,353,494,499,501 /branches/xmlunit-1.x/tests/org/custommonkey/xmlunit/test_Diff.java:346 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2013-02-03 09:41:56
|
Revision: 505 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=505&view=rev Author: bodewig Date: 2013-02-03 09:41:49 +0000 (Sun, 03 Feb 2013) Log Message: ----------- some additonal tests Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/DOMDifferenceEngineTest.java trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/XPathContextTest.java Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java 2013-02-03 08:35:12 UTC (rev 504) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/diff/DOMDifferenceEngine.java 2013-02-03 09:41:49 UTC (rev 505) @@ -665,10 +665,13 @@ } private static QName valueAsQName(Attr attribute) { + // split QName into prefix and local name String[] pieces = attribute.getValue().split(":"); if (pieces.length < 2) { + // unprefixed name pieces = new String[] { null, pieces[0] }; } else if (pieces.length > 2) { + // actually, this is not a valid QName - be lenient pieces = new String[] { pieces[0], attribute.getValue().substring(pieces[0].length() + 1) 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 2013-02-03 08:35:12 UTC (rev 504) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/DOMDifferenceEngineTest.java 2013-02-03 09:41:49 UTC (rev 505) @@ -759,4 +759,127 @@ assertEquals(1, ex.invoked); } + @Test public void xsiTypesWithDifferentPrefixes() { + Document d1 = + documentForString("<foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + Document d2 = + documentForString("<foo xsi:type='p2:Foo'" + + " xmlns:p2='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.addDifferenceListener(ex); + d.setDifferenceEvaluator(DifferenceEvaluators.DefaultStopWhenDifferent); + assertEquals(ComparisonResult.EQUAL, + d.compareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + @Test public void xsiTypesWithDefaultNamespace() { + Document d1 = + documentForString("<a:foo xsi:type='Foo'" + + " xmlns='urn:xmlunit:test'" + + " xmlns:a='urn:xmlunit:test2'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + Document d2 = + documentForString("<a:foo xsi:type='p2:Foo'" + + " xmlns:p2='urn:xmlunit:test'" + + " xmlns:a='urn:xmlunit:test2'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.addDifferenceListener(ex); + d.setDifferenceEvaluator(DifferenceEvaluators.DefaultStopWhenDifferent); + assertEquals(ComparisonResult.EQUAL, + d.compareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + @Test public void xsiTypesWithDifferentLocalNames() { + Document d1 = + documentForString("<foo xsi:type='p1:Bar'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + Document d2 = + documentForString("<foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.addDifferenceListener(ex); + d.setDifferenceEvaluator(DifferenceEvaluators.DefaultStopWhenDifferent); + assertEquals(ComparisonResult.CRITICAL, + d.compareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + @Test public void xsiTypesWithDifferentNamespaceURIs() { + Document d1 = + documentForString("<foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + Document d2 = + documentForString("<foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test2'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.addDifferenceListener(ex); + d.setDifferenceEvaluator(DifferenceEvaluators.DefaultStopWhenDifferent); + assertEquals(ComparisonResult.CRITICAL, + d.compareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + @Test public void xsiTypesWithNamespaceDeclarationOnDifferentLevels() { + Document d1 = + documentForString("<bar xmlns:p1='urn:xmlunit:test'>" + + "<foo xsi:type='p1:Foo'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/></bar>"); + Document d2 = + documentForString("<bar><foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/></bar>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.addDifferenceListener(ex); + d.setDifferenceEvaluator(DifferenceEvaluators.DefaultStopWhenDifferent); + assertEquals(ComparisonResult.EQUAL, + d.compareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + @Test public void xsiNil() { + Document d1 = + documentForString("<foo xsi:nil='true'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + Document d2 = + documentForString("<foo xsi:nil='false'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.addDifferenceListener(ex); + d.setDifferenceEvaluator(DifferenceEvaluators.DefaultStopWhenDifferent); + assertEquals(ComparisonResult.CRITICAL, + d.compareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + private Document documentForString(String s) { + return Convert.toDocument(Input.fromMemory(s).build()); + } } Modified: trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/XPathContextTest.java =================================================================== --- trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/XPathContextTest.java 2013-02-03 08:35:12 UTC (rev 504) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/diff/XPathContextTest.java 2013-02-03 09:41:49 UTC (rev 505) @@ -102,6 +102,15 @@ assertEquals("/foo[1]/@bar", ctx.getXPath()); } + @Test public void singleAttribute() { + XPathContext ctx = new XPathContext(); + ctx.setChildren(Linqy.singleton(new Element("foo"))); + ctx.navigateToChild(0); + ctx.addAttribute(new QName("bar")); + ctx.navigateToAttribute(new QName("bar")); + assertEquals("/foo[1]/@bar", ctx.getXPath()); + } + @Test public void mixed() { ArrayList<XPathContext.NodeInfo> l = new ArrayList<XPathContext.NodeInfo>(); l.add(new Text()); @@ -203,4 +212,4 @@ private static class CDATA extends NonElement { public short getType() { return Node.CDATA_SECTION_NODE; } } -} \ No newline at end of file +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2013-02-03 10:14:43
|
Revision: 506 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=506&view=rev Author: bodewig Date: 2013-02-03 10:14:36 +0000 (Sun, 03 Feb 2013) Log Message: ----------- Post xsi:type changes to .NET version Modified Paths: -------------- trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.cs trunk/xmlunit/src/main/net-core/diff/XPathContext.cs trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs trunk/xmlunit/src/tests/net-core/diff/XPathContextTest.cs Modified: trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.cs =================================================================== --- trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.cs 2013-02-03 09:41:49 UTC (rev 505) +++ trunk/xmlunit/src/main/net-core/diff/DOMDifferenceEngine.cs 2013-02-03 10:14:36 UTC (rev 506) @@ -424,6 +424,12 @@ } } + lastResult = CompareXsiType(controlAttributes.Type, controlContext, + testAttributes.Type, testContext); + if (lastResult == ComparisonResult.CRITICAL) { + return lastResult; + } + lastResult = Compare(new Comparison(ComparisonType.SCHEMA_LOCATION, control, GetXPath(controlContext), @@ -571,7 +577,69 @@ return lastResult; } + /// <summary> + /// Compares xsi:type attribute values + /// </summary> + private ComparisonResult CompareXsiType(XmlAttribute control, + XPathContext controlContext, + XmlAttribute test, + XPathContext testContext) { + bool mustChangeControlContext = control != null; + bool mustChangeTestContext = test != null; + if (!mustChangeControlContext && !mustChangeTestContext) { + return ComparisonResult.EQUAL; + } + + try { + if (mustChangeControlContext) { + XmlQualifiedName q = Nodes.GetQName(control); + controlContext.AddAttribute(q); + controlContext.NavigateToAttribute(q); + } + if (mustChangeTestContext) { + XmlQualifiedName q = Nodes.GetQName(test); + testContext.AddAttribute(q); + testContext.NavigateToAttribute(q); + } + ComparisonResult lastResult = + Compare(new Comparison(ComparisonType.ATTR_NAME_LOOKUP, + control, GetXPath(controlContext), + mustChangeControlContext, + test, GetXPath(testContext), + mustChangeTestContext)); + if (lastResult == ComparisonResult.CRITICAL) { + return lastResult; + } + if (mustChangeControlContext && mustChangeTestContext) { + lastResult = + CompareAttributeExplicitness(control, controlContext, + test, testContext); + if (lastResult == ComparisonResult.CRITICAL) { + return lastResult; + } + XmlQualifiedName controlQName = ValueAsQName(control); + XmlQualifiedName testQName = ValueAsQName(test); + lastResult = + Compare(new Comparison(ComparisonType.ATTR_VALUE, + control, + GetXPath(controlContext), + controlQName.ToString(), + test, GetXPath(testContext), + testQName.ToString())); + } + return lastResult; + } finally { + if (mustChangeControlContext) { + controlContext.NavigateToParent(); + } + if (mustChangeTestContext) { + testContext.NavigateToParent(); + } + } + } + + /// <summary> /// Compares properties of an attribute. /// </summary> private ComparisonResult CompareAttributes(XmlAttribute control, @@ -580,11 +648,8 @@ XPathContext testContext) { ComparisonResult lastResult = - Compare(new Comparison(ComparisonType.ATTR_VALUE_EXPLICITLY_SPECIFIED, - control, GetXPath(controlContext), - control.Specified, - test, GetXPath(testContext), - test.Specified)); + CompareAttributeExplicitness(control, controlContext, + test, testContext); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; @@ -598,6 +663,22 @@ } /// <summary> + // Compares whether two attributes are specified explicitly. + /// </summary> + private ComparisonResult + CompareAttributeExplicitness(XmlAttribute control, + XPathContext controlContext, + XmlAttribute test, + XPathContext testContext) { + return + Compare(new Comparison(ComparisonType.ATTR_VALUE_EXPLICITLY_SPECIFIED, + control, GetXPath(controlContext), + control.Specified, + test, GetXPath(testContext), + test.Specified)); + } + + /// <summary> /// Separates XML namespace related attributes from "normal" /// attributes. /// </summary> @@ -608,26 +689,49 @@ XmlAttribute nNsLoc = map.GetNamedItem("noNamespaceSchemaLocation", XmlSchema.InstanceNamespace) as XmlAttribute; + XmlAttribute type = map.GetNamedItem("type", + XmlSchema.InstanceNamespace) + as XmlAttribute; List<XmlAttribute> rest = new List<XmlAttribute>(); foreach (XmlAttribute a in map) { - if (XmlSchema.InstanceNamespace != a.NamespaceURI - && - "http://www.w3.org/2000/xmlns/" != a.NamespaceURI) { + if ("http://www.w3.org/2000/xmlns/" != a.NamespaceURI + && a != sLoc && a != nNsLoc && a != type) { rest.Add(a); } } - return new Attributes(sLoc, nNsLoc, rest); + return new Attributes(sLoc, nNsLoc, type, rest); } + private static XmlQualifiedName ValueAsQName(XmlAttribute attribute) { + // split QName into prefix and local name + string[] pieces = attribute.Value.Split(':'); + if (pieces.Length < 2) { + // unprefixed name + pieces = new string[] { string.Empty, pieces[0] }; + } else if (pieces.Length > 2) { + // actually, this is not a valid QName - be lenient + pieces = new string[] { + pieces[0], + attribute.Value.Substring(pieces[0].Length + 1) + }; + } + return new XmlQualifiedName(pieces[1] ?? string.Empty, + attribute + .GetNamespaceOfPrefix(pieces[0])); + } + internal class Attributes { internal readonly XmlAttribute SchemaLocation; internal readonly XmlAttribute NoNamespaceSchemaLocation; + internal readonly XmlAttribute Type; internal readonly IList<XmlAttribute> RemainingAttributes; internal Attributes(XmlAttribute schemaLocation, XmlAttribute noNamespaceSchemaLocation, + XmlAttribute type, IList<XmlAttribute> remainingAttributes) { this.SchemaLocation = schemaLocation; this.NoNamespaceSchemaLocation = noNamespaceSchemaLocation; + this.Type = type; this.RemainingAttributes = remainingAttributes; } } Modified: trunk/xmlunit/src/main/net-core/diff/XPathContext.cs =================================================================== --- trunk/xmlunit/src/main/net-core/diff/XPathContext.cs 2013-02-03 09:41:49 UTC (rev 505) +++ trunk/xmlunit/src/main/net-core/diff/XPathContext.cs 2013-02-03 10:14:36 UTC (rev 506) @@ -64,6 +64,12 @@ } } + public void AddAttribute(XmlQualifiedName attribute) { + Level current = path.Last.Value; + current.Attributes[attribute] = + new Level(ATTR + GetName(attribute)); + } + public void SetChildren<N>(IEnumerable<N> children) where N : INodeInfo { Level current = path.Last.Value; Modified: trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs =================================================================== --- trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs 2013-02-03 09:41:49 UTC (rev 505) +++ trunk/xmlunit/src/tests/net-core/diff/DOMDifferenceEngineTest.cs 2013-02-03 10:14:36 UTC (rev 506) @@ -750,5 +750,141 @@ e2, new XPathContext())); Assert.AreEqual(1, ex.invoked); } + + [Test] + public void XsiTypesWithDifferentPrefixes() { + XmlDocument d1 = + DocumentForString("<foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + XmlDocument d2 = + DocumentForString("<foo xsi:type='p2:Foo'" + + " xmlns:p2='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.DifferenceListener += ex.ComparisonPerformed; + d.DifferenceEvaluator = + DifferenceEvaluators.DefaultStopWhenDifferent; + Assert.AreEqual(ComparisonResult.EQUAL, + d.CompareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + [Test] + public void XsiTypesWithDefaultNamespace() { + XmlDocument d1 = + DocumentForString("<a:foo xsi:type='Foo'" + + " xmlns='urn:xmlunit:test'" + + " xmlns:a='urn:xmlunit:test2'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + XmlDocument d2 = + DocumentForString("<a:foo xsi:type='p2:Foo'" + + " xmlns:p2='urn:xmlunit:test'" + + " xmlns:a='urn:xmlunit:test2'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.DifferenceListener += ex.ComparisonPerformed; + d.DifferenceEvaluator = + DifferenceEvaluators.DefaultStopWhenDifferent; + Assert.AreEqual(ComparisonResult.EQUAL, + d.CompareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + [Test] + public void XsiTypesWithDifferentLocalNames() { + XmlDocument d1 = + DocumentForString("<foo xsi:type='p1:Bar'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + XmlDocument d2 = + DocumentForString("<foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.DifferenceListener += ex.ComparisonPerformed; + d.DifferenceEvaluator = + DifferenceEvaluators.DefaultStopWhenDifferent; + Assert.AreEqual(ComparisonResult.CRITICAL, + d.CompareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + [Test] + public void XsiTypesWithDifferentNamespaceURIs() { + XmlDocument d1 = + DocumentForString("<foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + XmlDocument d2 = + DocumentForString("<foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test2'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.DifferenceListener += ex.ComparisonPerformed; + d.DifferenceEvaluator = + DifferenceEvaluators.DefaultStopWhenDifferent; + Assert.AreEqual(ComparisonResult.CRITICAL, + d.CompareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + [Test] + public void XsiTypesWithNamespaceDeclarationOnDifferentLevels() { + XmlDocument d1 = + DocumentForString("<bar xmlns:p1='urn:xmlunit:test'>" + + "<foo xsi:type='p1:Foo'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/></bar>"); + XmlDocument d2 = + DocumentForString("<bar><foo xsi:type='p1:Foo'" + + " xmlns:p1='urn:xmlunit:test'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/></bar>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.DifferenceListener += ex.ComparisonPerformed; + d.DifferenceEvaluator = + DifferenceEvaluators.DefaultStopWhenDifferent; + Assert.AreEqual(ComparisonResult.EQUAL, + d.CompareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + [Test] + public void XsiNil() { + XmlDocument d1 = + DocumentForString("<foo xsi:nil='true'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + XmlDocument d2 = + DocumentForString("<foo xsi:nil='false'" + + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" + + "/>"); + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = new DiffExpecter(ComparisonType.ATTR_VALUE); + d.DifferenceListener += ex.ComparisonPerformed; + d.DifferenceEvaluator = + DifferenceEvaluators.DefaultStopWhenDifferent; + Assert.AreEqual(ComparisonResult.CRITICAL, + d.CompareNodes(d1, new XPathContext(), + d2, new XPathContext())); + } + + private XmlDocument DocumentForString(string s) { + return net.sf.xmlunit.util.Convert.ToDocument(Input.FromMemory(s).Build()); + } } } Modified: trunk/xmlunit/src/tests/net-core/diff/XPathContextTest.cs =================================================================== --- trunk/xmlunit/src/tests/net-core/diff/XPathContextTest.cs 2013-02-03 09:41:49 UTC (rev 505) +++ trunk/xmlunit/src/tests/net-core/diff/XPathContextTest.cs 2013-02-03 10:14:36 UTC (rev 506) @@ -106,6 +106,16 @@ } [Test] + public void singleAttribute() { + XPathContext ctx = new XPathContext(); + ctx.SetChildren(Linqy.Singleton(new Element("foo"))); + ctx.NavigateToChild(0); + ctx.AddAttribute(new XmlQualifiedName("bar")); + ctx.NavigateToAttribute(new XmlQualifiedName("bar")); + Assert.AreEqual("/foo[1]/@bar", ctx.XPath); + } + + [Test] public void Mixed() { List<XPathContext.INodeInfo> l = new List<XPathContext.INodeInfo>(); l.Add(new Text()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2013-04-14 16:29:52
|
Revision: 527 http://sourceforge.net/p/xmlunit/code/527 Author: bodewig Date: 2013-04-14 16:29:49 +0000 (Sun, 14 Apr 2013) Log Message: ----------- Port fix for Issue 60 by Eric Siegerman to 2.x branch Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEngine.java trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 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_DifferenceEngine.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_IgnoreTextAndAttributeValuesDifferenceListener.java trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java trunk/xmlunit/src/user-guide/XMLUnit-Java.xml Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEngine.java 2013-04-14 15:59:58 UTC (rev 526) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/DifferenceEngine.java 2013-04-14 16:29:49 UTC (rev 527) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2010, Jeff Martin, Tim Bacon +Copyright (c) 2001-2010,2013 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -322,16 +322,28 @@ protected void compareNodeChildren(Node control, Node test, DifferenceListener listener, ElementQualifier elementQualifier) throws DifferenceFoundException { - if (control.hasChildNodes() && test.hasChildNodes()) { - List controlChildren = nodeList2List(control.getChildNodes()); - List testChildren = nodeList2List(test.getChildNodes()); - Integer controlLength = new Integer(controlChildren.size()); - Integer testLength = new Integer(testChildren.size()); - compare(controlLength, testLength, control, test, listener, - CHILD_NODELIST_LENGTH); - compareNodeList(controlChildren, testChildren, - controlLength.intValue(), listener, elementQualifier); + List controlChildren = nodeList2List(control.getChildNodes()); + List testChildren = nodeList2List(test.getChildNodes()); + + Integer controlLength = new Integer(controlChildren.size()); + Integer testLength = new Integer(testChildren.size()); + compare(controlLength, testLength, control, test, listener, + CHILD_NODELIST_LENGTH); + + if (control.hasChildNodes() || test.hasChildNodes()) { + if (!control.hasChildNodes()) { + for (Iterator iter = testChildren.iterator(); iter.hasNext();) { + missingNode(null, (Node) iter.next(), listener); + } + } else if (!test.hasChildNodes()) { + for (Iterator iter = controlChildren.iterator(); iter.hasNext();) { + missingNode((Node) iter.next(), null, listener); + } + } else { + compareNodeList(controlChildren, testChildren, + controlLength.intValue(), listener, elementQualifier); + } } } Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2013-04-14 15:59:58 UTC (rev 526) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/NewDifferenceEngine.java 2013-04-14 16:29:49 UTC (rev 527) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2010, Jeff Martin, Tim Bacon +Copyright (c) 2001-2010,2013 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -40,6 +40,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.transform.Source; @@ -213,7 +214,8 @@ engine.compare(ctrlSource, tstSource); } - public static Difference toDifference(Comparison comp) { + public static Iterable<Difference> toDifference(Comparison comp) { + List<Difference> diffs = new LinkedList<Difference>(); Difference proto = null; switch (comp.getType()) { case ATTR_VALUE_EXPLICITLY_SPECIFIED: @@ -276,19 +278,19 @@ 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())); + diffs.add(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; @@ -306,10 +308,10 @@ break; } if (proto != null) { - return new Difference(proto, toNodeDetail(comp.getControlDetails()), - toNodeDetail(comp.getTestDetails())); + diffs.add(new Difference(proto, toNodeDetail(comp.getControlDetails()), + toNodeDetail(comp.getTestDetails()))); } - return null; + return diffs; } public static NodeDetail toNodeDetail(Comparison.Detail detail) { @@ -333,8 +335,7 @@ public void comparisonPerformed(Comparison comparison, ComparisonResult outcome) { - Difference diff = toDifference(comparison); - if (diff != null) { + for (Difference diff : toDifference(comparison)) { mt.matchFound(diff); } } @@ -350,8 +351,7 @@ public void comparisonPerformed(Comparison comparison, ComparisonResult outcome) { - Difference diff = toDifference(comparison); - if (diff != null) { + for (Difference diff : toDifference(comparison)) { dl.differenceFound(diff); } } @@ -412,9 +412,10 @@ public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { - Difference diff = toDifference(comparison); - if (diff != null && cc.haltComparison(diff)) { - return ComparisonResult.CRITICAL; + for (Difference diff : toDifference(comparison)) { + if (cc.haltComparison(diff)) { + return ComparisonResult.CRITICAL; + } } return outcome; } @@ -445,21 +446,31 @@ public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { - Difference diff = toDifference(comparison); - if (diff != null) { + ComparisonResult max = outcome; + for (Difference diff : toDifference(comparison)) { + ComparisonResult curr = null; switch (dl.differenceFound(diff)) { case DifferenceListener .RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL: - return ComparisonResult.EQUAL; + curr = ComparisonResult.EQUAL; + break; case DifferenceListener .RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR: - return ComparisonResult.SIMILAR; + curr = ComparisonResult.SIMILAR; + break; case DifferenceListener .RETURN_UPGRADE_DIFFERENCE_NODES_DIFFERENT: - return ComparisonResult.DIFFERENT; + curr = ComparisonResult.DIFFERENT; + break; + default: + // unknown result, ignore it + break; } + if (curr != null && curr.compareTo(max) > 0) { + max = curr; + } } - return outcome; + return max; } } 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 2013-04-14 15:59:58 UTC (rev 526) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DetailedDiff.java 2013-04-14 16:29:49 UTC (rev 527) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2008,2010 Jeff Martin, Tim Bacon +Copyright (c) 2001-2008,2010,2013 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -63,17 +63,19 @@ private void assertExpectedDifferencesFirstForecastControl(List differences, DetailedDiff detailedDiff) { - assertEquals("size: " + detailedDiff, 5, differences.size()); + assertEquals("size: " + detailedDiff, 6, differences.size()); assertEquals("first: " + detailedDiff, DifferenceConstants.HAS_CHILD_NODES, differences.get(0)); assertEquals("second: " + detailedDiff, - DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences.get(1)); + DifferenceConstants.CHILD_NODELIST_LENGTH, differences.get(1)); assertEquals("third: " + detailedDiff, - DifferenceConstants.ATTR_NAME_NOT_FOUND, differences.get(2)); - assertEquals("fourth: " + detailedDiff, - DifferenceConstants.ATTR_VALUE, differences.get(3)); + DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences.get(2)); + assertEquals("forth: " + detailedDiff, + DifferenceConstants.ATTR_NAME_NOT_FOUND, differences.get(3)); assertEquals("fifth: " + detailedDiff, - DifferenceConstants.CHILD_NODE_NOT_FOUND, differences.get(4)); + DifferenceConstants.ATTR_VALUE, differences.get(4)); + assertEquals("sixth: " + detailedDiff, + DifferenceConstants.CHILD_NODE_NOT_FOUND, differences.get(5)); } public void testAllDifferencesSecondForecastControl() throws Exception { @@ -82,18 +84,20 @@ List differences = detailedDiff.getAllDifferences(); - assertEquals("size: " + detailedDiff, 5, differences.size()); + assertEquals("size: " + detailedDiff, 6, differences.size()); assertEquals("first: " + detailedDiff, DifferenceConstants.HAS_CHILD_NODES, differences.get(0)); assertEquals("second: " + detailedDiff, - DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences.get(1)); + DifferenceConstants.CHILD_NODELIST_LENGTH, differences.get(1)); assertEquals("third: " + detailedDiff, - DifferenceConstants.ATTR_VALUE, differences.get(2)); + DifferenceConstants.ELEMENT_NUM_ATTRIBUTES, differences.get(2)); assertEquals("forth: " + detailedDiff, + DifferenceConstants.ATTR_VALUE, differences.get(3)); + assertEquals("fifth: " + detailedDiff, DifferenceConstants.ATTR_NAME_NOT_FOUND, - differences.get(3)); - assertEquals("fifth: " + detailedDiff, - DifferenceConstants.CHILD_NODE_NOT_FOUND, differences.get(4)); + differences.get(4)); + assertEquals("sixth: " + detailedDiff, + DifferenceConstants.CHILD_NODE_NOT_FOUND, differences.get(5)); } public void testPrototypeIsADetailedDiff() throws Exception { 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 2013-04-14 15:59:58 UTC (rev 526) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_Diff.java 2013-04-14 16:29:49 UTC (rev 527) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2013, Jeff Martin, Tim Bacon +Copyright (c) 2001-2013 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -789,9 +789,10 @@ // // NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0), // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) - assertEquals(14, count[0]); + assertEquals(15, count[0]); } public void testMatchTrackerSetViaEngine() throws Exception { @@ -816,8 +817,9 @@ // // NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), - // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) - assertEquals(12, count[0]); + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0) + assertEquals(13, count[0]); } public void testMatchTrackerSetViaOverrideOnEngine() throws Exception { @@ -843,8 +845,9 @@ // // NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), - // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) - assertEquals(12, count[0]); + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0) + assertEquals(13, count[0]); } public void testMatchTrackerSetViaNewEngine() throws Exception { @@ -869,9 +872,10 @@ // // NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0), // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) - assertEquals(14, count[0]); + assertEquals(15, count[0]); } public void testMatchTrackerSetViaOverrideOnNewEngine() throws Exception { @@ -897,9 +901,10 @@ // // NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0), // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) - assertEquals(14, count[0]); + assertEquals(15, count[0]); } public void testCDATAAndIgnoreWhitespace() throws Exception { 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 2013-04-14 15:59:58 UTC (rev 526) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_DifferenceEngine.java 2013-04-14 16:29:49 UTC (rev 527) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2008,2010 Jeff Martin, Tim Bacon +Copyright (c) 2001-2008,2010,2013 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -646,15 +646,15 @@ String test = "<stuff><item id=\"2\"/></stuff>"; listenToDifferences(control, test); assertEquals("15th difference type", - DifferenceEngine.HAS_CHILD_NODES_ID, + DifferenceEngine.CHILD_NODE_NOT_FOUND_ID, listener.comparingWhat); - assertEquals("15th difference control value", "true", + assertEquals("15th difference control value", "thing", listener.expected); - assertEquals("15th difference test value", "false", + assertEquals("15th difference test value", "null", listener.actual); - assertEquals("15th control xpath", "/stuff[1]/item[1]", + assertEquals("15th control xpath", "/stuff[1]/item[1]/thing[1]", listener.controlXpath); - assertEquals("15th test xpath", "/stuff[1]/item[1]", + assertNull("15th test xpath should be null but is " + listener.testXpath, listener.testXpath); } @@ -857,8 +857,9 @@ d.compare(control, test, listener, null); // NODE_TYPE (not null), NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), - // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) - assertEquals(7, count[0]); + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0) + assertEquals(8, count[0]); } public void testMatchTrackerSetViaSetter() throws Exception { @@ -873,8 +874,9 @@ engine.compare(control, test, listener, null); // NODE_TYPE (not null), NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), - // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) - assertEquals(7, count[0]); + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0) + assertEquals(8, count[0]); } /** 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 2013-04-14 15:59:58 UTC (rev 526) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_IgnoreTextAndAttributeValuesDifferenceListener.java 2013-04-14 16:29:49 UTC (rev 527) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 200, Jeff Martin, Tim Bacon +Copyright (c) 2001-2008,2013 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -146,9 +146,9 @@ new Diff(control, dissimilarTest)); dissimilarDetailedDiff.overrideDifferenceListener(listener); List differences = dissimilarDetailedDiff.getAllDifferences(); - assertEquals("has children, wrong number of attributes, missing attribute, different attribute value, and missing text node. " + assertEquals("has children, wrong number of attributes, missing attribute, different attribute value, number of children and missing text node. " + dissimilarDetailedDiff.toString(), - 5, differences.size()); + 6, differences.size()); int recoverable = 0; for (Iterator iter = differences.iterator(); iter.hasNext(); ) { Difference aDifference = (Difference) iter.next(); Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2013-04-14 15:59:58 UTC (rev 526) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/test_NewDifferenceEngine.java 2013-04-14 16:29:49 UTC (rev 527) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001-2008,2010 Jeff Martin, Tim Bacon +Copyright (c) 2001-2008,2010,2013 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -255,11 +255,11 @@ String test = "<stuff><item id=\"2\"/></stuff>"; listenToDifferences(control, test); assertEquals("15th difference type", - NewDifferenceEngine.HAS_CHILD_NODES_ID, + NewDifferenceEngine.CHILD_NODELIST_LENGTH_ID, listener.comparingWhat); - assertEquals("15th difference control value", "true", + assertEquals("15th difference control value", "1", listener.expected); - assertEquals("15th difference test value", "false", + assertEquals("15th difference test value", "0", listener.actual); assertEquals("15th control xpath", "/stuff[1]/item[1]", listener.controlXpath); @@ -390,9 +390,10 @@ d.compare(control, test, listener, null); // NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0), // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) - assertEquals(8, count[0]); + assertEquals(9, count[0]); } public void testMatchTrackerSetViaSetter() throws Exception { @@ -407,9 +408,10 @@ engine.compare(control, test, listener, null); // NODE_TYPE(Element), NAMESPACE_URI(none), // NAMESPACE_PREFIX(none), HAS_CHILD_NODES(false), + // CHILD_NODELIST_LENGTH(0) // ELEMENT_TAG_NAME(foo), ELEMENT_NUM_ATTRIBUTE(none), // SCHEMA_LOCATION(none), NO_NAMESPACE_SCHEMA_LOCATION(none) - assertEquals(8, count[0]); + assertEquals(9, count[0]); } /** Modified: trunk/xmlunit/src/user-guide/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/user-guide/XMLUnit-Java.xml 2013-04-14 15:59:58 UTC (rev 526) +++ trunk/xmlunit/src/user-guide/XMLUnit-Java.xml 2013-04-14 16:29:49 UTC (rev 527) @@ -3695,6 +3695,46 @@ </section> </section> + <section id="Changes 1.5"> + <title>Changes from XMLUnit 1.4 to 1.5</title> + + <section id="Breaking Changes 1.5"> + <title>Breaking Changes</title> + + <itemizedlist> + <listitem> + If one node in the comparison has children while the other + one has not, XMLUnit 1.5 will signal a + <literal>CHILD_NODELIST_LENGTH</literal> difference and + <literal>CHILD_NODE_NOT_FOUND</literal> + differences for each child node of the node that has + children in addition to a <literal>HAS_CHILD_NODES</literal> difference. + <ulink + href="https://sourceforge.net/p/xmlunit/bugs/60/">Issue + 60</ulink> + </listitem> + </itemizedlist> + </section> + + <section id="New Features 1.5"> + <title>New Features</title> + + <itemizedlist> + <listitem> + </listitem> + </itemizedlist> + </section> + + <section id="Bugfixes 1.5"> + <title>Important Bug Fixes</title> + + <itemizedlist> + <listitem> + </listitem> + </itemizedlist> + </section> + </section> + </appendix> </article> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2013-04-25 16:22:28
|
Revision: 534 http://sourceforge.net/p/xmlunit/code/534 Author: bodewig Date: 2013-04-25 16:22:25 +0000 (Thu, 25 Apr 2013) Log Message: ----------- hamcrest matcher for schema validation by Robert Reimann Added Paths: ----------- trunk/xmlunit/src/main/java-hamcrest/net/sf/xmlunit/matcher/ trunk/xmlunit/src/main/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcher.java trunk/xmlunit/src/tests/java-hamcrest/net/sf/xmlunit/matcher/ trunk/xmlunit/src/tests/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcherTest.java Added: trunk/xmlunit/src/main/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcher.java =================================================================== --- trunk/xmlunit/src/main/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcher.java (rev 0) +++ trunk/xmlunit/src/main/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcher.java 2013-04-25 16:22:25 UTC (rev 534) @@ -0,0 +1,81 @@ +/* + 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.matcher; + +import net.sf.xmlunit.validation.JAXPValidator; +import net.sf.xmlunit.validation.Languages; +import net.sf.xmlunit.validation.ValidationProblem; +import net.sf.xmlunit.validation.ValidationResult; +import org.hamcrest.Description; +import org.hamcrest.Factory; +import org.hamcrest.TypeSafeMatcher; + +import javax.xml.transform.Source; +import java.util.Arrays; + +/** + * Hamcrest Matcher for XML Validation. + */ +public class ValidationMatcher extends TypeSafeMatcher<Source> { + + private final Source schemaSource[]; + private Source instance; + private ValidationResult result; + + public ValidationMatcher(Source... schemaSource) { + this.schemaSource = schemaSource; + } + + @Override + public boolean matchesSafely(Source instance) { + this.instance = instance; + JAXPValidator v = new JAXPValidator(Languages.W3C_XML_SCHEMA_NS_URI); + if (schemaSource.length <= 1) { + v.setSchemaSource(schemaSource[0]); + } else { + v.setSchemaSources(schemaSource); + } + this.result = v.validateInstance(instance); + return this.result.isValid(); + } + + @Override + public void describeTo(Description description) { + description.appendText(" that ") + .appendValue(instance.getSystemId()) + .appendText(" validates against "); + for (Source schema : Arrays.asList(schemaSource)) { + description.appendValue(schema.getSystemId()); + } + } + + @Override + protected void describeMismatchSafely(final Source instance, final Description mismatchDescription) { + if (this.result != null && this.result.getProblems() != null) { + mismatchDescription.appendText(" got validation errors: "); + for (ValidationProblem problem : this.result.getProblems()) { + mismatchDescription.appendText(problem.toString()); + } + } else { + mismatchDescription.appendText(" got unexpected error!"); + } + } + + @Factory + public static ValidationMatcher valid(final Source schemaSource) { + return new ValidationMatcher(schemaSource); + } + + +} Property changes on: trunk/xmlunit/src/main/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcher.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/xmlunit/src/tests/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcherTest.java =================================================================== --- trunk/xmlunit/src/tests/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcherTest.java (rev 0) +++ trunk/xmlunit/src/tests/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcherTest.java 2013-04-25 16:22:25 UTC (rev 534) @@ -0,0 +1,43 @@ +/* + 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.matcher; + +import org.junit.Test; + +import javax.xml.transform.stream.StreamSource; +import java.io.File; + +import static net.sf.xmlunit.matcher.ValidationMatcher.valid; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; + +/** + * Tests for ValidationMatcher. + */ +public class ValidationMatcherTest { + + @Test + public void shouldSuccessfullyValidateInstance() { + assertThat(new StreamSource(new File("src/tests/resources/BookXsdGenerated.xml")), + is(valid(new StreamSource(new File("src/tests/resources/Book.xsd"))))); + + } + + @Test + public void shouldFailOnBrokenInstance() { + assertThat(new StreamSource(new File("src/tests/resources/invalidBook.xml")), + is(not(valid(new StreamSource(new File("src/tests/resources/Book.xsd")))))); + } +} Property changes on: trunk/xmlunit/src/tests/java-hamcrest/net/sf/xmlunit/matcher/ValidationMatcherTest.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2013-08-13 11:50:35
|
Revision: 539 http://sourceforge.net/p/xmlunit/code/539 Author: bodewig Date: 2013-08-13 11:50:32 +0000 (Tue, 13 Aug 2013) Log Message: ----------- merge test for Bug#62 from 1.x branch Modified Paths: -------------- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/examples/test_RecursiveElementNameAndTextQualifier.java trunk/xmlunit/src/user-guide/XMLUnit-Java.xml Modified: trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/examples/test_RecursiveElementNameAndTextQualifier.java =================================================================== --- trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/examples/test_RecursiveElementNameAndTextQualifier.java 2013-08-13 11:45:07 UTC (rev 538) +++ trunk/xmlunit/src/tests/java-legacy/org/custommonkey/xmlunit/examples/test_RecursiveElementNameAndTextQualifier.java 2013-08-13 11:50:32 UTC (rev 539) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2008-2009, Jeff Martin, Tim Bacon +Copyright (c) 2008-2009,2013 Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -167,6 +167,25 @@ assertTrue(d.toString(), d.similar()); } + /** + * @see "http://sourceforge.net/p/xmlunit/bugs/62/" + */ + public void testMultipleTextValuesWithAdditionalElement() throws Exception { + ElementQualifier qualifier = + new RecursiveElementNameAndTextQualifier(); + + Element control = document.createElement(TAG_NAME); + control.appendChild(document.createTextNode(TEXT_A)); + control.appendChild(document.createTextNode(TEXT_B)); + control.appendChild(document.createElement(TAG_NAME)); + + Element test = document.createElement(TAG_NAME); + test.appendChild(document.createTextNode(TEXT_A + TEXT_B)); + test.appendChild(document.createElement(TAG_NAME)); + assertTrue("denormalised control text comparable to normalised test text", + qualifier.qualifyForComparison(control, test)); + } + public void setUp() throws Exception { document = XMLUnit.newControlParser().newDocument(); } Modified: trunk/xmlunit/src/user-guide/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/user-guide/XMLUnit-Java.xml 2013-08-13 11:45:07 UTC (rev 538) +++ trunk/xmlunit/src/user-guide/XMLUnit-Java.xml 2013-08-13 11:50:32 UTC (rev 539) @@ -3730,6 +3730,11 @@ <itemizedlist> <listitem> + <literal>RecursiveElementNameAndTextQualifier</literal> had some indices + reversed leading to wrong results in some cases. + <ulink + href="https://sourceforge.net/p/xmlunit/bugs/62/">Issue + 62</ulink> </listitem> </itemizedlist> </section> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2014-12-04 17:36:25
|
Revision: 565 http://sourceforge.net/p/xmlunit/code/565 Author: bodewig Date: 2014-12-04 17:36:17 +0000 (Thu, 04 Dec 2014) Log Message: ----------- input builder for NIO channels Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/builder/Input.java trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/builder/InputTest.java Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/builder/Input.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/builder/Input.java 2014-12-01 21:00:51 UTC (rev 564) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/builder/Input.java 2014-12-04 17:36:17 UTC (rev 565) @@ -23,6 +23,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; import javax.xml.transform.Source; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; @@ -134,6 +136,13 @@ } /** + * Build a Source from a channel. + */ + public static Builder fromChannel(ReadableByteChannel c) { + return fromStream(Channels.newInputStream(c)); + } + + /** * Build a Source from an URL. */ public static Builder fromURL(URL url) { 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 2014-12-01 21:00:51 UTC (rev 564) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/builder/InputTest.java 2014-12-04 17:36:17 UTC (rev 565) @@ -19,6 +19,7 @@ import java.io.FileReader; import java.net.URI; import java.net.URL; +import java.nio.channels.FileChannel; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; @@ -83,6 +84,23 @@ } } + @Test public void shouldParseAnExistingFileFromChannel() throws Exception { + FileChannel fc = null; + FileInputStream is = null; + try { + is = new FileInputStream(TestResources.ANIMAL_FILE); + fc = is.getChannel(); + allIsWellFor(Input.fromChannel(fc).build()); + } finally { + if (fc != null) { + fc.close(); + } + if (is != null) { + is.close(); + } + } + } + @Test public void shouldParseString() throws Exception { allIsWellFor(Input.fromMemory(new String(readTestFile(), "UTF-8")) .build()); @@ -173,4 +191,4 @@ return false; } } -} \ No newline at end of file +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |