/*******************************************************************************
* Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.test.utility.diff;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.persistence.tools.workbench.test.utility.TestTools;
import org.eclipse.persistence.tools.workbench.test.utility.diff.model.Employee;
import org.eclipse.persistence.tools.workbench.utility.diff.CompositeDiff;
import org.eclipse.persistence.tools.workbench.utility.diff.Diff;
import org.eclipse.persistence.tools.workbench.utility.diff.Differentiator;
import org.eclipse.persistence.tools.workbench.utility.diff.EqualityDifferentiator;
import org.eclipse.persistence.tools.workbench.utility.diff.IdentityDifferentiator;
import org.eclipse.persistence.tools.workbench.utility.diff.NullDifferentiator;
import org.eclipse.persistence.tools.workbench.utility.diff.ReflectiveDifferentiator;
public abstract class AbstractReflectiveDiffTests extends TestCase {
protected Differentiator differentiator;
protected Employee employee1;
protected Employee employee2;
public AbstractReflectiveDiffTests(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
this.differentiator = this.buildDifferentiator();
this.employee1 = this.buildEmployee();
this.employee2 = this.buildEmployee();
}
protected abstract Differentiator buildDifferentiator();
protected Employee buildEmployee() {
Employee result = this.buildEmployee(1, "Fred Flintstone");
result.setSalary(20000.20f);
result.setPosition("long-neck operator");
result.addComment("animated sitcom character");
result.addComment("member of Moose Lodge");
result.addComment("not too bright");
return result;
}
protected abstract Employee buildEmployee(int id, String name);
protected abstract ReflectiveDifferentiator employeeDifferentiator();
protected void tearDown() throws Exception {
TestTools.clear(this);
super.tearDown();
}
public void testNoDifference() {
Diff diff = this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
diff = this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
}
public void testOneNull() {
Diff diff = this.differentiator.diff(null, this.employee2);
this.verifyDiffMismatch(diff, null, this.employee2);
diff = this.differentiator.keyDiff(null, this.employee2);
this.verifyDiffMismatch(diff, null, this.employee2);
diff = this.differentiator.diff(this.employee1, null);
this.verifyDiffMismatch(diff, this.employee1, null);
diff = this.differentiator.keyDiff(this.employee1, null);
this.verifyDiffMismatch(diff, this.employee1, null);
}
public void testClassMismatch() {
Object object2 = new Integer(42);
Diff diff = this.differentiator.diff(this.employee1, object2);
this.verifyDiffMismatch(diff, this.employee1, object2);
diff = this.differentiator.keyDiff(this.employee1, object2);
this.verifyDiffMismatch(diff, this.employee1, object2);
diff = this.differentiator.diff(object2, this.employee2);
this.verifyDiffMismatch(diff, object2, this.employee2);
diff = this.differentiator.keyDiff(object2, this.employee2);
this.verifyDiffMismatch(diff, object2, this.employee2);
}
public void testOneFieldMismatch() {
this.employee2.setName("Barney Rubble");
CompositeDiff diff = (CompositeDiff) this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
List leafMismatches = DiffTestTools.differentLeafDiffList(diff);
assertEquals(1, leafMismatches.size());
Diff leafDiff = (Diff) leafMismatches.get(0); // name
assertEquals("Fred Flintstone", leafDiff.getObject1());
assertEquals("Barney Rubble", leafDiff.getObject2());
diff = (CompositeDiff) this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
}
public void testTwoFieldMismatch() {
this.employee2.setId(77);
this.employee2.setName("Barney Rubble");
CompositeDiff diff = (CompositeDiff) this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
List leafMismatches = DiffTestTools.differentLeafDiffList(diff);
assertEquals(2, leafMismatches.size());
// alphabetical order...
Diff leafDiff;
leafDiff = (Diff) leafMismatches.get(0); // id
assertEquals(new Integer(1), leafDiff.getObject1());
assertEquals(new Integer(77), leafDiff.getObject2());
leafDiff = (Diff) leafMismatches.get(1); // name
assertEquals("Fred Flintstone", leafDiff.getObject1());
assertEquals("Barney Rubble", leafDiff.getObject2());
diff = (CompositeDiff) this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
}
public void testCollectionFieldMismatch() {
this.employee2.addComment("bogus comment");
CompositeDiff diff = (CompositeDiff) this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
List leafMismatches = DiffTestTools.differentLeafDiffList(diff);
assertEquals(1, leafMismatches.size());
Diff leafDiff = (Diff) leafMismatches.get(0); // comments
assertTrue(((Collection) leafDiff.getObject2()).contains("bogus comment"));
diff = (CompositeDiff) this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
for (Iterator stream = this.employee2.comments(); stream.hasNext(); ) {
String comment = (String) stream.next();
if (comment.equals("bogus comment")) {
stream.remove();
}
}
diff = (CompositeDiff) this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
diff = (CompositeDiff) this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
String removedComment = null;
for (Iterator stream = this.employee2.comments(); stream.hasNext(); ) {
String comment = (String) stream.next();
if (comment.startsWith("animated")) {
stream.remove();
removedComment = comment;
}
}
diff = (CompositeDiff) this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
leafMismatches = DiffTestTools.differentLeafDiffList(diff);
assertEquals(1, leafMismatches.size());
leafDiff = (Diff) leafMismatches.get(0); // comments
assertTrue(((Collection) leafDiff.getObject1()).contains(removedComment));
assertFalse(((Collection) leafDiff.getObject2()).contains(removedComment));
diff = (CompositeDiff) this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
}
public void testAllFieldMismatch() {
this.employee2.setId(77);
this.employee2.setName("Barney Rubble");
this.employee2.setSalary(200000.01f);
this.employee2.setPosition("troublemaker");
String addedComment = "Fred's sidekick";
this.employee2.addComment(addedComment);
CompositeDiff diff = (CompositeDiff) this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
List leafMismatches = DiffTestTools.differentLeafDiffList(diff);
assertEquals(5, leafMismatches.size());
// alphabetical order...
Diff leafDiff;
leafDiff = (Diff) leafMismatches.get(0); // comments
assertFalse(((Collection) leafDiff.getObject1()).contains(addedComment));
assertTrue(((Collection) leafDiff.getObject2()).contains(addedComment));
leafDiff = (Diff) leafMismatches.get(1); // id
assertEquals(new Integer(1), leafDiff.getObject1());
assertEquals(new Integer(77), leafDiff.getObject2());
leafDiff = (Diff) leafMismatches.get(2); // name
assertEquals("Fred Flintstone", leafDiff.getObject1());
assertEquals("Barney Rubble", leafDiff.getObject2());
leafDiff = (Diff) leafMismatches.get(3); // position
assertEquals("long-neck operator", leafDiff.getObject1());
assertEquals("troublemaker", leafDiff.getObject2());
leafDiff = (Diff) leafMismatches.get(4); // salary
assertEquals(new Float(20000.20f), leafDiff.getObject1());
assertEquals(new Float(200000.01f), leafDiff.getObject2());
diff = (CompositeDiff) this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
leafMismatches = DiffTestTools.differentLeafDiffList(diff);
assertEquals(1, leafMismatches.size());
leafDiff = (Diff) leafMismatches.get(0); // id
assertEquals(new Integer(1), leafDiff.getObject1());
assertEquals(new Integer(77), leafDiff.getObject2());
}
public void testNullFieldMismatch() {
this.employee2.setPosition(null);
CompositeDiff diff = (CompositeDiff) this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
List leafMismatches = DiffTestTools.differentLeafDiffList(diff);
assertEquals(1, leafMismatches.size());
Diff leafDiff = (Diff) leafMismatches.get(0); // position
assertEquals("long-neck operator", leafDiff.getObject1());
assertNull(leafDiff.getObject2());
diff = (CompositeDiff) this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
}
public void testIgnoreField() {
this.employee2.setPosition("troublemaker");
Diff diff = this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
ReflectiveDifferentiator rd = this.employeeDifferentiator();
rd.ignoreFieldNamed("position");
diff = this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
diff = this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
boolean exCaught = false;
try {
rd.ignoreFieldNamed("positionXXX");
} catch (IllegalArgumentException ex) {
if (ex.getMessage().indexOf("positionXXX") != -1) {
exCaught = true;
}
}
assertTrue(exCaught);
}
public void testFieldDifferentiator() {
this.employee2.setSalary(this.employee1.getSalary() + 0.02f);
Diff diff = this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
diff = this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
ReflectiveDifferentiator rd = this.employeeDifferentiator();
rd.setFieldDifferentiator("salary", this.buildCustomSalaryDifferentiator());
diff = this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
diff = this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
this.employee2.setSalary(this.employee1.getSalary() + 1.02f);
diff = this.differentiator.diff(this.employee1, this.employee2);
this.verifyDiffMismatch(diff, this.employee1, this.employee2);
diff = this.differentiator.keyDiff(this.employee1, this.employee2);
this.verifyDiffMatch(diff, this.employee1, this.employee2);
boolean exCaught = false;
try {
rd.setFieldDifferentiator("salaryXXX", IdentityDifferentiator.instance());
} catch (IllegalArgumentException ex) {
if (ex.getMessage().indexOf("salaryXXX") != -1) {
exCaught = true;
}
}
assertTrue(exCaught);
exCaught = false;
try {
rd.setFieldDifferentiator("salary", IdentityDifferentiator.instance());
} catch (IllegalArgumentException ex) {
if (ex.getMessage().indexOf("salary") != -1) {
exCaught = true;
}
}
assertTrue(exCaught);
}
protected Differentiator buildCustomSalaryDifferentiator() {
return new Differentiator() {
public Diff diff(Object object1, Object object2) {
float salary1 = ((Float) object1).floatValue();
float salary2 = ((Float) object2).floatValue();
if (Math.abs(salary2 - salary1) < 1) {
return NullDifferentiator.instance().diff(object1, object2);
}
return EqualityDifferentiator.instance().diff(object1, object2);
}
public Diff keyDiff(Object object1, Object object2) {
return this.diff(object1, object2);
}
public boolean comparesValueObjects() {
return true;
}
};
}
public void testInterface() {
Class bogusClass = Collection.class;
boolean exCaught = false;
try {
this.differentiator = new ReflectiveDifferentiator(bogusClass);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().indexOf(bogusClass.getName()) != -1) {
exCaught = true;
}
}
assertTrue(exCaught);
}
protected void verifyDiffMatch(Diff diff, Object object1, Object object2) {
assertEquals(object1, diff.getObject1());
assertEquals(object2, diff.getObject2());
assertTrue(diff.identical());
assertFalse(diff.different());
assertEquals(0, diff.getDescription().length());
}
protected void verifyDiffMismatch(Diff diff, Object object1, Object object2) {
assertEquals(object1, diff.getObject1());
assertEquals(object2, diff.getObject2());
assertFalse(diff.identical());
assertTrue(diff.different());
assertTrue(diff.getDescription().length() > 0);
}
}