<lambda>null1 package org.jetbrains.dokka.tests
2
3 import com.google.inject.Guice
4 import com.intellij.openapi.application.PathManager
5 import com.intellij.openapi.util.Disposer
6 import com.intellij.openapi.util.io.FileUtil
7 import com.intellij.rt.execution.junit.FileComparisonFailure
8 import org.jetbrains.dokka.*
9 import org.jetbrains.dokka.Utilities.DokkaAnalysisModule
10 import org.jetbrains.kotlin.cli.common.config.ContentRoot
11 import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
12 import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
13 import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
14 import org.jetbrains.kotlin.cli.common.messages.MessageCollector
15 import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
16 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
17 import org.junit.Assert
18 import org.junit.Assert.fail
19 import java.io.File
20
21 fun verifyModel(vararg roots: ContentRoot,
22 withJdk: Boolean = false,
23 withKotlinRuntime: Boolean = false,
24 format: String = "html",
25 includeNonPublic: Boolean = true,
26 perPackageOptions: List<DokkaConfiguration.PackageOptions> = emptyList(),
27 noStdlibLink: Boolean = true,
28 collectInheritedExtensionsFromLibraries: Boolean = false,
29 verifier: (DocumentationModule) -> Unit) {
30 val documentation = DocumentationModule("test")
31
32 val options = DocumentationOptions(
33 "",
34 format,
35 includeNonPublic = includeNonPublic,
36 skipEmptyPackages = false,
37 includeRootPackage = true,
38 sourceLinks = listOf(),
39 perPackageOptions = perPackageOptions,
40 generateClassIndexPage = false,
41 generatePackageIndexPage = false,
42 noStdlibLink = noStdlibLink,
43 noJdkLink = false,
44 cacheRoot = "default",
45 languageVersion = null,
46 apiVersion = null,
47 collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries
48 )
49
50 appendDocumentation(documentation, *roots,
51 withJdk = withJdk,
52 withKotlinRuntime = withKotlinRuntime,
53 options = options)
54 documentation.prepareForGeneration(options)
55
56 verifier(documentation)
57 }
58
appendDocumentationnull59 fun appendDocumentation(documentation: DocumentationModule,
60 vararg roots: ContentRoot,
61 withJdk: Boolean = false,
62 withKotlinRuntime: Boolean = false,
63 options: DocumentationOptions,
64 defaultPlatforms: List<String> = emptyList()) {
65 val messageCollector = object : MessageCollector {
66 override fun clear() {
67
68 }
69
70 override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
71 when (severity) {
72 CompilerMessageSeverity.STRONG_WARNING,
73 CompilerMessageSeverity.WARNING,
74 CompilerMessageSeverity.LOGGING,
75 CompilerMessageSeverity.OUTPUT,
76 CompilerMessageSeverity.INFO,
77 CompilerMessageSeverity.ERROR -> {
78 println("$severity: $message at $location")
79 }
80 CompilerMessageSeverity.EXCEPTION -> {
81 fail("$severity: $message at $location")
82 }
83 }
84 }
85
86 override fun hasErrors() = false
87 }
88
89 val environment = AnalysisEnvironment(messageCollector)
90 environment.apply {
91 if (withJdk || withKotlinRuntime) {
92 val stringRoot = PathManager.getResourceRoot(String::class.java, "/java/lang/String.class")
93 addClasspath(File(stringRoot))
94 }
95 if (withKotlinRuntime) {
96 val kotlinStrictfpRoot = PathManager.getResourceRoot(Strictfp::class.java, "/kotlin/jvm/Strictfp.class")
97 addClasspath(File(kotlinStrictfpRoot))
98 }
99 addRoots(roots.toList())
100
101 loadLanguageVersionSettings(options.languageVersion, options.apiVersion)
102 }
103 val defaultPlatformsProvider = object : DefaultPlatformsProvider {
104 override fun getDefaultPlatforms(descriptor: DeclarationDescriptor) = defaultPlatforms
105 }
106 val injector = Guice.createInjector(
107 DokkaAnalysisModule(environment, options, defaultPlatformsProvider, documentation.nodeRefGraph, DokkaConsoleLogger))
108 buildDocumentationModule(injector, documentation)
109 Disposer.dispose(environment)
110 }
111
verifyModelnull112 fun verifyModel(source: String,
113 withJdk: Boolean = false,
114 withKotlinRuntime: Boolean = false,
115 format: String = "html",
116 includeNonPublic: Boolean = true,
117 verifier: (DocumentationModule) -> Unit) {
118 if (!File(source).exists()) {
119 throw IllegalArgumentException("Can't find test data file $source")
120 }
121 verifyModel(contentRootFromPath(source),
122 withJdk = withJdk,
123 withKotlinRuntime = withKotlinRuntime,
124 format = format,
125 includeNonPublic = includeNonPublic,
126 verifier = verifier)
127 }
128
verifyPackageMembernull129 fun verifyPackageMember(source: String,
130 withJdk: Boolean = false,
131 withKotlinRuntime: Boolean = false,
132 verifier: (DocumentationNode) -> Unit) {
133 verifyModel(source, withJdk = withJdk, withKotlinRuntime = withKotlinRuntime) { model ->
134 val pkg = model.members.single()
135 verifier(pkg.members.single())
136 }
137 }
138
verifyJavaModelnull139 fun verifyJavaModel(source: String,
140 withKotlinRuntime: Boolean = false,
141 format: String = "html",
142 verifier: (DocumentationModule) -> Unit) {
143 val tempDir = FileUtil.createTempDirectory("dokka", "")
144 try {
145 val sourceFile = File(source)
146 FileUtil.copy(sourceFile, File(tempDir, sourceFile.name))
147 verifyModel(JavaSourceRoot(tempDir, null), format = format, withJdk = true, withKotlinRuntime = withKotlinRuntime, verifier = verifier)
148 }
149 finally {
150 FileUtil.delete(tempDir)
151 }
152 }
153
verifyJavaPackageMembernull154 fun verifyJavaPackageMember(source: String,
155 withKotlinRuntime: Boolean = false,
156 verifier: (DocumentationNode) -> Unit) {
157 verifyJavaModel(source, withKotlinRuntime) { model ->
158 val pkg = model.members.single()
159 verifier(pkg.members.single())
160 }
161 }
162
verifyOutputnull163 fun verifyOutput(roots: Array<ContentRoot>,
164 outputExtension: String,
165 withJdk: Boolean = false,
166 withKotlinRuntime: Boolean = false,
167 format: String = "html",
168 includeNonPublic: Boolean = true,
169 noStdlibLink: Boolean = true,
170 collectInheritedExtensionsFromLibraries: Boolean = false,
171 outputGenerator: (DocumentationModule, StringBuilder) -> Unit) {
172 verifyModel(
173 *roots,
174 withJdk = withJdk,
175 withKotlinRuntime = withKotlinRuntime,
176 format = format,
177 includeNonPublic = includeNonPublic,
178 noStdlibLink = noStdlibLink,
179 collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries
180 ) {
181 verifyModelOutput(it, outputExtension, roots.first().path, outputGenerator)
182 }
183 }
184
verifyModelOutputnull185 fun verifyModelOutput(it: DocumentationModule,
186 outputExtension: String,
187 sourcePath: String,
188 outputGenerator: (DocumentationModule, StringBuilder) -> Unit) {
189 val output = StringBuilder()
190 outputGenerator(it, output)
191 val ext = outputExtension.removePrefix(".")
192 val expectedFile = File(sourcePath.replaceAfterLast(".", ext, sourcePath + "." + ext))
193 assertEqualsIgnoringSeparators(expectedFile, output.toString())
194 }
195
verifyOutputnull196 fun verifyOutput(
197 path: String,
198 outputExtension: String,
199 withJdk: Boolean = false,
200 withKotlinRuntime: Boolean = false,
201 format: String = "html",
202 includeNonPublic: Boolean = true,
203 noStdlibLink: Boolean = true,
204 collectInheritedExtensionsFromLibraries: Boolean = false,
205 outputGenerator: (DocumentationModule, StringBuilder) -> Unit
206 ) {
207 verifyOutput(
208 arrayOf(contentRootFromPath(path)),
209 outputExtension,
210 withJdk,
211 withKotlinRuntime,
212 format,
213 includeNonPublic,
214 noStdlibLink,
215 collectInheritedExtensionsFromLibraries,
216 outputGenerator
217 )
218 }
219
verifyJavaOutputnull220 fun verifyJavaOutput(path: String,
221 outputExtension: String,
222 withKotlinRuntime: Boolean = false,
223 format: String = "html",
224 outputGenerator: (DocumentationModule, StringBuilder) -> Unit) {
225 verifyJavaModel(path, withKotlinRuntime, format) { model ->
226 verifyModelOutput(model, outputExtension, path, outputGenerator)
227 }
228 }
229
assertEqualsIgnoringSeparatorsnull230 fun assertEqualsIgnoringSeparators(expectedFile: File, output: String) {
231 if (!expectedFile.exists()) expectedFile.createNewFile()
232 val expectedText = expectedFile.readText().replace("\r\n", "\n")
233 val actualText = output.replace("\r\n", "\n")
234
235 if(expectedText != actualText)
236 throw FileComparisonFailure("", expectedText, actualText, expectedFile.canonicalPath)
237 }
238
assertEqualsIgnoringSeparatorsnull239 fun assertEqualsIgnoringSeparators(expectedOutput: String, output: String) {
240 Assert.assertEquals(expectedOutput.replace("\r\n", "\n"), output.replace("\r\n", "\n"))
241 }
242
StringBuildernull243 fun StringBuilder.appendChildren(node: ContentBlock): StringBuilder {
244 for (child in node.children) {
245 val childText = child.toTestString()
246 append(childText)
247 }
248 return this
249 }
250
StringBuildernull251 fun StringBuilder.appendNode(node: ContentNode): StringBuilder {
252 when (node) {
253 is ContentText -> {
254 append(node.text)
255 }
256 is ContentEmphasis -> append("*").appendChildren(node).append("*")
257 is ContentBlockCode -> {
258 if (node.language.isNotBlank())
259 appendln("[code lang=${node.language}]")
260 else
261 appendln("[code]")
262 appendChildren(node)
263 appendln()
264 appendln("[/code]")
265 }
266 is ContentNodeLink -> {
267 append("[")
268 appendChildren(node)
269 append(" -> ")
270 append(node.node.toString())
271 append("]")
272 }
273 is ContentBlock -> {
274 appendChildren(node)
275 }
276 is NodeRenderContent -> {
277 append("render(")
278 append(node.node)
279 append(",")
280 append(node.mode)
281 append(")")
282 }
283 is ContentSymbol -> { append(node.text) }
284 is ContentEmpty -> { /* nothing */ }
285 else -> throw IllegalStateException("Don't know how to format node $node")
286 }
287 return this
288 }
289
toTestStringnull290 fun ContentNode.toTestString(): String {
291 val node = this
292 return StringBuilder().apply {
293 appendNode(node)
294 }.toString()
295 }
296
297 val ContentRoot.path: String
298 get() = when(this) {
299 is KotlinSourceRoot -> path
300 is JavaSourceRoot -> file.path
301 else -> throw UnsupportedOperationException()
302 }
303