Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an ability to compare equal by equals() method objects with ReflectionBuilder #1137

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public class ReflectionDiffBuilder<T> implements Builder<DiffResult<T>> {

private final T left;
private final T right;
private final boolean testTriviallyEqual;
private final DiffBuilder<T> diffBuilder;

/**
Expand Down Expand Up @@ -103,9 +104,38 @@ public class ReflectionDiffBuilder<T> implements Builder<DiffResult<T>> {
* if {@code lhs} or {@code rhs} is {@code null}
*/
public ReflectionDiffBuilder(final T lhs, final T rhs, final ToStringStyle style) {
this(lhs, rhs, style, true);
}

/**
* Constructs a builder for the specified objects with the specified style.
*
* <p>
* If {@code lhs == rhs} or {@code lhs.equals(rhs)} then the builder will
* not evaluate any calls to {@code append(...)} and will return an empty
* {@link DiffResult} when {@link #build()} is executed.
* </p>
* @param lhs
* {@code this} object
* @param rhs
* the object to diff against
* @param style
* the style will use when outputting the objects, {@code null}
* uses the default
* @param testTriviallyEqual
* If true, this will test if lhs and rhs are the same or equal.
* All of the append(fieldName, lhs, rhs) methods will abort
* without creating a field {@link Diff} if the trivially equal
* test is enabled and returns true. The result of this test
* is never changed throughout the life of this {@link ReflectionDiffBuilder}
* @throws IllegalArgumentException
* if {@code lhs} or {@code rhs} is {@code null}
*/
public ReflectionDiffBuilder(final T lhs, final T rhs, final ToStringStyle style, boolean testTriviallyEqual) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not add another constructor. This class provides a builder for new settings.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor is the purpose of this change. If I remove it, then the change becomes useless

this.left = lhs;
this.right = rhs;
this.diffBuilder = new DiffBuilder<>(lhs, rhs, style);
this.testTriviallyEqual = testTriviallyEqual;
this.diffBuilder = new DiffBuilder<>(lhs, rhs, style, testTriviallyEqual);
}

private boolean accept(final Field field) {
Expand Down Expand Up @@ -143,7 +173,7 @@ private void appendFields(final Class<?> clazz) {

@Override
public DiffResult<T> build() {
if (left.equals(right)) {
if (testTriviallyEqual && left.equals(right)) {
return diffBuilder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,31 @@ private static final class TypeTestChildClass extends TypeTestClass {
String field = "a";
}

@SuppressWarnings("unused")
private static class TypeTestEntityClass implements Diffable<TypeTestEntityClass> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename TypeTestEntityClass to EntityTestClass.
Add a class Javadoc that states the intent for the test fixture to emulate a JPA entity class.


private Long id;
private String field1;

@Override
public DiffResult<TypeTestEntityClass> diff(TypeTestEntityClass obj) {
return new ReflectionDiffBuilder(this, obj, SHORT_STYLE, false).build();
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always use blocks ({...}}

if (obj == null || getClass() != obj.getClass()) return false;
TypeTestEntityClass that = (TypeTestEntityClass) obj;
return new EqualsBuilder().append(id, that.id).build();
}

@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(id).toHashCode();
}
}

@SuppressWarnings("unused")
private static class TypeTestClass implements Diffable<TypeTestClass> {
private static int staticField;
Expand Down Expand Up @@ -184,4 +209,18 @@ public void testGetExcludeFieldNamesWithNullValuesInExcludedFieldNames() {
assertEquals("charField", excludeFieldNames[0]);
}

@Test
public void testEqualsObjectDiff() {
final TypeTestEntityClass firstObject = new TypeTestEntityClass();
firstObject.id = 1L;
firstObject.field1 = "a";

final TypeTestEntityClass secondObject = new TypeTestEntityClass();
secondObject.id = 1L;
secondObject.field1 = "b";

final DiffResult list = firstObject.diff(secondObject);
assertEquals(1, list.getNumberOfDiffs());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test should assert what the difference is; IOW, make assertions on the other properties of the DiffResult and Diff instances.

}

}