From e80f46d8f5269918f0ff2a86bc46ddcd315d0384 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 13:22:27 +0900 Subject: [PATCH 1/5] =?UTF-8?q?docs(README):=20=EB=A9=94=EB=AA=A8=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 07935c9..45d3f5a 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ - `int visibleStart (nullable)`: 선택한 시작 줄 - 저장은 시간 순서대로 저장이 되어야 한다. -### ⚠️ 메모 저장 기능 제약 상황 +### ⚠️ 메모 저장 기능 고려 사항 - 메모의 `content`가 blank라면 저장이 되어선 안된다. - `selectionStart`가 `selectionEnd`보다 앞에 있어야 한다. @@ -30,12 +30,14 @@ --- -### ☑️ 메모 조회 기능 +### 🏁 메모 조회 기능 - 메모의 id를 이용해서 데이터를 조회할 수 있어야 한다. - 전체 메모를 날짜순으로 조회할 수 있어야 한다. -### ⚠️ 메모 조회 기능 예외 상황 +### ⚠️ 메모 조회 기능 고려 사항 + +- 각 조건마다 조회할 데이터가 없다면 빈 리스트를 반환해야 한다. --- From 234c96ebda8f4a8cd1f3c0c68dc7ac411ead7538 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 13:32:22 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat(MemoService):=20=EB=A9=94=EB=AA=A8=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devlog/domain/memo/repository/MemoRepository.kt | 5 +++-- .../yeoli/devlog/domain/memo/service/MemoService.kt | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/repository/MemoRepository.kt b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/repository/MemoRepository.kt index 1bb9ee8..dad3d3d 100644 --- a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/repository/MemoRepository.kt +++ b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/repository/MemoRepository.kt @@ -1,5 +1,6 @@ package com.github.yeoli.devlog.domain.memo.repository +import com.github.yeoli.devlog.domain.memo.domain.Memo import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.components.Service import com.intellij.openapi.components.State @@ -23,7 +24,7 @@ class MemoRepository : PersistentStateComponent { state.memos.add(memo) } - fun getAll(): List { - return state.memos + fun getAll(): List { + return state.memos.map { it.toDomain() } } } diff --git a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoService.kt b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoService.kt index 497471b..3337c01 100644 --- a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoService.kt +++ b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoService.kt @@ -87,4 +87,14 @@ class MemoService(private val project: Project) { logger.warn("[saveMemo] 메모 저장 중 알 수 없는 에러가 발생했습니다. ${e.message}", e) } } + + fun getAllMemos(): List { + try { + return memoRepository.getAll() + } catch (e: Exception) { + logger.warn("[getAllMemos] 메모 조회 중 알 수 없는 에러가 발생했습니다. ${e.message}", e) + } + + return mutableListOf() + } } \ No newline at end of file From 87d6b44be934a87c0373d937039e627c4c345fd6 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 13:33:29 +0900 Subject: [PATCH 3/5] =?UTF-8?q?refactor(MemoRepositroy):=20=EB=A9=94?= =?UTF-8?q?=EB=AA=A8=20=EC=A0=80=EC=9E=A5=20=EA=B8=B0=EB=8A=A5=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=20=EC=8B=9C,=20Memo=EB=A5=BC=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=EB=A1=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yeoli/devlog/domain/memo/repository/MemoRepository.kt | 4 ++-- .../github/yeoli/devlog/domain/memo/service/MemoService.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/repository/MemoRepository.kt b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/repository/MemoRepository.kt index dad3d3d..df5cadb 100644 --- a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/repository/MemoRepository.kt +++ b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/repository/MemoRepository.kt @@ -20,8 +20,8 @@ class MemoRepository : PersistentStateComponent { this.state = state } - fun save(memo: MemoState) { - state.memos.add(memo) + fun save(memo: Memo) { + state.memos.add(memo.toState()) } fun getAll(): List { diff --git a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoService.kt b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoService.kt index 3337c01..fe09bbe 100644 --- a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoService.kt +++ b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoService.kt @@ -82,7 +82,7 @@ class MemoService(private val project: Project) { fun saveMemo(memo: Memo) { try { - memoRepository.save(memo.toState()) + memoRepository.save(memo) } catch (e: Exception) { logger.warn("[saveMemo] 메모 저장 중 알 수 없는 에러가 발생했습니다. ${e.message}", e) } From 7db961b7ae27d7509f6094b0bb72dda00dfd5678 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 14:05:05 +0900 Subject: [PATCH 4/5] =?UTF-8?q?test(MemoServiceTest):=20=EB=A9=94=EB=AA=A8?= =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/memo/service/MemoServiceTest.kt | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/test/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoServiceTest.kt b/src/test/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoServiceTest.kt index 6ee0d2c..f8c7736 100644 --- a/src/test/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoServiceTest.kt +++ b/src/test/kotlin/com/github/yeoli/devlog/domain/memo/service/MemoServiceTest.kt @@ -1,6 +1,7 @@ package com.github.yeoli.devlog.domain.memo.service import com.github.yeoli.devlog.domain.memo.domain.Memo +import com.github.yeoli.devlog.domain.memo.repository.MemoRepository import com.intellij.mock.MockFileDocumentManagerImpl import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.EditorFactory @@ -10,10 +11,28 @@ import com.intellij.openapi.util.Disposer import com.intellij.testFramework.fixtures.BasePlatformTestCase import com.intellij.testFramework.replaceService import com.intellij.util.Function +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever import java.awt.Point +import kotlin.test.assertTrue class MemoServiceTest : BasePlatformTestCase() { + private lateinit var memoRepository: MemoRepository + + override fun setUp() { + super.setUp() + + // mock 생성 + memoRepository = mock() + + project.replaceService( + MemoRepository::class.java, + memoRepository, + testRootDisposable + ) + } + fun `test 메모 생성 성공`() { // given val psiFile = myFixture.configureByText( @@ -132,7 +151,6 @@ class MemoServiceTest : BasePlatformTestCase() { val document = editor.document val snippet = "val selected = 42" val selectionStart = document.text.indexOf(snippet) - assertTrue("선택할 코드 스니펫을 찾지 못했습니다.", selectionStart >= 0) val selectionEnd = selectionStart + snippet.length editor.selectionModel.setSelection(selectionStart, selectionEnd) @@ -167,4 +185,60 @@ class MemoServiceTest : BasePlatformTestCase() { } } + // ========= 메모 조회 기능 ========= + fun `test 메모 전체 조회 기능 성공`() { + // given + val memo1 = Memo( + id = System.currentTimeMillis(), + createdAt = java.time.LocalDateTime.now(), + updatedAt = java.time.LocalDateTime.now(), + content = "메모1", + commitHash = null, + filePath = "/path/to/file1", + selectedCodeSnippet = "snippet1", + selectionStart = 0, + selectionEnd = 5, + visibleStart = 1, + visibleEnd = 3 + ) + + val memo2 = Memo( + id = System.currentTimeMillis() + 1, + createdAt = java.time.LocalDateTime.now(), + updatedAt = java.time.LocalDateTime.now(), + content = "메모2", + commitHash = null, + filePath = "/path/to/file2", + selectedCodeSnippet = "snippet2", + selectionStart = 10, + selectionEnd = 20, + visibleStart = 4, + visibleEnd = 10 + ) + + whenever(memoRepository.getAll()).thenReturn(listOf(memo1, memo2)) + + // when + val result = MemoService(project).getAllMemos() + + // then + assertEquals(2, result.size) + assertEquals("메모1", result[0].content) + assertEquals("메모2", result[1].content) + assertEquals("/path/to/file1", result[0].filePath) + assertEquals("/path/to/file2", result[1].filePath) + } + + fun `test 메모 전체 조회 기능 실패 - 예외 발생시 빈 리스트`() { + // given + whenever(memoRepository.getAll()).thenThrow(RuntimeException("DB error")) + + // when + val result = MemoService(project).getAllMemos() + + // then + assertTrue(result.isEmpty(), "예외 발생 시 빈 리스트를 반환해야 합니다.") + } + } + From bd7e8beb2a087d9065cf79702eb1b5a097371d72 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 14:05:45 +0900 Subject: [PATCH 5/5] =?UTF-8?q?chore(Build):=20Mokito=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index df4a29b..e178b35 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,6 +37,9 @@ dependencies { testImplementation(kotlin("test")) testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0") + + testImplementation("org.mockito:mockito-core:5.12.0") + testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1") // IntelliJ Platform Gradle Plugin Dependencies Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html intellijPlatform {