1
1
Fork 0

Inheritance & Extensions/Exercise 2 rewording

This commit is contained in:
Pavel Nikolaev 2020-07-30 20:14:53 +02:00
parent 5874b94d44
commit 70902156fe
2 changed files with 82 additions and 11 deletions

View File

@ -1,11 +1,59 @@
package inheritanceAndExtensionsExercise2
import org.junit.FixMethodOrder
import org.junit.Test
import util.unimplementedTest
import org.junit.runners.MethodSorters
import util.*
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
import kotlin.test.assertEquals
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class TestInheritanceAndExtensionsExercise2 {
@Test fun testSolution() {
//TODO: implement your test here
unimplementedTest()
private val packageName = "inheritanceAndExtensionsExercise2"
private fun loadClass(className: String): KClass<*> = loadClass(packageName, className)
@Test
fun `#01 classes structure`() {
val dogClass = loadClass("Dog").apply {
assertOpen()
assertNoInheritance()
assertDeclaredMemberFunction("speak")
assertDeclaredMemberFunction("sit")
}
val realDogClass = loadClass("RealDog").apply {
assertOpen()
assertInheritance("Dog")
assertDeclaredMemberFunction("feed")
}
val toyDogClass = loadClass("ToyDog").apply {
assertInheritance("Dog")
assertDeclaredMemberFunction("speak")
assertDeclaredMemberFunction("changeBatteries")
}
val fileFacade = loadFileFacade(packageName)
loadToplevelFunction(fileFacade, "play", dogClass)
loadToplevelFunction(fileFacade, "play", realDogClass)
loadToplevelFunction(fileFacade, "play", toyDogClass)
}
@Test
fun `#02 play with toy dog`() {
val fileFacade = loadFileFacade(packageName)
val toyDogClass = loadClass("ToyDog")
val play = loadToplevelFunction(fileFacade, "play", toyDogClass)
play.invoke(null, toyDogClass.createInstance())
assertEquals(
message = "Incorrect sequence of bites and panic",
actual = loadTraceContent(),
expected = listOf(
"b.a.r.k.",
"Sitting..."
)
)
}
}

View File

@ -347,25 +347,48 @@ fun loadToplevelField(fileFacade: KFileFacade, memberName: String): Field {
).single()
}
private fun loadToplevelMember(fileFacade: KFileFacade, memberName: String, isGetter: Boolean): Method {
private fun loadToplevelMember(
fileFacade: KFileFacade,
memberName: String,
firstParameterType: KClass<*>? = null,
isGetter: Boolean
): Method {
val name = if (isGetter && !memberName.startsWith("is"))
"get" + memberName.capitalize()
else
memberName
return fileFacade.jClass.declaredMethods
.filter { it.name == name }
.checkFoundEntities(
what = if (isGetter) "'$memberName' property" else "'$memberName()' function",
.let { memberCandidates ->
when(firstParameterType) {
null -> memberCandidates
else -> memberCandidates.filter {
it.parameters.first().type == firstParameterType.javaObjectType
}
}
}.apply {
val member = if (isGetter) "'$memberName' property" else "'$memberName()' function"
val what = when(firstParameterType) {
null -> member
else -> "${firstParameterType.simpleName}.$member"
}
checkFoundEntities(
what = what,
where = "'${fileFacade.fileName}.kt' file"
).single()
)
}.single()
}
fun loadToplevelFunction(fileFacade: KFileFacade, functionName: String): Method {
return loadToplevelMember(fileFacade, functionName, false)
return loadToplevelMember(fileFacade, functionName, null,false)
}
fun loadToplevelFunction(fileFacade: KFileFacade, functionName: String, firstParameterType: KClass<*>): Method {
return loadToplevelMember(fileFacade, functionName, firstParameterType, false)
}
fun loadToplevelPropertyGetter(fileFacade: KFileFacade, propertyName: String): Method {
return loadToplevelMember(fileFacade, propertyName, true)
return loadToplevelMember(fileFacade, propertyName, null,true)
}
fun loadMainFunction(fileFacade: KFileFacade): Method {