-
-
Notifications
You must be signed in to change notification settings - Fork 331
/
JvmSignatureValueGenerator.kt
57 lines (50 loc) · 2.11 KB
/
JvmSignatureValueGenerator.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package io.mockk.impl.recording
import io.mockk.impl.instantiation.AbstractInstantiator
import io.mockk.impl.instantiation.AnyValueGenerator
import io.mockk.core.ValueClassSupport.boxedClass
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.full.cast
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.isAccessible
class JvmSignatureValueGenerator(val rnd: Random) : SignatureValueGenerator {
override fun <T : Any> signatureValue(
cls: KClass<T>,
anyValueGeneratorProvider: () -> AnyValueGenerator,
instantiator: AbstractInstantiator,
): T {
if (cls.isValue) {
val valueCls = cls.boxedClass
val valueSig = signatureValue(valueCls, anyValueGeneratorProvider, instantiator)
val constructor = cls.primaryConstructor!!.apply { isAccessible = true }
return constructor.call(valueSig)
}
return cls.cast(instantiate(cls, anyValueGeneratorProvider, instantiator))
}
private fun <T : Any> instantiate(
cls: KClass<T>,
anyValueGeneratorProvider: () -> AnyValueGenerator,
instantiator: AbstractInstantiator
): Any = when (cls) {
Boolean::class -> rnd.nextBoolean()
Byte::class -> rnd.nextInt().toByte()
Short::class -> rnd.nextInt().toShort()
Character::class -> rnd.nextInt().toChar()
Integer::class -> rnd.nextInt()
Long::class -> rnd.nextLong()
Float::class -> rnd.nextFloat()
Double::class -> rnd.nextDouble()
String::class -> rnd.nextLong().toString(16)
else ->
if (cls.isSealed) {
cls.sealedSubclasses.firstNotNullOfOrNull {
instantiate(it, anyValueGeneratorProvider, instantiator)
} ?: error("Unable to create proxy for sealed class $cls, available subclasses: ${cls.sealedSubclasses}")
} else {
@Suppress("UNCHECKED_CAST")
anyValueGeneratorProvider().anyValue(cls, isNullable = false) {
instantiator.instantiate(cls)
} as T
}
}
}