1 /* 2 * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.coroutines.test 6 7 import kotlinx.atomicfu.* 8 import kotlin.test.* 9 import kotlin.time.* 10 import kotlin.time.Duration.Companion.seconds 11 12 /** 13 * The number of milliseconds that is sure not to pass [assertRunsFast]. 14 */ 15 const val SLOW = 100_000L 16 17 /** 18 * Asserts that a block completed within [timeout]. 19 */ 20 @OptIn(ExperimentalTime::class) assertRunsFastnull21inline fun <T> assertRunsFast(timeout: Duration, block: () -> T): T { 22 val result: T 23 val elapsed = TimeSource.Monotonic.measureTime { result = block() } 24 assertTrue("Should complete in $timeout, but took $elapsed") { elapsed < timeout } 25 return result 26 } 27 28 /** 29 * Asserts that a block completed within two seconds. 30 */ assertRunsFastnull31inline fun <T> assertRunsFast(block: () -> T): T = assertRunsFast(2.seconds, block) 32 33 /** 34 * Passes [test] as an argument to [block], but as a function returning not a [TestResult] but [Unit]. 35 */ 36 expect fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult): TestResult 37 38 class TestException(message: String? = null): Exception(message) 39 40 /** 41 * A class inheriting from which allows to check the execution order inside tests. 42 * 43 * @see TestBase 44 */ 45 open class OrderedExecutionTestBase { 46 private val actionIndex = atomic(0) 47 private val finished = atomic(false) 48 49 /** Expect the next action to be [index] in order. */ 50 protected fun expect(index: Int) { 51 val wasIndex = actionIndex.incrementAndGet() 52 check(index == wasIndex) { "Expecting action index $index but it is actually $wasIndex" } 53 } 54 55 /** Expect this action to be final, with the given [index]. */ 56 protected fun finish(index: Int) { 57 expect(index) 58 check(!finished.getAndSet(true)) { "Should call 'finish(...)' at most once" } 59 } 60 61 @AfterTest 62 fun ensureFinishCalls() { 63 assertTrue(finished.value || actionIndex.value == 0, "Expected `finish` to be called") 64 } 65 } 66 voidnull67internal fun <T> T.void() { } 68 69 @OptionalExpectation 70 expect annotation class NoJs() 71 72 @OptionalExpectation 73 expect annotation class NoNative() 74