aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/test/kotlin/utils/TestUtils.kt
blob: 39ac4b231f9ee7426919dd09cb4cc79a4946af53 (plain)
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
 * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package utils

import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.model.doc.P
import kotlin.collections.orEmpty
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import kotlin.test.asserter
import kotlin.test.fail

@DslMarker
annotation class TestDSL

@TestDSL
abstract class ModelDSL : BaseAbstractTest() {
    operator fun Documentable?.div(name: String): Documentable? =
        this?.children?.find { it.name == name }

    inline fun <reified T : Documentable> Documentable?.cast(): T =
        (this as? T).assertNotNull()
}

@TestDSL
interface AssertDSL {
    infix fun Any?.equals(other: Any?) = assertEquals(other, this)
    infix fun Collection<Any>?.allEquals(other: Any?) =
        this?.onEach { it equals other } ?: run { fail("Collection is empty") }
    infix fun <T> Collection<T>?.exists(e: T) {
        assertTrue(this.orEmpty().isNotEmpty(), "Collection cannot be null or empty")
        assertTrue(this!!.any{it == e}, "Collection doesn't contain $e")
    }

    infix fun <T> Collection<T>?.counts(n: Int) = this.orEmpty().assertCount(n)

    infix fun <T> T?.notNull(name: String): T = this.assertNotNull(name)

    fun <T> Collection<T>.assertCount(n: Int, prefix: String = "") =
        assertEquals(n, count(), "${prefix}Expected $n, got ${count()}")
}

/*
 * TODO replace with kotlin.test.assertContains after migrating to Kotlin 1.5+
 */
internal fun <T> assertContains(iterable: Iterable<T>, element: T, ) {
    asserter.assertTrue(
        { "Expected the collection to contain the element.\nCollection <$iterable>, element <$element>." },
        iterable.contains(element)
    )
}

inline fun <reified T : Any> Any?.assertIsInstance(name: String): T =
    this.let { it as? T } ?: throw AssertionError("$name should not be null")

fun TagWrapper.text(): String = when (val t = this) {
    is NamedTagWrapper -> "${t.name}: [${t.root.text()}]"
    else -> t.root.text()
}

fun DocTag.text(): String = when (val t = this) {
    is Text -> t.body
    is Code -> t.children.joinToString("\n") { it.text() }
    is P -> t.children.joinToString("") { it.text() } + "\n"
    else -> t.children.joinToString("") { it.text() }
}

fun <T : Documentable> T?.comments(): String = docs().map { it.text() }
    .joinToString(separator = "\n") { it }

fun <T> T?.assertNotNull(name: String = ""): T = this ?: throw AssertionError("$name should not be null")

fun <T : Documentable> T?.docs() = this?.documentation.orEmpty().values.flatMap { it.children }

val DClass.supers
    get() = supertypes.flatMap { it.component2() }

val Bound.name: String?
    get() = when (this) {
        is Nullable -> inner.name
        is DefinitelyNonNullable -> inner.name
        is TypeParameter -> name
        is PrimitiveJavaType -> name
        is TypeConstructor -> dri.classNames
        is JavaObject -> "Object"
        is Void -> "void"
        is Dynamic -> "dynamic"
        is UnresolvedBound -> "<ERROR CLASS>"
        is TypeAliased -> typeAlias.name
    }