[Native][tests] Naive implementation of glob expansion
This commit is contained in:
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.konan.blackboxtest
|
||||
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.expandGlob
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.sanitizedName
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.fail
|
||||
import java.io.File
|
||||
import kotlin.io.path.createTempDirectory
|
||||
|
||||
class GlobsExpansionTest {
|
||||
private lateinit var testDir: File
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
testDir = createTempDirectory(GlobsExpansionTest::class.java.sanitizedName).toFile()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun noGlobs() {
|
||||
val fileName = "file.kt"
|
||||
val dirNames = listOf(null, "foo", "foo/bar", "foo/bar/baz")
|
||||
|
||||
dirNames.forEach { dirName ->
|
||||
val fullPattern = testDir.resolveNullable(dirName).resolve(fileName)
|
||||
val expansionResult = expandGlob(fullPattern)
|
||||
|
||||
assertEquals(1, expansionResult.size)
|
||||
assertEquals(fullPattern, expansionResult.first())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun filePattern() {
|
||||
val fileNames = listOf("one.kt", "two.kt", "three.kt", "four.java", "five.py")
|
||||
val dirNames = listOf(null, "foo", "foo/bar", "foo/bar/baz")
|
||||
val pattern = "*.kt"
|
||||
|
||||
dirNames.forEach { dirName ->
|
||||
val dir = createDirWithFiles(dirName, fileNames)
|
||||
|
||||
val fullPattern = dir.resolve(pattern)
|
||||
val expansionResult = expandGlob(fullPattern)
|
||||
|
||||
val kotlinOnyFiles = findAllKotlinFiles(dirName)
|
||||
|
||||
assertEquals(kotlinOnyFiles.size, expansionResult.size)
|
||||
assertEquals(kotlinOnyFiles, expansionResult.toSet())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dirPattern() {
|
||||
val fileNames = listOf("one.kt", "two.kt", "three.kt", "four.java", "five.py")
|
||||
val dirNames = listOf(null, "foo", "bar", "baz")
|
||||
val pattern = "ba*/*.kt" // covers "bar" & "baz" dirs
|
||||
|
||||
dirNames.forEach { dirName -> createDirWithFiles(dirName, fileNames) }
|
||||
|
||||
val fullPattern = testDir.resolve(pattern)
|
||||
val expansionResult = expandGlob(fullPattern)
|
||||
|
||||
val kotlinOnyFiles = findAllKotlinFiles("bar", "baz")
|
||||
assertEquals(kotlinOnyFiles.size, expansionResult.size)
|
||||
assertEquals(kotlinOnyFiles, expansionResult.toSet())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun doubleStarPattern() {
|
||||
val fileNames = listOf("one.kt", "two.kt", "three.kt", "four.java", "five.py")
|
||||
val dirNames = listOf(null, "foo", "foo/bar", "foo/bar/baz")
|
||||
val pattern = "foo/**.kt" // covers "foo" and all subdirectories
|
||||
|
||||
dirNames.forEach { dirName -> createDirWithFiles(dirName, fileNames) }
|
||||
|
||||
val fullPattern = testDir.resolve(pattern)
|
||||
val expansionResult = expandGlob(fullPattern)
|
||||
|
||||
val kotlinOnyFiles = findAllKotlinFiles("foo", "foo/bar", "foo/bar/baz")
|
||||
assertEquals(kotlinOnyFiles.size, expansionResult.size)
|
||||
assertEquals(kotlinOnyFiles, expansionResult.toSet())
|
||||
}
|
||||
|
||||
private fun createDirWithFiles(dirName: String?, fileNames: Collection<String>): File {
|
||||
val dir = testDir.resolveNullable(dirName)
|
||||
dir.mkdirs()
|
||||
|
||||
fileNames.forEach { fileName ->
|
||||
dir.resolve(fileName).apply { createNewFile() }
|
||||
}
|
||||
|
||||
return dir
|
||||
}
|
||||
|
||||
private fun findAllKotlinFiles(vararg dirNames: String?): Set<File> = buildSet {
|
||||
dirNames.forEach { dirName ->
|
||||
val dir = testDir.resolveNullable(dirName)
|
||||
assertTrue(dir.isDirectory) { "Directory does not exist or is not a directory: $dir ($dirName)." }
|
||||
|
||||
val files = dir.listFiles()?.takeIf { it.isNotEmpty() }
|
||||
?: fail { "Unexpectedly empty directory: $dir ($dirName)." }
|
||||
|
||||
files.mapNotNullTo(this) { if (it.isFile && it.extension == "kt") it else null }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun File.resolveNullable(nullable: String?): File = if (nullable != null) resolve(nullable) else this
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.konan.blackboxtest.support.util
|
||||
|
||||
import java.io.File
|
||||
import java.nio.file.*
|
||||
import java.nio.file.attribute.BasicFileAttributes
|
||||
import kotlin.io.path.name
|
||||
|
||||
/**
|
||||
* Naive sub-optimal implementation of glob expansion.
|
||||
*/
|
||||
internal fun expandGlobTo(unexpendedPath: File, output: MutableCollection<File>) {
|
||||
val normalizedUnexpandedPath = Paths.get(unexpendedPath.path).toAbsolutePath().normalize()
|
||||
|
||||
val paths = generateSequence(normalizedUnexpandedPath) { it.parent }.toMutableList().apply { reverse() }
|
||||
for (index in 1 until paths.size) {
|
||||
val path = paths[index]
|
||||
|
||||
val isGlob = '*' in path.name
|
||||
if (isGlob) {
|
||||
val basePath = paths[index - 1]
|
||||
|
||||
val pattern = basePath.relativize(normalizedUnexpandedPath).toString()
|
||||
val matcher = FileSystems.getDefault().getPathMatcher("glob:$pattern")
|
||||
|
||||
Files.walkFileTree(basePath, object : SimpleFileVisitor<Path>() {
|
||||
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
|
||||
if (matcher.matches(basePath.relativize(file))) output += file.toFile()
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// No globs to expand.
|
||||
output += normalizedUnexpandedPath.toFile()
|
||||
}
|
||||
|
||||
internal fun expandGlob(unexpendedPath: File): Collection<File> = buildList { expandGlobTo(unexpendedPath, this) }
|
||||
+14
-4
@@ -5,11 +5,21 @@
|
||||
|
||||
package org.jetbrains.kotlin.konan.blackboxtest.support.util
|
||||
|
||||
internal val Class<*>.sanitizedName: String
|
||||
get() = name.map { if (it.isLetterOrDigit() || it == '_') it else '_' }.joinToString("")
|
||||
internal val Class<*>.sanitizedName: String get() = sanitize(name)
|
||||
|
||||
internal fun getSanitizedFileName(fileName: String): String =
|
||||
fileName.map { if (it.isLetterOrDigit() || it == '_' || it == '.') it else '_' }.joinToString("")
|
||||
internal fun getSanitizedFileName(fileName: String): String = sanitize(fileName, allowDots = true)
|
||||
|
||||
private fun sanitize(s: String, allowDots: Boolean = false) = buildString {
|
||||
s.forEach { ch ->
|
||||
append(
|
||||
when {
|
||||
ch.isLetterOrDigit() || ch == '_' -> ch
|
||||
allowDots && ch == '.' -> ch
|
||||
else -> '_'
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal const val DEFAULT_FILE_NAME = "main.kt"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user