blob: f79ad4ba748198feb30a837ff0d87a5ae7047e01 [file] [log] [blame]
package kotlinx.coroutines.exceptions
import kotlinx.coroutines.*
import java.io.*
import kotlin.test.*
public fun verifyStackTrace(e: Throwable, vararg traces: String) {
val stacktrace = toStackTrace(e)
val normalizedActual = stacktrace.normalizeStackTrace()
traces.forEach {
val normalizedExpected = it.normalizeStackTrace()
if (!normalizedActual.contains(normalizedExpected)) {
// A more readable error message would be produced by assertEquals
assertEquals(normalizedExpected, normalizedActual, "Actual trace does not contain expected one")
}
}
// Check "Caused by" counts
val causes = stacktrace.count("Caused by")
assertNotEquals(0, causes)
assertEquals(traces.map { it.count("Caused by") }.sum(), causes)
}
public fun verifyStackTrace(path: String, e: Throwable) {
val resource = Job::class.java.classLoader.getResourceAsStream("stacktraces/$path.txt")
val lines = resource.reader().readLines()
verifyStackTrace(e, *lines.toTypedArray())
}
public fun toStackTrace(t: Throwable): String {
val sw = StringWriter() as Writer
t.printStackTrace(PrintWriter(sw))
return sw.toString()
}
public fun String.normalizeStackTrace(): String =
applyBackspace()
.replace(Regex(":[0-9]+"), "") // remove line numbers
.replace("kotlinx_coroutines_core_main", "") // yay source sets
.replace("kotlinx_coroutines_core", "")
.replace(Regex("@[0-9a-f]+"), "") // remove hex addresses in debug toStrings
.lines().joinToString("\n") // normalize line separators
public fun String.applyBackspace(): String {
val array = toCharArray()
val stack = CharArray(array.size)
var stackSize = -1
for (c in array) {
if (c != '\b') {
stack[++stackSize] = c
} else {
--stackSize
}
}
return String(stack, 0, stackSize)
}
public fun String.count(substring: String): Int = split(substring).size - 1