Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-core/js/test/TestBase.kt (Kotlin)

Code before:
/*
 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.coroutines

import kotlin.js.*

public actual val isStressTest: Boolean = false
public actual val stressTestMultiplier: Int = 1

public actual open class TestBase actual constructor() {
    public actual val isJs = true
    private var actionIndex = 0
    private var finished = false
    private var error: Throwable? = null
    private var lastTestPromise: Promise<*>? = null

    /**
     * Throws [IllegalStateException] like `error` in stdlib, but also ensures that the test will not
     * complete successfully even if this exception is consumed somewhere in the test.
     */
    @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
    public actual fun error(message: Any, cause: Throwable? = null): Nothing {
        if (cause != null) console.log(cause)
        val exception = IllegalStateException(
            if (cause == null) message.toString() else "$message; caused by $cause")
        if (error == null) error = exception
        throw exception
    }

    private fun printError(message: String, cause: Throwable) {
        if (error == null) error = cause
        println("$message: $cause")
        console.log(cause)
    }

    /**

Review comment (suggestion):
I strongly dislike the name of this flag.

Consider the following scenario: we learn that there's no longer a two-second timeout on JS (also, where does the timeout come from?). However, it doesn't give us a clear indication to change anything about these tests: `isJs` should still be true. Instead, we're supposed to go looking through the tests to find those that are affected by the timeout no longer being there.

As an alternative, there's a much worse-sounding but, in my opinion, the more accurate name `timesOutAfterTwoSeconds` or something like this. This is what distinguishes the JS platform currently, this is what tests check for, the documentation for it is the place that could explain where the timeout comes from.

Code after:
/*
 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.coroutines

import kotlin.js.*

public actual val isStressTest: Boolean = false
public actual val stressTestMultiplier: Int = 1

public actual open class TestBase actual constructor() {
    public actual val isBoundByJsTestTimeout = true
    private var actionIndex = 0
    private var finished = false
    private var error: Throwable? = null
    private var lastTestPromise: Promise<*>? = null

    /**
     * Throws [IllegalStateException] like `error` in stdlib, but also ensures that the test will not
     * complete successfully even if this exception is consumed somewhere in the test.
     */
    @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
    public actual fun error(message: Any, cause: Throwable? = null): Nothing {
        if (cause != null) console.log(cause)
        val exception = IllegalStateException(
            if (cause == null) message.toString() else "$message; caused by $cause")
        if (error == null) error = exception
        throw exception
    }

    private fun printError(message: String, cause: Throwable) {
        if (error == null) error = cause
        println("$message: $cause")
        console.log(cause)
    }

    /**