All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.kotlinx.rpc.krpc.test.KRPCTestServiceBackend.kt Maven / Gradle / Ivy

/*
 * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.rpc.krpc.test

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.serialization.Serializable
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.resumeWithException
import kotlin.test.assertEquals

@OptIn(ExperimentalCoroutinesApi::class)
class KRPCTestServiceBackend(override val coroutineContext: CoroutineContext) : KRPCTestService {
    companion object {
        const val SHARED_FLOW_REPLAY = 5
    }

    override suspend fun empty() {
        println("empty")
    }

    override suspend fun returnType(): String {
        return "test"
    }

    override suspend fun simpleWithParams(name: String): String {
        return name.reversed()
    }

    override suspend fun genericReturnType(): List {
        return listOf("hello", "world")
    }

    override suspend fun doubleGenericReturnType(): List> {
        return listOf(listOf("1", "2"), listOf("a", "b"))
    }

    override suspend fun paramsSingle(arg1: String) {
        println("SINGLE: $arg1")
    }

    override suspend fun paramsDouble(arg1: String, arg2: String) {
        println("double $arg1 $arg2")
    }

    override suspend fun varargParams(arg1: String, vararg arg2: String) {
        println("vararg $arg1 ${arg2.joinToString()}")
    }

    override suspend fun genericParams(arg1: List) {
        println("Received list: ${arg1.joinToString()}")
    }

    override suspend fun doubleGenericParams(arg1: List>) {
        println("Received list of lists: ${arg1.joinToString { it.joinToString() }} }}")
    }

    @Suppress("detekt.MaxLineLength")
    override suspend fun mapParams(arg1: Map>>) {
        println("Received map: ${arg1.entries.joinToString { "${it.key} -> ${it.value.entries.joinToString { (key, value) -> "$key -> ${value.joinToString()}" }}" }}")
    }

    override suspend fun customType(arg1: TestClass): TestClass {
        return arg1
    }

    override suspend fun nullable(arg1: String?): TestClass? {
        println("nullable $arg1")
        return if (arg1 == null) null else TestClass()
    }

    override suspend fun variance(
        arg2: TestList,
        arg3: TestList2<*>
    ): TestList {
        println("variance: $arg2 $arg3")
        return TestList(3)
    }

    override suspend fun incomingStreamSyncCollect(arg1: Flow): Int {
        return arg1.count()
    }

    @OptIn(DelicateCoroutinesApi::class)
    override suspend fun incomingStreamAsyncCollect(arg1: Flow): Int {
        @Suppress("detekt.GlobalCoroutineUsage")
        GlobalScope.launch {
            arg1.collect { println("incomingStreamAsyncCollect item $it") }
        }
        return 5
    }

    override suspend fun outgoingStream(): Flow {
        return flow { emit("a"); emit("b"); emit("c") }
    }

    override suspend fun bidirectionalStream(arg1: Flow): Flow {
        return arg1.map { it.reversed() }
    }

    override suspend fun echoStream(arg1: Flow): Flow = flow {
        arg1.collect {
            emit(it)
        }
    }

    override suspend fun streamInDataClass(payloadWithStream: PayloadWithStream): Int {
        return payloadWithStream.payload.length + payloadWithStream.stream.count()
    }

    // necessary for older Kotlin versions
    @Suppress("UnnecessaryOptInAnnotation")
    @OptIn(FlowPreview::class)
    override suspend fun streamInStream(payloadWithStream: Flow): Int {
        return payloadWithStream.flatMapConcat { it.stream }.count()
    }

    override suspend fun streamOutDataClass(): PayloadWithStream {
        return payload()
    }

    override suspend fun streamOfStreamsInReturn(): Flow> {
        return flow {
            emit(flow { emit("a"); emit("b"); emit("c") })
            emit(flow { emit("1"); emit("2"); emit("3") })
        }
    }

    override suspend fun streamOfPayloadsInReturn(): Flow {
        return payloadStream()
    }

    override suspend fun streamInDataClassWithStream(payloadWithPayload: PayloadWithPayload): Int {
        payloadWithPayload.collectAndPrint()
        return 5
    }

    override suspend fun streamInStreamWithStream(payloadWithPayload: Flow): Int {
        payloadWithPayload.collect {
            it.collectAndPrint()
        }
        return 5
    }

    override suspend fun returnPayloadWithPayload(): PayloadWithPayload {
        return payloadWithPayload()
    }

    override suspend fun returnFlowPayloadWithPayload(): Flow {
        return payloadWithPayloadStream()
    }

    override suspend fun bidirectionalFlowOfPayloadWithPayload(
        payloadWithPayload: Flow
    ): Flow {
        return payloadWithPayload
    }

    override suspend fun getNInts(n: Int): Flow {
        return flow {
            for (it in 1..n) {
                emit(it)
            }
        }
    }

    override suspend fun getNIntsBatched(n: Int): Flow> {
        return flow {
            for (it in (1..n).chunked(1000)) {
                emit(it)
            }
        }
    }

    @Suppress("detekt.EmptyFunctionBlock")
    override suspend fun bytes(byteArray: ByteArray) { }

    @Suppress("detekt.EmptyFunctionBlock")
    override suspend fun nullableBytes(byteArray: ByteArray?) { }

    @Suppress("detekt.TooGenericExceptionThrown")
    override suspend fun throwsIllegalArgument(message: String) {
        throw IllegalArgumentException(message)
    }

    @Serializable
    class SerializableTestException(
        override val message: String?,
        override val cause: SerializableTestException? = null,
    ) : Exception()

    override suspend fun throwsSerializableWithMessageAndCause(message: String) {
        throw SerializableTestException(message, SerializableTestException("cause: $message"))
    }

    @Suppress("detekt.TooGenericExceptionThrown")
    override suspend fun throwsThrowable(message: String) {
        throw Throwable(message)
    }

    override suspend fun throwsUNSTOPPABLEThrowable(message: String) {
        suspendCancellableCoroutine { continuation ->
            Thread {
                continuation.resumeWithException(Throwable(message))
            }.start()
        }
    }

    override suspend fun nullableInt(v: Int?): Int? = v
    override suspend fun nullableList(v: List?): List? = v

    override suspend fun delayForever(): Flow = flow {
        emit(true)
        delay(Int.MAX_VALUE.toLong())
    }

    override suspend fun answerToAnything(arg: String): Int {
        println("Return 42")
        return 42
    }

    override val plainFlowOfInts: Flow = plainFlow { it }

    override val plainFlowOfFlowsOfInts: Flow> = plainFlow { plainFlow { i -> i } }

    override val plainFlowOfFlowsOfFlowsOfInts: Flow>> = plainFlow { plainFlow { plainFlow { i -> i } } }

    override val sharedFlowOfInts: SharedFlow =
        sharedFlowOfT { it }

    override val sharedFlowOfFlowsOfInts: SharedFlow> =
        sharedFlowOfT { sharedFlowOfT { it } }

    override val sharedFlowOfFlowsOfFlowsOfInts: SharedFlow>> =
        sharedFlowOfT { sharedFlowOfT { sharedFlowOfT { it } } }

    override val stateFlowOfInts: MutableStateFlow =
        stateFlowOfT { it }

    override val stateFlowOfFlowsOfInts: MutableStateFlow> =
        stateFlowOfT { stateFlowOfT { it } }

    override val stateFlowOfFlowsOfFlowsOfInts: MutableStateFlow>> =
        stateFlowOfT { stateFlowOfT { stateFlowOfT { it } } }

    override suspend fun emitNextForStateFlowOfInts(value: Int) {
        stateFlowOfInts.emit(value)
    }

    override suspend fun emitNextForStateFlowOfFlowsOfInts(value: Int) {
        stateFlowOfFlowsOfInts.value.emit(value)
        stateFlowOfFlowsOfInts.emit(MutableStateFlow(value))
    }

    override suspend fun emitNextForStateFlowOfFlowsOfFlowsOfInts(value: Int) {
        stateFlowOfFlowsOfFlowsOfInts.value.value.emit(value)
        stateFlowOfFlowsOfFlowsOfInts.value.emit(MutableStateFlow(value))
        stateFlowOfFlowsOfFlowsOfInts.emit(MutableStateFlow(MutableStateFlow(value)))
    }

    override suspend fun sharedFlowInFunction(sharedFlow: SharedFlow): StateFlow {
        val state = MutableStateFlow(-1)

        launch {
            assertEquals(listOf(0, 1, 2, 3, 4), sharedFlow.take(5).toList())
            println("hello 1")
            state.emit(1)
            println("hello 2")
        }

        return state
    }

    override suspend fun stateFlowInFunction(stateFlow: StateFlow): StateFlow {
        val state = MutableStateFlow(-1)
        assertEquals(-1, stateFlow.value)

        launch {
            assertEquals(42, stateFlow.first { it == 42 })
            state.emit(1)
        }

        return state
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy