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를 이용해서 데이터를 조회할 수 있어야 한다. - 전체 메모를 날짜순으로 조회할 수 있어야 한다. -### ⚠️ 메모 조회 기능 예외 상황 +### ⚠️ 메모 조회 기능 고려 사항 + +- 각 조건마다 조회할 데이터가 없다면 빈 리스트를 반환해야 한다. --- 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 { 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..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 @@ -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 @@ -19,11 +20,11 @@ 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 { - 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..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,9 +82,19 @@ 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) } } + + fun getAllMemos(): List { + try { + return memoRepository.getAll() + } catch (e: Exception) { + logger.warn("[getAllMemos] 메모 조회 중 알 수 없는 에러가 발생했습니다. ${e.message}", e) + } + + return mutableListOf() + } } \ No newline at end of file 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(), "예외 발생 시 빈 리스트를 반환해야 합니다.") + } + } +