blob: 179073cc657dec0ffe124d757c13d6a39c401770 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.devsite.testing
import com.google.common.truth.Truth.assertThat
import com.google.devsite.DevsitePlugin
import com.google.devsite.renderer.Language
import com.google.devsite.renderer.converters.isFromBaseClass
import com.google.devsite.renderer.impl.paths.DacJavaFilePathProvider
import com.google.devsite.renderer.impl.paths.DacKotlinFilePathProvider
import com.google.devsite.renderer.impl.paths.ExternalDokkaLocationProvider
import kotlinx.coroutines.runBlocking
import org.jetbrains.dokka.CoreExtensions
import org.jetbrains.dokka.ExternalDocumentationLink
import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.model.DModule
import org.jetbrains.dokka.pages.ModulePageNode
import org.jetbrains.dokka.pages.RootPageNode
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.DokkaPlugin
import org.jetbrains.dokka.renderers.Renderer
import java.io.File
import java.net.URL
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
internal abstract class ConverterTestBase(
private val language: Language = Language.JAVA
) : BaseAbstractTest() {
protected fun List<String>.render(): DModule = testWithRootPageNode(this)
protected fun String.render(java: Boolean = false): DModule = if (java) {
testJavaWithRootPageNode(trimMargin())
} else {
testWithRootPageNode(trimMargin())
}
protected fun DModule.classlike() = packages.single().classlikes
.firstOrNull { it.name != "Nullable" }
protected fun DModule.function(name: String? = null) =
packages.single().functions.singleOrNull { it.name == name && !it.dri.isFromBaseClass() }
?: classlike()?.functions?.singleOrNull { it.name == name && !it.dri.isFromBaseClass() }
?: packages.single().functions.singleOrNull { !it.dri.isFromBaseClass() }
?: classlike()?.functions?.singleOrNull { !it.dri.isFromBaseClass() }
protected fun DModule.functions() =
packages.single().functions.nullIfEmpty()
?: classlike()?.functions
protected fun DModule.property(name: String? = null) =
packages.single().properties.singleOrNull { it.name == name }
?: classlike()?.properties?.singleOrNull { it.name == name }
?: packages.single().properties.singleOrNull()
?: classlike()?.properties?.singleOrNull()
protected fun DModule.properties() =
packages.single().properties.nullIfEmpty()
?: classlike()?.properties
private fun <E> List<E>.nullIfEmpty() = if (this.isNotEmpty()) this else null
protected fun assertPath(actual: String, expected: String) {
when (language) {
Language.JAVA -> assertThat(actual).isEqualTo("/reference/$expected")
Language.KOTLIN -> assertThat(actual).isEqualTo("/reference/kotlin/$expected")
}
}
protected fun pathProvider(
externalLocationProvider: ExternalDokkaLocationProvider? = null
) = when (language) {
Language.JAVA -> DacJavaFilePathProvider("androidx", externalLocationProvider)
Language.KOTLIN -> DacKotlinFilePathProvider("androidx", externalLocationProvider)
}
protected fun javaOnly(block: () -> Unit) {
if (language == Language.JAVA) {
block()
}
}
protected fun kotlinOnly(block: () -> Unit) {
if (language == Language.KOTLIN) {
block()
}
}
private fun testWithRootPageNode(sourceFiles: List<String>): DModule = runBlocking {
val externalLinks = mapOf(
"coroutines" to "https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core",
"android" to "https://developer.android.com/reference",
"guava" to "https://guava.dev/releases/18.0/api/docs/package-list",
"kotlin" to "https://kotlinlang.org/api/latest/jvm/stdlib/"
).map {
ExternalDocumentationLink(
url = URL(it.value),
packageListUrl = File("testData").toPath()
.resolve("package-lists/${it.key}/package-list").toUri().toURL()
)
}
val configuration = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("src/main")
classpath = listOfNotNull(jvmStdlibPath, commonStdlibPath)
externalDocumentationLinks = externalLinks
}
}
offlineMode = true
}
suspendCoroutine { cont ->
testInline(
sourceFiles.joinToString("\n\n"),
configuration,
pluginOverrides = listOf(NoopPlugin)
) {
renderingStage = { node: RootPageNode, _: DokkaContext ->
val module = (node as ModulePageNode).documentable as DModule
cont.resume(module)
}
}
}
}
private fun testWithRootPageNode(sourceCode: String): DModule {
val source = """
|/src/main/kotlin/androidx/example/Test.kt
|package androidx.example
|
|$sourceCode
""".trimMargin()
return testWithRootPageNode(listOf(source))
}
private fun testJavaWithRootPageNode(sourceCode: String): DModule {
val source = """
|/src/main/java/androidx/example/Test.java
|package androidx.example;
|annotation class Nullable
|public class Test {
|$sourceCode
|}
""".trimMargin()
return testWithRootPageNode(listOf(source))
}
object NoopPlugin : DokkaPlugin() {
private val devsite by lazy { plugin<DevsitePlugin>() }
val renderer by extending {
CoreExtensions.renderer providing { NoopRenderer } override devsite.renderer
}
private object NoopRenderer : Renderer {
override fun render(root: RootPageNode) = Unit
}
}
}