diff --git a/modules/mockk-agent-android/api/mockk-agent-android.api b/modules/mockk-agent-android/api/mockk-agent-android.api index 7ba2bd2ea..f1432b778 100644 --- a/modules/mockk-agent-android/api/mockk-agent-android.api +++ b/modules/mockk-agent-android/api/mockk-agent-android.api @@ -1,8 +1,3 @@ -public final class io/mockk/ValueClassSupportAndroidKt { - public static final fun getBoxedClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass; - public static final fun getBoxedValue (Ljava/lang/Object;)Ljava/lang/Object; -} - public final class io/mockk/proxy/android/AndroidMockKAgentFactory : io/mockk/proxy/MockKAgentFactory { public static final field Companion Lio/mockk/proxy/android/AndroidMockKAgentFactory$Companion; public field constructorProxyMaker Lio/mockk/proxy/MockKConstructorProxyMaker; diff --git a/modules/mockk-agent-android/build.gradle.kts b/modules/mockk-agent-android/build.gradle.kts index 9275bca15..b566cd44d 100644 --- a/modules/mockk-agent-android/build.gradle.kts +++ b/modules/mockk-agent-android/build.gradle.kts @@ -45,6 +45,8 @@ dependencies { api(projects.modules.mockkAgentApi) api(projects.modules.mockkAgent) + implementation(projects.modules.mockkCore) + implementation(kotlin("reflect")) implementation("com.linkedin.dexmaker:dexmaker:${buildsrc.config.Deps.Versions.dexmaker}") implementation("org.objenesis:objenesis:${buildsrc.config.Deps.Versions.objenesis}") diff --git a/modules/mockk-agent-android/src/main/kotlin/io/mockk/ValueClassSupportAndroid.kt b/modules/mockk-agent-android/src/main/kotlin/io/mockk/ValueClassSupportAndroid.kt deleted file mode 100644 index b139cd1b6..000000000 --- a/modules/mockk-agent-android/src/main/kotlin/io/mockk/ValueClassSupportAndroid.kt +++ /dev/null @@ -1,68 +0,0 @@ -package io.mockk - -import kotlin.reflect.KClass -import kotlin.reflect.KProperty1 -import kotlin.reflect.full.declaredMemberProperties -import kotlin.reflect.jvm.internal.KotlinReflectionInternalError -import kotlin.reflect.jvm.isAccessible -import kotlin.reflect.jvm.javaField - -// TODO this class is copy-pasted and should be de-duplicated -// see https://github.com/mockk/mockk/issues/857 - -/** - * Underlying property value of a **`value class`** or self. - * - * The type of the return might also be a `value class`! - */ -val T.boxedValue: Any? - @Suppress("UNCHECKED_CAST") - get() = if (!this::class.isValue_safe) { - this - } else { - (this::class as KClass).boxedProperty.get(this) - } - -/** - * Underlying property class of a **`value class`** or self. - * - * The returned class might also be a `value class`! - */ -val KClass<*>.boxedClass: KClass<*> - get() = if (!this.isValue_safe) { - this - } else { - this.boxedProperty.returnType.classifier as KClass<*> - } - -private val valueClassFieldCache = mutableMapOf, KProperty1>() - -/** - * Underlying property of a **`value class`**. - * - * The underlying property might also be a `value class`! - */ -private val KClass.boxedProperty: KProperty1 - get() = if (!this.isValue_safe) { - throw UnsupportedOperationException("$this is not a value class") - } else { - @Suppress("UNCHECKED_CAST") - valueClassFieldCache.getOrPut(this) { - // value classes always have exactly one property with a backing field - this.declaredMemberProperties.first { it.javaField != null }.apply { isAccessible = true } - } as KProperty1 - } - -/** - * Returns `true` if calling [KClass.isValue] is safe. - * - * (In some instances [KClass.isValue] can throw an exception.) - */ -private val KClass.isValue_safe: Boolean - get() = try { - this.isValue - } catch (_: UnsupportedOperationException) { - false - } catch (_: KotlinReflectionInternalError) { - false - } diff --git a/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt b/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt index 4c4dd594f..0225d7a6b 100644 --- a/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt +++ b/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt @@ -5,7 +5,7 @@ package io.mockk.proxy.android.advice -import io.mockk.boxedValue +import io.mockk.core.ValueClassSupport.boxedValue import io.mockk.proxy.MockKAgentException import io.mockk.proxy.android.AndroidMockKMap import io.mockk.proxy.android.MethodDescriptor diff --git a/modules/mockk-agent/api/mockk-agent.api b/modules/mockk-agent/api/mockk-agent.api index f6faa7f05..a29884c89 100644 --- a/modules/mockk-agent/api/mockk-agent.api +++ b/modules/mockk-agent/api/mockk-agent.api @@ -1,8 +1,3 @@ -public final class io/mockk/ValueClassSupportKt { - public static final fun getBoxedClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass; - public static final fun getBoxedValue (Ljava/lang/Object;)Ljava/lang/Object; -} - public class io/mockk/proxy/jvm/ClassLoadingStrategyChooser { public fun ()V public static fun chooseClassLoadingStrategy (Ljava/lang/Class;)Lnet/bytebuddy/dynamic/loading/ClassLoadingStrategy; diff --git a/modules/mockk-agent/build.gradle.kts b/modules/mockk-agent/build.gradle.kts index a660bc601..f97c3058a 100644 --- a/modules/mockk-agent/build.gradle.kts +++ b/modules/mockk-agent/build.gradle.kts @@ -24,6 +24,7 @@ kotlin { dependencies { api(projects.modules.mockkAgentApi) implementation(kotlin("reflect")) + implementation(projects.modules.mockkCore) } } val commonTest by getting { diff --git a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/ValueClassSupport.kt b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/ValueClassSupport.kt deleted file mode 100644 index b139cd1b6..000000000 --- a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/ValueClassSupport.kt +++ /dev/null @@ -1,68 +0,0 @@ -package io.mockk - -import kotlin.reflect.KClass -import kotlin.reflect.KProperty1 -import kotlin.reflect.full.declaredMemberProperties -import kotlin.reflect.jvm.internal.KotlinReflectionInternalError -import kotlin.reflect.jvm.isAccessible -import kotlin.reflect.jvm.javaField - -// TODO this class is copy-pasted and should be de-duplicated -// see https://github.com/mockk/mockk/issues/857 - -/** - * Underlying property value of a **`value class`** or self. - * - * The type of the return might also be a `value class`! - */ -val T.boxedValue: Any? - @Suppress("UNCHECKED_CAST") - get() = if (!this::class.isValue_safe) { - this - } else { - (this::class as KClass).boxedProperty.get(this) - } - -/** - * Underlying property class of a **`value class`** or self. - * - * The returned class might also be a `value class`! - */ -val KClass<*>.boxedClass: KClass<*> - get() = if (!this.isValue_safe) { - this - } else { - this.boxedProperty.returnType.classifier as KClass<*> - } - -private val valueClassFieldCache = mutableMapOf, KProperty1>() - -/** - * Underlying property of a **`value class`**. - * - * The underlying property might also be a `value class`! - */ -private val KClass.boxedProperty: KProperty1 - get() = if (!this.isValue_safe) { - throw UnsupportedOperationException("$this is not a value class") - } else { - @Suppress("UNCHECKED_CAST") - valueClassFieldCache.getOrPut(this) { - // value classes always have exactly one property with a backing field - this.declaredMemberProperties.first { it.javaField != null }.apply { isAccessible = true } - } as KProperty1 - } - -/** - * Returns `true` if calling [KClass.isValue] is safe. - * - * (In some instances [KClass.isValue] can throw an exception.) - */ -private val KClass.isValue_safe: Boolean - get() = try { - this.isValue - } catch (_: UnsupportedOperationException) { - false - } catch (_: KotlinReflectionInternalError) { - false - } diff --git a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt index 1ce1673cf..71ee71812 100644 --- a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt +++ b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt @@ -1,6 +1,6 @@ package io.mockk.proxy.jvm.advice -import io.mockk.boxedValue +import io.mockk.core.ValueClassSupport.boxedValue import io.mockk.proxy.MockKInvocationHandler import java.lang.reflect.Method import java.util.concurrent.Callable diff --git a/modules/mockk-core/api/mockk-core.api b/modules/mockk-core/api/mockk-core.api new file mode 100644 index 000000000..e7cebf530 --- /dev/null +++ b/modules/mockk-core/api/mockk-core.api @@ -0,0 +1,6 @@ +public final class io/mockk/core/ValueClassSupport { + public static final field INSTANCE Lio/mockk/core/ValueClassSupport; + public final fun getBoxedClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass; + public final fun getBoxedValue (Ljava/lang/Object;)Ljava/lang/Object; +} + diff --git a/modules/mockk-core/build.gradle.kts b/modules/mockk-core/build.gradle.kts new file mode 100644 index 000000000..305f13417 --- /dev/null +++ b/modules/mockk-core/build.gradle.kts @@ -0,0 +1,39 @@ +import buildsrc.config.Deps + +plugins { + buildsrc.convention.`kotlin-multiplatform` + + buildsrc.convention.`mockk-publishing` +} + +description = "MockK functionality that is used by other MockK modules" + +val mavenName: String by extra("MockK Core") +val mavenDescription: String by extra("${project.description}") + +kotlin { + jvm() + + sourceSets { + val commonMain by getting { + dependencies { + } + } + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + } + } + val jvmMain by getting { + dependencies { + implementation(kotlin("reflect")) + } + } + val jvmTest by getting { + dependencies { + implementation(kotlin("test-junit5")) + implementation(Deps.Libs.junitJupiter) + } + } + } +} diff --git a/modules/mockk-core/src/commonMain/kotlin/io/mockk/core/ValueClassSupport.kt b/modules/mockk-core/src/commonMain/kotlin/io/mockk/core/ValueClassSupport.kt new file mode 100644 index 000000000..c5b50db58 --- /dev/null +++ b/modules/mockk-core/src/commonMain/kotlin/io/mockk/core/ValueClassSupport.kt @@ -0,0 +1,22 @@ +package io.mockk.core + +import kotlin.reflect.KClass + + +expect object ValueClassSupport { + + /** + * Underlying property value of a **`value class`** or self. + * + * The type of the return might also be a `value class`! + */ + val T.boxedValue: Any? + + /** + * Underlying property class of a **`value class`**, or self. + * + * The result might also be a value class! So check recursively, if necessary. + */ + val KClass<*>.boxedClass: KClass<*> + +} diff --git a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/ValueClassSupportDsl.kt b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/core/ValueClassSupport.kt similarity index 82% rename from modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/ValueClassSupportDsl.kt rename to modules/mockk-core/src/jvmMain/kotlin/io/mockk/core/ValueClassSupport.kt index 9ad287209..797926d90 100644 --- a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/ValueClassSupportDsl.kt +++ b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/core/ValueClassSupport.kt @@ -1,26 +1,21 @@ -package io.mockk +package io.mockk.core import kotlin.reflect.KClass import kotlin.reflect.KProperty1 import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.full.primaryConstructor import kotlin.reflect.jvm.isAccessible import kotlin.reflect.jvm.javaField -/** - * Provides value class support in the `mockk-dsl-jvm` subproject. - * - * This is marked as internal so that it won't clash with the other class in `mockk-agent-jvm`. - * - * TODO this class is copy-pasted and should be de-duplicated, see https://github.com/mockk/mockk/issues/857 - */ -internal object ValueClassSupportDsl { + +actual object ValueClassSupport { /** * Underlying property value of a **`value class`** or self. * * The type of the return might also be a `value class`! */ - val T.boxedValue: Any? + actual val T.boxedValue: Any? @Suppress("UNCHECKED_CAST") get() = if (!this::class.isValue_safe) { this @@ -33,7 +28,7 @@ internal object ValueClassSupportDsl { * * The returned class might also be a `value class`! */ - val KClass<*>.boxedClass: KClass<*> + actual val KClass<*>.boxedClass: KClass<*> get() = if (!this.isValue_safe) { this } else { @@ -69,4 +64,5 @@ internal object ValueClassSupportDsl { } catch (_: UnsupportedOperationException) { false } + } diff --git a/modules/mockk-dsl/api/mockk-dsl.api b/modules/mockk-dsl/api/mockk-dsl.api index 10ced70e5..cecd93fc8 100644 --- a/modules/mockk-dsl/api/mockk-dsl.api +++ b/modules/mockk-dsl/api/mockk-dsl.api @@ -326,7 +326,6 @@ public final class io/mockk/InternalPlatformDsl { public final fun toArray (Ljava/lang/Object;)[Ljava/lang/Object; public final fun toStr (Ljava/lang/Object;)Ljava/lang/String; public final fun unboxChar (Ljava/lang/Object;)Ljava/lang/Object; - public final fun unboxClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass; } public abstract interface class io/mockk/InternalRef { diff --git a/modules/mockk-dsl/build.gradle.kts b/modules/mockk-dsl/build.gradle.kts index 4324bd3cf..b1007d768 100644 --- a/modules/mockk-dsl/build.gradle.kts +++ b/modules/mockk-dsl/build.gradle.kts @@ -20,6 +20,7 @@ kotlin { implementation(dependencies.platform(Deps.Libs.kotlinCoroutinesBom)) implementation(Deps.Libs.kotlinCoroutinesCore) implementation(kotlin("reflect")) + implementation(projects.modules.mockkCore) } } val commonTest by getting { diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt index defebb02a..0378e1a0e 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt @@ -4,9 +4,9 @@ package io.mockk import io.mockk.InternalPlatformDsl.toStr import io.mockk.MockKGateway.* +import io.mockk.core.ValueClassSupport.boxedClass import kotlin.coroutines.Continuation import kotlin.reflect.KClass -import io.mockk.* /** * Exception thrown by library @@ -536,14 +536,14 @@ object MockKDsl { inline fun internalUnmockkConstructor(vararg classes: KClass<*>) { classes.forEach { MockKGateway.implementation().constructorMockFactory.clear( - it, - MockKGateway.ClearOptions( - answers = true, - recordedCalls = true, - childMocks = true, - verificationMarks = true, - exclusionRules = true - ) + it, + MockKGateway.ClearOptions( + answers = true, + recordedCalls = true, + childMocks = true, + verificationMarks = true, + exclusionRules = true + ) ) MockKCancellationRegistry .subRegistry(MockKCancellationRegistry.Type.CONSTRUCTOR) @@ -3553,7 +3553,7 @@ interface TypedMatcher { return when { argumentType.simpleName === null -> true else -> { - val unboxedClass = InternalPlatformDsl.unboxClass(argumentType) + val unboxedClass = argumentType.boxedClass return unboxedClass.isInstance(arg) } } diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt index 461c3247d..d461ba618 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -37,22 +37,13 @@ expect object InternalPlatformDsl { fun coroutineCall(lambda: suspend () -> T): CoroutineCall - /** - * Get the [KClass] of the single value that a `value class` contains. - * - * The result might also be a value class! So check recursively, if necessary. - * - * @return [KClass] of boxed value, if this is `value class`, else [cls]. - */ - internal fun unboxClass(cls: KClass<*>): KClass<*> - /** * Normally this simply casts [arg] to `T` * * However, if `T` is a `value class` (of type [cls]) this will construct a new instance of the * value class, and set [arg] as the value. */ - internal fun boxCast( + internal fun boxCast( cls: KClass<*>, arg: Any, ): T diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt index 100cad605..9a8e49981 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt @@ -56,7 +56,7 @@ data class FunctionMatcher( override fun equivalent(): Matcher = ConstantMatcher(true) override fun match(arg: T?): Boolean { - return if(arg == null) { + return if (arg == null) { false } else { try { @@ -79,7 +79,7 @@ data class FunctionWithNullableArgMatcher( override fun match(arg: T?): Boolean = matchingFunc(arg) override fun checkType(arg: Any?): Boolean { - if(arg == null) { + if (arg == null) { return true } @@ -125,7 +125,7 @@ data class CaptureNullableMatcher( override fun match(arg: T?): Boolean = true override fun checkType(arg: Any?): Boolean { - if(arg == null) { + if (arg == null) { return true } diff --git a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt index 7ad64fc0f..0bcb6d982 100644 --- a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -1,27 +1,21 @@ package io.mockk -import io.mockk.ValueClassSupportDsl.boxedClass +import kotlinx.coroutines.runBlocking import java.lang.reflect.AccessibleObject import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method import java.util.concurrent.atomic.AtomicLong import kotlin.coroutines.Continuation -import kotlin.reflect.KClass -import kotlin.reflect.KFunction -import kotlin.reflect.KMutableProperty1 -import kotlin.reflect.KProperty1 -import kotlin.reflect.KType -import kotlin.reflect.KTypeParameter +import kotlin.reflect.* import kotlin.reflect.full.allSuperclasses -import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.full.functions import kotlin.reflect.full.memberProperties import kotlin.reflect.full.primaryConstructor import kotlin.reflect.jvm.isAccessible import kotlin.reflect.jvm.javaMethod -import kotlinx.coroutines.runBlocking actual object InternalPlatformDsl { + actual fun identityHashCode(obj: Any): Int = System.identityHashCode(obj) actual fun runCoroutine(block: suspend () -> T): T { @@ -128,8 +122,10 @@ actual object InternalPlatformDsl { return@firstOrNull true } - ?: throw MockKException("can't find function $methodName(${args.joinToString(", ")}) of class ${self.javaClass.name} for dynamic call.\n" + - "If you were trying to verify a private function, make sure to provide type information to exactly match the functions signature.") + ?: throw MockKException( + "can't find function $methodName(${args.joinToString(", ")}) of class ${self.javaClass.name} for dynamic call.\n" + + "If you were trying to verify a private function, make sure to provide type information to exactly match the functions signature." + ) func.javaMethod?.let { makeAccessible(it) } return if (func.isSuspend) { @@ -218,8 +214,6 @@ actual object InternalPlatformDsl { actual fun coroutineCall(lambda: suspend () -> T): CoroutineCall = JvmCoroutineCall(lambda) - actual fun unboxClass(cls: KClass<*>): KClass<*> = cls.boxedClass - @Suppress("UNCHECKED_CAST") internal actual fun boxCast( cls: KClass<*>, diff --git a/modules/mockk/build.gradle.kts b/modules/mockk/build.gradle.kts index d672d1387..7c53e65ad 100644 --- a/modules/mockk/build.gradle.kts +++ b/modules/mockk/build.gradle.kts @@ -22,6 +22,7 @@ kotlin { api(projects.modules.mockkDsl) api(projects.modules.mockkAgent) api(projects.modules.mockkAgentApi) + api(projects.modules.mockkCore) implementation(dependencies.platform(Deps.Libs.kotlinCoroutinesBom)) implementation(Deps.Libs.kotlinCoroutinesCore) diff --git a/modules/mockk/src/commonMain/kotlin/io/mockk/impl/annotations/MockK.kt b/modules/mockk/src/commonMain/kotlin/io/mockk/impl/annotations/MockK.kt index 737730e86..c7a3d5cf1 100644 --- a/modules/mockk/src/commonMain/kotlin/io/mockk/impl/annotations/MockK.kt +++ b/modules/mockk/src/commonMain/kotlin/io/mockk/impl/annotations/MockK.kt @@ -25,4 +25,4 @@ annotation class MockK( val name: String = "", val relaxed: Boolean = false, val relaxUnitFun: Boolean = false -) \ No newline at end of file +) diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt index 4b2dc598a..b5cf10450 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt @@ -3,16 +3,15 @@ package io.mockk.impl import io.mockk.InternalPlatformDsl import io.mockk.MockKException import io.mockk.StackElement -import io.mockk.boxedClass -import io.mockk.boxedValue import io.mockk.impl.platform.CommonIdentityHashMapOf import io.mockk.impl.platform.CommonRef import io.mockk.impl.platform.JvmWeakConcurrentMap +import io.mockk.core.ValueClassSupport.boxedClass +import io.mockk.core.ValueClassSupport.boxedValue import java.lang.ref.WeakReference import java.lang.reflect.Modifier -import java.util.Collections +import java.util.* import java.util.Collections.synchronizedList -import java.util.Locale import kotlin.reflect.KClass import kotlin.reflect.full.cast @@ -83,6 +82,7 @@ actual object InternalPlatform { "test {\n" + " jvmArgs '-XX:-OmitStackTraceInFastThrow'\n" + "}" + else -> "Class cast exception happened.\n" + "Probably type information was erased.\n" + "In this case use `hint` before call to specify " + diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt index b08b9250d..06a82a767 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt @@ -3,6 +3,7 @@ package io.mockk.impl.instantiation import io.mockk.* import io.mockk.impl.InternalPlatform import io.mockk.impl.stub.Stub +import io.mockk.core.ValueClassSupport.boxedClass import io.mockk.proxy.MockKInvocationHandler import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method @@ -127,6 +128,7 @@ object JvmMockFactoryHelper { val returnTypeIsUnit = when { kotlinFunc != null -> kotlinFunc.returnType.toString() == "kotlin.Unit" + else -> returnType == Void.TYPE } diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt index 6428d98e7..20a0278e2 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt @@ -1,9 +1,9 @@ package io.mockk.impl.recording -import io.mockk.InternalPlatformDsl import io.mockk.impl.instantiation.AbstractInstantiator import io.mockk.impl.instantiation.AnyValueGenerator -import java.util.Random +import io.mockk.core.ValueClassSupport.boxedClass +import java.util.* import kotlin.reflect.KClass import kotlin.reflect.full.cast import kotlin.reflect.full.primaryConstructor @@ -17,7 +17,7 @@ class JvmSignatureValueGenerator(val rnd: Random) : SignatureValueGenerator { ): T { if (cls.isValue) { - val valueCls = InternalPlatformDsl.unboxClass(cls) + val valueCls = cls.boxedClass val valueSig = signatureValue(valueCls, anyValueGeneratorProvider, instantiator) val constructor = cls.primaryConstructor!!.apply { isAccessible = true } diff --git a/settings.gradle.kts b/settings.gradle.kts index d53d10207..e291ec322 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,6 +14,7 @@ include( ":modules:mockk", ":modules:mockk-agent-api", ":modules:mockk-agent", + ":modules:mockk-core", ":modules:mockk-dsl", ":test-modules:client-tests",