[Test] Add ability to specify directive for test file

Rules of directives resolving:
- If no `MODULE` or `FILE` was declared in test then all directives
  belongs to module
- If `FILE` is declared, then all directives after it will belong to
  file until next `FILE` or `MODULE` directive will be declared
- All directives between `MODULE` and `FILE` directives belongs to module
- All directives before first `MODULE` are global and belongs to each
  declared module
This commit is contained in:
Dmitriy Novozhilov
2021-01-15 14:01:42 +03:00
committed by TeamCityServer
parent e17153fab9
commit 28cff22cd0
3 changed files with 34 additions and 6 deletions
@@ -43,7 +43,8 @@ class TestFile(
* isAdditional means that this file provided as addition to sources of testdata * isAdditional means that this file provided as addition to sources of testdata
* and there is no need to apply any handlers or preprocessors over it * and there is no need to apply any handlers or preprocessors over it
*/ */
val isAdditional: Boolean val isAdditional: Boolean,
val directives: RegisteredDirectives
) { ) {
val name: String = relativePath.split("/").last() val name: String = relativePath.split("/").last()
} }
@@ -26,7 +26,14 @@ abstract class AdditionalSourceProvider(val testServices: TestServices) {
} }
protected fun File.toTestFile(): TestFile { protected fun File.toTestFile(): TestFile {
return TestFile(this.name, this.readText(), this, startLineNumberInOriginalFile = 0, isAdditional = true) return TestFile(
this.name,
this.readText(),
originalFile = this,
startLineNumberInOriginalFile = 0,
isAdditional = true,
directives = RegisteredDirectives.Empty
)
} }
} }
@@ -25,6 +25,14 @@ import org.jetbrains.kotlin.test.util.joinToArrayString
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import java.io.File import java.io.File
/*
* Rules of directives resolving:
* - If no `MODULE` or `FILE` was declared in test then all directives belongs to module
* - If `FILE` is declared, then all directives after it will belong to
* file until next `FILE` or `MODULE` directive will be declared
* - All directives between `MODULE` and `FILE` directives belongs to module
* - All directives before first `MODULE` are global and belongs to each declared module
*/
class ModuleStructureExtractorImpl( class ModuleStructureExtractorImpl(
testServices: TestServices, testServices: TestServices,
additionalSourceProviders: List<AdditionalSourceProvider>, additionalSourceProviders: List<AdditionalSourceProvider>,
@@ -32,6 +40,7 @@ class ModuleStructureExtractorImpl(
) : ModuleStructureExtractor(testServices, additionalSourceProviders) { ) : ModuleStructureExtractor(testServices, additionalSourceProviders) {
companion object { companion object {
private val allowedExtensionsForFiles = listOf(".kt", ".kts", ".java") private val allowedExtensionsForFiles = listOf(".kt", ".kts", ".java")
/* /*
* ([\w-]+) module name * ([\w-]+) module name
* \((.*?)\) module dependencies * \((.*?)\) module dependencies
@@ -82,12 +91,14 @@ class ModuleStructureExtractorImpl(
private var startLineNumberOfCurrentFile = 0 private var startLineNumberOfCurrentFile = 0
private var directivesBuilder = RegisteredDirectivesParser(directivesContainer, assertions) private var directivesBuilder = RegisteredDirectivesParser(directivesContainer, assertions)
private var moduleDirectivesBuilder: RegisteredDirectivesParser = directivesBuilder
private var fileDirectivesBuilder: RegisteredDirectivesParser? = null
private var globalDirectives: RegisteredDirectives? = null private var globalDirectives: RegisteredDirectives? = null
private val modules = mutableListOf<TestModule>() private val modules = mutableListOf<TestModule>()
private val moduleDirectiveBuilder = RegisteredDirectivesParser(ModuleStructureDirectives, assertions) private val moduleStructureDirectiveBuilder = RegisteredDirectivesParser(ModuleStructureDirectives, assertions)
fun splitTestDataByModules(): TestModuleStructure { fun splitTestDataByModules(): TestModuleStructure {
for (testDataFile in testDataFiles) { for (testDataFile in testDataFiles) {
@@ -143,7 +154,7 @@ class ModuleStructureExtractorImpl(
*/ */
private fun tryParseStructureDirective(rawDirective: RegisteredDirectivesParser.RawDirective?, lineNumber: Int): Boolean { private fun tryParseStructureDirective(rawDirective: RegisteredDirectivesParser.RawDirective?, lineNumber: Int): Boolean {
if (rawDirective == null) return false if (rawDirective == null) return false
val (directive, values) = moduleDirectiveBuilder.convertToRegisteredDirective(rawDirective) ?: return false val (directive, values) = moduleStructureDirectiveBuilder.convertToRegisteredDirective(rawDirective) ?: return false
when (directive) { when (directive) {
ModuleStructureDirectives.MODULE -> { ModuleStructureDirectives.MODULE -> {
/* /*
@@ -236,7 +247,7 @@ class ModuleStructureExtractorImpl(
private fun finishModule() { private fun finishModule() {
finishFile() finishFile()
val moduleDirectives = directivesBuilder.build() + testServices.defaultDirectives + globalDirectives val moduleDirectives = moduleDirectivesBuilder.build() + testServices.defaultDirectives + globalDirectives
currentModuleLanguageVersionSettingsBuilder.configureUsingDirectives(moduleDirectives, environmentConfigurators) currentModuleLanguageVersionSettingsBuilder.configureUsingDirectives(moduleDirectives, environmentConfigurators)
val moduleName = currentModuleName ?: defaultModuleName val moduleName = currentModuleName ?: defaultModuleName
val testModule = TestModule( val testModule = TestModule(
@@ -293,7 +304,8 @@ class ModuleStructureExtractorImpl(
originalContent = linesOfCurrentFile.joinToString(separator = "\n", postfix = "\n"), originalContent = linesOfCurrentFile.joinToString(separator = "\n", postfix = "\n"),
originalFile = currentTestDataFile, originalFile = currentTestDataFile,
startLineNumberInOriginalFile = startLineNumberOfCurrentFile, startLineNumberInOriginalFile = startLineNumberOfCurrentFile,
isAdditional = false isAdditional = false,
directives = fileDirectivesBuilder?.build() ?: RegisteredDirectives.Empty
) )
) )
firstFileInModule = false firstFileInModule = false
@@ -310,15 +322,23 @@ class ModuleStructureExtractorImpl(
filesOfCurrentModule = mutableListOf() filesOfCurrentModule = mutableListOf()
dependenciesOfCurrentModule = mutableListOf() dependenciesOfCurrentModule = mutableListOf()
friendsOfCurrentModule = mutableListOf() friendsOfCurrentModule = mutableListOf()
resetDirectivesBuilder()
moduleDirectivesBuilder = directivesBuilder
}
private fun resetDirectivesBuilder() {
directivesBuilder = RegisteredDirectivesParser(directivesContainer, assertions) directivesBuilder = RegisteredDirectivesParser(directivesContainer, assertions)
} }
private fun resetFileCaches() { private fun resetFileCaches() {
if (!firstFileInModule) { if (!firstFileInModule) {
linesOfCurrentFile = mutableListOf() linesOfCurrentFile = mutableListOf()
moduleDirectivesBuilder = directivesBuilder
} }
currentFileName = null currentFileName = null
startLineNumberOfCurrentFile = 0 startLineNumberOfCurrentFile = 0
resetDirectivesBuilder()
fileDirectivesBuilder = directivesBuilder
} }
private fun tryParseRegularDirective(rawDirective: RegisteredDirectivesParser.RawDirective?) { private fun tryParseRegularDirective(rawDirective: RegisteredDirectivesParser.RawDirective?) {