PlaceholderDifferenceEvaluatorTest.java
/*
This file is licensed to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.xmlunit.placeholder;
import org.junit.Test;
import org.xmlunit.XMLUnitException;
import org.xmlunit.builder.DiffBuilder;
import org.xmlunit.diff.*;
import javax.xml.namespace.QName;
import java.util.Iterator;
import java.util.regex.Pattern;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;
/**
* Not testing the {@link PlaceholderDifferenceEvaluator} class directly, but testing it via the {@link DiffBuilder} and {@link Diff}. <br><br>
*/
public class PlaceholderDifferenceEvaluatorTest {
@Test
public void regression_NoPlaceholder_Equal() throws Exception {
String control = "<elem1><elem11>123</elem11></elem1>";
String test = "<elem1><elem11>123</elem11></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void regression_NoPlaceholder_Different() throws Exception {
String control = "<elem1><elem11>123</elem11></elem1>";
String test = "<elem1><elem11>abc</elem11></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
int count = 0;
Iterator it = diff.getDifferences().iterator();
while (it.hasNext()) {
count++;
Difference difference = (Difference) it.next();
assertEquals(ComparisonResult.DIFFERENT, difference.getResult());
}
assertEquals(1, count);
}
@Test
public void regression_NoPlaceholder_Different_EmptyExpectedElement() throws Exception {
String control = "<elem1><elem11/></elem1>";
String test = "<elem1><elem11>abc</elem11></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
int count = 0;
Iterator it = diff.getDifferences().iterator();
while (it.hasNext()) {
count++;
Difference difference = (Difference) it.next();
assertEquals(ComparisonResult.DIFFERENT, difference.getResult());
Comparison comparison = difference.getComparison();
if (count == 1) {
String xpath = "/elem1[1]/elem11[1]";
assertEquals(ComparisonType.CHILD_NODELIST_LENGTH, comparison.getType());
assertEquals(xpath, comparison.getControlDetails().getXPath());
assertEquals(0, comparison.getControlDetails().getValue());
assertEquals(xpath, comparison.getTestDetails().getXPath());
assertEquals(1, comparison.getTestDetails().getValue());
} else {
assertEquals(ComparisonType.CHILD_LOOKUP, comparison.getType());
assertEquals(null, comparison.getControlDetails().getXPath());
assertEquals(null, comparison.getControlDetails().getValue());
assertEquals("/elem1[1]/elem11[1]/text()[1]", comparison.getTestDetails().getXPath());
assertEquals(QName.valueOf("#text"), comparison.getTestDetails().getValue());
}
}
assertEquals(2, count);
}
@Test
public void hasIgnorePlaceholder_Equal_NoWhitespaceInPlaceholder() throws Exception {
String control = "<elem1><elem11>${xmlunit.ignore}</elem11></elem1>";
String test = "<elem1><elem11>abc</elem11></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_Equal_NoWhitespaceInPlaceholder_CDATA_Control() throws Exception {
String control = "<elem1><elem11><![CDATA[${xmlunit.ignore}]]></elem11></elem1>";
String test = "<elem1><elem11>abc</elem11></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(DifferenceEvaluators.chain(
DifferenceEvaluators.Default, new PlaceholderDifferenceEvaluator()))
.build();
assertFalse(diff.toString(), diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_Equal_NoWhitespaceInPlaceholder_CDATA_TEST() throws Exception {
String control = "<elem1><elem11>${xmlunit.ignore}</elem11></elem1>";
String test = "<elem1><elem11><![CDATA[abc]]></elem11></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(DifferenceEvaluators.chain(
DifferenceEvaluators.Default, new PlaceholderDifferenceEvaluator()))
.build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_CustomDelimiters_Equal_NoWhitespaceInPlaceholder() throws Exception {
String control = "<elem1><elem11>#{xmlunit.ignore}</elem11></elem1>";
String test = "<elem1><elem11>abc</elem11></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator("#\\{", null)).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_Equal_StartAndEndWhitespacesInPlaceholder() throws Exception {
String control = "<elem1><elem11>${ xmlunit.ignore }</elem11></elem1>";
String test = "<elem1><elem11>abc</elem11></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_Equal_EmptyActualElement() throws Exception {
String control = "<elem1><elem11>${xmlunit.ignore}</elem11></elem1>";
String test = "<elem1><elem11/></elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_Exception_ExclusivelyOccupy() throws Exception {
String control = "<elem1><elem11> ${xmlunit.ignore}abc</elem11></elem1>";
String test = "<elem1><elem11>abc</elem11></elem1>";
DiffBuilder diffBuilder = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator());
try {
diffBuilder.build();
fail();
} catch (XMLUnitException e) {
assertEquals("The placeholder must exclusively occupy the text node.", e.getCause().getMessage());
}
}
@Test
public void regression_NoPlaceholder_Attributes_Equal() throws Exception {
String control = "<elem1 attr='123'/>";
String test = "<elem1 attr='123'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void regression_NoPlaceholder_Attributes_Different() throws Exception {
String control = "<elem1 attr='123'/>";
String test = "<elem1 attr='abc'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
int count = 0;
Iterator it = diff.getDifferences().iterator();
while (it.hasNext()) {
count++;
Difference difference = (Difference) it.next();
assertEquals(ComparisonResult.DIFFERENT, difference.getResult());
}
assertEquals(1, count);
}
@Test
public void regression_NoPlaceholder_Missing_Attribute() throws Exception {
String control = "<elem1/>";
String test = "<elem1 attr='abc'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
int count = 0;
Iterator it = diff.getDifferences().iterator();
while (it.hasNext()) {
count++;
Difference difference = (Difference) it.next();
assertEquals(ComparisonResult.DIFFERENT, difference.getResult());
Comparison comparison = difference.getComparison();
if (count == 1) {
String xpath = "/elem1[1]";
assertEquals(ComparisonType.ELEMENT_NUM_ATTRIBUTES, comparison.getType());
assertEquals(xpath, comparison.getControlDetails().getXPath());
assertEquals(0, comparison.getControlDetails().getValue());
assertEquals(xpath, comparison.getTestDetails().getXPath());
assertEquals(1, comparison.getTestDetails().getValue());
} else {
assertEquals(ComparisonType.ATTR_NAME_LOOKUP, comparison.getType());
assertEquals("/elem1[1]", comparison.getControlDetails().getXPath());
assertEquals(null, comparison.getControlDetails().getValue());
assertEquals("/elem1[1]/@attr", comparison.getTestDetails().getXPath());
}
}
assertEquals(2, count);
}
@Test
public void hasIgnorePlaceholder_Attribute_Equal_NoWhitespaceInPlaceholder() throws Exception {
String control = "<elem1 attr='${xmlunit.ignore}'/>";
String test = "<elem1 attr='abc'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_CustomDelimiters_Attribute_Equal_NoWhitespaceInPlaceholder() throws Exception {
String control = "<elem1 attr='#{xmlunit.ignore}'/>";
String test = "<elem1 attr='abc'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator("#\\{", null)).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_Attribute_Equal_StartAndEndWhitespacesInPlaceholder() throws Exception {
String control = "<elem1 attr='${ xmlunit.ignore }'/>";
String test = "<elem1 attr='abc'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_Attribute_Equal_MissingActualAttribute() throws Exception {
String control = "<elem1 attr='${xmlunit.ignore}'/>";
String test = "<elem1/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void missingAttributeWithMoreThanOneAttribute() throws Exception {
String control = "<elem1 attr='${xmlunit.ignore}' a='b'/>";
String test = "<elem1 a='b'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void missingAttributeWithMoreThanOneIgnore() throws Exception {
String control = "<elem1 attr='${xmlunit.ignore}' a='${xmlunit.ignore}'/>";
String test = "<elem1/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void missingAttributeWithMissingControlAttribute() throws Exception {
String control = "<elem1 attr='${xmlunit.ignore}' a='${xmlunit.ignore}'/>";
String test = "<elem1 b='a'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
}
@Test
public void hasIgnorePlaceholder_Attribute_Exception_ExclusivelyOccupy() throws Exception {
String control = "<elem1 attr='${xmlunit.ignore}abc'/>";
String test = "<elem1 attr='abc'/>";
DiffBuilder diffBuilder = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator());
try {
diffBuilder.build();
fail();
} catch (XMLUnitException e) {
assertEquals("The placeholder must exclusively occupy the text node.", e.getCause().getMessage());
}
}
@Test
public void hasIsNumberPlaceholder_Attribute_NotNumber() {
String control = "<elem1 attr='${xmlunit.isNumber}'/>";
String test = "<elem1 attr='abc'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
}
@Test
public void hasIsNumberPlaceholder_Attribute_IsNumber() {
String control = "<elem1 attr='${xmlunit.isNumber}'/>";
String test = "<elem1 attr='123'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasIsNumberPlaceholder_Element_NotNumber() {
String control = "<elem1>${xmlunit.isNumber}</elem1>";
String test = "<elem1>abc</elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
}
@Test
public void hasIsNumberPlaceholder_Element_IsNumber() {
String control = "<elem1>${xmlunit.isNumber}</elem1>";
String test = "<elem1>123</elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasMatchesRegexPlaceholder_Attribute_Matches() {
String control = "<elem1 attr='${xmlunit.matchesRegex(^\\d+$)}'>qwert</elem1>";
String test = "<elem1 attr='023'>qwert</elem1>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasMatchesRegexPlaceholder_Attribute_NotMatches() {
String control = "<elem1 attr='${xmlunit.matchesRegex(^\\d+$)}'>qwert</elem1>";
String test = "<elem1 attr='023asd'>qwert</elem1>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertTrue(diff.hasDifferences());
}
@Test
public void hasMatchesRegexPlaceholder_Element_Matches() {
String control = "<elem1>${xmlunit.matchesRegex(^\\d+$)}</elem1>";
String test = "<elem1>023</elem1>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertFalse(diff.hasDifferences());
}
@Test
public void hasMatchesRegexPlaceholder_Element_NotMatches() {
String control = "<elem1>${xmlunit.matchesRegex(^\\d+$)}</elem1>";
String test = "<elem1>23abc</elem1>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertTrue(diff.hasDifferences());
}
@Test
public void hasMatchesRegexPlaceholder_Element_Exception_MalformedRegex() {
String control = "<elem1>${xmlunit.matchesRegex[^(\\d+$]}</elem1>";
String test = "<elem1>23abc</elem1>";
DiffBuilder diffBuilder = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator(null, null, Pattern.quote("["), Pattern.quote("]"), null));
try {
diffBuilder.build();
fail();
} catch (XMLUnitException e) {
assertThat(e.getCause().getMessage(), containsString("Unclosed group near index"));
}
}
@Test
public void hasMalformedPlaceholder_Attribute() {
String control = "<elem1 attr='${xmlunit.,}'>qwert</elem1>";
String test = "<elem1 attr='023'>qwert</elem1>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertTrue(diff.hasDifferences());
}
@Test
public void isDateTimePlaceholder_Attribute_NotDateTime() {
String control = "<elem1 attr='${xmlunit.isDateTime}'/>";
String test = "<elem1 attr='abc'/>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertTrue(diff.hasDifferences());
}
@Test
public void isDateTimePlaceholder_Attribute_IsDateTime() {
String control = "<elem1 attr='${xmlunit.isDateTime}'/>";
String test = "<elem1 attr='2020-01-01 15:00:00Z'/>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertFalse(diff.hasDifferences());
}
@Test
public void isDateTimePlaceholder_Attribute_IsDateTime_CustomFormat() {
String control = "<elem1 attr='${xmlunit.isDateTime(dd.MM.yyyy)}'/>";
String test = "<elem1 attr='05.09.2020'/>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void isDateTimePlaceholder_Element_NotDateTime() {
String control = "<elem1>${xmlunit.isDateTime}</elem1>";
String test = "<elem1>abc</elem1>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertTrue(diff.hasDifferences());
}
@Test
public void isDateTimePlaceholder_Element_IsDateTime() {
String control = "<elem1>${xmlunit.isDateTime}</elem1>";
String test = "<elem1>2020-01-01 15:00:00Z</elem1>";
Diff diff = PlaceholderSupport.withPlaceholderSupport(DiffBuilder.compare(control).withTest(test)).build();
assertFalse(diff.hasDifferences());
}
@Test
public void isDateTimePlaceholder_Element_IsDateTime_CustomFormat() {
String control = "<elem1>${xmlunit.isDateTime(dd.MM.yyyy)}</elem1>";
String test = "<elem1>05.09.2020</elem1>";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void canCompareDocmentsWithXsiTypes() {
String control = "<element"
+ " xmlns:myns=\"https://example.org/some-ns\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xsi:type=\"myns:some-type\" />";
String test = "<element"
+ " xmlns:myns=\"https://example.org/some-ns\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xsi:type=\"myns:some-other-type\" />";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
int count = 0;
Iterator it = diff.getDifferences().iterator();
while (it.hasNext()) {
count++;
Difference difference = (Difference) it.next();
assertEquals(ComparisonResult.DIFFERENT, difference.getResult());
assertEquals(ComparisonType.ATTR_VALUE,
difference.getComparison().getType());
}
assertEquals(1, count);
}
@Test
public void canIgnoreXsiTypeDifference() {
String control = "<element"
+ " xmlns:myns=\"https://example.org/some-ns\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xsi:type=\"myns:${xmlunit.ignore}\" />";
String test = "<element"
+ " xmlns:myns=\"https://example.org/some-ns\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xsi:type=\"myns:some-other-type\" />";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
@Test
public void cantIgnoreXsiNamespaceDifference() {
String control = "<element"
+ " xmlns:myns=\"https://example.org/some-other-ns\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xsi:type=\"myns:${xmlunit.ignore}\" />";
String test = "<element"
+ " xmlns:myns=\"https://example.org/some-ns\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xsi:type=\"myns:some-other-type\" />";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertTrue(diff.hasDifferences());
}
@Test
public void canCompareXsiTypeWithhRegex() {
String control = "<element"
+ " xmlns:myns=\"https://example.org/some-ns\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xsi:type=\"myns:${xmlunit.matchesRegex(.*-type)}\" />";
String test = "<element"
+ " xmlns:myns=\"https://example.org/some-ns\""
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ " xsi:type=\"myns:some-other-type\" />";
Diff diff = DiffBuilder.compare(control).withTest(test)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()).build();
assertFalse(diff.hasDifferences());
}
}