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 58 59 60
|
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package test.coroutines
import test.assertStaticAndRuntimeTypeIs
import kotlin.test.*
import kotlin.coroutines.experimental.*
/**
* Test to ensure that coroutine machinery does not call equals/hashCode/toString anywhere.
*/
class CoroutinesReferenceValuesTest {
class BadClass {
override fun equals(other: Any?): Boolean = error("equals")
override fun hashCode(): Int = error("hashCode")
override fun toString(): String = error("toString")
}
var counter = 0
// tail-suspend function via suspendCoroutine (test SafeContinuation)
suspend fun getBadClassViaSuspend(): BadClass = suspendCoroutine { cont ->
counter++
cont.resume(BadClass())
}
// state machine
suspend fun checkBadClassTwice() {
assertStaticAndRuntimeTypeIs<BadClass>(getBadClassViaSuspend())
assertStaticAndRuntimeTypeIs<BadClass>(getBadClassViaSuspend())
}
fun <T> suspend(block: suspend () -> T) = block
@Test
fun testBadClass() {
val bad = suspend {
checkBadClassTwice()
getBadClassViaSuspend()
}
var result: BadClass? = null
bad.startCoroutine(object : Continuation<BadClass> {
override val context: CoroutineContext = EmptyCoroutineContext
override fun resume(value: BadClass) {
assertTrue(result == null)
result = value
}
override fun resumeWithException(exception: Throwable) {
throw exception
}
})
assertTrue(result is BadClass)
assertEquals(3, counter)
}
}
|