diff options
Diffstat (limited to 'core/src/test')
-rw-r--r-- | core/src/test/kotlin/TestAPI.kt | 214 | ||||
-rw-r--r-- | core/src/test/kotlin/format/HtmlFormatTest.kt | 157 | ||||
-rw-r--r-- | core/src/test/kotlin/format/MarkdownFormatTest.kt | 218 | ||||
-rw-r--r-- | core/src/test/kotlin/format/PackageDocsTest.kt | 18 | ||||
-rw-r--r-- | core/src/test/kotlin/javadoc/JavadocTest.kt | 44 | ||||
-rw-r--r-- | core/src/test/kotlin/markdown/ParserTest.kt | 142 | ||||
-rw-r--r-- | core/src/test/kotlin/model/ClassTest.kt | 275 | ||||
-rw-r--r-- | core/src/test/kotlin/model/CommentTest.kt | 153 | ||||
-rw-r--r-- | core/src/test/kotlin/model/FunctionTest.kt | 227 | ||||
-rw-r--r-- | core/src/test/kotlin/model/JavaTest.kt | 197 | ||||
-rw-r--r-- | core/src/test/kotlin/model/KotlinAsJavaTest.kt | 40 | ||||
-rw-r--r-- | core/src/test/kotlin/model/LinkTest.kt | 48 | ||||
-rw-r--r-- | core/src/test/kotlin/model/PackageTest.kt | 86 | ||||
-rw-r--r-- | core/src/test/kotlin/model/PropertyTest.kt | 103 |
14 files changed, 1922 insertions, 0 deletions
diff --git a/core/src/test/kotlin/TestAPI.kt b/core/src/test/kotlin/TestAPI.kt new file mode 100644 index 00000000..d7833e36 --- /dev/null +++ b/core/src/test/kotlin/TestAPI.kt @@ -0,0 +1,214 @@ +package org.jetbrains.dokka.tests + +import com.google.inject.Guice +import com.intellij.openapi.application.PathManager +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.dokka.* +import org.jetbrains.dokka.Utilities.DokkaModule +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot +import org.jetbrains.kotlin.config.ContentRoot +import org.jetbrains.kotlin.config.KotlinSourceRoot +import org.junit.Assert +import java.io.File +import kotlin.test.fail + +public fun verifyModel(vararg roots: ContentRoot, + withJdk: Boolean = false, + withKotlinRuntime: Boolean = false, + format: String = "html", + verifier: (DocumentationModule) -> Unit) { + val messageCollector = object : MessageCollector { + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { + when (severity) { + CompilerMessageSeverity.WARNING, + CompilerMessageSeverity.LOGGING, + CompilerMessageSeverity.OUTPUT, + CompilerMessageSeverity.INFO, + CompilerMessageSeverity.ERROR -> { + println("$severity: $message at $location") + } + CompilerMessageSeverity.EXCEPTION -> { + fail("$severity: $message at $location") + } + } + } + } + + val environment = AnalysisEnvironment(messageCollector) + environment.apply { + if (withJdk || withKotlinRuntime) { + val stringRoot = PathManager.getResourceRoot(String::class.java, "/java/lang/String.class") + addClasspath(File(stringRoot)) + } + if (withKotlinRuntime) { + val kotlinPairRoot = PathManager.getResourceRoot(Pair::class.java, "/kotlin/Pair.class") + addClasspath(File(kotlinPairRoot)) + } + addRoots(roots.toList()) + } + val options = DocumentationOptions("", format, includeNonPublic = true, skipEmptyPackages = false, sourceLinks = listOf<SourceLinkDefinition>()) + val injector = Guice.createInjector(DokkaModule(environment, options, DokkaConsoleLogger)) + val documentation = buildDocumentationModule(injector, "test") + verifier(documentation) + Disposer.dispose(environment) +} + +public fun verifyModel(source: String, + withJdk: Boolean = false, + withKotlinRuntime: Boolean = false, + format: String = "html", + verifier: (DocumentationModule) -> Unit) { + if (!File(source).exists()) { + throw IllegalArgumentException("Can't find test data file $source") + } + verifyModel(contentRootFromPath(source), + withJdk = withJdk, + withKotlinRuntime = withKotlinRuntime, + format = format, + verifier = verifier) +} + +public fun verifyPackageMember(source: String, + withJdk: Boolean = false, + withKotlinRuntime: Boolean = false, + verifier: (DocumentationNode) -> Unit) { + verifyModel(source, withJdk = withJdk, withKotlinRuntime = withKotlinRuntime) { model -> + val pkg = model.members.single() + verifier(pkg.members.single()) + } +} + +public fun verifyJavaModel(source: String, + withKotlinRuntime: Boolean = false, + verifier: (DocumentationModule) -> Unit) { + val tempDir = FileUtil.createTempDirectory("dokka", "") + try { + val sourceFile = File(source) + FileUtil.copy(sourceFile, File(tempDir, sourceFile.name)) + verifyModel(JavaSourceRoot(tempDir, null), withJdk = true, withKotlinRuntime = withKotlinRuntime, verifier = verifier) + } + finally { + FileUtil.delete(tempDir) + } +} + +public fun verifyJavaPackageMember(source: String, + withKotlinRuntime: Boolean = false, + verifier: (DocumentationNode) -> Unit) { + verifyJavaModel(source, withKotlinRuntime) { model -> + val pkg = model.members.single() + verifier(pkg.members.single()) + } +} + +public fun verifyOutput(roots: Array<ContentRoot>, + outputExtension: String, + withJdk: Boolean = false, + withKotlinRuntime: Boolean = false, + outputGenerator: (DocumentationModule, StringBuilder) -> Unit) { + verifyModel(*roots, withJdk = withJdk, withKotlinRuntime = withKotlinRuntime) { + verifyModelOutput(it, outputExtension, outputGenerator, roots.first().path) + } +} + +private fun verifyModelOutput(it: DocumentationModule, + outputExtension: String, + outputGenerator: (DocumentationModule, StringBuilder) -> Unit, + sourcePath: String) { + val output = StringBuilder() + outputGenerator(it, output) + val ext = outputExtension.removePrefix(".") + val path = sourcePath + val expectedOutput = File(path.replaceAfterLast(".", ext, path + "." + ext)).readText() + assertEqualsIgnoringSeparators(expectedOutput, output.toString()) +} + +public fun verifyOutput(path: String, + outputExtension: String, + withJdk: Boolean = false, + withKotlinRuntime: Boolean = false, + outputGenerator: (DocumentationModule, StringBuilder) -> Unit) { + verifyOutput(arrayOf(contentRootFromPath(path)), outputExtension, withJdk, withKotlinRuntime, outputGenerator) +} + +public fun verifyJavaOutput(path: String, + outputExtension: String, + withKotlinRuntime: Boolean = false, + outputGenerator: (DocumentationModule, StringBuilder) -> Unit) { + verifyJavaModel(path, withKotlinRuntime) { model -> + verifyModelOutput(model, outputExtension, outputGenerator, path) + } +} + +public fun assertEqualsIgnoringSeparators(expectedOutput: String, output: String) { + Assert.assertEquals(expectedOutput.replace("\r\n", "\n"), output.replace("\r\n", "\n")) +} + +fun StringBuilder.appendChildren(node: ContentBlock): StringBuilder { + for (child in node.children) { + val childText = child.toTestString() + append(childText) + } + return this +} + +fun StringBuilder.appendNode(node: ContentNode): StringBuilder { + when (node) { + is ContentText -> { + append(node.text) + } + is ContentEmphasis -> append("*").appendChildren(node).append("*") + is ContentBlockCode -> { + appendln("[code]") + appendChildren(node) + appendln() + appendln("[/code]") + } + is ContentNodeLink -> { + append("[") + appendChildren(node) + append(" -> ") + append(node.node.toString()) + append("]") + } + is ContentBlock -> { + appendChildren(node) + } + is ContentEmpty -> { /* nothing */ } + else -> throw IllegalStateException("Don't know how to format node $node") + } + return this +} + +fun ContentNode.toTestString(): String { + val node = this + return StringBuilder().apply { + appendNode(node) + }.toString() +} + +class InMemoryLocation(override val path: String): Location { + override fun relativePathTo(other: Location, anchor: String?): String = + if (anchor != null) other.path + "#" + anchor else other.path +} + +object InMemoryLocationService: LocationService { + override fun location(qualifiedName: List<String>, hasMembers: Boolean) = + InMemoryLocation(relativePathToNode(qualifiedName, hasMembers)) + + override val root: Location + get() = InMemoryLocation("") +} + +val tempLocation = InMemoryLocation("") + +val ContentRoot.path: String + get() = when(this) { + is KotlinSourceRoot -> path + is JavaSourceRoot -> file.path + else -> throw UnsupportedOperationException() + } diff --git a/core/src/test/kotlin/format/HtmlFormatTest.kt b/core/src/test/kotlin/format/HtmlFormatTest.kt new file mode 100644 index 00000000..593dbfe6 --- /dev/null +++ b/core/src/test/kotlin/format/HtmlFormatTest.kt @@ -0,0 +1,157 @@ +package org.jetbrains.dokka.tests + +import org.jetbrains.dokka.HtmlFormatService +import org.jetbrains.dokka.HtmlTemplateService +import org.jetbrains.dokka.KotlinLanguageService +import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot +import org.jetbrains.kotlin.config.KotlinSourceRoot +import org.junit.Test +import java.io.File + +public class HtmlFormatTest { + private val htmlService = HtmlFormatService(InMemoryLocationService, KotlinLanguageService(), HtmlTemplateService.default()) + + @Test fun classWithCompanionObject() { + verifyOutput("testdata/format/classWithCompanionObject.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun htmlEscaping() { + verifyOutput("testdata/format/htmlEscaping.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun overloads() { + verifyOutput("testdata/format/overloads.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members) + } + } + + @Test fun overloadsWithDescription() { + verifyOutput("testdata/format/overloadsWithDescription.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun overloadsWithDifferentDescriptions() { + verifyOutput("testdata/format/overloadsWithDifferentDescriptions.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun deprecated() { + verifyOutput("testdata/format/deprecated.kt", ".package.html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members) + } + verifyOutput("testdata/format/deprecated.kt", ".class.html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun brokenLink() { + verifyOutput("testdata/format/brokenLink.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun codeSpan() { + verifyOutput("testdata/format/codeSpan.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun parenthesis() { + verifyOutput("testdata/format/parenthesis.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun bracket() { + verifyOutput("testdata/format/bracket.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun see() { + verifyOutput("testdata/format/see.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun tripleBackticks() { + verifyOutput("testdata/format/tripleBackticks.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun typeLink() { + verifyOutput("testdata/format/typeLink.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Bar"} ) + } + } + + @Test fun parameterAnchor() { + verifyOutput("testdata/format/parameterAnchor.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun javaSupertypeLink() { + verifyJavaOutput("testdata/format/javaSupertype.java", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members.single { it.name == "C"}.members.filter { it.name == "Bar"} ) + } + } + + @Test fun javaLinkTag() { + verifyJavaOutput("testdata/format/javaLinkTag.java", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun javaLinkTagWithLabel() { + verifyJavaOutput("testdata/format/javaLinkTagWithLabel.java", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun javaSeeTag() { + verifyJavaOutput("testdata/format/javaSeeTag.java", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun javaDeprecated() { + verifyJavaOutput("testdata/format/javaDeprecated.java", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members.single { it.name == "Foo" }.members.filter { it.name == "foo" }) + } + } + + @Test fun crossLanguageKotlinExtendsJava() { + verifyOutput(arrayOf(KotlinSourceRoot("testdata/format/crossLanguage/kotlinExtendsJava/Bar.kt"), + JavaSourceRoot(File("testdata/format/crossLanguage/kotlinExtendsJava"), null)), + ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Bar" }) + } + } + + @Test fun orderedList() { + verifyOutput("testdata/format/orderedList.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Bar" }) + } + } + + @Test fun linkWithLabel() { + verifyOutput("testdata/format/linkWithLabel.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Bar" }) + } + } + + @Test fun entity() { + verifyOutput("testdata/format/entity.kt", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Bar" }) + } + } +} + diff --git a/core/src/test/kotlin/format/MarkdownFormatTest.kt b/core/src/test/kotlin/format/MarkdownFormatTest.kt new file mode 100644 index 00000000..e2339707 --- /dev/null +++ b/core/src/test/kotlin/format/MarkdownFormatTest.kt @@ -0,0 +1,218 @@ +package org.jetbrains.dokka.tests + +import org.jetbrains.dokka.KotlinLanguageService +import org.jetbrains.dokka.MarkdownFormatService +import org.junit.Test + +public class MarkdownFormatTest { + private val markdownService = MarkdownFormatService(InMemoryLocationService, KotlinLanguageService()) + + @Test fun emptyDescription() { + verifyOutput("testdata/format/emptyDescription.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun classWithCompanionObject() { + verifyOutput("testdata/format/classWithCompanionObject.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun annotations() { + verifyOutput("testdata/format/annotations.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun annotationClass() { + verifyOutput("testdata/format/annotationClass.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun annotationParams() { + verifyOutput("testdata/format/annotationParams.kt", ".md", withKotlinRuntime = true) { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun extensions() { + verifyOutput("testdata/format/extensions.kt", ".package.md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members) + } + verifyOutput("testdata/format/extensions.kt", ".class.md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun enumClass() { + verifyOutput("testdata/format/enumClass.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + verifyOutput("testdata/format/enumClass.kt", ".value.md") { model, output -> + val enumClassNode = model.members.single().members[0] + markdownService.appendNodes(tempLocation, output, + enumClassNode.members.filter { it.name == "LOCAL_CONTINUE_AND_BREAK" }) + } + } + + @Test fun varargsFunction() { + verifyOutput("testdata/format/varargsFunction.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun overridingFunction() { + verifyOutput("testdata/format/overridingFunction.kt", ".md") { model, output -> + val classMembers = model.members.single().members.first { it.name == "D" }.members + markdownService.appendNodes(tempLocation, output, classMembers.filter { it.name == "f" }) + } + + } + + @Test fun propertyVar() { + verifyOutput("testdata/format/propertyVar.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun functionWithDefaultParameter() { + verifyOutput("testdata/format/functionWithDefaultParameter.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun accessor() { + verifyOutput("testdata/format/accessor.kt", ".md") { model, output -> + val propertyNode = model.members.single().members.first { it.name == "C" }.members.filter { it.name == "x" } + markdownService.appendNodes(tempLocation, output, propertyNode) + } + } + + @Test fun paramTag() { + verifyOutput("testdata/format/paramTag.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun throwsTag() { + verifyOutput("testdata/format/throwsTag.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun typeParameterBounds() { + verifyOutput("testdata/format/typeParameterBounds.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun typeParameterVariance() { + verifyOutput("testdata/format/typeParameterVariance.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun typeProjectionVariance() { + verifyOutput("testdata/format/typeProjectionVariance.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun javadocHtml() { + verifyJavaOutput("testdata/format/javadocHtml.java", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun javaCodeLiteralTags() { + verifyJavaOutput("testdata/format/javaCodeLiteralTags.java", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun javaCodeInParam() { + verifyJavaOutput("testdata/format/javaCodeInParam.java", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun javaSpaceInAuthor() { + verifyJavaOutput("testdata/format/javaSpaceInAuthor.java", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun nullability() { + verifyOutput("testdata/format/nullability.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun operatorOverloading() { + verifyOutput("testdata/format/operatorOverloading.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members.single { it.name == "C" }.members.filter { it.name == "plus" }) + } + } + + @Test fun javadocOrderedList() { + verifyJavaOutput("testdata/format/javadocOrderedList.java", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Bar" }) + } + } + + @Test fun companionObjectExtension() { + verifyOutput("testdata/format/companionObjectExtension.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Foo" }) + } + } + + @Test fun starProjection() { + verifyOutput("testdata/format/starProjection.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun extensionFunctionParameter() { + verifyOutput("testdata/format/extensionFunctionParameter.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun summarizeSignatures() { + verifyOutput("testdata/format/summarizeSignatures.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members) + } + } + + @Test fun summarizeSignaturesProperty() { + verifyOutput("testdata/format/summarizeSignaturesProperty.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members) + } + } + + @Test fun reifiedTypeParameter() { + verifyOutput("testdata/format/reifiedTypeParameter.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun annotatedTypeParameter() { + verifyOutput("testdata/format/annotatedTypeParameter.kt", ".md", withKotlinRuntime = true) { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } + + @Test fun inheritedMembers() { + verifyOutput("testdata/format/inheritedMembers.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Bar" }) + } + } + + @Test fun inheritedExtensions() { + verifyOutput("testdata/format/inheritedExtensions.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members.filter { it.name == "Bar" }) + } + } +} diff --git a/core/src/test/kotlin/format/PackageDocsTest.kt b/core/src/test/kotlin/format/PackageDocsTest.kt new file mode 100644 index 00000000..4d7852da --- /dev/null +++ b/core/src/test/kotlin/format/PackageDocsTest.kt @@ -0,0 +1,18 @@ +package org.jetbrains.dokka.tests.format + +import org.jetbrains.dokka.ContentBlock +import org.jetbrains.dokka.ContentText +import org.jetbrains.dokka.DokkaConsoleLogger +import org.jetbrains.dokka.PackageDocs +import org.junit.Test +import kotlin.test.assertEquals + +public class PackageDocsTest { + @Test fun verifyParse() { + val docs = PackageDocs(null, DokkaConsoleLogger) + docs.parse("testdata/packagedocs/stdlib.md", null) + val packageContent = docs.packageContent["kotlin"]!! + val block = (packageContent.children.single() as ContentBlock).children.first() as ContentText + assertEquals("Core functions and types", block.text) + } +} diff --git a/core/src/test/kotlin/javadoc/JavadocTest.kt b/core/src/test/kotlin/javadoc/JavadocTest.kt new file mode 100644 index 00000000..4f0049ac --- /dev/null +++ b/core/src/test/kotlin/javadoc/JavadocTest.kt @@ -0,0 +1,44 @@ +package org.jetbrains.dokka.javadoc + +import org.jetbrains.dokka.DokkaConsoleLogger +import org.jetbrains.dokka.tests.verifyModel +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +class JavadocTest { + @Test fun testTypes() { + verifyModel("testdata/javadoc/types.kt", format = "javadoc", withJdk = true) { model -> + val doc = ModuleNodeAdapter(model, StandardReporter(DokkaConsoleLogger), "") + val classDoc = doc.classNamed("foo.TypesKt")!! + val method = classDoc.methods().find { it.name() == "foo" }!! + + val type = method.returnType() + assertFalse(type.asClassDoc().isIncluded) + assertEquals("java.lang.String", type.qualifiedTypeName()) + assertEquals("java.lang.String", type.asClassDoc().qualifiedName()) + + val params = method.parameters() + assertTrue(params[0].type().isPrimitive) + assertFalse(params[1].type().asClassDoc().isIncluded) + } + } + + @Test fun testObject() { + verifyModel("testdata/javadoc/obj.kt", format = "javadoc") { model -> + val doc = ModuleNodeAdapter(model, StandardReporter(DokkaConsoleLogger), "") + + val classDoc = doc.classNamed("foo.O") + assertNotNull(classDoc) + + val companionDoc = doc.classNamed("foo.O.Companion") + assertNotNull(companionDoc) + + val pkgDoc = doc.packageNamed("foo")!! + assertEquals(2, pkgDoc.allClasses().size) + } + } + +} diff --git a/core/src/test/kotlin/markdown/ParserTest.kt b/core/src/test/kotlin/markdown/ParserTest.kt new file mode 100644 index 00000000..5a7adf05 --- /dev/null +++ b/core/src/test/kotlin/markdown/ParserTest.kt @@ -0,0 +1,142 @@ +package org.jetbrains.dokka.tests + +import org.junit.Test +import org.jetbrains.dokka.toTestString +import org.jetbrains.dokka.parseMarkdown +import org.junit.Ignore + +@Ignore public class ParserTest { + fun runTestFor(text : String) { + println("MD: ---") + println(text) + val markdownTree = parseMarkdown(text) + println("AST: ---") + println(markdownTree.toTestString()) + println() + } + + @Test fun text() { + runTestFor("text") + } + + @Test fun textWithSpaces() { + runTestFor("text and string") + } + + @Test fun textWithColon() { + runTestFor("text and string: cool!") + } + + @Test fun link() { + runTestFor("text [links]") + } + + @Test fun linkWithHref() { + runTestFor("text [links](http://google.com)") + } + + @Test fun multiline() { + runTestFor( + """ +text +and +string +""") + } + + @Test fun para() { + runTestFor( + """ +paragraph number +one + +paragraph +number two +""") + } + + @Test fun bulletList() { + runTestFor( + """* list item 1 +* list item 2 +""") + } + + @Test fun bulletListWithLines() { + runTestFor( + """ +* list item 1 + continue 1 +* list item 2 + continue 2 + """) + } + + @Test fun bulletListStrong() { + runTestFor( + """ +* list *item* 1 + continue 1 +* list *item* 2 + continue 2 + """) + } + + @Test fun emph() { + runTestFor("*text*") + } + + @Test fun directive() { + runTestFor("A text \${code with.another.value} with directive") + } + + @Test fun emphAndEmptySection() { + runTestFor("*text*\n\$sec:\n") + } + + @Test fun emphAndSection() { + runTestFor("*text*\n\$sec: some text\n") + } + + @Test fun emphAndBracedSection() { + runTestFor("Text *bold* text \n\${sec}: some text") + } + + @Test fun section() { + runTestFor( + "Plain text \n\$one: Summary \n\${two}: Description with *emphasis* \n\${An example of a section}: Example") + } + + @Test fun anonymousSection() { + runTestFor("Summary\n\nDescription\n") + } + + @Test fun specialSection() { + runTestFor( + "Plain text \n\$\$summary: Summary \n\${\$description}: Description \n\${\$An example of a section}: Example") + } + + @Test fun emptySection() { + runTestFor( + "Plain text \n\$summary:") + } + + val b = "$" + @Test fun pair() { + runTestFor( + """Represents a generic pair of two values. + +There is no meaning attached to values in this class, it can be used for any purpose. +Pair exhibits value semantics, i.e. two pairs are equal if both components are equal. + +An example of decomposing it into values: +${b}{code test.tuples.PairTest.pairMultiAssignment} + +${b}constructor: Creates new instance of [Pair] +${b}first: First value +${b}second: Second value"""" + ) + } + +} + diff --git a/core/src/test/kotlin/model/ClassTest.kt b/core/src/test/kotlin/model/ClassTest.kt new file mode 100644 index 00000000..981791c4 --- /dev/null +++ b/core/src/test/kotlin/model/ClassTest.kt @@ -0,0 +1,275 @@ +package org.jetbrains.dokka.tests + +import org.jetbrains.dokka.Content +import org.jetbrains.dokka.DocumentationNode +import org.jetbrains.dokka.DocumentationReference +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +public class ClassTest { + @Test fun emptyClass() { + verifyModel("testdata/classes/emptyClass.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(DocumentationNode.Kind.Class, kind) + assertEquals("Klass", name) + assertEquals(Content.Empty, content) + assertEquals("<init>", members.single().name) + assertTrue(links.none()) + } + } + } + + @Test fun emptyObject() { + verifyModel("testdata/classes/emptyObject.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(DocumentationNode.Kind.Object, kind) + assertEquals("Obj", name) + assertEquals(Content.Empty, content) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun classWithConstructor() { + verifyModel("testdata/classes/classWithConstructor.kt") { model -> + with (model.members.single().members.single()) { + assertEquals(DocumentationNode.Kind.Class, kind) + assertEquals("Klass", name) + assertEquals(Content.Empty, content) + assertTrue(links.none()) + + assertEquals(1, members.count()) + with(members.elementAt(0)) { + assertEquals("<init>", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Constructor, kind) + assertEquals(2, details.count()) + assertEquals("public", details.elementAt(0).name) + with(details.elementAt(1)) { + assertEquals("name", name) + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals(Content.Empty, content) + assertEquals("String", details.single().name) + assertTrue(links.none()) + assertTrue(members.none()) + } + assertTrue(links.none()) + assertTrue(members.none()) + } + } + } + } + + @Test fun classWithFunction() { + verifyModel("testdata/classes/classWithFunction.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(DocumentationNode.Kind.Class, kind) + assertEquals("Klass", name) + assertEquals(Content.Empty, content) + assertTrue(links.none()) + + assertEquals(2, members.count()) + with(members.elementAt(0)) { + assertEquals("<init>", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Constructor, kind) + assertEquals(1, details.count()) + assertEquals("public", details.elementAt(0).name) + assertTrue(links.none()) + assertTrue(members.none()) + } + with(members.elementAt(1)) { + assertEquals("fn", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Function, kind) + assertEquals("Unit", detail(DocumentationNode.Kind.Type).name) + assertTrue(links.none()) + assertTrue(members.none()) + } + } + } + } + + @Test fun classWithProperty() { + verifyModel("testdata/classes/classWithProperty.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(DocumentationNode.Kind.Class, kind) + assertEquals("Klass", name) + assertEquals(Content.Empty, content) + assertTrue(links.none()) + + assertEquals(2, members.count()) + with(members.elementAt(0)) { + assertEquals("<init>", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Constructor, kind) + assertEquals(1, details.count()) + assertEquals("public", details.elementAt(0).name) + assertTrue(members.none()) + assertTrue(links.none()) + } + with(members.elementAt(1)) { + assertEquals("name", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Property, kind) + assertEquals("String", detail(DocumentationNode.Kind.Type).name) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + } + + @Test fun classWithCompanionObject() { + verifyModel("testdata/classes/classWithCompanionObject.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(DocumentationNode.Kind.Class, kind) + assertEquals("Klass", name) + assertEquals(Content.Empty, content) + assertTrue(links.none()) + + assertEquals(3, members.count()) + with(members.elementAt(0)) { + assertEquals("<init>", name) + assertEquals(Content.Empty, content) + } + with(members.elementAt(1)) { + assertEquals("x", name) + assertEquals(DocumentationNode.Kind.CompanionObjectProperty, kind) + assertTrue(members.none()) + assertTrue(links.none()) + } + with(members.elementAt(2)) { + assertEquals("foo", name) + assertEquals(DocumentationNode.Kind.CompanionObjectFunction, kind) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + } + + @Test fun annotatedClass() { + verifyPackageMember("testdata/classes/annotatedClass.kt", withKotlinRuntime = true) { cls -> + assertEquals(1, cls.annotations.count()) + with(cls.annotations[0]) { + assertEquals("Strictfp", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + } + } + } + + @Test fun dataClass() { + verifyPackageMember("testdata/classes/dataClass.kt") { cls -> + val modifiers = cls.details(DocumentationNode.Kind.Modifier).map { it.name } + assertTrue("data" in modifiers) + } + } + + @Test fun sealedClass() { + verifyPackageMember("testdata/classes/sealedClass.kt") { cls -> + val modifiers = cls.details(DocumentationNode.Kind.Modifier).map { it.name } + assertEquals(1, modifiers.count { it == "sealed" }) + } + } + + @Test fun annotatedClassWithAnnotationParameters() { + verifyModel("testdata/classes/annotatedClassWithAnnotationParameters.kt") { model -> + with(model.members.single().members.single()) { + with(deprecation!!) { + assertEquals("Deprecated", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Value, kind) + assertEquals("\"should no longer be used\"", name) + } + } + } + } + } + } + + @Test fun javaAnnotationClass() { + verifyModel("testdata/classes/javaAnnotationClass.kt", withJdk = true) { model -> + with(model.members.single().members.single()) { + assertEquals(1, annotations.count()) + with(annotations[0]) { + assertEquals("Retention", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Value, kind) + assertEquals("RetentionPolicy.SOURCE", name) + } + } + } + } + } + } + + @Test fun notOpenClass() { + verifyModel("testdata/classes/notOpenClass.kt") { model -> + with(model.members.single().members.first { it.name == "D"}.members.first { it.name == "f" }) { + val modifiers = details(DocumentationNode.Kind.Modifier) + assertEquals(2, modifiers.size) + assertEquals("final", modifiers[1].name) + + val overrideReferences = references(DocumentationReference.Kind.Override) + assertEquals(1, overrideReferences.size) + } + } + } + + @Test fun indirectOverride() { + verifyModel("testdata/classes/indirectOverride.kt") { model -> + with(model.members.single().members.first { it.name == "E"}.members.first { it.name == "foo" }) { + val modifiers = details(DocumentationNode.Kind.Modifier) + assertEquals(2, modifiers.size) + assertEquals("final", modifiers[1].name) + + val overrideReferences = references(DocumentationReference.Kind.Override) + assertEquals(1, overrideReferences.size) + } + } + } + + @Test fun innerClass() { + verifyPackageMember("testdata/classes/innerClass.kt") { cls -> + val innerClass = cls.members.single { it.name == "D" } + val modifiers = innerClass.details(DocumentationNode.Kind.Modifier) + assertEquals(3, modifiers.size) + assertEquals("inner", modifiers[2].name) + } + } + + @Test fun companionObjectExtension() { + verifyModel("testdata/classes/companionObjectExtension.kt") { model -> + val pkg = model.members.single() + val cls = pkg.members.single { it.name == "Foo" } + val extensions = cls.extensions.filter { it.kind == DocumentationNode.Kind.CompanionObjectProperty } + assertEquals(1, extensions.size) + } + } + + @Test fun secondaryConstructor() { + verifyPackageMember("testdata/classes/secondaryConstructor.kt") { cls -> + val constructors = cls.members(DocumentationNode.Kind.Constructor) + assertEquals(2, constructors.size) + with (constructors.first { it.details(DocumentationNode.Kind.Parameter).size == 1}) { + assertEquals("<init>", name) + assertEquals("This is a secondary constructor.", summary.toTestString()) + } + } + } +} diff --git a/core/src/test/kotlin/model/CommentTest.kt b/core/src/test/kotlin/model/CommentTest.kt new file mode 100644 index 00000000..f3792610 --- /dev/null +++ b/core/src/test/kotlin/model/CommentTest.kt @@ -0,0 +1,153 @@ +package org.jetbrains.dokka.tests + +import org.junit.Test +import kotlin.test.* +import org.jetbrains.dokka.* + +public class CommentTest { + @Test fun emptyDoc() { + verifyModel("testdata/comments/emptyDoc.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(Content.Empty, content) + } + } + } + + @Test fun emptyDocButComment() { + verifyModel("testdata/comments/emptyDocButComment.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(Content.Empty, content) + } + } + } + + @Test fun multilineDoc() { + verifyModel("testdata/comments/multilineDoc.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("doc1", content.summary.toTestString()) + assertEquals("doc2\ndoc3", content.description.toTestString()) + } + } + } + + @Test fun multilineDocWithComment() { + verifyModel("testdata/comments/multilineDocWithComment.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("doc1", content.summary.toTestString()) + assertEquals("doc2\ndoc3", content.description.toTestString()) + } + } + } + + @Test fun oneLineDoc() { + verifyModel("testdata/comments/oneLineDoc.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("doc", content.summary.toTestString()) + } + } + } + + @Test fun oneLineDocWithComment() { + verifyModel("testdata/comments/oneLineDocWithComment.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("doc", content.summary.toTestString()) + } + } + } + + @Test fun oneLineDocWithEmptyLine() { + verifyModel("testdata/comments/oneLineDocWithEmptyLine.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("doc", content.summary.toTestString()) + } + } + } + + @Test fun emptySection() { + verifyModel("testdata/comments/emptySection.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Summary", content.summary.toTestString()) + assertEquals(1, content.sections.count()) + with (content.findSectionByTag("one")!!) { + assertEquals("One", tag) + assertEquals("", toTestString()) + } + } + } + } + + @Test fun section1() { + verifyModel("testdata/comments/section1.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Summary", content.summary.toTestString()) + assertEquals(1, content.sections.count()) + with (content.findSectionByTag("one")!!) { + assertEquals("One", tag) + assertEquals("section one", toTestString()) + } + } + } + } + + @Test fun section2() { + verifyModel("testdata/comments/section2.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Summary", content.summary.toTestString()) + assertEquals(2, content.sections.count()) + with (content.findSectionByTag("one")!!) { + assertEquals("One", tag) + assertEquals("section one", toTestString()) + } + with (content.findSectionByTag("two")!!) { + assertEquals("Two", tag) + assertEquals("section two", toTestString()) + } + } + } + } + + @Test fun multilineSection() { + verifyModel("testdata/comments/multilineSection.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Summary", content.summary.toTestString()) + assertEquals(1, content.sections.count()) + with (content.findSectionByTag("one")!!) { + assertEquals("One", tag) + assertEquals("""line one +line two""", toTestString()) + } + } + } + } + + @Test fun directive() { + verifyModel("testdata/comments/directive.kt") { model -> + with(model.members.single().members.first()) { + assertEquals("Summary", content.summary.toTestString()) + with (content.description) { + assertEqualsIgnoringSeparators("""[code] +if (true) { + println(property) +} +[/code] +[code] +if (true) { + println(property) +} +[/code] +[code] +if (true) { + println(property) +} +[/code] +[code] +if (true) { + println(property) +} +[/code] +""", toTestString()) + } + } + } + } +} diff --git a/core/src/test/kotlin/model/FunctionTest.kt b/core/src/test/kotlin/model/FunctionTest.kt new file mode 100644 index 00000000..83fd8223 --- /dev/null +++ b/core/src/test/kotlin/model/FunctionTest.kt @@ -0,0 +1,227 @@ +package org.jetbrains.dokka.tests + +import org.jetbrains.dokka.Content +import org.jetbrains.dokka.DocumentationNode +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +public class FunctionTest { + @Test fun function() { + verifyModel("testdata/functions/function.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("fn", name) + assertEquals(DocumentationNode.Kind.Function, kind) + assertEquals("Function fn", content.summary.toTestString()) + assertEquals("Unit", detail(DocumentationNode.Kind.Type).name) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun functionWithReceiver() { + verifyModel("testdata/functions/functionWithReceiver.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("kotlin.String", name) + assertEquals(DocumentationNode.Kind.ExternalClass, kind) + assertEquals(2, members.count()) + with(members[0]) { + assertEquals("fn", name) + assertEquals(DocumentationNode.Kind.Function, kind) + assertEquals("Function with receiver", content.summary.toTestString()) + assertEquals("public", details.elementAt(0).name) + assertEquals("final", details.elementAt(1).name) + with(details.elementAt(2)) { + assertEquals("<this>", name) + assertEquals(DocumentationNode.Kind.Receiver, kind) + assertEquals(Content.Empty, content) + assertEquals("String", details.single().name) + assertTrue(members.none()) + assertTrue(links.none()) + } + assertEquals("Unit", details.elementAt(3).name) + assertTrue(members.none()) + assertTrue(links.none()) + } + with(members[1]) { + assertEquals("fn", name) + assertEquals(DocumentationNode.Kind.Function, kind) + } + } + } + } + + @Test fun genericFunction() { + verifyModel("testdata/functions/genericFunction.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("generic", name) + assertEquals(DocumentationNode.Kind.Function, kind) + assertEquals("generic function", content.summary.toTestString()) + + assertEquals("private", details.elementAt(0).name) + assertEquals("final", details.elementAt(1).name) + with(details.elementAt(2)) { + assertEquals("T", name) + assertEquals(DocumentationNode.Kind.TypeParameter, kind) + assertEquals(Content.Empty, content) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + assertEquals("Unit", details.elementAt(3).name) + + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + @Test fun genericFunctionWithConstraints() { + verifyModel("testdata/functions/genericFunctionWithConstraints.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("generic", name) + assertEquals(DocumentationNode.Kind.Function, kind) + assertEquals("generic function", content.summary.toTestString()) + + assertEquals("public", details.elementAt(0).name) + assertEquals("final", details.elementAt(1).name) + with(details.elementAt(2)) { + assertEquals("T", name) + assertEquals(DocumentationNode.Kind.TypeParameter, kind) + assertEquals(Content.Empty, content) + with(details.single()) { + assertEquals("R", name) + assertEquals(DocumentationNode.Kind.UpperBound, kind) + assertEquals(Content.Empty, content) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + assertTrue(members.none()) + assertTrue(links.none()) + } + with(details.elementAt(3)) { + assertEquals("R", name) + assertEquals(DocumentationNode.Kind.TypeParameter, kind) + assertEquals(Content.Empty, content) + assertTrue(members.none()) + assertTrue(links.none()) + } + assertEquals("Unit", details.elementAt(4).name) + + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun functionWithParams() { + verifyModel("testdata/functions/functionWithParams.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("function", name) + assertEquals(DocumentationNode.Kind.Function, kind) + assertEquals("Multiline", content.summary.toTestString()) + assertEquals("""Function +Documentation""", content.description.toTestString()) + + assertEquals("public", details.elementAt(0).name) + assertEquals("final", details.elementAt(1).name) + with(details.elementAt(2)) { + assertEquals("x", name) + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals("parameter", content.summary.toTestString()) + assertEquals("Int", details.single().name) + assertTrue(members.none()) + assertTrue(links.none()) + } + assertEquals("Unit", details.elementAt(3).name) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun annotatedFunction() { + verifyPackageMember("testdata/functions/annotatedFunction.kt", withKotlinRuntime = true) { func -> + assertEquals(1, func.annotations.count()) + with(func.annotations[0]) { + assertEquals("Strictfp", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + } + } + } + + @Test fun functionWithNotDocumentedAnnotation() { + verifyPackageMember("testdata/functions/functionWithNotDocumentedAnnotation.kt") { func -> + assertEquals(0, func.annotations.count()) + } + } + + @Test fun inlineFunction() { + verifyPackageMember("testdata/functions/inlineFunction.kt") { func -> + val modifiers = func.details(DocumentationNode.Kind.Modifier).map { it.name } + assertTrue("inline" in modifiers) + } + } + + @Test fun functionWithAnnotatedParam() { + verifyModel("testdata/functions/functionWithAnnotatedParam.kt") { model -> + with(model.members.single().members.single { it.name == "function"} ) { + with(details.elementAt(2)) { + assertEquals(1, annotations.count()) + with(annotations[0]) { + assertEquals("Fancy", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + } + } + } + } + } + + @Test fun functionWithNoinlineParam() { + verifyPackageMember("testdata/functions/functionWithNoinlineParam.kt") { func -> + with(func.details.elementAt(2)) { + val modifiers = details(DocumentationNode.Kind.Modifier).map { it.name } + assertTrue("noinline" in modifiers) + } + } + } + + @Test fun annotatedFunctionWithAnnotationParameters() { + verifyModel("testdata/functions/annotatedFunctionWithAnnotationParameters.kt") { model -> + with(model.members.single().members.single { it.name == "f"}) { + assertEquals(1, annotations.count()) + with(annotations[0]) { + assertEquals("Fancy", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Value, kind) + assertEquals("1", name) + } + } + } + } + } + } + + @Test fun functionWithDefaultParameter() { + verifyModel("testdata/functions/functionWithDefaultParameter.kt") { model -> + with(model.members.single().members.single()) { + with(details.elementAt(2)) { + val value = details(DocumentationNode.Kind.Value) + assertEquals(1, value.count()) + with(value[0]) { + assertEquals("\"\"", name) + } + } + } + } + } +} diff --git a/core/src/test/kotlin/model/JavaTest.kt b/core/src/test/kotlin/model/JavaTest.kt new file mode 100644 index 00000000..903260d3 --- /dev/null +++ b/core/src/test/kotlin/model/JavaTest.kt @@ -0,0 +1,197 @@ +package org.jetbrains.dokka.tests + +import org.jetbrains.dokka.DocumentationNode +import org.jetbrains.dokka.DocumentationReference +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +public class JavaTest { + @Test fun function() { + verifyJavaPackageMember("testdata/java/member.java") { cls -> + assertEquals("Test", cls.name) + assertEquals(DocumentationNode.Kind.Class, cls.kind) + with(cls.members(DocumentationNode.Kind.Function).single()) { + assertEquals("fn", name) + assertEquals("Summary for Function", content.summary.toTestString().trimEnd()) + assertEquals(3, content.sections.size) + with(content.sections[0]) { + assertEquals("Parameters", tag) + assertEquals("name", subjectName) + assertEquals("is String parameter ", toTestString()) + } + with(content.sections[1]) { + assertEquals("Parameters", tag) + assertEquals("value", subjectName) + assertEquals("is int parameter ", toTestString()) + } + with(content.sections[2]) { + assertEquals("Author", tag) + assertEquals("yole", toTestString()) + } + assertEquals("Unit", detail(DocumentationNode.Kind.Type).name) + assertTrue(members.none()) + assertTrue(links.none()) + with(details.first { it.name == "name" }) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals("String", detail(DocumentationNode.Kind.Type).name) + } + with(details.first { it.name == "value" }) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals("Int", detail(DocumentationNode.Kind.Type).name) + } + } + } + } + + @Test fun memberWithModifiers() { + verifyJavaPackageMember("testdata/java/memberWithModifiers.java") { cls -> + val modifiers = cls.details(DocumentationNode.Kind.Modifier).map { it.name } + assertTrue("abstract" in modifiers) + with(cls.members.single { it.name == "fn" }) { + assertEquals("protected", details[0].name) + } + with(cls.members.single { it.name == "openFn" }) { + assertEquals("open", details[1].name) + } + } + } + + @Test fun superClass() { + verifyJavaPackageMember("testdata/java/superClass.java") { cls -> + val superTypes = cls.details(DocumentationNode.Kind.Supertype) + assertEquals(2, superTypes.size) + assertEquals("Exception", superTypes[0].name) + assertEquals("Cloneable", superTypes[1].name) + } + } + + @Test fun arrayType() { + verifyJavaPackageMember("testdata/java/arrayType.java") { cls -> + with(cls.members(DocumentationNode.Kind.Function).single()) { + val type = detail(DocumentationNode.Kind.Type) + assertEquals("Array", type.name) + assertEquals("String", type.detail(DocumentationNode.Kind.Type).name) + with(details(DocumentationNode.Kind.Parameter).single()) { + val parameterType = detail(DocumentationNode.Kind.Type) + assertEquals("IntArray", parameterType.name) + } + } + } + } + + @Test fun typeParameter() { + verifyJavaPackageMember("testdata/java/typeParameter.java") { cls -> + val typeParameters = cls.details(DocumentationNode.Kind.TypeParameter) + with(typeParameters.single()) { + assertEquals("T", name) + with(detail(DocumentationNode.Kind.UpperBound)) { + assertEquals("Comparable", name) + assertEquals("T", detail(DocumentationNode.Kind.Type).name) + } + } + with(cls.members(DocumentationNode.Kind.Function).single()) { + val methodTypeParameters = details(DocumentationNode.Kind.TypeParameter) + with(methodTypeParameters.single()) { + assertEquals("E", name) + } + } + } + } + + @Test fun constructors() { + verifyJavaPackageMember("testdata/java/constructors.java") { cls -> + val constructors = cls.members(DocumentationNode.Kind.Constructor) + assertEquals(2, constructors.size) + with(constructors[0]) { + assertEquals("<init>", name) + } + } + } + + @Test fun innerClass() { + verifyJavaPackageMember("testdata/java/innerClass.java") { cls -> + val innerClass = cls.members(DocumentationNode.Kind.Class).single() + assertEquals("D", innerClass.name) + } + } + + @Test fun varargs() { + verifyJavaPackageMember("testdata/java/varargs.java") { cls -> + val fn = cls.members(DocumentationNode.Kind.Function).single() + val param = fn.detail(DocumentationNode.Kind.Parameter) + assertEquals("vararg", param.details(DocumentationNode.Kind.Modifier).first().name) + val psiType = param.detail(DocumentationNode.Kind.Type) + assertEquals("String", psiType.name) + assertTrue(psiType.details(DocumentationNode.Kind.Type).isEmpty()) + } + } + + @Test fun fields() { + verifyJavaPackageMember("testdata/java/field.java") { cls -> + val i = cls.members(DocumentationNode.Kind.Property).single { it.name == "i" } + assertEquals("Int", i.detail(DocumentationNode.Kind.Type).name) + assertTrue("var" in i.details(DocumentationNode.Kind.Modifier).map { it.name }) + + val s = cls.members(DocumentationNode.Kind.Property).single { it.name == "s" } + assertEquals("String", s.detail(DocumentationNode.Kind.Type).name) + assertFalse("var" in s.details(DocumentationNode.Kind.Modifier).map { it.name }) + assertTrue("static" in s.details(DocumentationNode.Kind.Modifier).map { it.name }) + } + } + + @Test fun staticMethod() { + verifyJavaPackageMember("testdata/java/staticMethod.java") { cls -> + val m = cls.members(DocumentationNode.Kind.Function).single { it.name == "foo" } + assertTrue("static" in m.details(DocumentationNode.Kind.Modifier).map { it.name }) + } + } + + @Test fun annotatedAnnotation() { + verifyJavaPackageMember("testdata/java/annotatedAnnotation.java") { cls -> + assertEquals(1, cls.annotations.size) + with(cls.annotations[0]) { + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Value, kind) + assertEquals("[AnnotationTarget.FIELD, AnnotationTarget.CLASS, AnnotationTarget.FILE, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER]", name) + } + } + } + } + } + + @Test fun deprecation() { + verifyJavaPackageMember("testdata/java/deprecation.java") { cls -> + val fn = cls.members(DocumentationNode.Kind.Function).single() + assertEquals("This should no longer be used", fn.deprecation!!.content.toTestString()) + } + } + + @Test fun javaLangObject() { + verifyJavaPackageMember("testdata/java/javaLangObject.java") { cls -> + val fn = cls.members(DocumentationNode.Kind.Function).single() + assertEquals("Any", fn.detail(DocumentationNode.Kind.Type).name) + } + } + + @Test fun enumValues() { + verifyJavaPackageMember("testdata/java/enumValues.java") { cls -> + val superTypes = cls.details(DocumentationNode.Kind.Supertype) + assertEquals(0, superTypes.size) + assertEquals(1, cls.members(DocumentationNode.Kind.EnumItem).size) + } + } + + @Test fun inheritorLinks() { + verifyJavaPackageMember("testdata/java/inheritorLinks.java") { cls -> + val fooClass = cls.members.single { it.name == "Foo" } + val inheritors = fooClass.references(DocumentationReference.Kind.Inheritor) + assertEquals(1, inheritors.size) + } + } +} diff --git a/core/src/test/kotlin/model/KotlinAsJavaTest.kt b/core/src/test/kotlin/model/KotlinAsJavaTest.kt new file mode 100644 index 00000000..b439d399 --- /dev/null +++ b/core/src/test/kotlin/model/KotlinAsJavaTest.kt @@ -0,0 +1,40 @@ +package org.jetbrains.dokka.tests + +import org.jetbrains.dokka.DocumentationModule +import org.jetbrains.dokka.DocumentationNode +import org.junit.Test +import kotlin.test.assertEquals + +class KotlinAsJavaTest { + @Test fun function() { + verifyModelAsJava("testdata/functions/function.kt") { model -> + val pkg = model.members.single() + + val facadeClass = pkg.members.single { it.name == "FunctionKt" } + assertEquals(DocumentationNode.Kind.Class, facadeClass.kind) + + val fn = facadeClass.members.single() + assertEquals("fn", fn.name) + assertEquals(DocumentationNode.Kind.Function, fn.kind) + } + } + + @Test fun propertyWithComment() { + verifyModelAsJava("testdata/comments/oneLineDoc.kt") { model -> + val facadeClass = model.members.single().members.single { it.name == "OneLineDocKt" } + val getter = facadeClass.members.single { it.name == "getProperty" } + assertEquals(DocumentationNode.Kind.Function, getter.kind) + assertEquals("doc", getter.content.summary.toTestString()) + } + } +} + +fun verifyModelAsJava(source: String, + withJdk: Boolean = false, + withKotlinRuntime: Boolean = false, + verifier: (DocumentationModule) -> Unit) { + verifyModel(source, + withJdk = withJdk, withKotlinRuntime = withKotlinRuntime, + format = "html-as-java", + verifier = verifier) +} diff --git a/core/src/test/kotlin/model/LinkTest.kt b/core/src/test/kotlin/model/LinkTest.kt new file mode 100644 index 00000000..c30e1c10 --- /dev/null +++ b/core/src/test/kotlin/model/LinkTest.kt @@ -0,0 +1,48 @@ +package org.jetbrains.dokka.tests + +import org.junit.Test +import kotlin.test.* +import org.jetbrains.dokka.* + +public class LinkTest { + @Test fun linkToSelf() { + verifyModel("testdata/links/linkToSelf.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Foo", name) + assertEquals(DocumentationNode.Kind.Class, kind) + assertEquals("This is link to [Foo -> Class:Foo]", content.summary.toTestString()) + } + } + } + + @Test fun linkToMember() { + verifyModel("testdata/links/linkToMember.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Foo", name) + assertEquals(DocumentationNode.Kind.Class, kind) + assertEquals("This is link to [member -> Function:member]", content.summary.toTestString()) + } + } + } + + @Test fun linkToQualifiedMember() { + verifyModel("testdata/links/linkToQualifiedMember.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Foo", name) + assertEquals(DocumentationNode.Kind.Class, kind) + assertEquals("This is link to [Foo.member -> Function:member]", content.summary.toTestString()) + } + } + } + + @Test fun linkToParam() { + verifyModel("testdata/links/linkToParam.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Foo", name) + assertEquals(DocumentationNode.Kind.Function, kind) + assertEquals("This is link to [param -> Parameter:param]", content.summary.toTestString()) + } + } + } + +}
\ No newline at end of file diff --git a/core/src/test/kotlin/model/PackageTest.kt b/core/src/test/kotlin/model/PackageTest.kt new file mode 100644 index 00000000..aa5a059a --- /dev/null +++ b/core/src/test/kotlin/model/PackageTest.kt @@ -0,0 +1,86 @@ +package org.jetbrains.dokka.tests + +import org.jetbrains.dokka.Content +import org.jetbrains.dokka.DocumentationNode +import org.jetbrains.kotlin.config.KotlinSourceRoot +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +public class PackageTest { + @Test fun rootPackage() { + verifyModel("testdata/packages/rootPackage.kt") { model -> + with(model.members.single()) { + assertEquals(DocumentationNode.Kind.Package, kind) + assertEquals("", name) + assertEquals(Content.Empty, content) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun simpleNamePackage() { + verifyModel("testdata/packages/simpleNamePackage.kt") { model -> + with(model.members.single()) { + assertEquals(DocumentationNode.Kind.Package, kind) + assertEquals("simple", name) + assertEquals(Content.Empty, content) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun dottedNamePackage() { + verifyModel("testdata/packages/dottedNamePackage.kt") { model -> + with(model.members.single()) { + assertEquals(DocumentationNode.Kind.Package, kind) + assertEquals("dot.name", name) + assertEquals(Content.Empty, content) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun multipleFiles() { + verifyModel(KotlinSourceRoot("testdata/packages/dottedNamePackage.kt"), + KotlinSourceRoot("testdata/packages/simpleNamePackage.kt")) { model -> + assertEquals(2, model.members.count()) + with(model.members.single { it.name == "simple" }) { + assertEquals(DocumentationNode.Kind.Package, kind) + assertEquals("simple", name) + assertEquals(Content.Empty, content) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + with(model.members.single { it.name == "dot.name" }) { + assertEquals(DocumentationNode.Kind.Package, kind) + assertEquals(Content.Empty, content) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun multipleFilesSamePackage() { + verifyModel(KotlinSourceRoot("testdata/packages/simpleNamePackage.kt"), + KotlinSourceRoot("testdata/packages/simpleNamePackage2.kt")) { model -> + assertEquals(1, model.members.count()) + with(model.members.elementAt(0)) { + assertEquals(DocumentationNode.Kind.Package, kind) + assertEquals("simple", name) + assertEquals(Content.Empty, content) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } +}
\ No newline at end of file diff --git a/core/src/test/kotlin/model/PropertyTest.kt b/core/src/test/kotlin/model/PropertyTest.kt new file mode 100644 index 00000000..716aac54 --- /dev/null +++ b/core/src/test/kotlin/model/PropertyTest.kt @@ -0,0 +1,103 @@ +package org.jetbrains.dokka.tests + +import org.jetbrains.dokka.Content +import org.jetbrains.dokka.DocumentationNode +import org.jetbrains.dokka.DocumentationReference +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +public class PropertyTest { + @Test fun valueProperty() { + verifyModel("testdata/properties/valueProperty.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("property", name) + assertEquals(DocumentationNode.Kind.Property, kind) + assertEquals(Content.Empty, content) + assertEquals("String", detail(DocumentationNode.Kind.Type).name) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun variableProperty() { + verifyModel("testdata/properties/variableProperty.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("property", name) + assertEquals(DocumentationNode.Kind.Property, kind) + assertEquals(Content.Empty, content) + assertEquals("String", detail(DocumentationNode.Kind.Type).name) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } + + @Test fun valuePropertyWithGetter() { + verifyModel("testdata/properties/valuePropertyWithGetter.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("property", name) + assertEquals(DocumentationNode.Kind.Property, kind) + assertEquals(Content.Empty, content) + assertEquals("String", detail(DocumentationNode.Kind.Type).name) + assertTrue(links.none()) + assertTrue(members.none()) + } + } + } + + @Test fun variablePropertyWithAccessors() { + verifyModel("testdata/properties/variablePropertyWithAccessors.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("property", name) + assertEquals(DocumentationNode.Kind.Property, kind) + assertEquals(Content.Empty, content) + assertEquals("String", detail(DocumentationNode.Kind.Type).name) + val modifiers = details(DocumentationNode.Kind.Modifier).map { it.name } + assertTrue("final" in modifiers) + assertTrue("public" in modifiers) + assertTrue("var" in modifiers) + assertTrue(links.none()) + assertTrue(members.none()) + } + } + } + + @Test fun annotatedProperty() { + verifyModel("testdata/properties/annotatedProperty.kt", withKotlinRuntime = true) { model -> + with(model.members.single().members.single()) { + assertEquals(1, annotations.count()) + with(annotations[0]) { + assertEquals("Volatile", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + } + } + } + } + + @Test fun propertyWithReceiver() { + verifyModel("testdata/properties/propertyWithReceiver.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("kotlin.String", name) + assertEquals(DocumentationNode.Kind.ExternalClass, kind) + with(members.single()) { + assertEquals("foobar", name) + assertEquals(DocumentationNode.Kind.Property, kind) + } + } + } + } + + @Test fun propertyOverride() { + verifyModel("testdata/properties/propertyOverride.kt") { model -> + with(model.members.single().members.single { it.name == "Bar" }.members.single { it.name == "xyzzy"}) { + assertEquals("xyzzy", name) + val override = references(DocumentationReference.Kind.Override).single().to + assertEquals("xyzzy", override.name) + assertEquals("Foo", override.owner!!.name) + } + } + } +} |