From 2b581cf9dde5248bdd4f42d0df16004ea75b88a8 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 21:22:45 +0900 Subject: [PATCH 01/11] =?UTF-8?q?docs(README):=20=EB=A9=94=EB=AA=A8=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e75a9a..bc3bce7 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ --- -### ☑️ 메모 추출 기능 +### 🏁 메모 추출 기능 - 저장된 메모를 한 개 이상 선택하여 txt 파일로 추출할 수 있어야 한다. - 추출한 단위 메모의 구성 내용은 다음과 같다. From 2055510b77c785b7f646ac3afc0c6ac85bca6dbb Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 21:24:30 +0900 Subject: [PATCH 02/11] =?UTF-8?q?test(MemoTest):=20=EB=A9=94=EB=AA=A8=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=20=ED=98=95=EC=8B=9D=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devlog/domain/memo/domain/MemoTest.kt | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/test/kotlin/com/github/yeoli/devlog/domain/memo/domain/MemoTest.kt b/src/test/kotlin/com/github/yeoli/devlog/domain/memo/domain/MemoTest.kt index 4533a23..01dd20d 100644 --- a/src/test/kotlin/com/github/yeoli/devlog/domain/memo/domain/MemoTest.kt +++ b/src/test/kotlin/com/github/yeoli/devlog/domain/memo/domain/MemoTest.kt @@ -1,6 +1,7 @@ package com.github.yeoli.devlog.domain.memo.domain import com.github.yeoli.devlog.domain.memo.repository.MemoState +import java.time.LocalDateTime import kotlin.test.* class MemoTest { @@ -99,4 +100,93 @@ class MemoTest { assertNotNull(memoState.createdAt) assertNotNull(memoState.updatedAt) } + + @Test + fun `test buildMemoBlock - 정상적으로 문자열 생성`() { + val created = LocalDateTime.of(2025, 11, 22, 13, 11, 10) + val updated = LocalDateTime.of(2025, 11, 22, 13, 12, 0) + + val memo = Memo( + id = 1L, + createdAt = created, + updatedAt = updated, + content = "메모 내용입니다.", + commitHash = "abc123", + filePath = "/path/to/file", + selectedCodeSnippet = "println(\"Hello\")", + selectionStart = 0, + selectionEnd = 5, + visibleStart = 1, + visibleEnd = 10 + ) + + val block = memo.buildMemoBlock(1) + + assertTrue(block.contains("# Memo 1")) + assertTrue(block.contains("📅 생성 시간 : $created")) + assertTrue(block.contains("📅 수정 시간 : $updated")) + assertTrue(block.contains("📌 Content")) + assertTrue(block.contains("메모 내용입니다.")) + assertTrue(block.contains("Commit: abc123")) + assertTrue(block.contains("File Path: /path/to/file")) + assertTrue(block.contains("Visible Lines: 1 ~ 10")) + assertTrue(block.contains("println(\"Hello\")")) + } + + @Test + fun `test buildMemoBlock - 모든 값이 있을 때 정상적으로 표시되는지`() { + val created = LocalDateTime.of(2025, 11, 22, 13, 11, 10) + val updated = LocalDateTime.of(2025, 11, 22, 13, 15, 30) + + val memo = Memo( + id = 2L, + createdAt = created, + updatedAt = updated, + content = "전체 필드 테스트", + commitHash = "ff12aa", + filePath = "/full/path/file.kt", + selectedCodeSnippet = "val x = 10", + selectionStart = 3, + selectionEnd = 9, + visibleStart = 2, + visibleEnd = 12 + ) + + val block = memo.buildMemoBlock(2) + + assertTrue(block.contains("# Memo 2")) + assertTrue(block.contains("📅 생성 시간 : $created")) + assertTrue(block.contains("📅 수정 시간 : $updated")) + assertTrue(block.contains("전체 필드 테스트")) + assertTrue(block.contains("Commit: ff12aa")) + assertTrue(block.contains("File Path: /full/path/file.kt")) + assertTrue(block.contains("Visible Lines: 2 ~ 12")) + assertTrue(block.contains("val x = 10")) + } + + @Test + fun `test buildMemoBlock - null 값들이 기본값으로 표시되는지`() { + val created = LocalDateTime.of(2025, 11, 22, 13, 11, 10) + + val memo = Memo( + id = 1L, + createdAt = created, + updatedAt = created, + content = "내용", + commitHash = null, + filePath = null, + selectedCodeSnippet = null, + selectionStart = null, + selectionEnd = null, + visibleStart = null, + visibleEnd = null + ) + + val block = memo.buildMemoBlock(0) + + assertTrue(block.contains("Commit: N/A")) + assertTrue(block.contains("File Path: N/A")) + assertTrue(block.contains("Visible Lines: ? ~ ?")) + assertTrue(block.contains("(no selected code)")) + } } From 5f634970ac1835d7dc3af09e64c09de6538cd4ea Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 21:24:51 +0900 Subject: [PATCH 03/11] =?UTF-8?q?feat(Memo):=20=EB=A9=94=EB=AA=A8=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=20=ED=98=95=EC=8B=9D=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yeoli/devlog/domain/memo/domain/Memo.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt index 1bb1b4f..276a2b4 100644 --- a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt +++ b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt @@ -93,4 +93,25 @@ class Memo( visibleEnd = this.visibleEnd ) } + + fun buildMemoBlock(index: Int): String { + return """ + + # Memo $index + 📅 생성 시간 : ${this.createdAt} + 📅 수정 시간 : ${this.updatedAt} + + 📌 Content + ${this.content} + + 🔗 Metadata + - Commit: ${this.commitHash ?: "N/A"} + - File Path: ${this.filePath ?: "N/A"} + - Visible Lines: ${this.visibleStart ?: "?"} ~ ${this.visibleEnd ?: "?"} + - Selected Code : + ${this.selectedCodeSnippet ?: "(no selected code)"} + + --------------------------------------- + """.trimIndent() + } } From ef05fe01aa29372c47bddf2707f381effc7ff33c Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 21:46:19 +0900 Subject: [PATCH 04/11] =?UTF-8?q?test(MemoTest):=20=EB=A9=94=EB=AA=A8=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=20=ED=97=A4=EB=8D=94=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/memo/service/MemoServiceTest.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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 5c776cb..fb1bb09 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 @@ -396,4 +396,22 @@ class MemoServiceTest : BasePlatformTestCase() { }) } + // ========= 메모 추출 기능 ========= + + fun `test buildHeader - 프로젝트명과 시간 포함`() { + // given + val service = MemoService(project) + + // when + val header = service.buildHeader() + + // then + assertTrue(header.contains("========== DEV LOG ==========")) + assertTrue(header.contains("💻 프로젝트 명: ${project.name}")) + assertTrue(header.contains("⏰ 추출 시간:")) + val regex = Regex("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}") + assertTrue(regex.containsMatchIn(header), "날짜 포맷이 잘못되었습니다.") + assertTrue(header.contains("---------------------------------------")) + } + } From 633a1782047e139875061b85fa1a57600d4fa1ba Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 21:53:52 +0900 Subject: [PATCH 05/11] =?UTF-8?q?feat(Memo):=20=EB=A9=94=EB=AA=A8=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=20=ED=97=A4=EB=8D=94=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devlog/domain/memo/service/MemoService.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 0874bd2..8490acb 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 @@ -11,6 +11,8 @@ import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project import git4idea.repo.GitRepositoryManager import java.awt.Point +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter @Service(Service.Level.PROJECT) class MemoService(private val project: Project) { @@ -119,4 +121,19 @@ class MemoService(private val project: Project) { logger.warn("[updateMemo] 메모 수정 중 알 수 없는 에러가 발생했습니다. ${e.message}", e) } } + + fun buildHeader(): String { + val projectName = project.name + val now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + return """ + ========== DEV LOG ========== + + # 요약 정보 + 💻 프로젝트 명: $projectName + ⏰ 추출 시간: $now + + --------------------------------------- + """.trimIndent() + } } \ No newline at end of file From beb4c9893dfb8d282da23c3b31cf707d0e161c96 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 21:54:20 +0900 Subject: [PATCH 06/11] =?UTF-8?q?refactor(Memo):=20=EB=A9=94=EB=AA=A8=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=20=EA=B8=B0=EB=8A=A5=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=B7=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/github/yeoli/devlog/domain/memo/domain/Memo.kt | 5 +++-- .../github/yeoli/devlog/domain/memo/domain/MemoTest.kt | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt index 276a2b4..da69aab 100644 --- a/src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt +++ b/src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt @@ -2,6 +2,7 @@ package com.github.yeoli.devlog.domain.memo.domain import com.github.yeoli.devlog.domain.memo.repository.MemoState import java.time.LocalDateTime +import java.time.format.DateTimeFormatter class Memo( val id: Long, @@ -98,8 +99,8 @@ class Memo( return """ # Memo $index - 📅 생성 시간 : ${this.createdAt} - 📅 수정 시간 : ${this.updatedAt} + 📅 생성 시간 : ${this.createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))} + 📅 수정 시간 : ${this.updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))} 📌 Content ${this.content} diff --git a/src/test/kotlin/com/github/yeoli/devlog/domain/memo/domain/MemoTest.kt b/src/test/kotlin/com/github/yeoli/devlog/domain/memo/domain/MemoTest.kt index 01dd20d..38df2f5 100644 --- a/src/test/kotlin/com/github/yeoli/devlog/domain/memo/domain/MemoTest.kt +++ b/src/test/kotlin/com/github/yeoli/devlog/domain/memo/domain/MemoTest.kt @@ -2,6 +2,7 @@ package com.github.yeoli.devlog.domain.memo.domain import com.github.yeoli.devlog.domain.memo.repository.MemoState import java.time.LocalDateTime +import java.time.format.DateTimeFormatter import kotlin.test.* class MemoTest { @@ -123,8 +124,8 @@ class MemoTest { val block = memo.buildMemoBlock(1) assertTrue(block.contains("# Memo 1")) - assertTrue(block.contains("📅 생성 시간 : $created")) - assertTrue(block.contains("📅 수정 시간 : $updated")) + assertTrue(block.contains("📅 생성 시간 : ${created.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))}")) + assertTrue(block.contains("📅 수정 시간 : ${updated.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))}")) assertTrue(block.contains("📌 Content")) assertTrue(block.contains("메모 내용입니다.")) assertTrue(block.contains("Commit: abc123")) @@ -155,8 +156,8 @@ class MemoTest { val block = memo.buildMemoBlock(2) assertTrue(block.contains("# Memo 2")) - assertTrue(block.contains("📅 생성 시간 : $created")) - assertTrue(block.contains("📅 수정 시간 : $updated")) + assertTrue(block.contains("📅 생성 시간 : ${created.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))}")) + assertTrue(block.contains("📅 수정 시간 : ${updated.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))}")) assertTrue(block.contains("전체 필드 테스트")) assertTrue(block.contains("Commit: ff12aa")) assertTrue(block.contains("File Path: /full/path/file.kt")) From ae737de62df7ad6861bfb26552ed0a92f05385f6 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 23:02:42 +0900 Subject: [PATCH 07/11] =?UTF-8?q?test(MemoServiceTest):=20=EB=A9=94?= =?UTF-8?q?=EB=AA=A8=20=EC=A0=84=EC=B2=B4=20=EB=82=B4=EC=9A=A9=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=20=EB=A9=94=EC=84=9C=EB=93=9C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/memo/service/MemoServiceTest.kt | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) 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 fb1bb09..f8f7f9e 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 @@ -414,4 +414,133 @@ class MemoServiceTest : BasePlatformTestCase() { assertTrue(header.contains("---------------------------------------")) } + fun `test buildExportText - 빈 메모 리스트`() { + // given + val service = MemoService(project) + + // when + val export = service.buildExportText(emptyList()) + + // then + assertTrue(export.contains("========== DEV LOG ==========")) + assertTrue(export.contains("(내보낼 메모가 없습니다.)")) + } + + fun `test buildExportText - 단일 메모 포함`() { + val now = LocalDateTime.of(2025, 1, 1, 10, 20, 30) + + val memo = Memo( + id = 1L, + createdAt = now, + updatedAt = now, + content = "hello", + commitHash = "abc123", + filePath = "/path/file", + selectedCodeSnippet = "val a = 1", + selectionStart = 0, + selectionEnd = 10, + visibleStart = 3, + visibleEnd = 5 + ) + + val service = MemoService(project) + + // when + val export = service.buildExportText(listOf(memo)) + + // then: 헤더 포함 + assertTrue(export.contains("========== DEV LOG ==========")) + assertTrue(export.contains("💻 프로젝트 명: ${project.name}")) + + // 메모 블록 정보 포함 확인 + assertTrue(export.contains("# Memo 1")) + assertTrue(export.contains("📌 Content")) + assertTrue(export.contains("hello")) + assertTrue(export.contains("abc123")) + assertTrue(export.contains("/path/file")) + assertTrue(export.contains("val a = 1")) + assertTrue(export.contains("3 ~ 5")) + } + + fun `test buildExportText - 여러 메모 순서대로 출력`() { + val now = LocalDateTime.of(2025, 1, 1, 9, 0, 0) + + val memo1 = Memo( + id = 1L, + createdAt = now, + updatedAt = now, + content = "first", + commitHash = null, + filePath = "/f1", + selectedCodeSnippet = null, + selectionStart = 0, + selectionEnd = 0, + visibleStart = 1, + visibleEnd = 1 + ) + + val memo2 = Memo( + id = 2L, + createdAt = now.plusHours(1), + updatedAt = now.plusHours(1), + content = "second", + commitHash = null, + filePath = "/f2", + selectedCodeSnippet = null, + selectionStart = 10, + selectionEnd = 10, + visibleStart = 2, + visibleEnd = 2 + ) + + val service = MemoService(project) + + // when + val export = service.buildExportText(listOf(memo1, memo2)) + + // then + assertTrue(export.contains("# Memo 1")) + assertTrue(export.contains("# Memo 2")) + + // 순서 보장 + val index1 = export.indexOf("# Memo 1") + val index2 = export.indexOf("# Memo 2") + assertTrue(index1 < index2, "Memo 1이 Memo 2보다 먼저 출력되어야 합니다.") + } + + fun `test buildExportText - memoBlock 필드 검증`() { + val now = LocalDateTime.of(2025, 1, 1, 12, 34, 56) + + val memo = Memo( + id = 10L, + createdAt = now, + updatedAt = now, + content = "내용입니다", + commitHash = null, + filePath = null, + selectedCodeSnippet = null, + selectionStart = 100, + selectionEnd = 200, + visibleStart = 3, + visibleEnd = 8 + ) + + val service = MemoService(project) + + // when + val export = service.buildExportText(listOf(memo)) + + // then + // 날짜 체크 + assertTrue(export.contains("2025-01-01 12:34:56")) + // content + assertTrue(export.contains("내용입니다")) + // null 매핑 + assertTrue(export.contains("- Commit: N/A")) + assertTrue(export.contains("- File Path: N/A")) + assertTrue(export.contains("(no selected code)")) + // visible range + assertTrue(export.contains("3 ~ 8")) + } + } From 03d5fbe2ae747d6e7eab5b96ddf2897328486b1b Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 23:02:52 +0900 Subject: [PATCH 08/11] =?UTF-8?q?feat(MemoService):=20=EB=A9=94=EB=AA=A8?= =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=20=EB=82=B4=EC=9A=A9=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devlog/domain/memo/service/MemoService.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 8490acb..50629f2 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 @@ -136,4 +136,20 @@ class MemoService(private val project: Project) { --------------------------------------- """.trimIndent() } + + fun buildExportText(selectedMemos: List): String { + val header = buildHeader() + + if (selectedMemos.isEmpty()) { + return header + "\n(내보낼 메모가 없습니다.)" + } + + val body = selectedMemos + .mapIndexed { index, memo -> + memo.buildMemoBlock(index + 1) + } + .joinToString(separator = "\n") + + return header + "\n\n" + body + } } \ No newline at end of file From af77d047bfc6979b539c553d1cec3a455dc40749 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 23:13:01 +0900 Subject: [PATCH 09/11] =?UTF-8?q?test(MemoServiceTest):=20=EB=A9=94?= =?UTF-8?q?=EB=AA=A8=20txt=20=ED=8C=8C=EC=9D=BC=EB=A1=9C=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C=20=EC=84=B1=EA=B3=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/memo/service/MemoServiceTest.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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 f8f7f9e..26b0989 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 @@ -543,4 +543,24 @@ class MemoServiceTest : BasePlatformTestCase() { assertTrue(export.contains("3 ~ 8")) } + fun `test exportToTxt - 파일 생성 및 내용 저장`() { + // given + val service = MemoService(project) + val text = "Hello DevLog Export Test" + + // IntelliJ 테스트용 임시 디렉토리 생성 (VirtualFile) + val exportDir = myFixture.tempDirFixture.findOrCreateDir("exports") + + // when + val exported = service.exportToTxt(text, exportDir) + + // then + assertNotNull(exported) + assertTrue(exported!!.exists()) + assertTrue(exported.name.startsWith("devlog-${project.name}-")) + + val content = String(exported.contentsToByteArray(), Charsets.UTF_8) + assertEquals(text, content) + } + } From 7b6ee16a36009d846aa3cb5a09c8053079bede28 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sat, 22 Nov 2025 23:13:21 +0900 Subject: [PATCH 10/11] =?UTF-8?q?feat(MemoService):=20=EB=A9=94=EB=AA=A8?= =?UTF-8?q?=20txt=20=ED=8C=8C=EC=9D=BC=20=EC=A0=80=EC=9E=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devlog/domain/memo/service/MemoService.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 50629f2..2be41b3 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 @@ -3,12 +3,14 @@ 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.ibm.icu.impl.IllegalIcuArgumentException +import com.intellij.openapi.command.WriteCommandAction import com.intellij.openapi.components.Service import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.editor.Editor import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile import git4idea.repo.GitRepositoryManager import java.awt.Point import java.time.LocalDateTime @@ -152,4 +154,17 @@ class MemoService(private val project: Project) { return header + "\n\n" + body } + + fun exportToTxt(text: String, directory: VirtualFile): VirtualFile? { + val date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss")) + val fileName = "devlog-${project.name}-$date.txt" + + var file: VirtualFile? = null + WriteCommandAction.runWriteCommandAction(project) { + file = directory.createChildData(this, fileName) + file!!.setBinaryContent(text.toByteArray(Charsets.UTF_8)) + } + + return file + } } \ No newline at end of file From 3387d0d6897b3aece8e4a97f3e19d3c874449287 Mon Sep 17 00:00:00 2001 From: yeo-li Date: Sun, 23 Nov 2025 00:11:21 +0900 Subject: [PATCH 11/11] =?UTF-8?q?test(MemoServiceTest):=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../github/yeoli/devlog/domain/memo/service/MemoServiceTest.kt | 2 -- 1 file changed, 2 deletions(-) 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 26b0989..d86b68b 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 @@ -547,8 +547,6 @@ class MemoServiceTest : BasePlatformTestCase() { // given val service = MemoService(project) val text = "Hello DevLog Export Test" - - // IntelliJ 테스트용 임시 디렉토리 생성 (VirtualFile) val exportDir = myFixture.tempDirFixture.findOrCreateDir("exports") // when