From cc03e1d52b682e1ce565234b1a36639002777965 Mon Sep 17 00:00:00 2001 From: Marcin Kuszczak <1508798+aartiPl@users.noreply.github.com> Date: Mon, 21 Aug 2023 13:39:56 +0200 Subject: [PATCH] * Changed signatures of Markers ('id' comes first) * Added tests --- build.gradle.kts | 1 + .../igsoft/typeutils/marker/AbstractMarker.kt | 8 ++-- .../typeutils/marker/AutoTypedMarker.kt | 6 +-- .../typeutils/marker/DefaultTypedMarker.kt | 10 ++--- .../net/igsoft/typeutils/marker/Marker.kt | 2 +- .../net/igsoft/typeutils/marker/Markers.kt | 2 + .../igsoft/typeutils/marker/TypedMarker.kt | 2 +- .../marker/DefaultTypedMarkerTest.kt | 38 ++++++++++++++++++- 8 files changed, 54 insertions(+), 15 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8f953e7..b4c25a0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -103,5 +103,6 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.0") testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.0") testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.26.1") + testImplementation("nl.jqno.equalsverifier:equalsverifier:3.15.1") testImplementation("io.mockk:mockk:1.13.2") } diff --git a/src/main/kotlin/net/igsoft/typeutils/marker/AbstractMarker.kt b/src/main/kotlin/net/igsoft/typeutils/marker/AbstractMarker.kt index 7ab0cf0..cedb040 100644 --- a/src/main/kotlin/net/igsoft/typeutils/marker/AbstractMarker.kt +++ b/src/main/kotlin/net/igsoft/typeutils/marker/AbstractMarker.kt @@ -1,7 +1,7 @@ package net.igsoft.typeutils.marker -abstract class AbstractMarker(override val clazz: Class<*>, override val id: Any) : Marker { - override fun equals(other: Any?): Boolean = Markers.markerEquals(this, other) - override fun hashCode(): Int = Markers.markerHashCode(this) - override fun toString(): String = "Marker(id=$id, clazz=$clazz)" +abstract class AbstractMarker(override val id: Any, override val clazz: Class<*>) : Marker { + final override fun equals(other: Any?): Boolean = Markers.markerEquals(this, other) + final override fun hashCode(): Int = Markers.markerHashCode(this) + override fun toString(): String = Markers.markerToString(this, id, clazz) } diff --git a/src/main/kotlin/net/igsoft/typeutils/marker/AutoTypedMarker.kt b/src/main/kotlin/net/igsoft/typeutils/marker/AutoTypedMarker.kt index 6e197c8..e126f2b 100644 --- a/src/main/kotlin/net/igsoft/typeutils/marker/AutoTypedMarker.kt +++ b/src/main/kotlin/net/igsoft/typeutils/marker/AutoTypedMarker.kt @@ -3,15 +3,15 @@ package net.igsoft.typeutils.marker import net.igsoft.typeutils.generator.IntGenerator @Suppress("unused") -class AutoTypedMarker internal constructor(override val clazz: Class, override val id: Any) : - DefaultTypedMarker(clazz, id) { +class AutoTypedMarker internal constructor(override val id: Any, override val clazz: Class) : + DefaultTypedMarker(id, clazz) { companion object { private val intGenerator = IntGenerator() @JvmStatic fun create(clazz: Class) = - AutoTypedMarker(clazz, intGenerator.next()) + AutoTypedMarker(intGenerator.next(), clazz) inline fun create() = create(T::class.java) diff --git a/src/main/kotlin/net/igsoft/typeutils/marker/DefaultTypedMarker.kt b/src/main/kotlin/net/igsoft/typeutils/marker/DefaultTypedMarker.kt index 44c2c5a..48780e0 100644 --- a/src/main/kotlin/net/igsoft/typeutils/marker/DefaultTypedMarker.kt +++ b/src/main/kotlin/net/igsoft/typeutils/marker/DefaultTypedMarker.kt @@ -3,18 +3,18 @@ package net.igsoft.typeutils.marker import kotlin.properties.ReadOnlyProperty @Suppress("unused") -open class DefaultTypedMarker(override val clazz: Class, override val id: Any) : TypedMarker, - AbstractMarker(clazz, id) { +open class DefaultTypedMarker(override val id: Any, override val clazz: Class) : TypedMarker, + AbstractMarker(id, clazz) { //Copying constructor (de facto alias of marker) - constructor(marker: TypedMarker) : this(marker.clazz, marker.id) + constructor(marker: TypedMarker) : this(marker.id, marker.clazz) companion object { inline fun create(id: Any) = - DefaultTypedMarker(T::class.java, id) + DefaultTypedMarker(id, T::class.java) inline fun create(): ReadOnlyProperty> { - return ReadOnlyProperty { _, property -> DefaultTypedMarker(T::class.java, property.name) } + return ReadOnlyProperty { _, property -> DefaultTypedMarker(property.name, T::class.java) } } } } diff --git a/src/main/kotlin/net/igsoft/typeutils/marker/Marker.kt b/src/main/kotlin/net/igsoft/typeutils/marker/Marker.kt index 3be7507..486edad 100644 --- a/src/main/kotlin/net/igsoft/typeutils/marker/Marker.kt +++ b/src/main/kotlin/net/igsoft/typeutils/marker/Marker.kt @@ -1,6 +1,6 @@ package net.igsoft.typeutils.marker interface Marker { - val clazz: Class<*> val id: Any + val clazz: Class<*> } diff --git a/src/main/kotlin/net/igsoft/typeutils/marker/Markers.kt b/src/main/kotlin/net/igsoft/typeutils/marker/Markers.kt index 12c41f7..96c17dc 100644 --- a/src/main/kotlin/net/igsoft/typeutils/marker/Markers.kt +++ b/src/main/kotlin/net/igsoft/typeutils/marker/Markers.kt @@ -9,4 +9,6 @@ object Markers { } fun markerHashCode(marker: Marker) = marker.id.hashCode() + + fun markerToString(anyMarker: Marker, id: Any, clazz: Class<*>) = "${anyMarker::class.java.simpleName}(id=$id, clazz=${clazz.canonicalName})" } diff --git a/src/main/kotlin/net/igsoft/typeutils/marker/TypedMarker.kt b/src/main/kotlin/net/igsoft/typeutils/marker/TypedMarker.kt index 6ba459a..f1c10a2 100644 --- a/src/main/kotlin/net/igsoft/typeutils/marker/TypedMarker.kt +++ b/src/main/kotlin/net/igsoft/typeutils/marker/TypedMarker.kt @@ -1,6 +1,6 @@ package net.igsoft.typeutils.marker interface TypedMarker : Marker { - override val clazz: Class override val id: Any + override val clazz: Class } diff --git a/src/test/kotlin/net/igsoft/typeutils/marker/DefaultTypedMarkerTest.kt b/src/test/kotlin/net/igsoft/typeutils/marker/DefaultTypedMarkerTest.kt index c797be8..7fb9746 100644 --- a/src/test/kotlin/net/igsoft/typeutils/marker/DefaultTypedMarkerTest.kt +++ b/src/test/kotlin/net/igsoft/typeutils/marker/DefaultTypedMarkerTest.kt @@ -3,6 +3,8 @@ package net.igsoft.typeutils.marker import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.prop +import nl.jqno.equalsverifier.EqualsVerifier +import nl.jqno.equalsverifier.Warning import org.junit.jupiter.api.Test class DefaultTypedMarkerTest { @@ -17,7 +19,7 @@ class DefaultTypedMarkerTest { @Test fun `Assert that TypedMarker can be created manually`() { - assertThat(DefaultTypedMarker(String::class.java, "s1")).apply { + assertThat(DefaultTypedMarker("s1", String::class.java)).apply { prop(DefaultTypedMarker::clazz).isEqualTo(String::class.java) prop(DefaultTypedMarker::id).isEqualTo("s1") } @@ -27,4 +29,38 @@ class DefaultTypedMarkerTest { prop(DefaultTypedMarker::id).isEqualTo("s2") } } + + @Test + fun `Assert that TypedMarker get other other TypedMarker and both will point to the same value`() { + val typedMarker = DefaultTypedMarker.create(5) + + assertThat(DefaultTypedMarker(typedMarker)).apply { + prop(DefaultTypedMarker::clazz).isEqualTo(String::class.java) + prop(DefaultTypedMarker::id).isEqualTo(5) + } + } + + @Test + fun `Assert that TypedMarkers are always different by 'id' field (no duplicates)`() { + var counter = 0 + + val list = generateSequence { + DefaultTypedMarker.create(counter++) + }.take(100).toList() + + assertThat(list.size).isEqualTo(list.map { it.id }.distinct().count()) + } + + @Test + fun `Assert that 'toString' works correctly`() { + assertThat(DefaultTypedMarker.create("v1").toString()).isEqualTo("DefaultTypedMarker(id=v1, clazz=java.lang.Integer)") + assertThat(DefaultTypedMarker.create("v2").toString()).isEqualTo("DefaultTypedMarker(id=v2, clazz=java.lang.String)") + } + + @Test + fun `Assert that 'equals' and 'hashCode' work correctly`() { + EqualsVerifier.forClass(DefaultTypedMarker::class.java) + .suppress(Warning.ALL_FIELDS_SHOULD_BE_USED) + .verify() + } }