Skip to content

Commit

Permalink
introduce test runner
Browse files Browse the repository at this point in the history
### What's done:
* .
  • Loading branch information
kgevorkyan committed May 25, 2023
1 parent 45d1663 commit 6241a32
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 0 deletions.
6 changes: 6 additions & 0 deletions save-common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@ kotlin {
implementation(libs.okio.fakefilesystem)
}
}

val jvmTest by getting {
dependencies {
implementation("junit:junit:4.13.2")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.saveourtool.save.core.annotations

enum class CheckedLanguage {
foo,
bar,
}

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class AnnotationForClass(
val databaseSuffix: String,
val ruleSuffix: String = "txt",
val codeBasePath: String,
val databasePath: String,
val ruleBasePath: String,
val checkedLanguage: CheckedLanguage,
val needParseSourceFile: Boolean = true
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.saveourtool.save.core.annotations

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class AnnotationForMethods(
val sourcePackage: String,
val headerPackage: String = "",
val jarPackage: String = "",
val databaseName: String,
val ruleName: String,
val resultSize: Int = 1,
val valid: Boolean = true
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package com.saveourtool.save.core.runners

import com.saveourtool.save.core.annotations.CheckedLanguage
import com.saveourtool.save.core.annotations.AnnotationForClass
import com.saveourtool.save.core.annotations.AnnotationForMethods
import org.junit.AssumptionViolatedException
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.Description
import org.junit.runner.notification.Failure
import org.junit.runner.notification.RunNotifier
import org.junit.runners.BlockJUnit4ClassRunner
import org.junit.runners.model.FrameworkMethod
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method


/**
* Runner, which provide interface for running tests, by setting configuration via annotations
*/
class CommonTestRunner(private val testClass: Class<*>) : BlockJUnit4ClassRunner(testClass) {
/**
* Run test cases in [testClass], annotated with [AnnotationForClass]
*
*
* If individual test is annotated with [AnnotationForMethods], run doTest()
* otherwise, invoke test as is
*
* @param frameworkMethod running method
* @param notifier notifier, which fires about actual status of test
*/
override fun runChild(
frameworkMethod: FrameworkMethod,
notifier: RunNotifier
) {
val method = frameworkMethod.method
val methodDescription = Description.createTestDescription(
testClass, method.name
)
notifier.fireTestStarted(methodDescription)
try {
if (testClass.isAnnotationPresent(Ignore::class.java) ||
method.isAnnotationPresent(Ignore::class.java)
) {
notifier.fireTestIgnored(methodDescription)
return
}
val testObject = testClass.getDeclaredConstructor().newInstance()
doRunChild(testObject, method, methodDescription, notifier)
notifier.fireTestFinished(methodDescription)
} catch (e: AssumptionViolatedException) {
val failure = Failure(methodDescription, e)
notifier.fireTestAssumptionFailed(failure)
} catch (e: Exception) {
val failure = Failure(methodDescription, e)
notifier.fireTestFailure(failure)
}
}

private fun doRunChild(
testObject: Any,
method: Method,
methodDescription: Description,
notifier: RunNotifier
) {
try {
if (testClass.isAnnotationPresent(Ignore::class.java) || method.isAnnotationPresent(Ignore::class.java)) {
notifier.fireTestIgnored(methodDescription)
return
}
if (testClass.isAnnotationPresent(AnnotationForClass::class.java) &&
method.isAnnotationPresent(Test::class.java) &&
method.isAnnotationPresent(AnnotationForMethods::class.java)
) {
// TODO:
// here you can collect configuration from annotations and do test
// doTest()

// if needed, invoke test itself
method.invoke(testObject)
} else if (testClass.isAnnotationPresent(AnnotationForClass::class.java) &&
method.isAnnotationPresent(Test::class.java)
) {
// support the case, when test is not annotated for some reasons,
// simply run the test
method.invoke(testObject)
}
} catch (e: InvocationTargetException) {
val targetException = e.targetException
// we need to distinguish AssumptionViolatedException separately
if (targetException is AssumptionViolatedException) {
throw targetException
} else {
throw e
}
}
}

// ==================== TestConfigParams Getters ====================== //

private fun databaseSuffix(): String {
return testClass.getAnnotation(AnnotationForClass::class.java).databaseSuffix
}

private fun ruleSuffix(): String {
return testClass.getAnnotation(AnnotationForClass::class.java).ruleSuffix
}

private fun codeBasePath(): String {
return testClass.getAnnotation(AnnotationForClass::class.java).codeBasePath
}

private fun databasePath(): String {
return testClass.getAnnotation(AnnotationForClass::class.java).databasePath
}

private fun ruleBasePath(): String {
return testClass.getAnnotation(AnnotationForClass::class.java).ruleBasePath
}

private fun checkedLanguage(): CheckedLanguage {
return testClass.getAnnotation(AnnotationForClass::class.java).checkedLanguage
}

private fun needParseSourceFile(): Boolean {
return testClass.getAnnotation(AnnotationForClass::class.java).needParseSourceFile
}

// ==================== TestcaseConfigParams Getters ====================== //

private fun sourcePackage(method: Method): String {
return method.getAnnotation(AnnotationForMethods::class.java).sourcePackage
}

private fun headerPackage(method: Method): String {
return method.getAnnotation(AnnotationForMethods::class.java).headerPackage
}

private fun jarPackage(method: Method): String {
return method.getAnnotation(AnnotationForMethods::class.java).jarPackage
}

private fun databaseName(method: Method): String {
return method.getAnnotation(AnnotationForMethods::class.java).databaseName
}

private fun ruleName(method: Method): String {
return method.getAnnotation(AnnotationForMethods::class.java).ruleName
}

private fun resultSize(method: Method): Int {
return method.getAnnotation(AnnotationForMethods::class.java).resultSize
}

private fun valid(method: Method): Boolean {
return method.getAnnotation(AnnotationForMethods::class.java).valid
}
}

0 comments on commit 6241a32

Please sign in to comment.