aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt15
-rw-r--r--plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt96
2 files changed, 100 insertions, 11 deletions
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
index 43ffff85..48e44f5f 100644
--- a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
+++ b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
@@ -105,14 +105,23 @@ open class DokkaLocationProvider(
companion object {
internal val reservedFilenames = setOf("index", "con", "aux", "lst", "prn", "nul", "eof", "inp", "out")
+ //Taken from: https://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names
+ internal val reservedCharacters = setOf('|', '>', '<', '*', ':', '"', '?', '%')
internal fun identifierToFilename(name: String): String {
if (name.isEmpty()) return "--root--"
- val escaped = name.replace("[<>]".toRegex(), "-")
- val lowercase = escaped.replace("[A-Z]".toRegex()) { matchResult -> "-" + matchResult.value.toLowerCase() }
- return if (lowercase in reservedFilenames) "--$lowercase--" else lowercase
+ return sanitizeFileName(name, reservedFilenames, reservedCharacters)
}
}
}
+internal fun sanitizeFileName(name: String, reservedFileNames: Set<String>, reservedCharacters: Set<Char>): String {
+ val lowercase = name.replace("[A-Z]".toRegex()) { matchResult -> "-" + matchResult.value.toLowerCase() }
+ val withoutReservedFileNames = if (lowercase in reservedFileNames) "--$lowercase--" else lowercase
+ return reservedCharacters.fold(withoutReservedFileNames){
+ acc, character ->
+ if(character in acc) acc.replace(character.toString(), "[${character.toInt()}]")
+ else acc
+ }
+}
diff --git a/plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt b/plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt
index 89161080..6426c0e1 100644
--- a/plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt
+++ b/plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt
@@ -2,21 +2,26 @@ package locationProvider
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider
+import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
import org.junit.jupiter.api.Assertions.assertNotEquals
import org.junit.jupiter.api.Test
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.MethodSource
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
-class DefaultLocationProviderTest: AbstractCoreTest() {
- @Test
- fun `#644 same directory for module and package`() {
- val configuration = dokkaConfiguration {
- sourceSets {
- sourceSet {
- sourceRoots = listOf("src/")
- }
+class DefaultLocationProviderTest : AbstractCoreTest() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/")
}
}
+ }
+ @Test
+ fun `#644 same directory for module and package`() {
testInline(
"""
|/src/main/kotlin/basic/Test.kt
@@ -38,4 +43,79 @@ class DefaultLocationProviderTest: AbstractCoreTest() {
}
}
}
+
+ @Test
+ fun `should escape illegal pipe character in file name`() {
+ /*
+ Currently even kotlin doesn't escape pipe characters in file names so it is impossible to have a
+ class named || on windows
+ */
+ testInline(
+ """
+ |/src/main/kotlin/basic/Test.kt
+ |
+ |class Test {
+ | fun `||`() { }
+ |}
+ """.trimMargin(),
+ configuration
+ ) {
+ var context: DokkaContext? = null
+ pluginsSetupStage = {
+ context = it
+ }
+
+ pagesGenerationStage = { module ->
+ val lp = DokkaLocationProvider(module, context!!)
+ val functionWithPipes = module.dfs { it.name == "||" }
+ assertNotNull(functionWithPipes, "Failed to find a page for a function named ||")
+ assertEquals(lp.resolve(functionWithPipes), "[root]/-test/[124][124].html")
+ }
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource
+ fun runEscapeTestForCharacter(data: TestData) {
+ testInline(
+ """
+ |/src/main/kotlin/basic/Test.kt
+ |
+ |class Test {
+ | fun `${data.tested}`() { }
+ |}
+ """.trimMargin(),
+ configuration
+ ) {
+ var context: DokkaContext? = null
+ pluginsSetupStage = {
+ context = it
+ }
+
+ pagesGenerationStage = { module ->
+ val lp = DokkaLocationProvider(module, context!!)
+ val functionWithPipes = module.dfs { it.name == "${data.tested}" }
+ assertNotNull(functionWithPipes, "Failed to find a page for a function named ${data.tested}")
+ assertEquals(lp.resolve(functionWithPipes), "[root]/-test/${data.expectedReplacement}.html")
+ }
+ }
+ }
+
+ data class TestData(val tested: Char, val expectedReplacement: String)
+
+ companion object TestDataSources {
+ @JvmStatic
+ fun runEscapeTestForCharacter(): List<TestData> = listOf(
+ '|' to "[124]",
+ '>' to "[62]",
+ '<' to "[60]",
+ '*' to "[42]",
+ ':' to "[58]",
+ '"' to "[34]",
+ '?' to "[63]",
+ '%' to "[37]"
+ ).map {
+ TestData(it.first, it.second)
+ }
+ }
}