Allow to mute JUnit 4 tests with parameters
This commit is contained in:
@@ -12,7 +12,6 @@ import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters
|
|||||||
import org.junit.runners.parameterized.ParametersRunnerFactory
|
import org.junit.runners.parameterized.ParametersRunnerFactory
|
||||||
import org.junit.runners.parameterized.TestWithParameters
|
import org.junit.runners.parameterized.TestWithParameters
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.reflect.Method
|
|
||||||
|
|
||||||
private class AutoMute(
|
private class AutoMute(
|
||||||
val file: String,
|
val file: String,
|
||||||
@@ -37,24 +36,44 @@ private class MutedTest(
|
|||||||
@Suppress("unused") val issue: String?,
|
@Suppress("unused") val issue: String?,
|
||||||
val hasFailFile: Boolean
|
val hasFailFile: Boolean
|
||||||
) {
|
) {
|
||||||
val methodName = key.substringAfterLast(".", "").replace("`", "").also {
|
val methodKey: String
|
||||||
if (it.isEmpty()) throw IllegalArgumentException("Can't get method name")
|
val classNameKey: String
|
||||||
|
val simpleClassName: String
|
||||||
|
|
||||||
|
init {
|
||||||
|
val noQuoteKey = key.replace("`", "")
|
||||||
|
val beforeParamsKey = noQuoteKey.substringBefore("[")
|
||||||
|
val params = noQuoteKey.substringAfterWithDelimiter("[", "")
|
||||||
|
|
||||||
|
methodKey = (beforeParamsKey.substringAfterLast(".", "") + params)
|
||||||
|
.also {
|
||||||
|
if (it.isEmpty()) throw IllegalArgumentException("Can't get method name")
|
||||||
|
}
|
||||||
|
|
||||||
|
classNameKey = beforeParamsKey.substringBeforeLast(".", "").also {
|
||||||
|
if (it.isEmpty()) throw IllegalArgumentException("Can't get class name")
|
||||||
|
}
|
||||||
|
|
||||||
|
simpleClassName = classNameKey.substringAfterLast(".")
|
||||||
}
|
}
|
||||||
val classNameKey = key.substringBeforeLast(".", "").also {
|
|
||||||
if (it.isEmpty()) throw IllegalArgumentException("Can't get class name")
|
companion object {
|
||||||
|
fun String.substringAfterWithDelimiter(delimiter: String, missingDelimiterValue: String = this): String {
|
||||||
|
val index = indexOf(delimiter)
|
||||||
|
return if (index == -1) missingDelimiterValue else (delimiter + substring(index + 1, length))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val simpleClassName = classNameKey.substringAfterLast(".")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MutedSet(muted: List<MutedTest>) {
|
private class MutedSet(muted: List<MutedTest>) {
|
||||||
// Method name -> Simple class name -> List of muted tests
|
// Method key -> Simple class name -> List of muted tests
|
||||||
private val cache: Map<String, Map<String, List<MutedTest>>> =
|
private val cache: Map<String, Map<String, List<MutedTest>>> =
|
||||||
muted
|
muted
|
||||||
.groupBy { it.methodName } // Method name -> List of muted tests
|
.groupBy { it.methodKey } // Method key -> List of muted tests
|
||||||
.mapValues { (_, tests) -> tests.groupBy { it.simpleClassName } }
|
.mapValues { (_, tests) -> tests.groupBy { it.simpleClassName } }
|
||||||
|
|
||||||
fun mutedTest(testClass: Class<*>, methodName: String): MutedTest? {
|
fun mutedTest(testClass: Class<*>, methodKey: String): MutedTest? {
|
||||||
val mutedTests = cache[methodName]?.get(testClass.simpleName) ?: return null
|
val mutedTests = cache[methodKey]?.get(testClass.simpleName) ?: return null
|
||||||
|
|
||||||
return mutedTests.firstOrNull { mutedTest ->
|
return mutedTests.firstOrNull { mutedTest ->
|
||||||
testClass.canonicalName.endsWith(mutedTest.classNameKey)
|
testClass.canonicalName.endsWith(mutedTest.classNameKey)
|
||||||
@@ -85,14 +104,21 @@ private fun loadMutedTests(file: File): List<MutedTest> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val MUTE_LINE_PARSE_REGEXP = Regex("^([^,\\[]+)(\\[[^]]+])?(,\\s*)?([^,]+)?(,\\s*)?([^,]+)?$")
|
||||||
|
|
||||||
private fun parseMutedTest(str: String): MutedTest {
|
private fun parseMutedTest(str: String): MutedTest {
|
||||||
val components = str.splitToSequence(",").map { it.trim() }.toList()
|
val matchResult = MUTE_LINE_PARSE_REGEXP.matchEntire(str) ?: throw ParseError("Can't parse the line: $str")
|
||||||
|
|
||||||
val key = components.getOrNull(0) ?: throw ParseError("Test key is absent (1 column): $str")
|
val methodFull = matchResult.groups[1]?.value ?: throw ParseError("Test key is absent (1 column): $str")
|
||||||
|
val params = matchResult.groups[2]?.value ?: ""
|
||||||
|
|
||||||
val issue = components.getOrNull(1)
|
val key = methodFull + params
|
||||||
|
|
||||||
val hasFailFile = when (val stateStr = components.getOrNull(2)) {
|
val issue = matchResult.groups[4]?.value
|
||||||
|
|
||||||
|
val stateStr = matchResult.groups[6]?.value
|
||||||
|
|
||||||
|
val hasFailFile = when (stateStr) {
|
||||||
"MUTE", "", null -> false
|
"MUTE", "", null -> false
|
||||||
"FAIL" -> true
|
"FAIL" -> true
|
||||||
else -> throw ParseError("Invalid state (`$stateStr`), MUTE, FAIL or empty are expected: $str")
|
else -> throw ParseError("Invalid state (`$stateStr`), MUTE, FAIL or empty are expected: $str")
|
||||||
@@ -115,12 +141,8 @@ internal fun isMutedInDatabase(testCase: TestCase): Boolean {
|
|||||||
return isMutedInDatabase(testCase.javaClass, testCase.name)
|
return isMutedInDatabase(testCase.javaClass, testCase.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isMutedInDatabase(method: Method): Boolean {
|
fun isMutedInDatabase(testClass: Class<*>, methodKey: String): Boolean {
|
||||||
return isMutedInDatabase(method.declaringClass, method.name)
|
val mutedTest = mutedSet.mutedTest(testClass, methodKey)
|
||||||
}
|
|
||||||
|
|
||||||
fun isMutedInDatabase(testClass: Class<*>, methodName: String): Boolean {
|
|
||||||
val mutedTest = mutedSet.mutedTest(testClass, methodName)
|
|
||||||
return mutedTest != null && !mutedTest.hasFailFile
|
return mutedTest != null && !mutedTest.hasFailFile
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,22 +174,28 @@ internal fun wrapWithMuteInDatabase(testCase: TestCase, f: () -> Unit): (() -> U
|
|||||||
|
|
||||||
private fun mutedMessage(key: String) = "MUTED TEST: $key"
|
private fun mutedMessage(key: String) = "MUTED TEST: $key"
|
||||||
|
|
||||||
private fun testKey(testCase: TestCase) = "${testCase::class.java.canonicalName}.${testCase.name}"
|
private fun testKey(klass: Class<*>, methodKey: String) = "${klass.canonicalName}.$methodKey"
|
||||||
private fun testKey(method: Method) = "${method.declaringClass.canonicalName}.${method.name}"
|
private fun testKey(testCase: TestCase) = testKey(testCase::class.java, testCase.name)
|
||||||
|
|
||||||
class RunnerFactoryWithMuteInDatabase: ParametersRunnerFactory {
|
class RunnerFactoryWithMuteInDatabase: ParametersRunnerFactory {
|
||||||
override fun createRunnerForTestWithParameters(test: TestWithParameters?): Runner {
|
override fun createRunnerForTestWithParameters(test: TestWithParameters?): Runner {
|
||||||
return object : BlockJUnit4ClassRunnerWithParameters(test) {
|
return object : BlockJUnit4ClassRunnerWithParameters(test) {
|
||||||
override fun isIgnored(child: FrameworkMethod): Boolean {
|
override fun isIgnored(child: FrameworkMethod): Boolean {
|
||||||
return super.isIgnored(child) || isIgnoredInDatabaseWithLog(child)
|
return super.isIgnored(child) || isIgnoredInDatabaseWithLog(child, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isIgnoredInDatabaseWithLog(child: FrameworkMethod): Boolean {
|
fun isIgnoredInDatabaseWithLog(child: FrameworkMethod, parametersName: String): Boolean {
|
||||||
if (isMutedInDatabase(child.method)) {
|
if (isMutedInDatabase(child.declaringClass, child.name)) {
|
||||||
System.err.println(mutedMessage(testKey(child.method)))
|
System.err.println(mutedMessage(testKey(child.declaringClass, child.name)))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
val methodWithParametersKey = child.method.name + parametersName
|
||||||
|
if (isMutedInDatabase(child.declaringClass, methodWithParametersKey)) {
|
||||||
|
System.err.println(mutedMessage(testKey(child.declaringClass, methodWithParametersKey)))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user