Skip to content

Commit f5fe30b

Browse files
committed
new builder methods that are aware of XML's idea of whitespace
see #39
1 parent 893c09b commit f5fe30b

File tree

2 files changed

+201
-1
lines changed

2 files changed

+201
-1
lines changed

src/main/net-core/Builder/DiffBuilder.cs

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ public class DiffBuilder : IDifferenceEngineConfigurer<DiffBuilder> {
7979

8080
private bool ignoreECW;
8181

82+
private bool ignoreXmlWhitespace;
83+
84+
private bool normalizeXmlWhitespace;
85+
86+
private bool ignoreXmlECW;
87+
8288
private bool ignoreComments;
8389

8490
private string ignoreCommentVersion = null;
@@ -121,19 +127,53 @@ private static ISource GetSource(object source) {
121127
/// If you only want to remove text nodes consisting solely of
122128
/// whitespace (AKA element content whitespace) but leave all
123129
/// other text nodes alone you should use
124-
/// ignoreElementContentWhitespace instead.
130+
/// <see cref="IgnoreElementContentWhitespace"/> instead.
125131
/// </para>
132+
/// <para>
133+
/// Unlike <see cref="IgnoreXmlWhitespace"/> this uses Unicode's idea
134+
/// of whitespace rather than the more restricted subset considered
135+
/// whitespace by XML.
136+
/// </para>
126137
/// </remarks>
127138
public DiffBuilder IgnoreWhitespace() {
128139
ignoreWhitespace = true;
129140
return this;
130141
}
131142

143+
/// <summary>
144+
/// Ignore XML whitespace by removing all empty text nodes and trimming the non-empty ones.
145+
/// </summary>
146+
/// <remarks>
147+
/// <para>
148+
/// If you only want to remove text nodes consisting solely of
149+
/// whitespace (AKA element content whitespace) but leave all
150+
/// other text nodes alone you should use
151+
/// <see cref="IgnoreXmlElementContentWhitespace"/> instead.
152+
/// </para>
153+
/// <para>
154+
/// Unlike <see cref="IgnoreWhitespace"/> this uses XML's idea
155+
/// of whitespace rather than the more extensive set considered
156+
/// whitespace by Unicode.
157+
/// </para>
158+
/// <para>
159+
/// since XMLUnit 2.10.0
160+
/// </para>
161+
/// </remarks>
162+
public DiffBuilder IgnoreXmlWhitespace() {
163+
ignoreXmlWhitespace = true;
164+
return this;
165+
}
166+
132167
/// <summary>
133168
/// Ignore element content whitespace by removing all text
134169
/// nodes solely consisting of whitespace.
135170
/// </summary>
136171
/// <remarks>
172+
/// <para>
173+
/// Unlike <see cref="IgnoreXmlElementContentWhitespace"/> this uses Unicode's idea
174+
/// of whitespace rather than the more restricted subset considered
175+
/// whitespace by XML.
176+
/// </para>
137177
/// <para>
138178
/// since XMLUnit 2.6.0
139179
/// </para>
@@ -143,6 +183,25 @@ public DiffBuilder IgnoreElementContentWhitespace() {
143183
return this;
144184
}
145185

186+
/// <summary>
187+
/// Ignore element content whitespace by removing all text
188+
/// nodes solely consisting of XML whitespace.
189+
/// </summary>
190+
/// <remarks>
191+
/// <para>
192+
/// Unlike <see cref="IgnoreElementContentWhitespace"/> this uses XML's idea
193+
/// of whitespace rather than the more extensive set considered
194+
/// whitespace by Unicode.
195+
/// </para>
196+
/// <para>
197+
/// since XMLUnit 2.10.0
198+
/// </para>
199+
/// </remarks>
200+
public DiffBuilder IgnoreXmlElementContentWhitespace() {
201+
ignoreXmlECW = true;
202+
return this;
203+
}
204+
146205
/// <summary>
147206
/// Normalize Text-Elements by removing all empty text nodes and normalizing the non-empty ones.
148207
/// </summary>
@@ -152,12 +211,48 @@ public DiffBuilder IgnoreElementContentWhitespace() {
152211
/// characters are replaced by space characters and
153212
/// consecutive whitespace characters are collapsed.
154213
/// </para>
214+
/// <para>
215+
/// This method is similiar to <see cref="IgnoreWhitespace"/>
216+
/// but in addition "normalizes" whitespace.
217+
/// </para>
218+
/// <para>
219+
/// Unlike <see cref="NormalizeXmlWhitespace"/> this uses Unicode's idea
220+
/// of whitespace rather than the more restricted subset considered
221+
/// whitespace by XML.
222+
/// </para>
155223
/// </remarks>
156224
public DiffBuilder NormalizeWhitespace() {
157225
normalizeWhitespace = true;
158226
return this;
159227
}
160228

229+
/// <summary>
230+
/// Normalize Text-Elements by removing all empty text nodes and normalizing the non-empty ones.
231+
/// </summary>
232+
/// <remarks>
233+
/// <para>
234+
/// "normalized" in this context means all XML whitespace
235+
/// characters are replaced by space characters and
236+
/// consecutive XML whitespace characters are collapsed.
237+
/// </para>
238+
/// <para>
239+
/// This method is similiar to <see cref="IgnoreXmlWhitespace"/>
240+
/// but in addition "normalizes" XML whitespace.
241+
/// </para>
242+
/// <para>
243+
/// Unlike <see cref="NormalizeWhitespace"/> this uses XML's idea
244+
/// of whitespace rather than the more extensive set considered
245+
/// whitespace by Unicode.
246+
/// </para>
247+
/// <para>
248+
/// since XMLUnit 2.10.0
249+
/// </para>
250+
/// </remarks>
251+
public DiffBuilder NormalizeXmlWhitespace() {
252+
normalizeXmlWhitespace = true;
253+
return this;
254+
}
255+
161256
/// <summary>
162257
/// Will remove all comment-Tags "&lt;!-- Comment --&gt;" from
163258
/// test- and control-XML before comparing.
@@ -405,9 +500,15 @@ private ISource Wrap(ISource source) {
405500
if (ignoreWhitespace) {
406501
newSource = new WhitespaceStrippedSource(newSource);
407502
}
503+
if (ignoreXmlWhitespace) {
504+
newSource = new XmlWhitespaceStrippedSource(newSource);
505+
}
408506
if (normalizeWhitespace) {
409507
newSource = new WhitespaceNormalizedSource(newSource);
410508
}
509+
if (normalizeXmlWhitespace) {
510+
newSource = new XmlWhitespaceNormalizedSource(newSource);
511+
}
411512
if (ignoreComments) {
412513
newSource = ignoreCommentVersion == null
413514
? new CommentLessSource(newSource)
@@ -416,6 +517,9 @@ private ISource Wrap(ISource source) {
416517
if (ignoreECW) {
417518
newSource = new ElementContentWhitespaceStrippedSource(newSource);
418519
}
520+
if (ignoreXmlECW) {
521+
newSource = new XmlElementContentWhitespaceStrippedSource(newSource);
522+
}
419523
return newSource;
420524
}
421525

src/tests/net-core/Builder/DiffBuilderTest.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,38 @@ public void TestDiff_withIgnoreWhitespaces_shouldSucceed() {
5656
Assert.IsFalse(myDiff.HasDifferences(), "XML similar " + myDiff.ToString());
5757
}
5858

59+
[Test]
60+
public void IgnoreWhitespaceAndIgnoreXmlWhitespaceWorkAsExpected() {
61+
// prepare testData
62+
string controlXml = "<a><b>Test Value</b></a>";
63+
string testXml1 = "<a>\n <b>\n Test Value\n </b>\n</a>";
64+
string testXml2 = "<a>\n\u00a0<b>\n Test Value\n </b>\n</a>";
65+
66+
// run test
67+
var plainDiff1 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
68+
.WithTest(Input.FromString(testXml1).Build())
69+
.IgnoreWhitespace()
70+
.Build();
71+
var xmlDiff1 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
72+
.WithTest(Input.FromString(testXml1).Build())
73+
.IgnoreXmlWhitespace()
74+
.Build();
75+
var plainDiff2 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
76+
.WithTest(Input.FromString(testXml2).Build())
77+
.IgnoreWhitespace()
78+
.Build();
79+
var xmlDiff2 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
80+
.WithTest(Input.FromString(testXml2).Build())
81+
.IgnoreXmlWhitespace()
82+
.Build();
83+
84+
// validate result
85+
Assert.IsFalse(plainDiff1.HasDifferences(), "XML similar " + plainDiff1.ToString());
86+
Assert.IsFalse(xmlDiff1.HasDifferences(), "XML similar " + xmlDiff1.ToString());
87+
Assert.IsFalse(plainDiff2.HasDifferences(), "XML similar " + plainDiff2.ToString());
88+
Assert.IsTrue(xmlDiff2.HasDifferences(), "XML similar " + xmlDiff2.ToString());
89+
}
90+
5991
[Test]
6092
public void TestDiff_withoutNormalizeWhitespaces_shouldFail() {
6193
// prepare testData
@@ -87,6 +119,38 @@ public void TestDiff_withNormalizeWhitespaces_shouldSucceed() {
87119
Assert.IsFalse(myDiff.HasDifferences(), "XML similar " + myDiff.ToString());
88120
}
89121

122+
[Test]
123+
public void NormalizeWhitespaceAndNormalizeXmlWhitespaceWorkAsExpected() {
124+
// prepare testData
125+
string controlXml = "<a><b>Test Value</b></a>";
126+
string testXml1 = "<a>\n <b>\n Test\nValue\n </b>\n</a>";
127+
string testXml2 = "<a>\n <b>\n Test\u00a0Value\n </b>\n</a>";
128+
129+
// run test
130+
var plainDiff1 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
131+
.WithTest(Input.FromString(testXml1).Build())
132+
.NormalizeWhitespace()
133+
.Build();
134+
var xmlDiff1 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
135+
.WithTest(Input.FromString(testXml1).Build())
136+
.NormalizeXmlWhitespace()
137+
.Build();
138+
var plainDiff2 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
139+
.WithTest(Input.FromString(testXml2).Build())
140+
.NormalizeWhitespace()
141+
.Build();
142+
var xmlDiff2 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
143+
.WithTest(Input.FromString(testXml2).Build())
144+
.NormalizeXmlWhitespace()
145+
.Build();
146+
147+
// validate result
148+
Assert.IsFalse(plainDiff1.HasDifferences(), "XML similar " + plainDiff1.ToString());
149+
Assert.IsFalse(xmlDiff1.HasDifferences(), "XML similar " + xmlDiff1.ToString());
150+
Assert.IsFalse(plainDiff2.HasDifferences(), "XML similar " + plainDiff2.ToString());
151+
Assert.IsTrue(xmlDiff2.HasDifferences(), "XML similar " + xmlDiff2.ToString());
152+
}
153+
90154
[Test]
91155
public void TestDiff_withNormalizeAndIgnoreWhitespaces_shouldSucceed() {
92156
// prepare testData
@@ -486,6 +550,38 @@ public void TestDiff_withIgnoreElementContentWhitespaces_shouldSucceed() {
486550
Assert.IsFalse(myDiff.HasDifferences(), "XML similar " + myDiff.ToString());
487551
}
488552

553+
[Test]
554+
public void IgnoreElementContentWhitespacesAndIgnoreXmlElementContentWhitespacesWorkAsExpected() {
555+
// prepare testData
556+
string controlXml = "<a><b>Test Value</b></a>";
557+
string testXml1 = "<a>\n <b>Test Value</b>\n</a>";
558+
string testXml2 = "<a>\n <b>Test Value</b>\u00a0</a>";
559+
560+
// run test
561+
var plainDiff1 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
562+
.WithTest(Input.FromString(testXml1).Build())
563+
.IgnoreElementContentWhitespace()
564+
.Build();
565+
var plainDiff2 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
566+
.WithTest(Input.FromString(testXml2).Build())
567+
.IgnoreElementContentWhitespace()
568+
.Build();
569+
var xmlDiff1 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
570+
.WithTest(Input.FromString(testXml1).Build())
571+
.IgnoreXmlElementContentWhitespace()
572+
.Build();
573+
var xmlDiff2 = DiffBuilder.Compare(Input.FromString(controlXml).Build())
574+
.WithTest(Input.FromString(testXml2).Build())
575+
.IgnoreXmlElementContentWhitespace()
576+
.Build();
577+
578+
// validate result
579+
Assert.IsFalse(plainDiff1.HasDifferences(), "XML similar " + plainDiff1.ToString());
580+
Assert.IsFalse(plainDiff2.HasDifferences(), "XML similar " + plainDiff2.ToString());
581+
Assert.IsFalse(xmlDiff1.HasDifferences(), "XML similar " + xmlDiff1.ToString());
582+
Assert.IsTrue(xmlDiff2.HasDifferences(), "XML similar " + xmlDiff2.ToString());
583+
}
584+
489585
internal class DummyComparisonFormatter : IComparisonFormatter {
490586
public string GetDescription(Comparison difference) {
491587
return "foo";

0 commit comments

Comments
 (0)