Skip to content

Commit

Permalink
XPath for CHILD_LOOKUP differences was affected by NodeFilter
Browse files Browse the repository at this point in the history
closes #29
  • Loading branch information
bodewig committed Mar 1, 2020
1 parent ca50b31 commit c790386
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
6 changes: 5 additions & 1 deletion RELEASE_NOTES.md
@@ -1,6 +1,10 @@
# Release Notes

## XMLUnit.NET 2.7.1 - /not released, yet/
## XMLUnit.NET 2.7.2 - /not released, yet/

* the XPath values for comparisons resulting in `CHILD_LOOKUP`
differences could be wrong when `NodeFilter`s were present.
Issue [#29](https://github.com/xmlunit/xmlunit.net/issues/29)

## XMLUnit.NET 2.7.1 - /Released 2019-06-21/

Expand Down
17 changes: 11 additions & 6 deletions src/main/net-core/Diff/DOMDifferenceEngine.cs
Expand Up @@ -500,11 +500,14 @@ public sealed class DOMDifferenceEngine : AbstractDifferenceEngine {
}

return chain
.AndThen(UnmatchedControlNodes(controlList, controlContext, seen, testContext))
.AndThen(UnmatchedTestNodes(testList, testContext, seen, controlContext));
.AndThen(UnmatchedControlNodes(controlListForXpath, controlList, controlContext,
seen, testContext))
.AndThen(UnmatchedTestNodes(testListForXpath, testList, testContext, seen,
controlContext));
}

private Func<ComparisonState> UnmatchedControlNodes(IList<XmlNode> controlList,
private Func<ComparisonState> UnmatchedControlNodes(IList<XmlNode> controlListForXpath,
IList<XmlNode> controlList,
XPathContext controlContext,
ICollection<XmlNode> seen,
XPathContext testContext) {
Expand All @@ -513,7 +516,8 @@ public sealed class DOMDifferenceEngine : AbstractDifferenceEngine {
int controlSize = controlList.Count;
for (int i = 0; i < controlSize; i++) {
if (!seen.Contains(controlList[i])) {
controlContext.NavigateToChild(i);
controlContext
.NavigateToChild(controlListForXpath.IndexOf(controlList[i]));
try {
chain = chain
.AndThen(new Comparison(ComparisonType.CHILD_LOOKUP,
Expand All @@ -532,7 +536,8 @@ public sealed class DOMDifferenceEngine : AbstractDifferenceEngine {
};
}

private Func<ComparisonState> UnmatchedTestNodes(IList<XmlNode> testList,
private Func<ComparisonState> UnmatchedTestNodes(IList<XmlNode> testListForXpath,
IList<XmlNode> testList,
XPathContext testContext,
ICollection<XmlNode> seen,
XPathContext controlContext) {
Expand All @@ -541,7 +546,7 @@ public sealed class DOMDifferenceEngine : AbstractDifferenceEngine {
int testSize = testList.Count;
for (int i = 0; i < testSize; i++) {
if (!seen.Contains(testList[i])) {
testContext.NavigateToChild(i);
testContext.NavigateToChild(testListForXpath.IndexOf(testList[i]));
try {
chain = chain
.AndThen(new Comparison(ComparisonType.CHILD_LOOKUP,
Expand Down
36 changes: 36 additions & 0 deletions src/tests/net-core/Diff/DOMDifferenceEngineTest.cs
Expand Up @@ -1135,6 +1135,42 @@ internal DiffExpecter(ComparisonType type, int expected)
Assert.AreEqual(ComparisonType.NAMESPACE_PREFIX, diff.Differences.First().Comparison.Type);
}

[Test]
public void XPathKnowsAboutNodeFiltersForUnmatchedControlNodes() {
var diff = DiffBuilder.Compare("<Document><Section><Binding /><Binding /><Finding /><Finding /><Finding /><Finding /><Finding /><Finding /><Finding /></Section></Document>")
.WithTest("<Document><Section><Binding /><Binding /><Finding /><Finding /><Finding /><Finding /><Finding /><Finding /></Section></Document>")
.IgnoreWhitespace()
.WithNodeFilter(node => "Document,Section,Finding".Split(',').Contains(node.Name))
.WithNodeMatcher(new DefaultNodeMatcher(ElementSelectors.ByNameAndText))
.Build();
Assert.AreEqual(2, diff.Differences.Count());
Assert.AreEqual(ComparisonType.CHILD_NODELIST_LENGTH, diff.Differences.First().Comparison.Type);
Assert.AreEqual("/Document[1]/Section[1]", diff.Differences.First().Comparison.ControlDetails.XPath);
Assert.AreEqual("/Document[1]/Section[1]", diff.Differences.First().Comparison.TestDetails.XPath);
Assert.AreEqual(ComparisonType.CHILD_LOOKUP, diff.Differences.Last().Comparison.Type);
Assert.AreEqual("/Document[1]/Section[1]/Finding[7]", diff.Differences.Last().Comparison.ControlDetails.XPath);
Assert.IsNull(diff.Differences.Last().Comparison.TestDetails.XPath);
Assert.AreEqual("/Document[1]/Section[1]", diff.Differences.Last().Comparison.TestDetails.ParentXPath);
}

[Test]
public void XPathKnowsAboutNodeFiltersForUnmatchedTestNodes() {
var diff = DiffBuilder.Compare("<Document><Section><Binding /><Binding /><Finding /><Finding /><Finding /><Finding /><Finding /><Finding /></Section></Document>")
.WithTest("<Document><Section><Binding /><Binding /><Finding /><Finding /><Finding /><Finding /><Finding /><Finding /><Finding /></Section></Document>")
.IgnoreWhitespace()
.WithNodeFilter(node => "Document,Section,Finding".Split(',').Contains(node.Name))
.WithNodeMatcher(new DefaultNodeMatcher(ElementSelectors.ByNameAndText))
.Build();
Assert.AreEqual(2, diff.Differences.Count());
Assert.AreEqual(ComparisonType.CHILD_NODELIST_LENGTH, diff.Differences.First().Comparison.Type);
Assert.AreEqual("/Document[1]/Section[1]", diff.Differences.First().Comparison.ControlDetails.XPath);
Assert.AreEqual("/Document[1]/Section[1]", diff.Differences.First().Comparison.TestDetails.XPath);
Assert.AreEqual(ComparisonType.CHILD_LOOKUP, diff.Differences.Last().Comparison.Type);
Assert.AreEqual("/Document[1]/Section[1]/Finding[7]", diff.Differences.Last().Comparison.TestDetails.XPath);
Assert.IsNull(diff.Differences.Last().Comparison.ControlDetails.XPath);
Assert.AreEqual("/Document[1]/Section[1]", diff.Differences.Last().Comparison.ControlDetails.ParentXPath);
}

private XmlDocument DocumentForString(string s) {
return Org.XmlUnit.Util.Convert.ToDocument(InputBuilder.FromString(s).Build());
}
Expand Down

0 comments on commit c790386

Please sign in to comment.