From c8a12a6053d7c3e1df656de1a4190a138b631951 Mon Sep 17 00:00:00 2001 From: Pavel Nikolaev Date: Thu, 30 Jul 2020 14:54:30 +0200 Subject: [PATCH] Abstract Classes/Exercise 1 tests --- .../Abstract Classes/Exercise 1/src/Task.kt | 32 ++++----- .../Exercise 1/task-info.yaml | 14 ++-- .../Abstract Classes/Exercise 1/task.md | 2 +- .../Abstract Classes/Exercise 1/test/Tests.kt | 66 +++++++++++++++++-- .../Composition/Exercise 3/test/Tests.kt | 2 - util/test/util.kt | 19 ++++-- 6 files changed, 100 insertions(+), 35 deletions(-) diff --git a/Object-Oriented Programming/Abstract Classes/Exercise 1/src/Task.kt b/Object-Oriented Programming/Abstract Classes/Exercise 1/src/Task.kt index 701a4f9a..756a7c35 100644 --- a/Object-Oriented Programming/Abstract Classes/Exercise 1/src/Task.kt +++ b/Object-Oriented Programming/Abstract Classes/Exercise 1/src/Task.kt @@ -1,5 +1,7 @@ package abstractClassesExercise1 +import atomictest.trace + abstract class Shape { abstract fun draw() abstract fun erase() @@ -7,23 +9,23 @@ abstract class Shape { open class Circle: Shape() { override fun draw() = - println("Draw Circle") + trace("Draw Circle") override fun erase() = - println("Erase Circle") + trace("Erase Circle") } open class Square: Shape() { override fun draw() = - println("Draw Square") + trace("Draw Square") override fun erase() = - println("Erase Square") + trace("Erase Square") } open class Triangle: Shape() { override fun draw() = - println("Draw Triangle") + trace("Draw Triangle") override fun erase() = - println("Erase Triangle") + trace("Erase Triangle") } fun main() { @@ -36,12 +38,12 @@ fun main() { shapes.forEach { it.draw() } shapes.forEach { it.erase() } */ -} -/* Exercise Output: -Draw Circle -Draw Square -Draw Triangle -Erase Circle -Erase Square -Erase Triangle -*/ \ No newline at end of file + trace eq """ + Draw Circle + Draw Square + Draw Triangle + Erase Circle + Erase Square + Erase Triangle + """ +} \ No newline at end of file diff --git a/Object-Oriented Programming/Abstract Classes/Exercise 1/task-info.yaml b/Object-Oriented Programming/Abstract Classes/Exercise 1/task-info.yaml index 9fcb65fa..5d51c10d 100644 --- a/Object-Oriented Programming/Abstract Classes/Exercise 1/task-info.yaml +++ b/Object-Oriented Programming/Abstract Classes/Exercise 1/task-info.yaml @@ -3,17 +3,17 @@ files: - name: src/Task.kt visible: true placeholders: - - offset: 34 + - offset: 59 length: 69 placeholder_text: abstract class Shape - - offset: 105 - length: 134 + - offset: 130 + length: 130 placeholder_text: class Circle - - offset: 241 - length: 134 + - offset: 262 + length: 130 placeholder_text: class Square - - offset: 377 - length: 140 + - offset: 394 + length: 136 placeholder_text: class Triangle - name: test/Tests.kt visible: false diff --git a/Object-Oriented Programming/Abstract Classes/Exercise 1/task.md b/Object-Oriented Programming/Abstract Classes/Exercise 1/task.md index 2d3f4888..8c0372da 100644 --- a/Object-Oriented Programming/Abstract Classes/Exercise 1/task.md +++ b/Object-Oriented Programming/Abstract Classes/Exercise 1/task.md @@ -3,7 +3,7 @@ Create an `abstract class Shape` with two `abstract` methods, `draw()` and `erase()`, each producing the default (`Unit`) return type. Inherit `Circle`, `Square` and `Triangle` from `Shape`, and override the `abstract` methods to -call `println()` with `"Draw Circle"`, `"Erase Circle"`, etc. `main()` +call `trace()` with `"Draw Circle"`, `"Erase Circle"`, etc. `main()` creates a `List` called `shapes` containing one of each subtype. Call `draw()` for each object in the `List`, then `erase()` for each object in the `List`, to match the exercise output. \ No newline at end of file diff --git a/Object-Oriented Programming/Abstract Classes/Exercise 1/test/Tests.kt b/Object-Oriented Programming/Abstract Classes/Exercise 1/test/Tests.kt index e1ad4133..3c184ce8 100644 --- a/Object-Oriented Programming/Abstract Classes/Exercise 1/test/Tests.kt +++ b/Object-Oriented Programming/Abstract Classes/Exercise 1/test/Tests.kt @@ -1,11 +1,69 @@ package abstractClassesExercise1 -import org.junit.Assert +import org.junit.FixMethodOrder import org.junit.Test +import org.junit.runners.MethodSorters +import util.* +import kotlin.test.assertEquals +@FixMethodOrder(MethodSorters.NAME_ASCENDING) class TestAbstractClassesExercise1 { - @Test fun testSolution() { - //TODO: implement your test here - Assert.assertTrue("Tests not implemented for the task", false) + + private val packageName = "abstractClassesExercise1" + + @Test + fun `#01 classes structure`() { + loadClass(packageName, "Shape").apply { + assertEquals( + message = "Class should have modifier 'abstract'", + expected = true, + actual = isAbstract + ) + loadMemberFunction(this, "draw").apply { + assertEquals( + message = "Method 'draw()' should have modifier 'abstract'", + expected = true, + actual = isAbstract + ) + } + loadMemberFunction(this, "erase").apply { + assertEquals( + message = "Method 'erase()' should have modifier 'abstract'", + expected = true, + actual = isAbstract + ) + } } + listOf("Circle", "Square", "Triangle").forEach { + loadClass(packageName, it).apply { + assertDeclaredMemberFunction("draw") + assertDeclaredMemberFunction("erase") + } + } + } + + @Test + fun `#02 shape operations`() { + val (draw, erase) = loadClass(packageName, "Shape").let { + loadMemberFunction(it, "draw") to loadMemberFunction(it, "erase") + } + val shapes = listOf("Circle", "Square", "Triangle").map { + loadClass(packageName, it).createInstance() + } + shapes.forEach { draw.call(it) } + shapes.forEach { erase.call(it) } + + assertEquals( + message = "Incorrect result of trace for draw/erase operations", + actual = loadTraceContent(), + expected = listOf( + "Draw Circle", + "Draw Square", + "Draw Triangle", + "Erase Circle", + "Erase Square", + "Erase Triangle" + ) + ) + } } \ No newline at end of file diff --git a/Object-Oriented Programming/Composition/Exercise 3/test/Tests.kt b/Object-Oriented Programming/Composition/Exercise 3/test/Tests.kt index c3fecdab..8f3f77d5 100644 --- a/Object-Oriented Programming/Composition/Exercise 3/test/Tests.kt +++ b/Object-Oriented Programming/Composition/Exercise 3/test/Tests.kt @@ -4,9 +4,7 @@ import org.junit.FixMethodOrder import org.junit.Test import org.junit.runners.MethodSorters import util.* -import kotlin.reflect.KTypeProjection import kotlin.reflect.full.createInstance -import kotlin.reflect.full.createType import kotlin.test.assertEquals @FixMethodOrder(MethodSorters.NAME_ASCENDING) diff --git a/util/test/util.kt b/util/test/util.kt index f768fee7..047eab16 100644 --- a/util/test/util.kt +++ b/util/test/util.kt @@ -8,10 +8,7 @@ import java.io.PrintStream import java.lang.reflect.Field import java.lang.reflect.Method import kotlin.reflect.* -import kotlin.reflect.full.createType -import kotlin.reflect.full.declaredMemberProperties -import kotlin.reflect.full.memberFunctions -import kotlin.reflect.full.memberProperties +import kotlin.reflect.full.* import kotlin.reflect.jvm.isAccessible import kotlin.test.assertEquals @@ -179,8 +176,18 @@ fun loadMemberFunction(kClass: KClass<*>, methodName: String): KFunction<*> { .single() } -fun KClass<*>.assertMemberFunction(methodName: String) { - loadMemberFunction(this, methodName) +fun KClass<*>.assertMemberFunction(methodName: String): KFunction<*> { + return memberFunctions + .filter { it.name == methodName } + .checkFoundEntities(what = "the '$methodName()' member function", where = "'${simpleName}' class") + .single() +} + +fun KClass<*>.assertDeclaredMemberFunction(methodName: String): KFunction<*> { + return declaredMemberFunctions + .filter { it.name == methodName } + .checkFoundEntities(what = "the '$methodName()' member function", where = "'${simpleName}' class") + .single() } fun KClass<*>.assertNoMemberFunction(methodName: String) {