From 83af0f99478e87148d5a16afdab2f915adbfb704 Mon Sep 17 00:00:00 2001 From: Artem Nagorny Date: Mon, 30 Oct 2023 15:16:58 +0300 Subject: [PATCH] solution of homework2 --- build.gradle | 5 ++ src/main/kotlin/ru/otus/homework/builder.kt | 38 +++++++++++ src/main/kotlin/ru/otus/homework/command.kt | 66 +++++++++++++++++++ src/main/kotlin/ru/otus/homework/decorator.kt | 31 +++++++++ src/main/kotlin/ru/otus/homework/singleton.kt | 21 ++++++ .../kotlin/ru/otus/homework/BuilderTest.kt | 38 +++++++++++ .../kotlin/ru/otus/homework/CommandTest.kt | 61 +++++++++++++++++ .../kotlin/ru/otus/homework/SingletonTest.kt | 33 ++++++++++ 8 files changed, 293 insertions(+) create mode 100644 src/main/kotlin/ru/otus/homework/builder.kt create mode 100644 src/main/kotlin/ru/otus/homework/command.kt create mode 100644 src/main/kotlin/ru/otus/homework/decorator.kt create mode 100644 src/main/kotlin/ru/otus/homework/singleton.kt create mode 100644 src/test/kotlin/ru/otus/homework/BuilderTest.kt create mode 100644 src/test/kotlin/ru/otus/homework/CommandTest.kt create mode 100644 src/test/kotlin/ru/otus/homework/SingletonTest.kt diff --git a/build.gradle b/build.gradle index c97e475..edd4be1 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,10 @@ plugins { id 'org.jetbrains.kotlin.jvm' version '1.7.21' } +test { + useJUnitPlatform() +} + group 'ru.otus' version '1.0-SNAPSHOT' @@ -11,4 +15,5 @@ repositories { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib" + testImplementation "org.junit.jupiter:junit-jupiter:5.8.1" } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/builder.kt b/src/main/kotlin/ru/otus/homework/builder.kt new file mode 100644 index 0000000..caaca6b --- /dev/null +++ b/src/main/kotlin/ru/otus/homework/builder.kt @@ -0,0 +1,38 @@ +package ru.otus.homework + +class Notification private constructor( + val iconRes: String?, + val title: String, + val subTitle: String?, +) { + data class Builder( + var iconRes: String? = null, + var title: String? = null, + var subTitle: String? = null, + ) { + fun iconRes(iconRes: String) = apply { + this.iconRes = iconRes + } + fun title(title: String) = apply { + this.title = title + } + fun subTitle(subTitle: String) = apply { + this.subTitle = subTitle + } + + fun build() = Notification( + iconRes = iconRes, + title = title ?: "", + subTitle = subTitle + ) + } +} + +fun main() { + val notification = Notification.Builder() + .title("test notification title") + .subTitle("test notification subtitle") + .build() + + println("Result notification iconRes: ${notification.iconRes}, title: ${notification.title}, subTitle: ${notification.subTitle}") +} \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/command.kt b/src/main/kotlin/ru/otus/homework/command.kt new file mode 100644 index 0000000..f3edca6 --- /dev/null +++ b/src/main/kotlin/ru/otus/homework/command.kt @@ -0,0 +1,66 @@ +package ru.otus.homework + +interface Command { + fun execute() + fun undo() +} + +data class Clipboard(var content: String = "") + +class Editor(initialContent: String) { + private var content = initialContent + + fun write(text: String) { + content += text + } + + fun remove(text: String) { + content = content.removeSuffix(text) + } + + fun read(): String = content +} + +class PasteCommand( + private val editor: Editor, + private val clipboard: Clipboard, +) : Command { + override fun execute() { + editor.write(clipboard.content) + } + + override fun undo() { + editor.remove(clipboard.content) + } +} + +class EditorInvoker { + private val commandsCache = mutableListOf() + + fun executeCommand(command: Command) { + commandsCache.add(command) + command.execute() + } + + fun undoLastCommand() { + if (commandsCache.isNotEmpty()) { + commandsCache.removeLast().undo() + } + } +} + +fun main() { + val editor = Editor("artem") + val invoker = EditorInvoker() + + println("initial editor: ${editor.read()}") + + invoker.executeCommand(PasteCommand(editor, Clipboard("test"))) + invoker.executeCommand(PasteCommand(editor, Clipboard("boo"))) + + println("after paste: ${editor.read()}") + + invoker.undoLastCommand() + + println("after undo: ${editor.read()}") +} \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/decorator.kt b/src/main/kotlin/ru/otus/homework/decorator.kt new file mode 100644 index 0000000..80733a5 --- /dev/null +++ b/src/main/kotlin/ru/otus/homework/decorator.kt @@ -0,0 +1,31 @@ +package ru.otus.homework + +interface Logger { + fun log(text: String) +} + +class PrintLogger : Logger { + override fun log(text: String) { + println(text) + } +} + +class MapLoggerDecorator( + private val map: MutableMap = mutableMapOf(), + private val logger: Logger, +): MutableMap by map { + override fun put(key: K, value: V): V? { + return map.put(key, value).apply { + logger.log("MapLoggerDecorator putted key: $key, value: $value. Result map: $map") + } + } +} + +fun main() { + val mapLoggerDecorator = MapLoggerDecorator( + logger = PrintLogger(), + ) + mapLoggerDecorator["artem"] = "tim" + mapLoggerDecorator["andrey"] = "drew" + mapLoggerDecorator["alexei"] = "alex" +} \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/singleton.kt b/src/main/kotlin/ru/otus/homework/singleton.kt new file mode 100644 index 0000000..8c100e7 --- /dev/null +++ b/src/main/kotlin/ru/otus/homework/singleton.kt @@ -0,0 +1,21 @@ +package ru.otus.homework + +class Singleton private constructor() { + companion object { + val instance: Singleton by lazy { + Singleton() + } + } + + private var i = 0 + + fun doSomething() = ++i +} + +fun main() { + val instance1 = Singleton.instance + println("instance1 increment: ${instance1.doSomething()}") + + val instance2 = Singleton.instance + println("instance2 increment: ${instance2.doSomething()}") +} diff --git a/src/test/kotlin/ru/otus/homework/BuilderTest.kt b/src/test/kotlin/ru/otus/homework/BuilderTest.kt new file mode 100644 index 0000000..7ae7d49 --- /dev/null +++ b/src/test/kotlin/ru/otus/homework/BuilderTest.kt @@ -0,0 +1,38 @@ +package ru.otus.homework + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test + +private const val notificationTitle = "test notification title" +private const val notificationSubTitle = "test notification subtitle" + +class BuilderTest { + private companion object { + val notification = Notification.Builder() + .title(notificationTitle) + .subTitle(notificationSubTitle) + .build() + } + + @Test + fun notificationIconRes() { + assertNull(notification.iconRes) + } + + @Test + fun notificationTitle() { + assertEquals( + notificationTitle, + notification.title + ) + } + + @Test + fun notificationSubTitle() { + assertEquals( + notificationSubTitle, + notification.subTitle + ) + } +} \ No newline at end of file diff --git a/src/test/kotlin/ru/otus/homework/CommandTest.kt b/src/test/kotlin/ru/otus/homework/CommandTest.kt new file mode 100644 index 0000000..fc14f29 --- /dev/null +++ b/src/test/kotlin/ru/otus/homework/CommandTest.kt @@ -0,0 +1,61 @@ +package ru.otus.homework + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.MethodOrderer +import org.junit.jupiter.api.Order +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestMethodOrder + +private const val initialEditorContent = "artem" +private const val clipboardFirstContent = "test" +private const val clipboardSecondContent = "boo" + +@TestMethodOrder(MethodOrderer.OrderAnnotation::class) +class CommandTest { + private companion object { + private val editor: Editor = Editor(initialEditorContent) + private val invoker = EditorInvoker() + } + + @Test + @Order(1) + fun shouldInitialValue() { + assertEquals( + initialEditorContent, + editor.read() + ) + } + + @Test + @Order(2) + fun shouldPasteFirst() { + invoker.executeCommand(PasteCommand(editor, Clipboard(clipboardFirstContent))) + + assertEquals( + "$initialEditorContent$clipboardFirstContent", + editor.read() + ) + } + + @Test + @Order(3) + fun shouldPasteSecond() { + invoker.executeCommand(PasteCommand(editor, Clipboard(clipboardSecondContent))) + + assertEquals( + "$initialEditorContent$clipboardFirstContent$clipboardSecondContent", + editor.read() + ) + } + + @Test + @Order(4) + fun shouldLastCommandUndo() { + invoker.undoLastCommand() + + assertEquals( + "$initialEditorContent$clipboardFirstContent", + editor.read() + ) + } +} \ No newline at end of file diff --git a/src/test/kotlin/ru/otus/homework/SingletonTest.kt b/src/test/kotlin/ru/otus/homework/SingletonTest.kt new file mode 100644 index 0000000..77a45f0 --- /dev/null +++ b/src/test/kotlin/ru/otus/homework/SingletonTest.kt @@ -0,0 +1,33 @@ +package ru.otus.homework + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.ClassOrderer.OrderAnnotation +import org.junit.jupiter.api.MethodOrderer +import org.junit.jupiter.api.Order +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestMethodOrder + +@TestMethodOrder(MethodOrderer.OrderAnnotation::class) +class SingletonTest { + @Test + @Order(1) + fun instance1Increment() { + val instance1: Singleton = Singleton.instance + + assertEquals( + 1, + instance1.doSomething() + ) + } + + @Test + @Order(2) + fun instance2Increment() { + val instance2: Singleton = Singleton.instance + + assertEquals( + 2, + instance2.doSomething() + ) + } +} \ No newline at end of file