ru.fix.corounit.allure.StepMethodWrapper.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of corounit-allure Show documentation
Show all versions of corounit-allure Show documentation
https://github.com/ru-fix/corounit
package ru.fix.corounit.allure
import java.lang.reflect.Method
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.reflect.KParameter
import kotlin.reflect.jvm.kotlinFunction
class StepMethodWrapper(
private val originMethod: Method,
private val originArgs: Array) {
private val newArgs: Array
private val methodAllureStep: AllureStep?
private val originContinuation: Continuation?
init {
originContinuation = originArgs.findLast { it is Continuation<*> } as? Continuation
if (originContinuation == null){
newArgs = originArgs
methodAllureStep = null
} else {
val parentStep = AllureStep.tryFromCoroutineContext(originContinuation.context)
if(parentStep == null){
newArgs = originArgs
methodAllureStep = null
} else {
val parameterNames = originMethod.kotlinFunction?.parameters
?.filter { it.kind == KParameter.Kind.VALUE }
?.map { it.name }
?: originMethod.parameters.map { it.name }
val title = "" +
originMethod.name + " " +
parameterNames
.zip(originArgs)
.map { (name, arg) -> "$name: $arg" }
.joinToString(prefix = "(", separator = ", ", postfix = ")")
val childCoroutineContext = parentStep.startChildStepWithCoroutineContext(title, originContinuation.context)
methodAllureStep = AllureStep.fromCoroutineContext(childCoroutineContext)
newArgs = originArgs.copyOf()
if (!isMethodInvokedRecursivelyWithItsInnerContinuation()) {
newArgs[newArgs.lastIndex] = object : Continuation {
override val context: CoroutineContext
get() = childCoroutineContext
override fun resumeWith(result: Result) {
methodAllureStep.stop()
originContinuation.resumeWith(result)
}
}
}
}
}
}
private fun isMethodInvokedRecursivelyWithItsInnerContinuation() =
originContinuation?.javaClass?.enclosingClass?.name ==
originMethod.declaringClass.name
fun wrappedInvoke(originalMethodInvocation: (newArgs: Array) -> Any?): Any? {
try {
val result = originalMethodInvocation(newArgs)
if (result != kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED) {
methodAllureStep?.stop()
}
return result
} catch (thr: Throwable) {
methodAllureStep?.stop(thr)
throw thr
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy