
de.codecentric.mule.assertobjectequals.ObjectComparator Maven / Gradle / Ivy
package de.codecentric.mule.assertobjectequals;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Compare two objects, drill down into List an
*/
public class ObjectComparator {
private ObjectCompareOptionsFactory optionFactory;
private class State {
final Path path;
final Object expected;
final Object actual;
final EnumSet options;
private State(Path path, Object expected, Object actual, EnumSet options) {
this.path = path;
this.expected = expected;
this.actual = actual;
this.options = options;
}
public State(Object expected, Object actual) {
path = new Path();
this.expected = expected;
this.actual = actual;
options = optionFactory.createOptions(null, path);
}
public State listEntry(int listIndex, int listSize, Object expected, Object actual) {
Path next = path.listEntry(listIndex, listSize);
return new State(next, expected, actual, optionFactory.createOptions(options, next));
}
public State mapEntry(String key, Object expected, Object actual) {
Path next = path.mapEntry(key);
return new State(next, expected, actual, optionFactory.createOptions(options, next));
}
}
public ObjectComparator(ObjectCompareOptionsFactory optionFactory) {
this.optionFactory = optionFactory;
}
/**
* Compare two objects. Drill down into {@link Map} and {@link List}, use {@link Object#equals(Object)} for all
* other classes.
*
* @param expected
* The expected value.
* @param actual
* The actual value.
* @return Textual description of the differences.
*/
public Collection compare(Object expected, Object actual) {
State state = new State(expected, actual);
Collection diffs = new ArrayList();
compare(state, diffs);
return diffs;
}
private void compare(State state, Collection diffs) {
if (state.options.contains(PathOption.IGNORE)) {
return;
}
if (state.expected == null) {
if (state.actual == null) {
// ok, null equals null
} else { // actual != null
diffs.add("at '" + state.path + "', expected is null, actual " + state.actual);
}
} else { // expected != null
if (state.actual == null) {
diffs.add("at '" + state.path + "', expected " + state.expected + ", actual is null");
} else { // actual != null
compareNonNullObjects(state, diffs);
}
}
}
private void compareNonNullObjects(State state, Collection diffs) {
if (state.expected instanceof List) {
if (state.actual instanceof List) {
compareLists(state, diffs);
} else {
diffs.add("at '" + state.path + "', expected List, but found " + state.actual.getClass().getName());
}
} else if (state.expected instanceof Map) {
if (state.actual instanceof Map) {
compareMaps(state, diffs);
}
} else {
if (!state.expected.equals(state.actual)) {
diffs.add("at '" + state.path + "', expected " + state.expected + ", but found " + state.actual);
}
}
}
private void compareLists(State state, Collection diffs) {
@SuppressWarnings("unchecked")
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy