From 23b0629c192e3f9aa47cb2b3bf634ed60411d343 Mon Sep 17 00:00:00 2001 From: Emil Kantis Date: Mon, 11 Mar 2024 03:44:12 +0100 Subject: [PATCH] Don't consider kotlinx and javax types to be builtin (#3899) Fixes #3855 --------- Co-authored-by: Sam --- .../io/kotest/matchers/equality/compare.kt | 2 +- .../io/kotest/matchers/equality/primitives.kt | 31 +++++++++++++++++++ .../io/kotest/matchers/equality/reflection.kt | 2 +- .../kotest-tests-core/build.gradle.kts | 2 ++ .../com/sksamuel/kotest/JaxbElementTest.kt | 29 +++++++++++++++++ 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/primitives.kt create mode 100644 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/JaxbElementTest.kt diff --git a/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/compare.kt b/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/compare.kt index 456ac879163..dcf86cc9ac9 100644 --- a/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/compare.kt +++ b/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/compare.kt @@ -161,7 +161,7 @@ internal fun useEq( val typeIsJavaOrKotlinBuiltIn by lazy { val bestName = typeName.bestName() bestName.startsWith("kotlin") || - bestName.startsWith("java") || + (bestName.startsWith("java") && !bestName.startsWith("javax.xml.bind.JAXBElement")) || builtins.contains(bestName) } val expectedOrActualIsEnum = actual is Enum<*> diff --git a/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/primitives.kt b/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/primitives.kt new file mode 100644 index 00000000000..3d95c3b9d27 --- /dev/null +++ b/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/primitives.kt @@ -0,0 +1,31 @@ +package io.kotest.matchers.equality + +/** + * This is currently unused but will form the basis of reflection based checks in 6.0 + */ +internal fun T.isBuiltInType() = + this is Number + || this is UInt + || this is ULong + || this is UByte + || this is UShort + || this is String + || this is Boolean + || this is Char + || this is IntArray + || this is CharArray + || this is LongArray + || this is ShortArray + || this is ByteArray + || this is DoubleArray + || this is FloatArray + || this is BooleanArray + || this is UIntArray + || this is ULongArray + || this is UByteArray + || this is UShortArray + || this is Array<*> + || this is List<*> + || this is Set<*> + || this is Map<*, *> + || this is Sequence<*> diff --git a/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/reflection.kt b/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/reflection.kt index bbcd57abe66..df926a9c747 100644 --- a/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/reflection.kt +++ b/kotest-assertions/kotest-assertions-core/src/jvmMain/kotlin/io/kotest/matchers/equality/reflection.kt @@ -620,7 +620,7 @@ private fun requiresUseOfDefaultEq( useDefaultEqualForFields: List ): Boolean { val expectedOrActualIsNull = actual == null || expected == null - val typeIsJavaOrKotlinBuiltIn by lazy { typeName.startsWith("kotlin") || typeName.startsWith("java") } + val typeIsJavaOrKotlinBuiltIn by lazy { typeName.startsWith("kotlin.") || typeName.startsWith("java.") } val expectedOrActualIsEnum = actual is Enum<*> || expected is Enum<*> || (actual != null && actual::class.java.isEnum) diff --git a/kotest-tests/kotest-tests-core/build.gradle.kts b/kotest-tests/kotest-tests-core/build.gradle.kts index f475c6ba35f..cc7a7948b3d 100644 --- a/kotest-tests/kotest-tests-core/build.gradle.kts +++ b/kotest-tests/kotest-tests-core/build.gradle.kts @@ -11,6 +11,8 @@ kotlin { implementation(projects.kotestAssertions.kotestAssertionsCore) // this is here to test that the intellij marker 'dummy' test doesn't appear in intellij implementation(libs.junit.jupiter.engine) + // We want to test that JAXBElement is compared properly + implementation("javax.xml.bind:jaxb-api:2.3.1") } } } diff --git a/kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/JaxbElementTest.kt b/kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/JaxbElementTest.kt new file mode 100644 index 00000000000..72218fff0a3 --- /dev/null +++ b/kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/JaxbElementTest.kt @@ -0,0 +1,29 @@ +package com.sksamuel.kotest + +import io.kotest.assertions.shouldFail +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.equality.shouldBeEqualToComparingFields +import io.kotest.matchers.string.shouldContain +import javax.xml.bind.JAXBElement +import javax.xml.namespace.QName + +class JaxbElementTest : FunSpec({ + + context("Comparing JAXBElement reflectively works as expected") { + + val jaxbElement = JAXBElement(QName.valueOf("name"), Int::class.java, 123) + val otherJaxbElement = JAXBElement(QName.valueOf("name"), Int::class.java, 124) + + test("!should pass when comparing equal elements") { + jaxbElement.shouldBeEqualToComparingFields(jaxbElement) + } + + test("!should fail when comparing different elements") { + shouldFail { + jaxbElement.shouldBeEqualToComparingFields(otherJaxbElement) + }.message.shouldContain( + """Value differ at:\s+1\) value:\s+expected:<124> but was:<123>""".toRegex() + ) + } + } +})