Skip to content

Commit

Permalink
Fixes incorrect error with unused lazy field
Browse files Browse the repository at this point in the history
  • Loading branch information
jqno committed Aug 2, 2023
1 parent fcdbdac commit 334bdc2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import static net.bytebuddy.matcher.ElementMatchers.named;
import static nl.jqno.equalsverifier.internal.util.Assert.assertTrue;

import java.util.Set;
import java.util.function.Function;
import nl.jqno.equalsverifier.internal.exceptions.EqualsVerifierInternalBugException;
import nl.jqno.equalsverifier.internal.prefabvalues.PrefabValues;
Expand All @@ -22,18 +21,18 @@ public class JpaLazyGetterFieldCheck<T> implements FieldCheck<T> {

private final Class<T> type;
private final ClassAccessor<T> accessor;
private final Set<String> ignoredFields;
private final PrefabValues prefabValues;
private final AnnotationCache annotationCache;
private final Function<String, String> fieldnameToGetter;
private final TypeTag typeTag;

public JpaLazyGetterFieldCheck(Configuration<T> config) {
this.type = config.getType();
this.accessor = config.getClassAccessor();
this.ignoredFields = config.getIgnoredFields();
this.prefabValues = config.getPrefabValues();
this.annotationCache = config.getAnnotationCache();
this.fieldnameToGetter = config.getFieldnameToGetter();
this.typeTag = config.getTypeTag();
}

@Override
Expand All @@ -45,7 +44,10 @@ public void execute(
String fieldName = fieldAccessor.getFieldName();
String getterName = fieldnameToGetter.apply(fieldName);

if (ignoredFields.contains(fieldName) || !fieldIsLazy(fieldAccessor)) {
if (
!fieldIsUsed(referenceAccessor, copyAccessor, fieldAccessor) ||
!fieldIsLazy(fieldAccessor)
) {
return;
}

Expand All @@ -72,6 +74,19 @@ public void execute(
assertEntity(fieldName, "hashCode", getterName, hashCodeExceptionCaught);
}

private boolean fieldIsUsed(
ObjectAccessor<T> referenceAccessor,
ObjectAccessor<T> copyAccessor,
FieldAccessor fieldAccessor
) {
T red = referenceAccessor.get();
T blue = copyAccessor
.withChangedField(fieldAccessor.getField(), prefabValues, typeTag)
.get();

return !red.equals(blue);
}

private boolean fieldIsLazy(FieldAccessor fieldAccessor) {
return (
annotationCache.hasFieldAnnotation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ public void basicGetterNotUsed_givenCorrespondingFieldIgnored() {
.verify();
}

@Test
public void basicGetterNotUsed_givenWarningSuppressed() {
EqualsVerifier
.forClass(CorrectBasicJakartaIgnoredLazyFieldContainer.class)
.suppress(Warning.ALL_FIELDS_SHOULD_BE_USED)
.verify();
}

@Test
public void basicGetterUsed_givenAnnotationIsOnGetter() {
getterNotUsed(IncorrectBasicJakartaLazyGetterContainer.class, "equals");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,27 @@ public class JpaLazyEntityTest {

@Test
public void gettersAreUsed() {
EqualsVerifier
.forClass(CorrectJpaLazyFieldContainer.class)
.suppress(Warning.NONFINAL_FIELDS)
.verify();
EqualsVerifier.forClass(CorrectJpaLazyFieldContainer.class).verify();
}

@Test
public void basicGetterNotUsed_givenEagerLoading() {
EqualsVerifier
.forClass(CorrectBasicJpaEagerFieldContainer.class)
.suppress(Warning.NONFINAL_FIELDS)
.verify();
EqualsVerifier.forClass(CorrectBasicJpaEagerFieldContainer.class).verify();
}

@Test
public void basicGetterNotUsed_givenCorrespondingFieldIgnored() {
EqualsVerifier
.forClass(CorrectBasicJpaIgnoredLazyFieldContainer.class)
.withIgnoredFields("basic")
.suppress(Warning.NONFINAL_FIELDS)
.verify();
}

@Test
public void basicGetterNotUsed_givenWarningSuppressed() {
EqualsVerifier
.forClass(CorrectBasicJpaIgnoredLazyFieldContainer.class)
.suppress(Warning.ALL_FIELDS_SHOULD_BE_USED)
.verify();
}

Expand Down Expand Up @@ -102,7 +103,6 @@ public void lazyGettersPickedUpInSuper() {
public void differentCodingStyle_single() {
EqualsVerifier
.forClass(DifferentCodingStyleContainer.class)
.suppress(Warning.NONFINAL_FIELDS)
.withFieldnameToGetterConverter(fn ->
"get" + Character.toUpperCase(fn.charAt(2)) + fn.substring(3)
)
Expand All @@ -113,7 +113,6 @@ public void differentCodingStyle_single() {
public void differentCodingStyle_configured() {
EqualsVerifier
.configure()
.suppress(Warning.NONFINAL_FIELDS)
.withFieldnameToGetterConverter(fn ->
"get" + Character.toUpperCase(fn.charAt(2)) + fn.substring(3)
)
Expand All @@ -125,7 +124,6 @@ public void differentCodingStyle_configured() {
public void differentCodingStyle_multiple() {
EqualsVerifier
.forClasses(Arrays.asList(DifferentCodingStyleContainer.class))
.suppress(Warning.NONFINAL_FIELDS)
.withFieldnameToGetterConverter(fn ->
"get" + Character.toUpperCase(fn.charAt(2)) + fn.substring(3)
)
Expand All @@ -134,16 +132,13 @@ public void differentCodingStyle_multiple() {

private void getterNotUsed(Class<?> type, String method) {
ExpectedException
.when(() -> EqualsVerifier.forClass(type).suppress(Warning.NONFINAL_FIELDS).verify())
.when(() -> EqualsVerifier.forClass(type).verify())
.assertFailure()
.assertMessageContains("JPA Entity", method, "direct reference");
}

private void getterNotUsed_warningSuppressed(Class<?> type) {
EqualsVerifier
.forClass(type)
.suppress(Warning.JPA_GETTER, Warning.NONFINAL_FIELDS)
.verify();
EqualsVerifier.forClass(type).suppress(Warning.JPA_GETTER).verify();
}

@Entity
Expand Down

0 comments on commit 334bdc2

Please sign in to comment.