Skip to content

Commit

Permalink
apply NodFilter when comparing XmlDocumentType
Browse files Browse the repository at this point in the history
closes #26
  • Loading branch information
bodewig committed Apr 21, 2018
1 parent c13bf32 commit 638c16d
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 7 deletions.
16 changes: 16 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion src/main/net-core/Diff/ComparisonType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ public enum ComparisonType {
/// <summary>
/// Do both documents have a DOCTYPE (or neither of each)?
/// </summary>
/// <remarks>
/// <para>
/// 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.
/// </para>
/// </remarks>
HAS_DOCTYPE_DECLARATION,
/// <summary>
/// If the documents both have DOCTYPEs, compare the names.
Expand Down Expand Up @@ -127,4 +135,4 @@ public enum ComparisonType {
/// </summary>
ATTR_NAME_LOOKUP,
}
}
}
8 changes: 6 additions & 2 deletions src/main/net-core/Diff/DOMDifferenceEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -217,6 +217,10 @@ private ComparisonState CompareDocuments(XmlDocument control,
testContext));
}

private T FilterNode<T>(T n) where T : XmlNode {
return n != null && NodeFilter(n) ? n : null;
}

/// <summary>
/// Compares properties of the doctype declaration.
/// </summary>
Expand Down
13 changes: 9 additions & 4 deletions src/main/net-core/Diff/DifferenceEvaluators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,14 @@ public static DifferenceEvaluator IgnorePrologDifferences() {
/// declaration that are part of the XML prolog.
/// </summary>
/// <remarks>
/// <p>Here "ignore" means return {@code ComparisonResult.EQUAL}.</p>
/// </remarks>
/// <remarks>
/// <para>
/// Here "ignore" means return ComparisonResult.EQUAL.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// since XMLUnit 2.1.0
/// </para>
Expand Down Expand Up @@ -211,4 +216,4 @@ private static bool IsSequenceOfRootElement(Comparison comparison) {
}

}
}
}
18 changes: 18 additions & 0 deletions src/main/net-core/Diff/NodeFilters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,27 @@ public static class NodeFilters {
/// <summary>
/// Suppresses document-type and XML declaration nodes.
/// </summary>
/// <remarks>
/// <para>
/// This is the default used by AbstractDifferenceEngine and
/// thus DOMDifferenceEngine.
/// </para>
/// </remarks>
public static bool Default(XmlNode n) {
return n.NodeType != XmlNodeType.DocumentType
&& n.NodeType != XmlNodeType.XmlDeclaration;
}

/// <summary>
/// Suppresses document-type and XML declaration nodes.
/// </summary>
/// <remarks>
/// <para>
/// since XMLUnit 2.6.0
/// </para>
/// </remarks>
public static bool AcceptAll(XmlNode n) {
return true;
}
}
}
31 changes: 31 additions & 0 deletions src/tests/net-core/Diff/DOMDifferenceEngineTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -370,6 +376,7 @@ public void CompareDocuments() {
return ComparisonResult.EQUAL;
};
d.ComparisonController = ComparisonControllers.StopWhenDifferent;
d.NodeFilter = NodeFilters.AcceptAll;

XmlDocument d1, d2;

Expand Down Expand Up @@ -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("<Book/>").Build());
d2 = new XmlDocument();
d2.LoadXml("<!DOCTYPE Book PUBLIC "
+ "\"XMLUNIT/TEST/PUB\" "
+ "\"" + TestResources.BOOK_DTD
+ "\">"
+ "<Book/>");
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();
Expand Down

0 comments on commit 638c16d

Please sign in to comment.