Skip to content

Commit 0e3c290

Browse files
authored
Merge pull request #49 from xmlunit/xsi-type-and-placeholders
improve placehiolder usage with xsi:type attributes
2 parents 94ae24c + c53973b commit 0e3c290

File tree

4 files changed

+120
-1
lines changed

4 files changed

+120
-1
lines changed

RELEASE_NOTES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## XMLUnit.NET 2.11.1 - /Not Released, yet/
44

5+
* placeholders can now also be used inside of the local part of `xsi:type` attributes.
6+
PR [#49](https://github.com/xmlunit/xmlunit.net/pull/49)
7+
8+
* PlaceholderDifferenceEvaluator would cause InvalidCastException for documents with
9+
differences in `xsi:type` attributes.
10+
Equivalent of XMLUnit Java Issue [#xmlunit/276](https://github.com/xmlunit/xmlunit/issues/276)
11+
512
* added readme files for the nuget packages.
613
Issue [#46](https://github.com/xmlunit/xmlunit.net/issues/46).
714

src/doc/monodoc/placeholders/ns-Org.XmlUnit.Placeholder.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@
7373
<c>org.xmlunit.diff.DifferenceEvaluator</c> and add it to the
7474
builder yourself.</para>
7575

76+
<para>Placeholder sequences must appear as values inside of
77+
attribute values or nested textual content of elements - inside
78+
the control document. As a special case they may also appear as
79+
local part of a type name of xsi:type attributes of control
80+
documents - i.e. <c>xsi:type="prefix:${xmlunit:ignore}"</c>. The
81+
namepace URIs of the compared types must match with the test
82+
document. Support for xsi:types has been added with XMLUnit.NET
83+
2.11.1.</para>
84+
7685
</remarks>
7786

7887

src/main/net-placeholders/PlaceholderDifferenceEvaluator.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,22 @@ public ComparisonResult Evaluate(Comparison comparison, ComparisonResult outcome
238238
return EvaluateConsideringPlaceholders(controlTarget.Value, testTarget.Value, outcome);
239239

240240
// comparing textual content of attributes
241-
} else if (comparison.Type == ComparisonType.ATTR_VALUE) {
241+
}
242+
else if (comparison.Type == ComparisonType.ATTR_VALUE && controlDetails.Value is string &&
243+
testDetails.Value is string)
244+
{
242245
return EvaluateConsideringPlaceholders((string) controlDetails.Value,
243246
(string) testDetails.Value, outcome);
244247

248+
}
249+
250+
// comparing QName content of attributes
251+
else if (comparison.Type == ComparisonType.ATTR_VALUE && controlDetails.Value is XmlQualifiedName &&
252+
testDetails.Value is XmlQualifiedName)
253+
{
254+
return EvaluateConsideringPlaceholders((XmlQualifiedName) controlDetails.Value,
255+
(XmlQualifiedName) testDetails.Value, outcome);
256+
245257
// "test document has no attribute but control document has"
246258
} else if (IsMissingAttributeDifference(comparison)) {
247259
return EvaluateMissingAttributeConsideringPlaceholders(comparison, outcome);
@@ -335,6 +347,19 @@ private ComparisonResult EvaluateAttributeListLengthConsideringPlaceholders(Comp
335347
return ComparisonResult.EQUAL;
336348
}
337349

350+
private ComparisonResult EvaluateConsideringPlaceholders(XmlQualifiedName controlQName,
351+
XmlQualifiedName testQName,
352+
ComparisonResult outcome)
353+
{
354+
if (controlQName.Namespace == testQName.Namespace)
355+
{
356+
return EvaluateConsideringPlaceholders(controlQName.Name, testQName.Name,
357+
outcome);
358+
}
359+
360+
return outcome;
361+
}
362+
338363
private ComparisonResult EvaluateConsideringPlaceholders(string controlText, string testText,
339364
ComparisonResult outcome) {
340365
Match placeholderMatch = placeholderRegex.Match(controlText);

src/tests/net-placeholders/PlaceholderDifferenceEvaluatorTest.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,5 +446,83 @@ public void IsDateTimePlaceholder_Element_IsDateTime_CustomFormat() {
446446

447447
Assert.IsFalse(diff.HasDifferences());
448448
}
449+
450+
[Test]
451+
public void CanCompareDocmentsWithXsiTypes() {
452+
string control = "<element"
453+
+ " xmlns:myns=\"https://example.org/some-ns\""
454+
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
455+
+ " xsi:type=\"myns:some-type\" />";
456+
string test = "<element"
457+
+ " xmlns:myns=\"https://example.org/some-ns\""
458+
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
459+
+ " xsi:type=\"myns:some-other-type\" />";
460+
461+
var diff = DiffBuilder.Compare(control).WithTest(test)
462+
.WithDifferenceEvaluator(new PlaceholderDifferenceEvaluator().Evaluate).Build();
463+
464+
Assert.IsTrue(diff.HasDifferences());
465+
int count = 0;
466+
foreach (Difference difference in diff.Differences) {
467+
count++;
468+
Assert.AreEqual(ComparisonResult.DIFFERENT, difference.Result);
469+
Assert.AreEqual(ComparisonType.ATTR_VALUE, difference.Comparison.Type);
470+
}
471+
Assert.AreEqual(1, count);
472+
}
473+
474+
[Test]
475+
public void CanIgnoreXsiTypeDifference()
476+
{
477+
string control = "<element"
478+
+ " xmlns:myns=\"https://example.org/some-ns\""
479+
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
480+
+ " xsi:type=\"myns:${xmlunit.ignore}\" />";
481+
string test = "<element"
482+
+ " xmlns:myns=\"https://example.org/some-ns\""
483+
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
484+
+ " xsi:type=\"myns:some-other-type\" />";
485+
486+
var diff = DiffBuilder.Compare(control).WithTest(test)
487+
.WithDifferenceEvaluator(new PlaceholderDifferenceEvaluator().Evaluate).Build();
488+
489+
Assert.IsFalse(diff.HasDifferences());
490+
}
491+
492+
[Test]
493+
public void CantIgnoreXsiNamespaceDifference()
494+
{
495+
string control = "<element"
496+
+ " xmlns:myns=\"https://example.org/some-other-ns\""
497+
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
498+
+ " xsi:type=\"myns:${xmlunit.ignore}\" />";
499+
string test = "<element"
500+
+ " xmlns:myns=\"https://example.org/some-ns\""
501+
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
502+
+ " xsi:type=\"myns:some-other-type\" />";
503+
504+
var diff = DiffBuilder.Compare(control).WithTest(test)
505+
.WithDifferenceEvaluator(new PlaceholderDifferenceEvaluator().Evaluate).Build();
506+
507+
Assert.IsTrue(diff.HasDifferences());
508+
}
509+
510+
[Test]
511+
public void CanCompareXsiTypeWithhRegex()
512+
{
513+
string control = "<element"
514+
+ " xmlns:myns=\"https://example.org/some-ns\""
515+
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
516+
+ " xsi:type=\"myns:${xmlunit.matchesRegex(.*-type)}\" />";
517+
string test = "<element"
518+
+ " xmlns:myns=\"https://example.org/some-ns\""
519+
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
520+
+ " xsi:type=\"myns:some-other-type\" />";
521+
522+
var diff = DiffBuilder.Compare(control).WithTest(test)
523+
.WithDifferenceEvaluator(new PlaceholderDifferenceEvaluator().Evaluate).Build();
524+
525+
Assert.IsFalse(diff.HasDifferences());
526+
}
449527
}
450528
}

0 commit comments

Comments
 (0)