Support several spec places to which tests are linked and require specify spec version for each test
This commit is contained in:
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.spec.models
|
||||
import org.jetbrains.kotlin.spec.*
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.issuesPattern
|
||||
import org.jetbrains.kotlin.spec.parsers.LinkedSpecTestPatterns.relevantPlacesPattern
|
||||
import org.jetbrains.kotlin.spec.parsers.TestCasePatterns.testCaseNumberPattern
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
@@ -28,7 +29,6 @@ enum class CommonSpecTestFileInfoElementType(
|
||||
override val valuePattern: Pattern? = null,
|
||||
override val required: Boolean = false
|
||||
) : SpecTestInfoElementType {
|
||||
SECTIONS(valuePattern = CommonPatterns.sectionsInFilePattern, required = true),
|
||||
NUMBER(required = true),
|
||||
DESCRIPTION(required = true)
|
||||
}
|
||||
@@ -37,7 +37,8 @@ enum class SpecTestCaseInfoElementType(
|
||||
override val valuePattern: Pattern? = null,
|
||||
override val required: Boolean = false
|
||||
) : SpecTestInfoElementType {
|
||||
TESTCASE_NUMBER(valuePattern = testCaseNumberPattern, required = true)
|
||||
TESTCASE_NUMBER(valuePattern = testCaseNumberPattern, required = true),
|
||||
RELEVANT_PLACES(valuePattern = relevantPlacesPattern),
|
||||
}
|
||||
|
||||
abstract class AbstractSpecTest(
|
||||
|
||||
@@ -13,7 +13,8 @@ import org.jetbrains.kotlin.spec.parsers.CommonPatterns.ls
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonParser.withUnderscores
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonParser.splitByPathSeparator
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonParser.withSpaces
|
||||
import org.jetbrains.kotlin.spec.parsers.LinkedSpecTestPatterns.sentencePattern
|
||||
import org.jetbrains.kotlin.spec.parsers.LinkedSpecTestPatterns.placePattern
|
||||
import org.jetbrains.kotlin.spec.parsers.LinkedSpecTestPatterns.relevantPlacesPattern
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -21,37 +22,44 @@ enum class LinkedSpecTestFileInfoElementType(
|
||||
override val valuePattern: Pattern? = null,
|
||||
override val required: Boolean = false
|
||||
) : SpecTestInfoElementType {
|
||||
PARAGRAPH(required = true),
|
||||
SENTENCE(valuePattern = sentencePattern, required = true)
|
||||
SPEC_VERSION(required = true),
|
||||
PLACE(valuePattern = placePattern, required = true),
|
||||
RELEVANT_PLACES(valuePattern = relevantPlacesPattern)
|
||||
}
|
||||
|
||||
data class SpecPlace(
|
||||
val sections: List<String>,
|
||||
val paragraphNumber: Int,
|
||||
val sentenceNumber: Int
|
||||
)
|
||||
|
||||
class LinkedSpecTest(
|
||||
private val specVersion: String,
|
||||
testArea: TestArea,
|
||||
testType: TestType,
|
||||
sections: List<String>,
|
||||
val paragraphNumber: Int,
|
||||
val sentenceNumber: Int,
|
||||
private val sentence: String,
|
||||
val place: SpecPlace,
|
||||
private val relevantPlaces: List<SpecPlace>?,
|
||||
testNumber: Int,
|
||||
description: String,
|
||||
cases: SpecTestCasesSet,
|
||||
unexpectedBehavior: Boolean,
|
||||
issues: Set<String>
|
||||
) : AbstractSpecTest(testArea, testType, sections, testNumber, description, cases, unexpectedBehavior, issues) {
|
||||
) : AbstractSpecTest(testArea, testType, place.sections, testNumber, description, cases, unexpectedBehavior, issues) {
|
||||
override fun checkPathConsistency(pathMatcher: Matcher) =
|
||||
testArea == TestArea.valueOf(pathMatcher.group("testArea").withUnderscores())
|
||||
&& testType == TestType.fromValue(pathMatcher.group("testType"))!!
|
||||
&& sections == pathMatcher.group("sections").splitByPathSeparator()
|
||||
&& paragraphNumber == pathMatcher.group("paragraphNumber").toInt()
|
||||
&& sentenceNumber == pathMatcher.group("sentenceNumber").toInt()
|
||||
&& place.paragraphNumber == pathMatcher.group("paragraphNumber").toInt()
|
||||
&& place.sentenceNumber == pathMatcher.group("sentenceNumber").toInt()
|
||||
&& testNumber == pathMatcher.group("testNumber").toInt()
|
||||
|
||||
override fun toString() = buildString {
|
||||
append("--------------------------------------------------$ls")
|
||||
super.getUnexpectedBehaviourText()?.let { append(it + ls) }
|
||||
append("${testArea.name.withSpaces()} $testType SPEC TEST (${testType.toString().withSpaces()})$ls")
|
||||
append("SECTIONS: ${sections.joinToString()} (paragraph: $paragraphNumber)$ls")
|
||||
append("SENTENCE $sentenceNumber: $sentence$ls")
|
||||
append("SPEC VERSION: $specVersion$ls")
|
||||
append("SPEC PLACE: ${sections.joinToString()} -> paragraph: ${place.paragraphNumber} -> sentence: ${place.sentenceNumber}$ls")
|
||||
relevantPlaces?.let { append("OTHER RELEVANT SPEC PLACES:${it.joinToString { "$ls\t${sections.joinToString()} -> paragraph: ${place.paragraphNumber} -> sentence: ${place.sentenceNumber}" }}$ls") }
|
||||
append("NUMBER: $testNumber$ls")
|
||||
append("TEST CASES: ${cases.byNumbers.size.coerceAtLeast(1)}$ls")
|
||||
append("DESCRIPTION: $description$ls")
|
||||
|
||||
@@ -13,13 +13,16 @@ import org.jetbrains.kotlin.spec.parsers.CommonParser.splitByPathSeparator
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonParser.withUnderscores
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonParser.withSpaces
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.ls
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.sectionsInFilePattern
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
|
||||
enum class NotLinkedSpecTestFileInfoElementType(
|
||||
override val valuePattern: Pattern? = null,
|
||||
override val required: Boolean = false
|
||||
) : SpecTestInfoElementType
|
||||
) : SpecTestInfoElementType {
|
||||
SECTIONS(valuePattern = sectionsInFilePattern, required = true)
|
||||
}
|
||||
|
||||
class NotLinkedSpecTest(
|
||||
testArea: TestArea,
|
||||
|
||||
@@ -8,16 +8,14 @@ package org.jetbrains.kotlin.spec.parsers
|
||||
import org.jetbrains.kotlin.spec.*
|
||||
import org.jetbrains.kotlin.spec.SpecTestInfoElementContent
|
||||
import org.jetbrains.kotlin.spec.SpecTestLinkedType
|
||||
import org.jetbrains.kotlin.spec.models.LinkedSpecTest
|
||||
import org.jetbrains.kotlin.spec.models.LinkedSpecTestFileInfoElementType
|
||||
import org.jetbrains.kotlin.spec.models.NotLinkedSpecTest
|
||||
import org.jetbrains.kotlin.spec.models.SpecTestInfoElements
|
||||
import org.jetbrains.kotlin.spec.models.*
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.testInfoElementPattern
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.testPathBaseRegexTemplate
|
||||
import org.jetbrains.kotlin.spec.parsers.LinkedSpecTestPatterns.testInfoPattern
|
||||
import org.jetbrains.kotlin.spec.parsers.TestCasePatterns.testCaseInfoPattern
|
||||
import org.jetbrains.kotlin.spec.validators.*
|
||||
import java.io.File
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
|
||||
object CommonParser {
|
||||
@@ -41,18 +39,33 @@ object CommonParser {
|
||||
throw SpecTestValidationException(SpecTestValidationFailedReason.FILENAME_NOT_VALID)
|
||||
}
|
||||
|
||||
private fun createSpecPlace(placeMatcher: Matcher, basePlaceMatcher: Matcher = placeMatcher) =
|
||||
SpecPlace(
|
||||
placeMatcher.group("sections")?.splitByComma() ?: basePlaceMatcher.group("sections").splitByComma(),
|
||||
placeMatcher.group("paragraphNumber")?.toInt() ?: basePlaceMatcher.group("paragraphNumber").toInt(),
|
||||
placeMatcher.group("sentenceNumber").toInt()
|
||||
)
|
||||
|
||||
private fun parseLinkedSpecTest(testFilePath: String, testFiles: TestFiles): LinkedSpecTest {
|
||||
val parsedTestFile = parseTestInfo(testFilePath, testFiles, SpecTestLinkedType.LINKED)
|
||||
val testInfoElements = parsedTestFile.testInfoElements
|
||||
val sentenceMatcher = testInfoElements[LinkedSpecTestFileInfoElementType.SENTENCE]!!.additionalMatcher!!
|
||||
val placeMatcher = testInfoElements[LinkedSpecTestFileInfoElementType.PLACE]!!.additionalMatcher!!
|
||||
val relevantPlacesMatcher = testInfoElements[LinkedSpecTestFileInfoElementType.RELEVANT_PLACES]?.additionalMatcher
|
||||
val relevantPlaces = relevantPlacesMatcher?.let {
|
||||
mutableListOf<SpecPlace>().apply {
|
||||
add(createSpecPlace(it, placeMatcher))
|
||||
while (it.find()) {
|
||||
add(createSpecPlace(it, placeMatcher))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LinkedSpecTest(
|
||||
testInfoElements[LinkedSpecTestFileInfoElementType.SPEC_VERSION]!!.content,
|
||||
parsedTestFile.testArea,
|
||||
parsedTestFile.testType,
|
||||
parsedTestFile.sections,
|
||||
testInfoElements[LinkedSpecTestFileInfoElementType.PARAGRAPH]!!.content.toInt(),
|
||||
sentenceMatcher.group("number").toInt(),
|
||||
sentenceMatcher.group("text"),
|
||||
createSpecPlace(placeMatcher),
|
||||
relevantPlaces,
|
||||
parsedTestFile.testNumber,
|
||||
parsedTestFile.testDescription,
|
||||
parsedTestFile.testCasesSet,
|
||||
@@ -63,11 +76,13 @@ object CommonParser {
|
||||
|
||||
private fun parseNotLinkedSpecTest(testFilePath: String, testFiles: TestFiles): NotLinkedSpecTest {
|
||||
val parsedTestFile = parseTestInfo(testFilePath, testFiles, SpecTestLinkedType.NOT_LINKED)
|
||||
val testInfoElements = parsedTestFile.testInfoElements
|
||||
val sectionsMatcher = testInfoElements[NotLinkedSpecTestFileInfoElementType.SECTIONS]!!.additionalMatcher!!
|
||||
|
||||
return NotLinkedSpecTest(
|
||||
parsedTestFile.testArea,
|
||||
parsedTestFile.testType,
|
||||
parsedTestFile.sections,
|
||||
sectionsMatcher.group("sections").splitByComma(),
|
||||
parsedTestFile.testNumber,
|
||||
parsedTestFile.testDescription,
|
||||
parsedTestFile.testCasesSet,
|
||||
|
||||
@@ -13,12 +13,13 @@ import org.jetbrains.kotlin.spec.parsers.CommonPatterns.INTEGER_REGEX
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.SINGLE_LINE_COMMENT_REGEX
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.ASTERISK_REGEX
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.directiveRegex
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.multilineCommentRegex
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.MULTILINE_COMMENT_REGEX
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.ps
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.testAreaRegex
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.testPathRegexTemplate
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.testTypeRegex
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonParser.withSpaces
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.SECTIONS_IN_FILE_REGEX
|
||||
import org.jetbrains.kotlin.spec.parsers.CommonPatterns.sectionsInPathRegex
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
@@ -28,20 +29,21 @@ object CommonPatterns {
|
||||
const val INTEGER_REGEX = """[1-9]\d*"""
|
||||
const val SINGLE_LINE_COMMENT_REGEX = """\/\/\s*%s"""
|
||||
const val ASTERISK_REGEX = """\*"""
|
||||
const val SECTIONS_IN_FILE_REGEX = """[\w-]+(,\s+[\w-]+)*"""
|
||||
const val MULTILINE_COMMENT_REGEX = """\/\*\s+?%s\s+\*\/(?:\n)*"""
|
||||
|
||||
val ls: String = System.lineSeparator()
|
||||
val ps: String = Pattern.quote(File.separator)
|
||||
|
||||
val multilineCommentRegex = """\/\*\s+?%s\s+\*\/(?:\n)*"""
|
||||
val directiveRegex =
|
||||
"""${SINGLE_LINE_COMMENT_REGEX.format("""[\w\s]+:""")}|${multilineCommentRegex.format(""" $ASTERISK_REGEX [\w\s]+:[\s\S]*?""")}"""
|
||||
"""${SINGLE_LINE_COMMENT_REGEX.format("""[\w\s]+:""")}|${MULTILINE_COMMENT_REGEX.format(""" $ASTERISK_REGEX [\w\s]+:[\s\S]*?""")}"""
|
||||
val testAreaRegex = """(?<testArea>${TestArea.joinedValues})"""
|
||||
val testTypeRegex = """(?<testType>${TestType.joinedValues})"""
|
||||
val testInfoElementPattern: Pattern = Pattern.compile("""(?: \* )?(?<name>[A-Z ]+?)(?::\s*(?<value>.*?))?\n""")
|
||||
val testPathBaseRegexTemplate = """^.*?$ps(?<testArea>diagnostics|psi|(?:codegen${ps}box))$ps%s"""
|
||||
val testPathRegexTemplate = """$testPathBaseRegexTemplate$ps(?<testType>pos|neg)$ps%s$"""
|
||||
val issuesPattern: Pattern = Pattern.compile("""(KT-[1-9]\d*)(,\s*KT-[1-9]\d*)*""")
|
||||
val sectionsInFilePattern: Pattern = Pattern.compile("""\w+(,\s+\w+)*""")
|
||||
val sectionsInFilePattern: Pattern = Pattern.compile("""(?<sections>$SECTIONS_IN_FILE_REGEX)""")
|
||||
val sectionsInPathRegex = """(?<sections>(?:[\w-]+)(?:$ps[\w-]+)*?)"""
|
||||
val packagePattern: Pattern = Pattern.compile("""(?:^|\n)package (?<packageName>.*?)(?:;|\n)""")
|
||||
}
|
||||
@@ -59,7 +61,7 @@ object NotLinkedSpecTestPatterns : BasePatterns {
|
||||
override val testPathPattern: Pattern =
|
||||
Pattern.compile(testPathRegexTemplate.format(pathPartRegex, FILENAME_REGEX))
|
||||
override val testInfoPattern: Pattern =
|
||||
Pattern.compile(multilineCommentRegex.format(""" $ASTERISK_REGEX KOTLIN $testAreaRegex NOT LINKED SPEC TEST \($testTypeRegex\)\n(?<infoElements>[\s\S]*?\n)"""))
|
||||
Pattern.compile(MULTILINE_COMMENT_REGEX.format(""" $ASTERISK_REGEX KOTLIN $testAreaRegex NOT LINKED SPEC TEST \($testTypeRegex\)\n(?<infoElements>[\s\S]*?\n)"""))
|
||||
}
|
||||
|
||||
object LinkedSpecTestPatterns : BasePatterns {
|
||||
@@ -70,9 +72,13 @@ object LinkedSpecTestPatterns : BasePatterns {
|
||||
override val testPathPattern: Pattern =
|
||||
Pattern.compile(testPathRegexTemplate.format(pathPartRegex, FILENAME_REGEX))
|
||||
override val testInfoPattern: Pattern =
|
||||
Pattern.compile(multilineCommentRegex.format(""" $ASTERISK_REGEX KOTLIN $testAreaRegex SPEC TEST \($testTypeRegex\)\n(?<infoElements>[\s\S]*?\n)"""))
|
||||
Pattern.compile(MULTILINE_COMMENT_REGEX.format(""" $ASTERISK_REGEX KOTLIN $testAreaRegex SPEC TEST \($testTypeRegex\)\n(?<infoElements>[\s\S]*?\n)"""))
|
||||
|
||||
val sentencePattern: Pattern = Pattern.compile("""^\[(?<number>$INTEGER_REGEX)\]\s*(?<text>.*?)$""")
|
||||
val placePattern: Pattern =
|
||||
Pattern.compile("""(?<sections>$SECTIONS_IN_FILE_REGEX) -> paragraph (?<paragraphNumber>$INTEGER_REGEX) -> sentence (?<sentenceNumber>$INTEGER_REGEX)""")
|
||||
|
||||
val relevantPlacesPattern: Pattern =
|
||||
Pattern.compile("""(( $ASTERISK_REGEX )?\s*((?<sections>$SECTIONS_IN_FILE_REGEX) -> )?(paragraph (?<paragraphNumber>$INTEGER_REGEX) -> )?sentence (?<sentenceNumber>$INTEGER_REGEX))+""")
|
||||
}
|
||||
|
||||
object TestCasePatterns {
|
||||
@@ -85,7 +91,7 @@ object TestCasePatterns {
|
||||
testCaseInfoElementsRegex.format("infoElementsSL", "", """\s*.""")
|
||||
) + testCaseInfoRegex.format("codeSL", "nextDirectiveSL")
|
||||
private val testCaseInfoMultilineRegex =
|
||||
multilineCommentRegex.format(
|
||||
MULTILINE_COMMENT_REGEX.format(
|
||||
testCaseInfoElementsRegex.format("infoElementsML", """ $ASTERISK_REGEX """, """[\s\S]""")
|
||||
) + testCaseInfoRegex.format("codeML", "nextDirectiveML")
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import java.io.File
|
||||
data class ParsedTestFile(
|
||||
val testArea: TestArea,
|
||||
val testType: TestType,
|
||||
val sections: List<String>,
|
||||
val testNumber: Int,
|
||||
val testDescription: String,
|
||||
val testInfoElements: SpecTestInfoElements<SpecTestInfoElementType>,
|
||||
@@ -47,7 +46,6 @@ fun parseTestInfo(testFilePath: String, testFiles: TestFiles, linkedTestType: Sp
|
||||
return ParsedTestFile(
|
||||
testArea = TestArea.valueOf(testInfoByContentMatcher.group("testArea").withUnderscores()),
|
||||
testType = TestType.valueOf(testInfoByContentMatcher.group("testType")),
|
||||
sections = testInfoElements[CommonSpecTestFileInfoElementType.SECTIONS]!!.content.splitByComma(),
|
||||
testNumber = testInfoElements[CommonSpecTestFileInfoElementType.NUMBER]!!.content.toInt(),
|
||||
testDescription = testInfoElements[CommonSpecTestFileInfoElementType.DESCRIPTION]!!.content,
|
||||
testInfoElements = testInfoElements,
|
||||
|
||||
@@ -20,8 +20,8 @@ object TestsJsonMapBuilder {
|
||||
|
||||
fun buildJsonElement(testInfo: LinkedSpecTest, testsMap: JsonObject) {
|
||||
val sectionElement = addJsonIfNotExist(testsMap, testInfo.sections[0])
|
||||
val paragraphElement = addJsonIfNotExist(sectionElement, testInfo.paragraphNumber)
|
||||
val sentenceElement = addJsonIfNotExist(paragraphElement, testInfo.sentenceNumber)
|
||||
val paragraphElement = addJsonIfNotExist(sectionElement, testInfo.place.paragraphNumber)
|
||||
val sentenceElement = addJsonIfNotExist(paragraphElement, testInfo.place.sentenceNumber)
|
||||
val testAreaElement = addJsonIfNotExist(sentenceElement, testInfo.testArea.name.toLowerCase())
|
||||
val testTypeElement = addJsonIfNotExist(testAreaElement, testInfo.testType.type)
|
||||
val testNumberElement = addJsonIfNotExist(testTypeElement, testInfo.testNumber)
|
||||
|
||||
Reference in New Issue
Block a user