diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b3bc6a5..5684297 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -39,6 +39,22 @@ `DiffBuilder` and `CompareConstraint`. Issue similar to [xmlunit/#119](https://github.com/xmlunit/xmlunit/issues/119). +* the configured `NodeFilter` is now applied before comparing + `XmlDocumentType` nodes. + + This change breaks backwards compatibility as the old behavior was + to ignore `XmlDocumentType` when counting the children of the + `XmlDocument` node but not when actually comparing the + `XmlDocumentType`. Prior to this change if one document had a document + type declaration but the other didn't, a `HAS_DOCTYPE_DECLARATION` + difference was detected, this will no longer be the case now. If you + want to detect this difference, you need to use a more lenient + `NodeFilter` than `NodeFilters.Default` + (i.e. `NodeFilters.AcceptAll`) but then you will see an additional + `CHILD_NODELIST_LENGTH` difference. + + Issue [#26](https://github.com/xmlunit/xmlunit.net/issues/26). + ## XMLUnit.NET 2.5.1 - /Released 2017-10-20/ * elements that only differed in namespace prefix resulted in a false diff --git a/src/main/net-core/Diff/ComparisonType.cs b/src/main/net-core/Diff/ComparisonType.cs index 137413f..f3d6167 100644 --- a/src/main/net-core/Diff/ComparisonType.cs +++ b/src/main/net-core/Diff/ComparisonType.cs @@ -35,6 +35,14 @@ public enum ComparisonType { /// /// Do both documents have a DOCTYPE (or neither of each)? /// + /// + /// + /// This difference is most likely masked by a + /// CHILD_NODELIST_LENGTH difference as the number of children + /// of the document node is tested before the presence of the + /// document type declaration. + /// + /// HAS_DOCTYPE_DECLARATION, /// /// If the documents both have DOCTYPEs, compare the names. @@ -127,4 +135,4 @@ public enum ComparisonType { /// ATTR_NAME_LOOKUP, } -} \ No newline at end of file +} diff --git a/src/main/net-core/Diff/DOMDifferenceEngine.cs b/src/main/net-core/Diff/DOMDifferenceEngine.cs index a420c9d..a72c8ee 100644 --- a/src/main/net-core/Diff/DOMDifferenceEngine.cs +++ b/src/main/net-core/Diff/DOMDifferenceEngine.cs @@ -200,8 +200,8 @@ private ComparisonState CompareDocuments(XmlDocument control, XPathContext controlContext, XmlDocument test, XPathContext testContext) { - XmlDocumentType controlDt = control.DocumentType; - XmlDocumentType testDt = test.DocumentType; + XmlDocumentType controlDt = FilterNode(control.DocumentType); + XmlDocumentType testDt = FilterNode(test.DocumentType); return Compare(new Comparison(ComparisonType.HAS_DOCTYPE_DECLARATION, control, GetXPath(controlContext), @@ -217,6 +217,10 @@ private ComparisonState CompareDocuments(XmlDocument control, testContext)); } + private T FilterNode(T n) where T : XmlNode { + return n != null && NodeFilter(n) ? n : null; + } + /// /// Compares properties of the doctype declaration. /// diff --git a/src/main/net-core/Diff/DifferenceEvaluators.cs b/src/main/net-core/Diff/DifferenceEvaluators.cs index 56c1ef3..ef5a6a3 100644 --- a/src/main/net-core/Diff/DifferenceEvaluators.cs +++ b/src/main/net-core/Diff/DifferenceEvaluators.cs @@ -159,9 +159,14 @@ public static DifferenceEvaluator IgnorePrologDifferences() { /// declaration that are part of the XML prolog. /// /// - ///

Here "ignore" means return {@code ComparisonResult.EQUAL}.

- ///
- /// + /// + /// Here "ignore" means return ComparisonResult.EQUAL. + /// + /// + /// In general different doctype declarations will be ignored + /// because of NodeFilters.Default, so if you want to detect + /// these differences you need to pick a different NodeFilter. + /// /// /// since XMLUnit 2.1.0 /// @@ -211,4 +216,4 @@ private static bool IsSequenceOfRootElement(Comparison comparison) { } } -} \ No newline at end of file +} diff --git a/src/main/net-core/Diff/NodeFilters.cs b/src/main/net-core/Diff/NodeFilters.cs index 0b8958b..d2179eb 100644 --- a/src/main/net-core/Diff/NodeFilters.cs +++ b/src/main/net-core/Diff/NodeFilters.cs @@ -23,9 +23,27 @@ public static class NodeFilters { /// /// Suppresses document-type and XML declaration nodes. /// + /// + /// + /// This is the default used by AbstractDifferenceEngine and + /// thus DOMDifferenceEngine. + /// + /// public static bool Default(XmlNode n) { return n.NodeType != XmlNodeType.DocumentType && n.NodeType != XmlNodeType.XmlDeclaration; } + + /// + /// Suppresses document-type and XML declaration nodes. + /// + /// + /// + /// since XMLUnit 2.6.0 + /// + /// + public static bool AcceptAll(XmlNode n) { + return true; + } } } diff --git a/src/tests/net-core/Diff/DOMDifferenceEngineTest.cs b/src/tests/net-core/Diff/DOMDifferenceEngineTest.cs index cd11b7e..68eda38 100644 --- a/src/tests/net-core/Diff/DOMDifferenceEngineTest.cs +++ b/src/tests/net-core/Diff/DOMDifferenceEngineTest.cs @@ -362,6 +362,12 @@ public void CompareDocuments() { d.DifferenceListener += ex.ComparisonPerformed; d.DifferenceEvaluator = delegate(Comparison comparison, ComparisonResult outcome) { + if (comparison.Type == ComparisonType.CHILD_NODELIST_LENGTH) { + Assert.AreEqual(ComparisonResult.DIFFERENT, outcome); + // downgrade so we get to see the + // HAS_DOCTYPE_DECLARATION difference + return ComparisonResult.EQUAL; + } if (comparison.Type == ComparisonType.HAS_DOCTYPE_DECLARATION) { Assert.AreEqual(ComparisonResult.DIFFERENT, outcome); return ComparisonResult.DIFFERENT; @@ -370,6 +376,7 @@ public void CompareDocuments() { return ComparisonResult.EQUAL; }; d.ComparisonController = ComparisonControllers.StopWhenDifferent; + d.NodeFilter = NodeFilters.AcceptAll; XmlDocument d1, d2; @@ -452,6 +459,30 @@ public void CompareDocuments() { Assert.AreEqual(1, ex.invoked); } + [Test] + public void NodeFilterAppliesToDocTypes() { + DOMDifferenceEngine d = new DOMDifferenceEngine(); + DiffExpecter ex = + new DiffExpecter(ComparisonType.HAS_DOCTYPE_DECLARATION); + d.DifferenceListener += ex.ComparisonPerformed; + d.ComparisonController = ComparisonControllers.StopWhenDifferent; + + XmlDocument d1, d2; + + d1 = Org.XmlUnit.Util.Convert + .ToDocument(InputBuilder.FromString("").Build()); + d2 = new XmlDocument(); + d2.LoadXml("" + + ""); + Assert.AreEqual(Wrap(ComparisonResult.EQUAL), + d.CompareNodes(d1, new XPathContext(), + d2, new XPathContext())); + Assert.AreEqual(0, ex.invoked); + } + [Test] public void CompareDocTypes() { DOMDifferenceEngine d = new DOMDifferenceEngine();