/
AbstractIntegrationTest.kt
168 lines (144 loc) · 6.08 KB
/
AbstractIntegrationTest.kt
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package org.jetbrains.dokka.it
import org.jsoup.Jsoup
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import java.io.File
import java.net.URL
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
@RunWith(JUnit4::class)
abstract class AbstractIntegrationTest {
@get:Rule
val temporaryTestFolder = TemporaryFolder()
val projectDir get() = File(temporaryTestFolder.root, "project")
fun File.allDescendentsWithExtension(extension: String): Sequence<File> =
this.walkTopDown().filter { it.isFile && it.extension == extension }
fun File.allHtmlFiles(): Sequence<File> = allDescendentsWithExtension("html")
fun File.allGfmFiles(): Sequence<File> = allDescendentsWithExtension("md")
protected fun assertContainsNoErrorClass(file: File) {
val fileText = file.readText()
assertFalse(
fileText.contains("ERROR CLASS", ignoreCase = true),
"Unexpected `ERROR CLASS` in ${file.path}\n" + fileText
)
}
protected fun assertNoEmptyLinks(file: File) {
val regex = Regex("[\"']#[\"']")
val fileText = file.readText()
assertFalse(
fileText.contains(regex),
"Unexpected empty link in ${file.path}\n" + fileText
)
}
protected fun assertNoUnresolvedLinks(file: File, exceptions: Set<String> = emptySet()) {
val fileText = file.readText()
val regex = Regex("""data-unresolved-link="\[(.+?(?=]"))""")
val match = regex.findAll(fileText).map { it.groups[1]!!.value }
assertTrue(
match.filterNot { it in exceptions }.toList().isEmpty(),
"Unexpected unresolved link in ${file.path}\n" + fileText
)
}
protected fun assertNoHrefToMissingLocalFileOrDirectory(
file: File, fileExtensions: Set<String> = setOf("html")
) {
val fileText = file.readText()
val html = Jsoup.parse(fileText)
html.allElements.toList().forEach { element ->
val href = (element.attr("href") ?: return@forEach)
if (href.startsWith("https")) return@forEach
if (href.startsWith("http")) return@forEach
val hrefWithoutAnchors = if (href.contains("#")) {
val hrefSplits = href.split("#")
if (hrefSplits.count() != 2) return@forEach
hrefSplits.first()
} else href
val targetFile = if (href.startsWith("file://")) {
File(URL(hrefWithoutAnchors).path)
} else {
File(file.parent, hrefWithoutAnchors)
}
if (targetFile.extension.isNotEmpty() && targetFile.extension !in fileExtensions) return@forEach
if (targetFile.extension.isEmpty() || targetFile.extension == "html" && !href.startsWith("#")) {
assertTrue(
targetFile.exists(),
"${file.relativeTo(projectDir).path}: href=\"$href\"\n" +
"file does not exist: ${targetFile.path}"
)
}
}
}
protected fun assertNoSuppressedMarker(file: File) {
val fileText = file.readText()
assertFalse(
fileText.contains("§SUPPRESSED§"),
"Unexpected `§SUPPRESSED§` in file ${file.path}"
)
}
protected fun assertNoEmptySpans(file: File) {
val fileText = file.readText()
assertFalse(
fileText.contains(Regex("""<span>\s*</span>""")),
"Unexpected empty <span></span> in file ${file.path}"
)
}
protected fun assertNoUnsubstitutedTemplatesInHtml(file: File) {
val parsedFile = Jsoup.parse(file, "UTF-8")
assertTrue(
parsedFile.select("dokka-template-command").isEmpty(),
"Expected all templates to be substituted"
)
}
/**
* Asserts that [contentFiles] have no pages where content contains special visibility markers,
* such as §INTERNAL§ for `internal`, §PROTECTED§ for `protected` and §PRIVATE§ for `private` modifiers
*
* This can be used to check whether actual documented code corresponds to configured documented visibility
*
* @param contentFiles any readable content file such as html/md/rst/etc
*/
protected fun assertContentVisibility(
contentFiles: List<File>,
documentPublic: Boolean,
documentProtected: Boolean,
documentInternal: Boolean,
documentPrivate: Boolean
) {
val hasPublic = contentFiles.any { file -> "§PUBLIC§" in file.readText() }
assertEquals(documentPublic, hasPublic, "Expected content visibility and file content do not match for public")
val hasInternal = contentFiles.any { file -> "§INTERNAL§" in file.readText() }
assertEquals(
documentInternal,
hasInternal,
"Expected content visibility and file content do not match for internal"
)
val hasProtected = contentFiles.any { file -> "§PROTECTED§" in file.readText() }
assertEquals(
documentProtected,
hasProtected,
"Expected content visibility and file content do not match for protected"
)
val hasPrivate = contentFiles.any { file -> "§PRIVATE§" in file.readText() }
assertEquals(
documentPrivate,
hasPrivate,
"Expected content visibility and file content do not match for private"
)
}
/**
* Check that [outputFiles] contain specific file paths provided in [expectedFilePaths].
* Can be used for checking whether expected folders/pages have been created.
*/
protected fun assertContainsFilePaths(outputFiles: List<File>, expectedFilePaths: List<Regex>) {
expectedFilePaths.forEach { pathRegex ->
assertNotNull(
outputFiles.any { it.absolutePath.contains(pathRegex) },
"Expected to find a file with path regex $pathRegex, but found nothing"
)
}
}
}