Skip to content

Commit

Permalink
* Changed signatures of Markers ('id' comes first)
Browse files Browse the repository at this point in the history
* Added tests
  • Loading branch information
aartiPl committed Aug 21, 2023
1 parent 98154ca commit cc03e1d
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 15 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
8 changes: 4 additions & 4 deletions src/main/kotlin/net/igsoft/typeutils/marker/AbstractMarker.kt
Original file line number Diff line number Diff line change
@@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ package net.igsoft.typeutils.marker
import net.igsoft.typeutils.generator.IntGenerator

@Suppress("unused")
class AutoTypedMarker<T> internal constructor(override val clazz: Class<T>, override val id: Any) :
DefaultTypedMarker<T>(clazz, id) {
class AutoTypedMarker<T> internal constructor(override val id: Any, override val clazz: Class<T>) :
DefaultTypedMarker<T>(id, clazz) {

companion object {
private val intGenerator = IntGenerator()

@JvmStatic
fun <T> create(clazz: Class<T>) =
AutoTypedMarker(clazz, intGenerator.next())
AutoTypedMarker(intGenerator.next(), clazz)

inline fun <reified T> create() =
create(T::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ package net.igsoft.typeutils.marker
import kotlin.properties.ReadOnlyProperty

@Suppress("unused")
open class DefaultTypedMarker<T>(override val clazz: Class<T>, override val id: Any) : TypedMarker<T>,
AbstractMarker(clazz, id) {
open class DefaultTypedMarker<T>(override val id: Any, override val clazz: Class<T>) : TypedMarker<T>,
AbstractMarker(id, clazz) {

//Copying constructor (de facto alias of marker)
constructor(marker: TypedMarker<T>) : this(marker.clazz, marker.id)
constructor(marker: TypedMarker<T>) : this(marker.id, marker.clazz)

companion object {
inline fun <reified T> create(id: Any) =
DefaultTypedMarker(T::class.java, id)
DefaultTypedMarker(id, T::class.java)

inline fun <reified T> create(): ReadOnlyProperty<Any?, DefaultTypedMarker<T>> {
return ReadOnlyProperty { _, property -> DefaultTypedMarker(T::class.java, property.name) }
return ReadOnlyProperty { _, property -> DefaultTypedMarker(property.name, T::class.java) }
}
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/net/igsoft/typeutils/marker/Marker.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.igsoft.typeutils.marker

interface Marker {
val clazz: Class<*>
val id: Any
val clazz: Class<*>
}
2 changes: 2 additions & 0 deletions src/main/kotlin/net/igsoft/typeutils/marker/Markers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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})"
}
2 changes: 1 addition & 1 deletion src/main/kotlin/net/igsoft/typeutils/marker/TypedMarker.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.igsoft.typeutils.marker

interface TypedMarker<T> : Marker {
override val clazz: Class<T>
override val id: Any
override val clazz: Class<T>
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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<String>::clazz).isEqualTo(String::class.java)
prop(DefaultTypedMarker<String>::id).isEqualTo("s1")
}
Expand All @@ -27,4 +29,38 @@ class DefaultTypedMarkerTest {
prop(DefaultTypedMarker<Int>::id).isEqualTo("s2")
}
}

@Test
fun `Assert that TypedMarker get other other TypedMarker and both will point to the same value`() {
val typedMarker = DefaultTypedMarker.create<String>(5)

assertThat(DefaultTypedMarker(typedMarker)).apply {
prop(DefaultTypedMarker<String>::clazz).isEqualTo(String::class.java)
prop(DefaultTypedMarker<String>::id).isEqualTo(5)
}
}

@Test
fun `Assert that TypedMarkers are always different by 'id' field (no duplicates)`() {
var counter = 0

val list = generateSequence {
DefaultTypedMarker.create<Int>(counter++)
}.take(100).toList()

assertThat(list.size).isEqualTo(list.map { it.id }.distinct().count())
}

@Test
fun `Assert that 'toString' works correctly`() {
assertThat(DefaultTypedMarker.create<Int>("v1").toString()).isEqualTo("DefaultTypedMarker(id=v1, clazz=java.lang.Integer)")
assertThat(DefaultTypedMarker.create<String>("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()
}
}

0 comments on commit cc03e1d

Please sign in to comment.