diff --git a/src/main/java/nl/jqno/equalsverifier/internal/prefabvalues/JavaApiPrefabValues.java b/src/main/java/nl/jqno/equalsverifier/internal/prefabvalues/JavaApiPrefabValues.java index 4f7d58191..0c007e930 100644 --- a/src/main/java/nl/jqno/equalsverifier/internal/prefabvalues/JavaApiPrefabValues.java +++ b/src/main/java/nl/jqno/equalsverifier/internal/prefabvalues/JavaApiPrefabValues.java @@ -11,12 +11,15 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.nio.*; +import java.rmi.dgc.VMID; +import java.rmi.server.UID; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.*; import java.util.concurrent.locks.StampedLock; import java.util.function.Supplier; import java.util.regex.Pattern; @@ -79,7 +82,8 @@ private void addJavaClasses() { addSets(); addQueues(); addNioBuffers(); - addAwtClasses(); + addAtomicClasses(); + addAncientJavaApiClasses(); addJavaFxClasses(); addJavaxApiClasses(); addGoogleGuavaMultisetCollectionsClasses(); @@ -263,11 +267,36 @@ private void addNioBuffers() { ShortBuffer.wrap(new short[] { 0 }), ShortBuffer.wrap(new short[] { 1 }), ShortBuffer.wrap(new short[] { 0 })); } - private void addAwtClasses() { + @SuppressWarnings({"unchecked", "rawtypes"}) + private void addAtomicClasses() { + addValues(AtomicBoolean.class, new AtomicBoolean(true), new AtomicBoolean(false), new AtomicBoolean(true)); + addValues(AtomicInteger.class, new AtomicInteger(1), new AtomicInteger(2), new AtomicInteger(1)); + addValues(AtomicIntegerArray.class, new AtomicIntegerArray(new int[] { 1 }), new AtomicIntegerArray(new int[] { 2 }), new AtomicIntegerArray(new int[] { 1 })); + addValues(AtomicLong.class, new AtomicLong(1L), new AtomicLong(2L), new AtomicLong(1L)); + addValues(AtomicLongArray.class, new AtomicLongArray(new long[] { 1L }), new AtomicLongArray(new long[] { 2L }), new AtomicLongArray(new long[] { 1 })); + addFactory(AtomicMarkableReference.class, simple(r -> new AtomicMarkableReference(r, true), null)); + addFactory(AtomicReference.class, simple(AtomicReference::new, null)); + addFactory(AtomicStampedReference.class, simple(r -> new AtomicStampedReference(r, 0), null)); + addFactory(AtomicReferenceArray.class, (tag, pv, stack) -> { + TypeTag y = tag.getGenericTypes().get(0); + Object[] red = new Object[] { pv.giveRed(y) }; + Object[] black = new Object[] { pv.giveBlack(y) }; + Object[] redCopy = new Object[] { pv.giveRedCopy(y) }; + return Tuple.of(new AtomicReferenceArray(red), new AtomicReferenceArray(black), new AtomicReferenceArray(redCopy)); + }); + } + + private void addAncientJavaApiClasses() { addLazyFactory("java.awt.Color", AWT_FACTORY); addLazyFactory("java.awt.color.ColorSpace", AWT_FACTORY); addLazyFactory("java.awt.color.ICC_ColorSpace", AWT_FACTORY); addLazyFactory("java.awt.color.ICC_Profile", AWT_FACTORY); + + VMID redVmid = new VMID(); + addValues(VMID.class, redVmid, new VMID(), redVmid); + UID redUid = new UID(); + addValues(UID.class, redUid, new UID(), redUid); + } private void addJavaFxClasses() { diff --git a/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/GenericTypesTest.java b/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/GenericTypesTest.java index a36e2ef48..a239aab69 100644 --- a/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/GenericTypesTest.java +++ b/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/GenericTypesTest.java @@ -7,6 +7,7 @@ import org.junit.Test; import java.util.*; +import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.function.Supplier; import static nl.jqno.equalsverifier.testhelpers.Util.defaultEquals; @@ -15,7 +16,7 @@ public class GenericTypesTest extends ExpectedExceptionTestBase { @Test public void succeed_whenEqualsLooksAtJava8TypesGenericContent() { - EqualsVerifier.forClass(Java8GenericTypeContainer.class) + EqualsVerifier.forClass(JavaGenericTypeContainer.class) .verify(); } @@ -109,29 +110,32 @@ public void succeed_whenClassHasTypeVariableThatExtendsSomethingThatSupersSometh .verify(); } - static final class Java8GenericTypeContainer { + static final class JavaGenericTypeContainer { private final Optional optional; private final Supplier supplier; + private final AtomicReferenceArray atomicReferenceArray; - public Java8GenericTypeContainer(Optional optional, Supplier supplier) { - this.optional = optional; this.supplier = supplier; + public JavaGenericTypeContainer(Optional optional, Supplier supplier, AtomicReferenceArray atomicReferenceArray) { + this.optional = optional; this.supplier = supplier; this.atomicReferenceArray = atomicReferenceArray; } @Override public boolean equals(Object obj) { - if (!(obj instanceof Java8GenericTypeContainer)) { + if (!(obj instanceof JavaGenericTypeContainer)) { return false; } - Java8GenericTypeContainer other = (Java8GenericTypeContainer)obj; + JavaGenericTypeContainer other = (JavaGenericTypeContainer)obj; Point thisOptionalPoint = optional != null ? optional.orElse(null) : null; Point thatOptionalPoint = other.optional != null ? other.optional.orElse(null) : null; Point thisSupplierPoint = supplier != null ? supplier.get() : null; Point thatSupplierPoint = other.supplier != null ? other.supplier.get() : null; - return Objects.equals(thisOptionalPoint, thatOptionalPoint) && Objects.equals(thisSupplierPoint, thatSupplierPoint); + Point thisAraPoint = atomicReferenceArray != null ? atomicReferenceArray.get(0) : null; + Point thatAraPoint = other.atomicReferenceArray != null ? other.atomicReferenceArray.get(0) : null; + return Objects.equals(thisOptionalPoint, thatOptionalPoint) && Objects.equals(thisSupplierPoint, thatSupplierPoint) && Objects.equals(thisAraPoint, thatAraPoint); } @Override public int hashCode() { return defaultHashCode(this); } - @Override public String toString() { return "Java8GenericTypeContainer: " + optional + ", " + supplier.get(); } + @Override public String toString() { return "JavaGenericTypeContainer: " + optional + ", " + supplier.get(); } } static final class ListContainer { diff --git a/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/JavaApiClassesTest.java b/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/JavaApiClassesTest.java index 941748c0a..126940659 100644 --- a/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/JavaApiClassesTest.java +++ b/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/JavaApiClassesTest.java @@ -15,6 +15,7 @@ import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.*; import java.util.concurrent.locks.StampedLock; import java.util.function.Supplier; import java.util.regex.Pattern; @@ -72,8 +73,14 @@ public void succeed_whenClassContainsACommonJava8ApiClass() { } @Test - public void succeed_whenClassContainsAnAwtClass() { - EqualsVerifier.forClass(AwtClassesContainer.class) + public void succeed_whenClassContainsAnAtomicValue() { + EqualsVerifier.forClass(AtomicClassesContainer.class) + .verify(); + } + + @Test + public void succeed_whenClassContainsAnAncientJavaApiClass() { + EqualsVerifier.forClass(AncientJavaApiClassesContainer.class) .verify(); } @@ -343,14 +350,42 @@ public Java8ApiClassesContainer(Optional optional, LocalDate localDate, Local } @SuppressWarnings("unused") // because of the use of defaultEquals and defaultHashCode - static final class AwtClassesContainer { + static final class AtomicClassesContainer { + private final AtomicBoolean atomicBoolean; + private final AtomicInteger atomicInteger; + private final AtomicIntegerArray atomicIntegerArray; + private final AtomicLong atomicLong; + private final AtomicLongArray atomicLongArray; + private final AtomicMarkableReference atomicMarkableReference; + private final AtomicReference atomicReference; + private final AtomicReferenceArray atomicReferenceArray; + private final AtomicStampedReference atomicStampedReference; + + // CHECKSTYLE: ignore ParameterNumber for 1 line. + public AtomicClassesContainer(AtomicBoolean atomicBoolean, AtomicInteger atomicInteger, AtomicIntegerArray atomicIntegerArray, + AtomicLong atomicLong, AtomicLongArray atomicLongArray, AtomicMarkableReference atomicMarkableReference, + AtomicReference atomicReference, AtomicReferenceArray atomicReferenceArray, AtomicStampedReference atomicStampedReference) { + this.atomicBoolean = atomicBoolean; this.atomicInteger = atomicInteger; this.atomicIntegerArray = atomicIntegerArray; + this.atomicLong = atomicLong; this.atomicLongArray = atomicLongArray; this.atomicMarkableReference = atomicMarkableReference; + this.atomicReference = atomicReference; this.atomicReferenceArray = atomicReferenceArray; this.atomicStampedReference = atomicStampedReference; + } + + @Override public boolean equals(Object obj) { return defaultEquals(this, obj); } + @Override public int hashCode() { return defaultHashCode(this); } + } + + + @SuppressWarnings("unused") // because of the use of defaultEquals and defaultHashCode + static final class AncientJavaApiClassesContainer { private final java.awt.color.ColorSpace awtColorSpace; private final java.awt.color.ICC_ColorSpace iccColorSpace; private final java.awt.color.ICC_Profile iccProfile; + private final java.rmi.dgc.VMID vmid; + private final java.rmi.server.UID uid; - public AwtClassesContainer(java.awt.color.ColorSpace awtColorSpace, java.awt.color.ICC_ColorSpace iccColorSpace, - java.awt.color.ICC_Profile iccProfile) { - this.awtColorSpace = awtColorSpace; this.iccColorSpace = iccColorSpace; this.iccProfile = iccProfile; + public AncientJavaApiClassesContainer(java.awt.color.ColorSpace awtColorSpace, java.awt.color.ICC_ColorSpace iccColorSpace, + java.awt.color.ICC_Profile iccProfile, java.rmi.dgc.VMID vmid, java.rmi.server.UID uid) { + this.awtColorSpace = awtColorSpace; this.iccColorSpace = iccColorSpace; this.iccProfile = iccProfile; this.vmid = vmid; this.uid = uid; } @Override public boolean equals(Object obj) { return defaultEquals(this, obj); }