[Native][tests] Re-organize TestCaseGroupProvider
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.konan.blackboxtest;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.NativeBlackBoxTestCaseGroupProvider;
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.NativeBlackBoxTestCaseGroupProvider;
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.ExtTestCaseGroupProvider;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.generators.tests
|
||||
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
||||
import org.jetbrains.kotlin.generators.model.annotation
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeBlackBoxTest
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.NativeBlackBoxTestCaseGroupProvider
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.NativeBlackBoxTestCaseGroupProvider
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.ExtTestCaseGroupProvider
|
||||
|
||||
fun main() {
|
||||
|
||||
+1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.konan.blackboxtest.support
|
||||
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeBlackBoxTest
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.NativeBlackBoxTestCaseGroupProvider
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.StandardTestCaseGroupProvider
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.TestCaseGroupProvider
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.*
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
* 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
|
||||
package org.jetbrains.kotlin.konan.blackboxtest.support.group
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* 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.group
|
||||
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.DEFAULT_FILE_NAME
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ThreadSafeFactory
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.computeGeneratedSourcesDir
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.computePackageName
|
||||
import org.jetbrains.kotlin.test.directives.model.Directive
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertFalse
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertNotEquals
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||
import org.jetbrains.kotlin.test.services.impl.RegisteredDirectivesParser
|
||||
import java.io.File
|
||||
|
||||
internal class StandardTestCaseGroupProvider(private val environment: TestEnvironment) : TestCaseGroupProvider {
|
||||
// Load test cases in groups on demand.
|
||||
private val lazyTestCaseGroups = ThreadSafeFactory<File, TestCaseGroup?> { testDataDir ->
|
||||
val testDataFiles = testDataDir.listFiles()
|
||||
?: return@ThreadSafeFactory null // `null` means that there is no such testDataDir.
|
||||
|
||||
val testCases = testDataFiles.mapNotNull { testDataFile ->
|
||||
if (!testDataFile.isFile || testDataFile.extension != "kt")
|
||||
return@mapNotNull null
|
||||
|
||||
createTestCase(testDataFile)
|
||||
}
|
||||
|
||||
TestCaseGroup.Default(disabledTestDataFileNames = emptySet(), testCases = testCases)
|
||||
}
|
||||
|
||||
override fun getTestCaseGroup(testDataDir: File) = lazyTestCaseGroups[testDataDir]
|
||||
|
||||
private fun createTestCase(testDataFile: File): TestCase {
|
||||
val generatedSourcesDir = computeGeneratedSourcesDir(
|
||||
testDataBaseDir = environment.testRoots.baseDir,
|
||||
testDataFile = testDataFile,
|
||||
generatedSourcesBaseDir = environment.testSourcesDir
|
||||
)
|
||||
|
||||
val effectivePackageName = computePackageName(
|
||||
testDataBaseDir = environment.testRoots.baseDir,
|
||||
testDataFile = testDataFile
|
||||
)
|
||||
|
||||
val testModules = hashMapOf<String, TestModule.Exclusive>()
|
||||
var currentTestModule: TestModule.Exclusive? = null
|
||||
|
||||
var currentTestFileName: String? = null
|
||||
val currentTestFileText = StringBuilder()
|
||||
|
||||
val directivesParser = RegisteredDirectivesParser(TestDirectives, JUnit5Assertions)
|
||||
var lastParsedDirective: Directive? = null
|
||||
|
||||
fun switchTestModule(newTestModule: TestModule.Exclusive, location: Location): TestModule.Exclusive {
|
||||
// Don't register new test module if there is another one with the same name.
|
||||
val testModule = testModules.getOrPut(newTestModule.name) { newTestModule }
|
||||
assertTrue(testModule === newTestModule || testModule.haveSameSymbols(newTestModule)) {
|
||||
"""
|
||||
$location: Two declarations of the same module with different dependencies or friends found:
|
||||
$testModule
|
||||
$newTestModule
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
currentTestModule = testModule
|
||||
return testModule
|
||||
}
|
||||
|
||||
fun beginTestFile(fileName: String) {
|
||||
assertEquals(null, currentTestFileName)
|
||||
currentTestFileName = fileName
|
||||
}
|
||||
|
||||
fun finishTestFile(forceFinish: Boolean, location: Location) {
|
||||
val needToFinish = forceFinish
|
||||
|| currentTestFileName != null
|
||||
|| (currentTestFileName == null /*&& testFiles.isEmpty()*/ && currentTestFileText.hasAnythingButComments())
|
||||
|
||||
if (needToFinish) {
|
||||
val fileName = currentTestFileName ?: DEFAULT_FILE_NAME
|
||||
val testModule = currentTestModule ?: switchTestModule(TestModule.newDefaultModule(), location)
|
||||
|
||||
testModule.files += TestFile.createUncommitted(
|
||||
location = generatedSourcesDir.resolve(testModule.name).resolve(fileName),
|
||||
module = testModule,
|
||||
text = currentTestFileText
|
||||
)
|
||||
|
||||
currentTestFileText.clear()
|
||||
repeat(location.lineNumber ?: 0) { currentTestFileText.appendLine() }
|
||||
currentTestFileName = null
|
||||
}
|
||||
}
|
||||
|
||||
testDataFile.readLines().forEachIndexed { lineNumber, line ->
|
||||
val location = Location(testDataFile, lineNumber)
|
||||
val expectFileDirectiveAfterModuleDirective =
|
||||
lastParsedDirective == TestDirectives.MODULE // Only FILE directive may follow MODULE directive.
|
||||
|
||||
val rawDirective = RegisteredDirectivesParser.parseDirective(line)
|
||||
if (rawDirective != null) {
|
||||
val parsedDirective = try {
|
||||
directivesParser.convertToRegisteredDirective(rawDirective)
|
||||
} catch (e: AssertionError) {
|
||||
// Enhance error message with concrete test data file and line number where the error has happened.
|
||||
throw AssertionError(
|
||||
"""
|
||||
$location: Error while parsing directive in test data file.
|
||||
Cause: ${e.message}
|
||||
""".trimIndent(),
|
||||
e
|
||||
)
|
||||
}
|
||||
|
||||
if (parsedDirective != null) {
|
||||
when (val directive = parsedDirective.directive) {
|
||||
TestDirectives.FILE -> {
|
||||
val newFileName = parseFileName(parsedDirective, location)
|
||||
finishTestFile(forceFinish = false, location)
|
||||
beginTestFile(newFileName)
|
||||
}
|
||||
else -> {
|
||||
assertFalse(expectFileDirectiveAfterModuleDirective) {
|
||||
"$location: Directive $directive encountered after ${TestDirectives.MODULE} directive but was expecting ${TestDirectives.FILE}"
|
||||
}
|
||||
|
||||
when (directive) {
|
||||
TestDirectives.MODULE -> {
|
||||
finishTestFile(forceFinish = false, location)
|
||||
switchTestModule(parseModule(parsedDirective, location), location)
|
||||
}
|
||||
else -> {
|
||||
assertNotEquals(TestDirectives.FILE, lastParsedDirective) {
|
||||
"$location: Global directive $directive encountered after ${TestDirectives.FILE} directive"
|
||||
}
|
||||
assertNotEquals(TestDirectives.MODULE, lastParsedDirective) {
|
||||
"$location: Global directive $directive encountered after ${TestDirectives.MODULE} directive"
|
||||
}
|
||||
|
||||
directivesParser.addParsedDirective(parsedDirective)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentTestFileText.appendLine()
|
||||
lastParsedDirective = parsedDirective.directive
|
||||
return@forEachIndexed
|
||||
}
|
||||
}
|
||||
|
||||
if (expectFileDirectiveAfterModuleDirective) {
|
||||
// Was expecting a line with the FILE directive as this is the only possible continuation of a line with
|
||||
// the MODULE directive, but failed.
|
||||
fail { "$location: ${TestDirectives.FILE} directive expected after ${TestDirectives.MODULE} directive" }
|
||||
}
|
||||
|
||||
currentTestFileText.appendLine(line)
|
||||
}
|
||||
|
||||
val location = Location(testDataFile)
|
||||
finishTestFile(forceFinish = true, location)
|
||||
|
||||
val registeredDirectives = directivesParser.build()
|
||||
|
||||
val freeCompilerArgs = parseFreeCompilerArgs(registeredDirectives, location)
|
||||
val expectedOutputDataFile = parseOutputDataFile(baseDir = testDataFile.parentFile, registeredDirectives, location)
|
||||
val testKind = parseTestKind(registeredDirectives, location)
|
||||
|
||||
if (testKind == TestKind.REGULAR) {
|
||||
// Fix package declarations to avoid unintended conflicts between symbols with the same name in different test cases.
|
||||
testModules.values.forEach { testModule ->
|
||||
testModule.files.forEach { testFile -> fixPackageDeclaration(testFile, effectivePackageName, testDataFile) }
|
||||
}
|
||||
}
|
||||
|
||||
val testCase = TestCase(
|
||||
kind = testKind,
|
||||
modules = testModules.values.toSet(),
|
||||
freeCompilerArgs = freeCompilerArgs,
|
||||
origin = TestOrigin.SingleTestDataFile(testDataFile),
|
||||
nominalPackageName = effectivePackageName,
|
||||
expectedOutputDataFile = expectedOutputDataFile,
|
||||
extras = if (testKind == TestKind.STANDALONE_NO_TR) {
|
||||
TestCase.StandaloneNoTestRunnerExtras(
|
||||
entryPoint = parseEntryPoint(registeredDirectives, location),
|
||||
inputDataFile = parseInputDataFile(baseDir = testDataFile.parentFile, registeredDirectives, location)
|
||||
)
|
||||
} else
|
||||
null
|
||||
)
|
||||
testCase.initialize(findSharedModule = null)
|
||||
|
||||
return testCase
|
||||
}
|
||||
|
||||
private fun CharSequence.hasAnythingButComments(): Boolean {
|
||||
var result = false
|
||||
runForFirstMeaningfulStatement { _, _ -> result = true }
|
||||
return result
|
||||
}
|
||||
|
||||
private fun fixPackageDeclaration(
|
||||
testFile: TestFile<TestModule.Exclusive>,
|
||||
packageName: PackageName,
|
||||
testDataFile: File
|
||||
) = testFile.update { text ->
|
||||
var existingPackageDeclarationLine: String? = null
|
||||
var existingPackageDeclarationLineNumber: Int? = null
|
||||
|
||||
text.runForFirstMeaningfulStatement { lineNumber, line ->
|
||||
// First meaningful line.
|
||||
val trimmedLine = line.trim()
|
||||
if (trimmedLine.startsWith("package ")) {
|
||||
existingPackageDeclarationLine = trimmedLine
|
||||
existingPackageDeclarationLineNumber = lineNumber
|
||||
}
|
||||
}
|
||||
|
||||
if (existingPackageDeclarationLine != null) {
|
||||
val existingPackageName = existingPackageDeclarationLine!!.substringAfter("package ").trimStart()
|
||||
assertTrue(
|
||||
existingPackageName == packageName
|
||||
|| (existingPackageName.length > packageName.length
|
||||
&& existingPackageName.startsWith(packageName)
|
||||
&& existingPackageName[packageName.length] == '.')
|
||||
) {
|
||||
val location = Location(testDataFile, existingPackageDeclarationLineNumber)
|
||||
"""
|
||||
$location: Invalid package name declaration found: $existingPackageDeclarationLine
|
||||
Expected: package $packageName
|
||||
""".trimIndent()
|
||||
}
|
||||
text
|
||||
} else
|
||||
"package $packageName $text"
|
||||
}
|
||||
|
||||
private inline fun CharSequence.runForFirstMeaningfulStatement(action: (lineNumber: Int, line: String) -> Unit) {
|
||||
var inMultilineComment = false
|
||||
|
||||
for ((lineNumber, line) in lines().withIndex()) {
|
||||
val trimmedLine = line.trim()
|
||||
when {
|
||||
inMultilineComment -> inMultilineComment = !trimmedLine.endsWith("*/")
|
||||
trimmedLine.startsWith("/*") -> inMultilineComment = true
|
||||
trimmedLine.isMeaningfulLine() -> {
|
||||
action(lineNumber, line)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.isMeaningfulLine() = isNotEmpty() && !startsWith("//") && !startsWith("@file:")
|
||||
}
|
||||
+1
-256
@@ -5,264 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.konan.blackboxtest.support.group
|
||||
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.DEFAULT_FILE_NAME
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ThreadSafeFactory
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.computeGeneratedSourcesDir
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.computePackageName
|
||||
import org.jetbrains.kotlin.test.directives.model.Directive
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertFalse
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertNotEquals
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||
import org.jetbrains.kotlin.test.services.impl.RegisteredDirectivesParser
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseGroup
|
||||
import java.io.File
|
||||
|
||||
internal interface TestCaseGroupProvider {
|
||||
fun getTestCaseGroup(testDataDir: File): TestCaseGroup?
|
||||
}
|
||||
|
||||
internal class StandardTestCaseGroupProvider(private val environment: TestEnvironment) : TestCaseGroupProvider {
|
||||
// Load test cases in groups on demand.
|
||||
private val lazyTestCaseGroups = ThreadSafeFactory<File, TestCaseGroup?> { testDataDir ->
|
||||
val testDataFiles = testDataDir.listFiles()
|
||||
?: return@ThreadSafeFactory null // `null` means that there is no such testDataDir.
|
||||
|
||||
val testCases = testDataFiles.mapNotNull { testDataFile ->
|
||||
if (!testDataFile.isFile || testDataFile.extension != "kt")
|
||||
return@mapNotNull null
|
||||
|
||||
createTestCase(testDataFile)
|
||||
}
|
||||
|
||||
TestCaseGroup.Default(disabledTestDataFileNames = emptySet(), testCases = testCases)
|
||||
}
|
||||
|
||||
override fun getTestCaseGroup(testDataDir: File) = lazyTestCaseGroups[testDataDir]
|
||||
|
||||
private fun createTestCase(testDataFile: File): TestCase {
|
||||
val generatedSourcesDir = computeGeneratedSourcesDir(
|
||||
testDataBaseDir = environment.testRoots.baseDir,
|
||||
testDataFile = testDataFile,
|
||||
generatedSourcesBaseDir = environment.testSourcesDir
|
||||
)
|
||||
|
||||
val effectivePackageName = computePackageName(
|
||||
testDataBaseDir = environment.testRoots.baseDir,
|
||||
testDataFile = testDataFile
|
||||
)
|
||||
|
||||
val testModules = hashMapOf<String, TestModule.Exclusive>()
|
||||
var currentTestModule: TestModule.Exclusive? = null
|
||||
|
||||
var currentTestFileName: String? = null
|
||||
val currentTestFileText = StringBuilder()
|
||||
|
||||
val directivesParser = RegisteredDirectivesParser(TestDirectives, JUnit5Assertions)
|
||||
var lastParsedDirective: Directive? = null
|
||||
|
||||
fun switchTestModule(newTestModule: TestModule.Exclusive, location: Location): TestModule.Exclusive {
|
||||
// Don't register new test module if there is another one with the same name.
|
||||
val testModule = testModules.getOrPut(newTestModule.name) { newTestModule }
|
||||
assertTrue(testModule === newTestModule || testModule.haveSameSymbols(newTestModule)) {
|
||||
"""
|
||||
$location: Two declarations of the same module with different dependencies or friends found:
|
||||
$testModule
|
||||
$newTestModule
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
currentTestModule = testModule
|
||||
return testModule
|
||||
}
|
||||
|
||||
fun beginTestFile(fileName: String) {
|
||||
assertEquals(null, currentTestFileName)
|
||||
currentTestFileName = fileName
|
||||
}
|
||||
|
||||
fun finishTestFile(forceFinish: Boolean, location: Location) {
|
||||
val needToFinish = forceFinish
|
||||
|| currentTestFileName != null
|
||||
|| (currentTestFileName == null /*&& testFiles.isEmpty()*/ && currentTestFileText.hasAnythingButComments())
|
||||
|
||||
if (needToFinish) {
|
||||
val fileName = currentTestFileName ?: DEFAULT_FILE_NAME
|
||||
val testModule = currentTestModule ?: switchTestModule(TestModule.newDefaultModule(), location)
|
||||
|
||||
testModule.files += TestFile.createUncommitted(
|
||||
location = generatedSourcesDir.resolve(testModule.name).resolve(fileName),
|
||||
module = testModule,
|
||||
text = currentTestFileText
|
||||
)
|
||||
|
||||
currentTestFileText.clear()
|
||||
repeat(location.lineNumber ?: 0) { currentTestFileText.appendLine() }
|
||||
currentTestFileName = null
|
||||
}
|
||||
}
|
||||
|
||||
testDataFile.readLines().forEachIndexed { lineNumber, line ->
|
||||
val location = Location(testDataFile, lineNumber)
|
||||
val expectFileDirectiveAfterModuleDirective =
|
||||
lastParsedDirective == TestDirectives.MODULE // Only FILE directive may follow MODULE directive.
|
||||
|
||||
val rawDirective = RegisteredDirectivesParser.parseDirective(line)
|
||||
if (rawDirective != null) {
|
||||
val parsedDirective = try {
|
||||
directivesParser.convertToRegisteredDirective(rawDirective)
|
||||
} catch (e: AssertionError) {
|
||||
// Enhance error message with concrete test data file and line number where the error has happened.
|
||||
throw AssertionError(
|
||||
"""
|
||||
$location: Error while parsing directive in test data file.
|
||||
Cause: ${e.message}
|
||||
""".trimIndent(),
|
||||
e
|
||||
)
|
||||
}
|
||||
|
||||
if (parsedDirective != null) {
|
||||
when (val directive = parsedDirective.directive) {
|
||||
TestDirectives.FILE -> {
|
||||
val newFileName = parseFileName(parsedDirective, location)
|
||||
finishTestFile(forceFinish = false, location)
|
||||
beginTestFile(newFileName)
|
||||
}
|
||||
else -> {
|
||||
assertFalse(expectFileDirectiveAfterModuleDirective) {
|
||||
"$location: Directive $directive encountered after ${TestDirectives.MODULE} directive but was expecting ${TestDirectives.FILE}"
|
||||
}
|
||||
|
||||
when (directive) {
|
||||
TestDirectives.MODULE -> {
|
||||
finishTestFile(forceFinish = false, location)
|
||||
switchTestModule(parseModule(parsedDirective, location), location)
|
||||
}
|
||||
else -> {
|
||||
assertNotEquals(TestDirectives.FILE, lastParsedDirective) {
|
||||
"$location: Global directive $directive encountered after ${TestDirectives.FILE} directive"
|
||||
}
|
||||
assertNotEquals(TestDirectives.MODULE, lastParsedDirective) {
|
||||
"$location: Global directive $directive encountered after ${TestDirectives.MODULE} directive"
|
||||
}
|
||||
|
||||
directivesParser.addParsedDirective(parsedDirective)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentTestFileText.appendLine()
|
||||
lastParsedDirective = parsedDirective.directive
|
||||
return@forEachIndexed
|
||||
}
|
||||
}
|
||||
|
||||
if (expectFileDirectiveAfterModuleDirective) {
|
||||
// Was expecting a line with the FILE directive as this is the only possible continuation of a line with
|
||||
// the MODULE directive, but failed.
|
||||
fail { "$location: ${TestDirectives.FILE} directive expected after ${TestDirectives.MODULE} directive" }
|
||||
}
|
||||
|
||||
currentTestFileText.appendLine(line)
|
||||
}
|
||||
|
||||
val location = Location(testDataFile)
|
||||
finishTestFile(forceFinish = true, location)
|
||||
|
||||
val registeredDirectives = directivesParser.build()
|
||||
|
||||
val freeCompilerArgs = parseFreeCompilerArgs(registeredDirectives, location)
|
||||
val expectedOutputDataFile = parseOutputDataFile(baseDir = testDataFile.parentFile, registeredDirectives, location)
|
||||
val testKind = parseTestKind(registeredDirectives, location)
|
||||
|
||||
if (testKind == TestKind.REGULAR) {
|
||||
// Fix package declarations to avoid unintended conflicts between symbols with the same name in different test cases.
|
||||
testModules.values.forEach { testModule ->
|
||||
testModule.files.forEach { testFile -> fixPackageDeclaration(testFile, effectivePackageName, testDataFile) }
|
||||
}
|
||||
}
|
||||
|
||||
val testCase = TestCase(
|
||||
kind = testKind,
|
||||
modules = testModules.values.toSet(),
|
||||
freeCompilerArgs = freeCompilerArgs,
|
||||
origin = TestOrigin.SingleTestDataFile(testDataFile),
|
||||
nominalPackageName = effectivePackageName,
|
||||
expectedOutputDataFile = expectedOutputDataFile,
|
||||
extras = if (testKind == TestKind.STANDALONE_NO_TR) {
|
||||
TestCase.StandaloneNoTestRunnerExtras(
|
||||
entryPoint = parseEntryPoint(registeredDirectives, location),
|
||||
inputDataFile = parseInputDataFile(baseDir = testDataFile.parentFile, registeredDirectives, location)
|
||||
)
|
||||
} else
|
||||
null
|
||||
)
|
||||
testCase.initialize(findSharedModule = null)
|
||||
|
||||
return testCase
|
||||
}
|
||||
|
||||
private fun CharSequence.hasAnythingButComments(): Boolean {
|
||||
var result = false
|
||||
runForFirstMeaningfulStatement { _, _ -> result = true }
|
||||
return result
|
||||
}
|
||||
|
||||
private fun fixPackageDeclaration(
|
||||
testFile: TestFile<TestModule.Exclusive>,
|
||||
packageName: PackageName,
|
||||
testDataFile: File
|
||||
) = testFile.update { text ->
|
||||
var existingPackageDeclarationLine: String? = null
|
||||
var existingPackageDeclarationLineNumber: Int? = null
|
||||
|
||||
text.runForFirstMeaningfulStatement { lineNumber, line ->
|
||||
// First meaningful line.
|
||||
val trimmedLine = line.trim()
|
||||
if (trimmedLine.startsWith("package ")) {
|
||||
existingPackageDeclarationLine = trimmedLine
|
||||
existingPackageDeclarationLineNumber = lineNumber
|
||||
}
|
||||
}
|
||||
|
||||
if (existingPackageDeclarationLine != null) {
|
||||
val existingPackageName = existingPackageDeclarationLine!!.substringAfter("package ").trimStart()
|
||||
assertTrue(
|
||||
existingPackageName == packageName
|
||||
|| (existingPackageName.length > packageName.length
|
||||
&& existingPackageName.startsWith(packageName)
|
||||
&& existingPackageName[packageName.length] == '.')
|
||||
) {
|
||||
val location = Location(testDataFile, existingPackageDeclarationLineNumber)
|
||||
"""
|
||||
$location: Invalid package name declaration found: $existingPackageDeclarationLine
|
||||
Expected: package $packageName
|
||||
""".trimIndent()
|
||||
}
|
||||
text
|
||||
} else
|
||||
"package $packageName $text"
|
||||
}
|
||||
|
||||
private inline fun CharSequence.runForFirstMeaningfulStatement(action: (lineNumber: Int, line: String) -> Unit) {
|
||||
var inMultilineComment = false
|
||||
|
||||
for ((lineNumber, line) in lines().withIndex()) {
|
||||
val trimmedLine = line.trim()
|
||||
when {
|
||||
inMultilineComment -> inMultilineComment = !trimmedLine.endsWith("*/")
|
||||
trimmedLine.startsWith("/*") -> inMultilineComment = true
|
||||
trimmedLine.isMeaningfulLine() -> {
|
||||
action(lineNumber, line)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.isMeaningfulLine() = isNotEmpty() && !startsWith("//") && !startsWith("@file:")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user