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

commonTest.CancellableContinuationTest.kt Maven / Gradle / Ivy

There is a newer version: 1.9.0
Show newest version
/*
 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */
@file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913

package kotlinx.coroutines

import kotlin.coroutines.*
import kotlin.test.*

class CancellableContinuationTest : TestBase() {
    @Test
    fun testResumeWithExceptionAndResumeWithException() = runTest {
        var continuation: Continuation? = null
        val job = launch {
            try {
                expect(2)
                suspendCancellableCoroutine { c ->
                    continuation = c
                }
            } catch (e: TestException) {
                expect(3)
            }
        }
        expect(1)
        yield()
        continuation!!.resumeWithException(TestException())
        yield()
        assertFailsWith { continuation!!.resumeWithException(TestException()) }
        job.join()
        finish(4)
    }

    @Test
    fun testResumeAndResumeWithException() = runTest {
        var continuation: Continuation? = null
        val job = launch {
            expect(2)
            suspendCancellableCoroutine { c ->
                continuation = c
            }
            expect(3)
        }
        expect(1)
        yield()
        continuation!!.resume(Unit)
        job.join()
        assertFailsWith { continuation!!.resumeWithException(TestException()) }
        finish(4)
    }

    @Test
    fun testResumeAndResume() = runTest {
        var continuation: Continuation? = null
        val job = launch {
            expect(2)
            suspendCancellableCoroutine { c ->
                continuation = c
            }
            expect(3)
        }
        expect(1)
        yield()
        continuation!!.resume(Unit)
        job.join()
        assertFailsWith { continuation!!.resume(Unit) }
        finish(4)
    }

    /**
     * Cancelling outer job may, in practise, race with attempt to resume continuation and resumes
     * should be ignored. Here suspended coroutine is cancelled but then resumed with exception.
     */
    @Test
    fun testCancelAndResumeWithException() = runTest {
        var continuation: Continuation? = null
        val job = launch {
            try {
                expect(2)
                suspendCancellableCoroutine { c ->
                    continuation = c
                }
            } catch (e: CancellationException) {
                expect(3)
            }
        }
        expect(1)
        yield()
        job.cancel() // Cancel job
        yield()
        continuation!!.resumeWithException(TestException()) // Should not fail
        finish(4)
    }

    /**
     * Cancelling outer job may, in practise, race with attempt to resume continuation and resumes
     * should be ignored. Here suspended coroutine is cancelled but then resumed with exception.
     */
    @Test
    fun testCancelAndResume() = runTest {
        var continuation: Continuation? = null
        val job = launch {
            try {
                expect(2)
                suspendCancellableCoroutine { c ->
                    continuation = c
                }
            } catch (e: CancellationException) {
                expect(3)
            }
        }
        expect(1)
        yield()
        job.cancel() // Cancel job
        yield()
        continuation!!.resume(Unit) // Should not fail
        finish(4)
    }

    @Test
    fun testCompleteJobWhileSuspended() = runTest {
        expect(1)
        val completableJob = Job()
        val coroutineBlock = suspend {
            assertFailsWith {
                suspendCancellableCoroutine { cont ->
                    expect(2)
                    assertSame(completableJob, cont.context[Job])
                    completableJob.complete()
                }
                expectUnreached()
            }
            expect(3)
        }
        coroutineBlock.startCoroutine(Continuation(completableJob) {
            assertEquals(Unit, it.getOrNull())
            expect(4)
        })
        finish(5)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy