1
1
Fork 0

improved assertion of interfaces and abstract classes

This commit is contained in:
Pavel Nikolaev 2020-07-30 15:34:41 +02:00
parent fbd569e550
commit bdb3151acc
3 changed files with 40 additions and 33 deletions

View File

@ -4,6 +4,7 @@ import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runners.MethodSorters
import util.*
import kotlin.reflect.KClass
import kotlin.test.assertEquals
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -11,31 +12,21 @@ class TestAbstractClassesExercise1 {
private val packageName = "abstractClassesExercise1"
private fun loadClass(className: String): KClass<*> = loadClass(packageName, className)
@Test
fun `#01 classes structure`() {
loadClass(packageName, "Shape").apply {
assertEquals(
message = "Class should have modifier 'abstract'",
expected = true,
actual = isAbstract
)
loadClass("Shape").apply {
assertIsAbstract()
loadMemberFunction(this, "draw").apply {
assertEquals(
message = "Method 'draw()' should have modifier 'abstract'",
expected = true,
actual = isAbstract
)
assertIsAbstract()
}
loadMemberFunction(this, "erase").apply {
assertEquals(
message = "Method 'erase()' should have modifier 'abstract'",
expected = true,
actual = isAbstract
)
assertIsAbstract()
}
}
listOf("Circle", "Square", "Triangle").forEach {
loadClass(packageName, it).apply {
loadClass(it).apply {
assertDeclaredMemberFunction("draw")
assertDeclaredMemberFunction("erase")
}
@ -44,11 +35,11 @@ class TestAbstractClassesExercise1 {
@Test
fun `#02 shape operations`() {
val (draw, erase) = loadClass(packageName, "Shape").let {
val (draw, erase) = loadClass("Shape").let {
loadMemberFunction(it, "draw") to loadMemberFunction(it, "erase")
}
val shapes = listOf("Circle", "Square", "Triangle").map {
loadClass(packageName, it).createInstance()
loadClass(it).createInstance()
}
shapes.forEach { draw.call(it) }
shapes.forEach { erase.call(it) }

View File

@ -4,6 +4,7 @@ import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runners.MethodSorters
import util.*
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
import kotlin.test.assertEquals
@ -12,25 +13,19 @@ class TestAbstractClassesExercise2 {
private val packageName = "abstractClassesExercise2"
private fun loadClass(className: String): KClass<*> = loadClass(packageName, className)
@Test
fun `#01 classes structure`() {
loadClass(packageName, "Movable").apply {
assertEquals(
message = "$simpleName should be an interface",
expected = true,
actual = isAbstract
)
loadClass("Movable").apply {
assertIsInterface()
assertDeclaredMemberFunction("move")
}
loadClass(packageName, "Sleepable").apply {
assertEquals(
message = "$simpleName should be an interface",
expected = true,
actual = isAbstract
)
loadClass("Sleepable").apply {
assertIsInterface()
assertDeclaredMemberFunction("sleepOn")
}
loadClass(packageName, "Sofa").apply {
loadClass("Sofa").apply {
assertNoDeclaredMemberFunction("move")
assertNoDeclaredMemberFunction("sleepOn")
assertInheritance("Movable", "Sleepable")
@ -39,7 +34,7 @@ class TestAbstractClassesExercise2 {
@Test
fun `#02 sofa operations`() {
loadClass(packageName, "Sofa").apply {
loadClass("Sofa").apply {
val sofa = createInstance()
assertEquals(
message = "Incorrect result of sofa.move() call",

View File

@ -131,6 +131,19 @@ fun loadClass(packageName: String, className: String): KClass<*> {
}
}
fun KClass<*>.assertIsAbstract(expected: Boolean = true) {
assertEquals(
message = "Class ${this.simpleName} should be abstract",
expected = expected,
actual = isAbstract
)
}
fun KClass<*>.assertIsInterface(expected: Boolean = true) {
assertIsAbstract()
assertConstructorNumber(0)
}
fun KClass<*>.assertInheritance(baseClass: KClass<*>) {
assertInherit(true, baseClass)
}
@ -202,6 +215,14 @@ fun KClass<*>.assertNoDeclaredMemberFunction(methodName: String) {
.checkNotFoundEntities("the declared '$methodName' member function", "'$simpleName' class")
}
fun KFunction<*>.assertAbstract(expected: Boolean = true) {
assertEquals(
message = "Method ${this.name}() should be abstract",
expected = expected,
actual = isAbstract
)
}
fun loadMemberProperty(kClass: KClass<*>, propertyName: String): KProperty<*> {
return kClass.memberProperties
.filter { it.name == propertyName }