From 0574ab75228524927e18252770e5a96011b5a54c Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 00:27:50 +0900 Subject: [PATCH 01/27] =?UTF-8?q?test:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/java/calculator/service/CalculatorServiceTest.java diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java new file mode 100644 index 0000000000..e2c1ad19c2 --- /dev/null +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -0,0 +1,28 @@ +package calculator.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@DisplayName("계산기 로직 테스트") +class CalculatorServiceTest { + + @DisplayName("구분자가 잘못 들어 왔을 시, 에러 발생") + @ParameterizedTest + @ValueSource(strings = { + "1;2", // 세미콜론은 기본 구분자가 아님 + "1|2", // 파이프는 기본 구분자가 아님 + "1 2", // 공백은 기본 구분자가 아님 + "1/2" // 슬래시는 기본 구분자가 아님 + }) + void add_invalidDelimiter_throwsException(String input) { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + CalculatorService.add(input); + }); + assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); + } + +} From f58e118b5fd2fd688ade0738337167479862a8e1 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 00:28:30 +0900 Subject: [PATCH 02/27] =?UTF-8?q?test:=20=EC=97=AC=EB=9F=AC=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20=EC=9E=85=EB=A0=A5=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=9E=98=EB=AA=BB=EB=90=9C=20=EA=B5=AC=EB=B6=84=EC=9E=90?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=97=90=EB=9F=AC=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index e2c1ad19c2..110d561db9 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; @DisplayName("계산기 로직 테스트") @@ -25,4 +26,22 @@ void add_invalidDelimiter_throwsException(String input) { assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); } + @DisplayName("여러 숫자 입력에 대한 구분자가 잘못 들어 왔을 시, 에러 발생") + @ParameterizedTest + @CsvSource({ + "'1,2;3,4'", // 첫 번째 잘못된 구분자 (세미콜론) + "'1,2,3;4'", // 두 번째 잘못된 구분자 (세미콜론) + "'1;2,3,4'", // 첫 번째 잘못된 구분자 (세미콜론) + "'1,2:3|4'", // 네 번째 잘못된 구분자 (파이프) + "'1:2,3/4'", // 네 번째 잘못된 구분자 (슬래시) + "'9:10,11/12'", // 네 번째 잘못된 구분자 (슬래시), 네 개의 숫자 + "'9:10,11/12,13'", // 네 번째 잘못된 구분자 (슬래시), 네 개의 숫자 + }) + void add_validAndInvalidMixedDelimiters_throwsException(String input) { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + CalculatorService.add(input); + }); + assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); + } + } From 560f33aae9dd87bc9a4ec640922e1047cff1f859 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 00:29:00 +0900 Subject: [PATCH 03/27] =?UTF-8?q?test:=20=EC=97=AC=EB=9F=AC=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20=EC=9E=85=EB=A0=A5=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=9E=98=EB=AA=BB=EB=90=9C=20=EA=B5=AC=EB=B6=84=EC=9E=90?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=97=90=EB=9F=AC=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 110d561db9..71ad80d30a 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -44,4 +44,24 @@ void add_validAndInvalidMixedDelimiters_throwsException(String input) { assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); } + @DisplayName("글자 입력이 들어오면, 에러 발생") + @ParameterizedTest + @CsvSource({ + "'1a2,3'", // 영어 'a'가 구분자로 들어온 경우 + "'1,2b3'", // 영어 'b'가 구분자로 들어온 경우 + "'1가2:3'", // 한글 '가'가 구분자로 들어온 경우 + "'1,나2,3'", // 한글 '나'가 구분자로 들어온 경우 + "'1,2c3,4'", // 영어 'c'가 구분자로 들어온 경우 + "'1,2,3한4'", // 한글 '한'이 구분자로 들어온 경우 + "'1d2:3,4'" // 영어 'd'가 구분자로 들어온 경우 + }) + void add_invalidCharacterDelimiter_throwsException(String input) { + + // 영어 또는 한글이 구분자로 포함되어 있으면 예외가 발생해야 함 + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + CalculatorService.add(input); + }); + + assertEquals("글자는 들어올 수 없습니다", exception.getMessage()); + } } From e43ab2e60e8a8cdea3680f5389252e511f2e1820 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 00:46:57 +0900 Subject: [PATCH 04/27] =?UTF-8?q?test:=20=EC=9D=8C=EC=88=98=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 71ad80d30a..e53060423e 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -64,4 +64,23 @@ void add_invalidCharacterDelimiter_throwsException(String input) { assertEquals("글자는 들어올 수 없습니다", exception.getMessage()); } + + @DisplayName("음수 입력이 들어오면, 에러 발생") + @ParameterizedTest + @ValueSource(strings = { + "1,-2,3", // 음수가 두 번째 위치 + "-1,2,3", // 음수가 첫 번째 위치 + "1,2,-3", // 음수가 세 번째 위치 + "-1,-2,3", // 음수가 첫 번째와 두 번째 위치 + "1,-2:-3" // 음수가 두 번째와 세 번째 위치, 콜론과 쉼표 혼합 + }) + void add_negativeNumber_throwsException(String input) { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + CalculatorService.add(input); + }); + + // 예외 메시지에 음수가 포함되어 있는지 확인 + assertEquals("음수는 허용되지 않습니다", exception.getMessage()); + } + } From 0b0416c5dbb97c9ecc0c075ee2cfb50b10629512 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 00:49:00 +0900 Subject: [PATCH 05/27] =?UTF-8?q?test:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=20=EB=A1=9C=EC=A7=81=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index e53060423e..5cb3524469 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -83,4 +83,21 @@ void add_negativeNumber_throwsException(String input) { assertEquals("음수는 허용되지 않습니다", exception.getMessage()); } + @DisplayName("커스텀 구분자에 대한 성공 로직 테스트") + @ParameterizedTest + @CsvSource({ + "'//;\n1;2;3', 6", // 세미콜론을 커스텀 구분자로 사용 + "'//|\n1|2|3', 6", // 파이프를 커스텀 구분자로 사용 + "'//@\n2@3@4', 9", // @를 커스텀 구분자로 사용 + "'//#\n1#2#3#4', 10", // #을 커스텀 구분자로 사용 + "'//.\n5.6.7', 18" // 점(.)을 커스텀 구분자로 사용 + }) + void add_withCustomDelimiters_returnsSum(String input, int expectedSum) { + // 입력 문자열을 기반으로 숫자 합계를 계산 + int result = CalculatorService.add(input); + + // 결과가 예상된 값과 같은지 확인 + assertEquals(expectedSum, result); + } + } From eb72ba04d7443228f3f794079289b566ec66f727 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 00:56:12 +0900 Subject: [PATCH 06/27] =?UTF-8?q?test:=20=EC=9D=BC=EB=B0=98=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=EB=A1=9C=EC=A7=81=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculator/service/CalculatorServiceTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 5cb3524469..d205d5e79d 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -100,4 +100,18 @@ void add_withCustomDelimiters_returnsSum(String input, int expectedSum) { assertEquals(expectedSum, result); } + @DisplayName("구분자에 대한 성공 로직 테스트") + @ParameterizedTest + @CsvSource({ + "'1,2,3', 6", // 쉼표 구분자 + "'1:2:3', 6", // 콜론 구분자 + "'1,2:3', 6", // 쉼표와 콜론 혼합 구분자 + }) + void add_withValidInput_returnsSum(String input, int expectedSum) { + // 입력 문자열을 기반으로 숫자 합계를 계산 + int result = CalculatorService.add(input); + + // 결과가 예상된 값과 같은지 확인 + assertEquals(expectedSum, result); + } } From ccc3b3b935dcf8b8e913c4a5d3426414361d1ec5 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 00:56:34 +0900 Subject: [PATCH 07/27] =?UTF-8?q?test:=20=EC=9E=85=EB=A0=A5=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=EC=9D=98=20=EC=8B=9C=EC=9E=91=EC=9D=B4=20?= =?UTF-8?q?=EB=B6=80=EC=A0=81=EC=A0=88=ED=95=9C=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index d205d5e79d..32424f14af 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -83,6 +83,25 @@ void add_negativeNumber_throwsException(String input) { assertEquals("음수는 허용되지 않습니다", exception.getMessage()); } + @DisplayName("입력 문자열의 시작이 잘못되면, 에러 발생") + @ParameterizedTest + @ValueSource(strings = { + "a1,2,3", // 첫 글자가 문자 + "#1,2,3", // 첫 글자가 특수 문자 + "@//;\n1;2;3", // 커스텀 구분자가 아닌 특수 문자로 시작 + " ,2,3", // 공백으로 시작 + ";1,2,3" // 잘못된 특수 문자로 시작 + }) + void add_invalidStartingCharacter_throwsException(String input) { + // 문자열이 숫자나 "//"로 시작하지 않으면 IllegalArgumentException이 발생하는지 확인 + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + CalculatorService.add(input); + }); + + // 예외 메시지가 예상된 것과 일치하는지 확인 + assertEquals("잘못된 형식입니다. 숫자 또는 '//'로 시작해야 합니다.", exception.getMessage()); + } + @DisplayName("커스텀 구분자에 대한 성공 로직 테스트") @ParameterizedTest @CsvSource({ From bae0fcef9e05d6f1253297e6d18818770cf4dd63 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 00:56:56 +0900 Subject: [PATCH 08/27] =?UTF-8?q?test:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=20=EC=A0=95=EC=9D=98=20=EC=8B=9C=20?= =?UTF-8?q?'\n'=EC=9D=B4=20=EB=88=84=EB=9D=BD=EC=9D=98=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 32424f14af..c162df4c4c 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -102,6 +102,24 @@ void add_invalidStartingCharacter_throwsException(String input) { assertEquals("잘못된 형식입니다. 숫자 또는 '//'로 시작해야 합니다.", exception.getMessage()); } + @DisplayName("커스텀 구분자 정의 시 '\\n'이 누락되면, IllegalArgumentException 발생") + @ParameterizedTest + @ValueSource(strings = { + "//;1;2;3", // '\n'이 없고 바로 숫자가 나옴 + "//|1|2|3", // '\n'이 없고 바로 숫자가 나옴 + "//.123", // '\n'이 없이 바로 숫자가 나옴 + "//#1#2" // '\n'이 없고 바로 숫자가 나옴 + }) + void add_missingNewlineAfterCustomDelimiter_throwsException(String input) { + // 문자열의 앞부분이 "//"인데 그 뒤에 '\n'이 없으면 IllegalArgumentException이 발생하는지 확인 + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + CalculatorService.add(input); + }); + + // 예외 메시지가 예상된 것과 일치하는지 확인 + assertEquals("잘못된 형식입니다. 커스텀 구분자 뒤에 '\\n'이 있어야 합니다.", exception.getMessage()); + } + @DisplayName("커스텀 구분자에 대한 성공 로직 테스트") @ParameterizedTest @CsvSource({ From 101301963d1c62af654b7270f0dc21d67946cde9 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 01:00:00 +0900 Subject: [PATCH 09/27] =?UTF-8?q?test:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=8B=9C,=20=EA=B0=92=EC=9D=B4=20=EC=97=86=EC=9D=84=20?= =?UTF-8?q?=EC=8B=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index c162df4c4c..9a719da0f9 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -151,4 +151,21 @@ void add_withValidInput_returnsSum(String input, int expectedSum) { // 결과가 예상된 값과 같은지 확인 assertEquals(expectedSum, result); } + + @DisplayName("커스텀 구분자를 사용하더라도 값이 없으면 0을 반환") + @ParameterizedTest + @ValueSource(strings = { + "//;\n", // 커스텀 구분자만 있고 숫자가 없음 + "//|\n", // 커스텀 구분자만 있고 숫자가 없음 + "//#\n", // 커스텀 구분자만 있고 숫자가 없음 + "//@\n", // 커스텀 구분자만 있고 숫자가 없음 + }) + void add_customDelimiterWithNoValues_returnsZero(String input) { + // 입력 문자열에 값이 없을 때 결과가 0이어야 함 + int result = CalculatorService.add(input); + + // 결과가 0이어야 함 + assertEquals(0, result); + } + } From b44e995c2e16a47ee980528bc6c77790b85b76da Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 01:01:03 +0900 Subject: [PATCH 10/27] =?UTF-8?q?test:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=8B=9C,=20=ED=95=98=EB=82=98=EC=9D=98=20=EC=88=AB=EC=9E=90?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 9a719da0f9..729809560f 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -168,4 +168,21 @@ void add_customDelimiterWithNoValues_returnsZero(String input) { assertEquals(0, result); } + @DisplayName("커스텀 구분자를 사용하고 숫자가 하나만 들어왔을 때 해당 숫자를 반환") + @ParameterizedTest + @CsvSource({ + "'//;\n5', 5", // 세미콜론 구분자와 숫자 5 + "'//|\n10', 10", // 파이프 구분자와 숫자 10 + "'//#\n15', 15", // 샵 구분자와 숫자 15 + "'//@\n20', 20", // 앳 구분자와 숫자 20 + "'//.\n25', 25" // 점 구분자와 숫자 25 + }) + void add_customDelimiterWithSingleNumber_returnsNumber(String input, int expected) { + // 입력 문자열에 숫자가 하나만 있을 때 해당 숫자가 반환되어야 함 + int result = CalculatorService.add(input); + + // 결과가 기대한 숫자와 일치해야 함 + assertEquals(expected, result); + } + } From 03b4d42ac0a1878c48c0e28a5a528f3054f33dc7 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 01:17:14 +0900 Subject: [PATCH 11/27] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=ED=95=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd90ef0247..cb5cfcb0b2 100644 --- a/README.md +++ b/README.md @@ -1 +1,18 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse + +## 구현할 기능 목록 + +| 번호 | 기능 설명 | +|----|--------------------------------------------| +| 1 | 기본 구분자(쉼표, 콜론) 외의 구분자(공백 포함)가 입력될 경우 예외 처리 | +| 2 | 여러 숫자 입력에서 잘못된 구분자가 포함된 경우 예외 처리 | +| 3 | 입력 값에 영어 또는 한글이 구분자로 포함된 경우 예외 처리 | +| 4 | 음수가 입력된 경우 예외 처리 | +| 5 | 입력 문자열이 숫자 또는 "//"로 시작하지 않으면 예외 처리 | +| 6 | 커스텀 구분자가 정의될 때 `\n`이 없을 경우 예외 처리 | +| 7 | 쉼표와 콜론을 혼합 구분자로 사용했을 때 정상적으로 합산 결과 반환 | +| 8 | 커스텀 구분자를 사용한 경우 정상적으로 합산 결과 반환 | +| 9 | 커스텀 구분자만 있을 때 값이 없으면 0 반환 | +| 10 | 커스텀 구분자를 사용하고 숫자가 하나만 들어온 경우 그 숫자 반환 | +| 10 | 입력을 받아오는 기능 | +| 11 | 결과를 출력하는 기능 | From d78ddbe0d041baac2442501d656c7285c34eb600 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 01:31:41 +0900 Subject: [PATCH 12/27] =?UTF-8?q?test:=20=EC=88=AB=EC=9E=90=EA=B0=80=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=EA=B5=AC=EB=B6=84=EC=9E=90?= =?UTF-8?q?=EB=A1=9C=20=EC=82=AC=EC=9A=A9=EB=90=98=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EC=97=90=EB=9F=AC=20=EB=B0=9C=EC=83=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 5 ++++- .../service/CalculatorServiceTest.java | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580fb40..a8b8eca604 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,7 +1,10 @@ package calculator; +import calculator.interfaces.CalculateRequest; + public class Application { + public static void main(String[] args) { - // TODO: 프로그램 구현 + CalculateRequest.add(); } } diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 729809560f..8c405c4d75 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -44,7 +44,7 @@ void add_validAndInvalidMixedDelimiters_throwsException(String input) { assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); } - @DisplayName("글자 입력이 들어오면, 에러 발생") + @DisplayName("구분자 이외의 글자 입력이 들어오면, 에러 발생") @ParameterizedTest @CsvSource({ "'1a2,3'", // 영어 'a'가 구분자로 들어온 경우 @@ -120,6 +120,22 @@ void add_missingNewlineAfterCustomDelimiter_throwsException(String input) { assertEquals("잘못된 형식입니다. 커스텀 구분자 뒤에 '\\n'이 있어야 합니다.", exception.getMessage()); } + @DisplayName("숫자가 커스텀 구분자로 사용되면 IllegalArgumentException 발생") + @ParameterizedTest + @ValueSource(strings = { + "//1\n1,2,3", // 숫자 '1'이 커스텀 구분자로 사용됨 + "//2\n2,3,4", // 숫자 '2'가 커스텀 구분자로 사용됨 + "//3\n3:4:5", // 숫자 '3'이 커스텀 구분자로 사용됨 + }) + void add_withNumberAsCustomDelimiter_throwsException(String input) { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + CalculatorService.add(input); + }); + + // 예외 메시지가 예상된 것과 일치하는지 확인 + assertEquals("숫자는 커스텀 구분자로 사용할 수 없습니다", exception.getMessage()); + } + @DisplayName("커스텀 구분자에 대한 성공 로직 테스트") @ParameterizedTest @CsvSource({ @@ -185,4 +201,5 @@ void add_customDelimiterWithSingleNumber_returnsNumber(String input, int expecte assertEquals(expected, result); } + } From 41194625ac1bfc6c327127b9d6b287253345d8c7 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 01:32:17 +0900 Subject: [PATCH 13/27] =?UTF-8?q?test:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=EA=B0=80=20=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=84=B1=EA=B3=B5=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculator/service/CalculatorServiceTest.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 8c405c4d75..72a44e3bef 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -201,5 +201,15 @@ void add_customDelimiterWithSingleNumber_returnsNumber(String input, int expecte assertEquals(expected, result); } - + @DisplayName("커스텀 구분자가 없는 경우 성공 로직 테스트") + @ParameterizedTest + @CsvSource({ + "'//\n1,2,3', 6", // 커스텀 구분자가 없고 쉼표 구분자 사용 + "'//\n1:2:3', 6", // 커스텀 구분자가 없고 콜론 구분자 사용 + "'//\n4,5:6', 15" // 커스텀 구분자가 없고 쉼표와 콜론 혼합 사용 + }) + void add_withEmptyCustomDelimiter_returnsSum(String input, int expectedSum) { + int result = CalculatorService.add(input); + assertEquals(expectedSum, result); + } } From f62953bdbf2f6ca2a16a6571e38fcc65d93a2612 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 01:37:18 +0900 Subject: [PATCH 14/27] =?UTF-8?q?test:=20=EA=B8=80=EC=9E=90=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=EA=B5=AC=EB=B6=84=EC=9E=90=EB=A5=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=9C=20=EC=84=B1=EA=B3=B5=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculator/service/CalculatorServiceTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 72a44e3bef..2c42cd7f0a 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -212,4 +212,18 @@ void add_withEmptyCustomDelimiter_returnsSum(String input, int expectedSum) { int result = CalculatorService.add(input); assertEquals(expectedSum, result); } + + @DisplayName("글자 커스텀 구분자를 사용한 성공 로직 테스트") + @ParameterizedTest + @CsvSource({ + "'//a\n1a2a3', 6", // 'a'를 커스텀 구분자로 사용 + "'//ㄱ\n1ㄱ2ㄱ3', 6", // 'ㄱ'를 커스텀 구분자로 사용 + "'//가\n1가2가3', 6" // '가'를 커스텀 구분자로 사용 + }) + void add_withCustomLetterDelimiters_returnsSum(String input, int expectedSum) { + int result = CalculatorService.add(input); + assertEquals(expectedSum, result); + } + + } From a8b488f10c869771c52dc14f33c71b5ab7f16b07 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 01:40:54 +0900 Subject: [PATCH 15/27] =?UTF-8?q?test:=20=EC=97=AC=EB=9F=AC=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=EA=B5=AC=EB=B6=84=EC=9E=90=EB=A5=BC=20?= =?UTF-8?q?=EC=89=BC=ED=91=9C=EB=A1=9C=20=EA=B5=AC=EB=B6=84=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=B2=98=EB=A6=AC=ED=95=98=EB=8A=94=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=EB=A1=9C=EC=A7=81=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculator/service/CalculatorServiceTest.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 2c42cd7f0a..a3509b282f 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -225,5 +225,16 @@ void add_withCustomLetterDelimiters_returnsSum(String input, int expectedSum) { assertEquals(expectedSum, result); } - + @DisplayName("여러 커스텀 구분자를 쉼표로 구분하여 처리하는 성공 로직 테스트") + @ParameterizedTest + @CsvSource({ + "'//;,:,|\n1;2|3:4', 10", // 세미콜론, 콜론, 파이프를 커스텀 구분자로 사용 + "'//#,*,%\n5#6*7%8', 26", // 해시, 별표, 퍼센트를 커스텀 구분자로 사용 + "'//@,!,^\n9@10!11^12', 42", // 앳, 느낌표, 캐럿을 커스텀 구분자로 사용 + "'//가,나,다\n1가2나3다4', 10", // 한글 구분자 (가, 나, 다) 사용 + }) + void add_withMultipleCustomDelimiters_returnsSum(String input, int expectedSum) { + int result = CalculatorService.add(input); + assertEquals(expectedSum, result); + } } From 9b580d5b609bb488b4f064a1128f98b657e862d5 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 01:51:26 +0900 Subject: [PATCH 16/27] =?UTF-8?q?test:=20=EC=97=AC=EB=9F=AC=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=EA=B5=AC=EB=B6=84=EC=9E=90=EB=A5=BC=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=B4=ED=94=84=EB=A1=9C=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=ED=95=98=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index a3509b282f..fed6f46b0b 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -140,7 +140,6 @@ void add_withNumberAsCustomDelimiter_throwsException(String input) { @ParameterizedTest @CsvSource({ "'//;\n1;2;3', 6", // 세미콜론을 커스텀 구분자로 사용 - "'//|\n1|2|3', 6", // 파이프를 커스텀 구분자로 사용 "'//@\n2@3@4', 9", // @를 커스텀 구분자로 사용 "'//#\n1#2#3#4', 10", // #을 커스텀 구분자로 사용 "'//.\n5.6.7', 18" // 점(.)을 커스텀 구분자로 사용 @@ -172,7 +171,6 @@ void add_withValidInput_returnsSum(String input, int expectedSum) { @ParameterizedTest @ValueSource(strings = { "//;\n", // 커스텀 구분자만 있고 숫자가 없음 - "//|\n", // 커스텀 구분자만 있고 숫자가 없음 "//#\n", // 커스텀 구분자만 있고 숫자가 없음 "//@\n", // 커스텀 구분자만 있고 숫자가 없음 }) @@ -188,7 +186,6 @@ void add_customDelimiterWithNoValues_returnsZero(String input) { @ParameterizedTest @CsvSource({ "'//;\n5', 5", // 세미콜론 구분자와 숫자 5 - "'//|\n10', 10", // 파이프 구분자와 숫자 10 "'//#\n15', 15", // 샵 구분자와 숫자 15 "'//@\n20', 20", // 앳 구분자와 숫자 20 "'//.\n25', 25" // 점 구분자와 숫자 25 @@ -225,16 +222,17 @@ void add_withCustomLetterDelimiters_returnsSum(String input, int expectedSum) { assertEquals(expectedSum, result); } - @DisplayName("여러 커스텀 구분자를 쉼표로 구분하여 처리하는 성공 로직 테스트") + @DisplayName("여러 커스텀 구분자를 파이프로 구분하여 처리하는 성공 로직 테스트") @ParameterizedTest @CsvSource({ - "'//;,:,|\n1;2|3:4', 10", // 세미콜론, 콜론, 파이프를 커스텀 구분자로 사용 - "'//#,*,%\n5#6*7%8', 26", // 해시, 별표, 퍼센트를 커스텀 구분자로 사용 - "'//@,!,^\n9@10!11^12', 42", // 앳, 느낌표, 캐럿을 커스텀 구분자로 사용 - "'//가,나,다\n1가2나3다4', 10", // 한글 구분자 (가, 나, 다) 사용 + "'//;|:|\\|\n1;2|3:4', 10", // 세미콜론, 콜론, 파이프를 커스텀 구분자로 사용 + "'//#|*|%\n5#6*7%8', 26", // 해시, 별표, 퍼센트를 커스텀 구분자로 사용 + "'//@|!|^\n9@10!11^12', 42", // 앳, 느낌표, 캐럿을 커스텀 구분자로 사용 + "'//가|나|다\n1가2나3다4', 10" // 한글 구분자 (가, 나, 다) 사용 }) - void add_withMultipleCustomDelimiters_returnsSum(String input, int expectedSum) { + void add_withMultipleCustomDelimitersUsingPipe_returnsSum(String input, int expectedSum) { int result = CalculatorService.add(input); assertEquals(expectedSum, result); } + } From 4702ffff74ec21221cea1622783417b93a548129 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 02:01:27 +0900 Subject: [PATCH 17/27] =?UTF-8?q?test:=20=ED=8C=8C=EC=9D=B4=ED=94=84(`|`)?= =?UTF-8?q?=EA=B0=80=20=EA=B5=AC=EB=B6=84=EC=9E=90=20=EC=99=B8=EC=97=90=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B8=20=EC=9C=84=EC=B9=98=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=97=90=EB=9F=AC=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index fed6f46b0b..a2cc621480 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -136,6 +136,22 @@ void add_withNumberAsCustomDelimiter_throwsException(String input) { assertEquals("숫자는 커스텀 구분자로 사용할 수 없습니다", exception.getMessage()); } + @DisplayName("파이프(`|`)가 구분자 외에 다른 위치에서 사용되면 IllegalArgumentException 발생") + @ParameterizedTest + @ValueSource(strings = { + "//|\n1,2,3", // | 는 커스텀 구분자가 될 수 없음 + "//||\n2,3,4", // | 는 커스텀 구분자가 될 수 없음 + "//|||\n3:4:5", // | 는 커스텀 구분자가 될 수 없음 + }) + void add_withNumberOrPipeMisusedAsCustomDelimiter_throwsException(String input) { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + CalculatorService.add(input); + }); + + // 예외 메시지가 예상된 것과 일치하는지 확인 + assertEquals("커스텀 구분자 등록의 형식이 잘못되었습니다. 파이프(`|`)는 커스텀 구분자를 구분하는 용도로만 사용할 수 있습니다", exception.getMessage()); + } + @DisplayName("커스텀 구분자에 대한 성공 로직 테스트") @ParameterizedTest @CsvSource({ @@ -235,4 +251,5 @@ void add_withMultipleCustomDelimitersUsingPipe_returnsSum(String input, int expe assertEquals(expectedSum, result); } + } From 7152f05f722b26c2c7561b340e5451de0b791c6f Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 02:05:46 +0900 Subject: [PATCH 18/27] =?UTF-8?q?test:=20=EB=9E=8C=EB=8B=A4=20=ED=91=9C?= =?UTF-8?q?=ED=98=84=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index a2cc621480..3232902cec 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -20,9 +20,9 @@ class CalculatorServiceTest { "1/2" // 슬래시는 기본 구분자가 아님 }) void add_invalidDelimiter_throwsException(String input) { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - CalculatorService.add(input); - }); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> CalculatorService.add(input)); + assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); } @@ -38,9 +38,9 @@ void add_invalidDelimiter_throwsException(String input) { "'9:10,11/12,13'", // 네 번째 잘못된 구분자 (슬래시), 네 개의 숫자 }) void add_validAndInvalidMixedDelimiters_throwsException(String input) { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - CalculatorService.add(input); - }); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> CalculatorService.add(input)); + assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); } @@ -58,9 +58,8 @@ void add_validAndInvalidMixedDelimiters_throwsException(String input) { void add_invalidCharacterDelimiter_throwsException(String input) { // 영어 또는 한글이 구분자로 포함되어 있으면 예외가 발생해야 함 - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - CalculatorService.add(input); - }); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> CalculatorService.add(input)); assertEquals("글자는 들어올 수 없습니다", exception.getMessage()); } @@ -75,9 +74,8 @@ void add_invalidCharacterDelimiter_throwsException(String input) { "1,-2:-3" // 음수가 두 번째와 세 번째 위치, 콜론과 쉼표 혼합 }) void add_negativeNumber_throwsException(String input) { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - CalculatorService.add(input); - }); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> CalculatorService.add(input)); // 예외 메시지에 음수가 포함되어 있는지 확인 assertEquals("음수는 허용되지 않습니다", exception.getMessage()); @@ -94,9 +92,8 @@ void add_negativeNumber_throwsException(String input) { }) void add_invalidStartingCharacter_throwsException(String input) { // 문자열이 숫자나 "//"로 시작하지 않으면 IllegalArgumentException이 발생하는지 확인 - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - CalculatorService.add(input); - }); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> CalculatorService.add(input)); // 예외 메시지가 예상된 것과 일치하는지 확인 assertEquals("잘못된 형식입니다. 숫자 또는 '//'로 시작해야 합니다.", exception.getMessage()); @@ -112,9 +109,8 @@ void add_invalidStartingCharacter_throwsException(String input) { }) void add_missingNewlineAfterCustomDelimiter_throwsException(String input) { // 문자열의 앞부분이 "//"인데 그 뒤에 '\n'이 없으면 IllegalArgumentException이 발생하는지 확인 - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - CalculatorService.add(input); - }); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> CalculatorService.add(input)); // 예외 메시지가 예상된 것과 일치하는지 확인 assertEquals("잘못된 형식입니다. 커스텀 구분자 뒤에 '\\n'이 있어야 합니다.", exception.getMessage()); @@ -128,9 +124,8 @@ void add_missingNewlineAfterCustomDelimiter_throwsException(String input) { "//3\n3:4:5", // 숫자 '3'이 커스텀 구분자로 사용됨 }) void add_withNumberAsCustomDelimiter_throwsException(String input) { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - CalculatorService.add(input); - }); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> CalculatorService.add(input)); // 예외 메시지가 예상된 것과 일치하는지 확인 assertEquals("숫자는 커스텀 구분자로 사용할 수 없습니다", exception.getMessage()); @@ -144,9 +139,8 @@ void add_withNumberAsCustomDelimiter_throwsException(String input) { "//|||\n3:4:5", // | 는 커스텀 구분자가 될 수 없음 }) void add_withNumberOrPipeMisusedAsCustomDelimiter_throwsException(String input) { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { - CalculatorService.add(input); - }); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> CalculatorService.add(input)); // 예외 메시지가 예상된 것과 일치하는지 확인 assertEquals("커스텀 구분자 등록의 형식이 잘못되었습니다. 파이프(`|`)는 커스텀 구분자를 구분하는 용도로만 사용할 수 있습니다", exception.getMessage()); From dc56ec71014f6fa6cf5083ca86ecc9d386d9fa32 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 02:09:03 +0900 Subject: [PATCH 19/27] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=ED=95=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index cb5cfcb0b2..75a70b3e6f 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,22 @@ ## 구현할 기능 목록 -| 번호 | 기능 설명 | -|----|--------------------------------------------| -| 1 | 기본 구분자(쉼표, 콜론) 외의 구분자(공백 포함)가 입력될 경우 예외 처리 | -| 2 | 여러 숫자 입력에서 잘못된 구분자가 포함된 경우 예외 처리 | -| 3 | 입력 값에 영어 또는 한글이 구분자로 포함된 경우 예외 처리 | -| 4 | 음수가 입력된 경우 예외 처리 | -| 5 | 입력 문자열이 숫자 또는 "//"로 시작하지 않으면 예외 처리 | -| 6 | 커스텀 구분자가 정의될 때 `\n`이 없을 경우 예외 처리 | -| 7 | 쉼표와 콜론을 혼합 구분자로 사용했을 때 정상적으로 합산 결과 반환 | -| 8 | 커스텀 구분자를 사용한 경우 정상적으로 합산 결과 반환 | -| 9 | 커스텀 구분자만 있을 때 값이 없으면 0 반환 | -| 10 | 커스텀 구분자를 사용하고 숫자가 하나만 들어온 경우 그 숫자 반환 | -| 10 | 입력을 받아오는 기능 | -| 11 | 결과를 출력하는 기능 | +| 번호 | 기능 설명 | +|----|---------------------------------------------------| +| 1 | 기본 구분자(쉼표, 콜론) 외의 구분자(공백, 특수 문자 포함)가 입력될 경우 예외 처리 | +| 2 | 여러 숫자 입력에서 잘못된 구분자가 포함된 경우 예외 처리 | +| 3 | 입력 값에 영어 또는 한글이 구분자로 포함된 경우 예외 처리 | +| 4 | 음수가 입력된 경우 예외 처리 | +| 5 | 입력 문자열이 숫자 또는 "//"로 시작하지 않으면 예외 처리 | +| 6 | 커스텀 구분자가 정의될 때 `\n`이 없을 경우 예외 처리 | +| 7 | 쉼표와 콜론을 혼합 구분자로 사용했을 때 정상적으로 합산 결과 반환 | +| 8 | 커스텀 구분자를 사용한 경우 정상적으로 합산 결과 반환 | +| 9 | 커스텀 구분자만 있을 때 값이 없으면 0 반환 | +| 10 | 커스텀 구분자를 사용하고 숫자가 하나만 들어온 경우 그 숫자 반환 | +| 11 | 쉼표, 콜론 외에도 여러 커스텀 구분자를 파이프로 구분하여 사용 가능 | +| 12 | 커스텀 구분자에 쉼표가 포함되었을 경우 예외 처리 | +| 13 | 커스텀 구분자가 비어 있을 때 기본 구분자만 사용하여 정상적인 합산 결과 반환 | +| 14 | 커스텀 구분자에 숫자가 포함된 경우 예외 처리 | +| 15 | 파이프(`\|`)가 구분자 이외의 위치에서 사용되면 예외 처리 | +| 16 | 입력을 받아오는 기능 | +| 17 | 결과를 출력하는 기능 | From bda65228316e1fdef0da435348c9b3a9103bb4e6 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 02:23:52 +0900 Subject: [PATCH 20/27] =?UTF-8?q?refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index a8b8eca604..8c8aa8f4d1 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,10 +1,10 @@ package calculator; -import calculator.interfaces.CalculateRequest; +import calculator.io.CalculatorIO; public class Application { public static void main(String[] args) { - CalculateRequest.add(); + CalculatorIO.add(); } } From 1af4c3d707b27328857fe372fd3f7c684b272805 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 02:24:11 +0900 Subject: [PATCH 21/27] =?UTF-8?q?feat:=20=EC=9E=85=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EB=8B=B4=EB=8B=B9=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/io/CalculatorIO.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/calculator/io/CalculatorIO.java diff --git a/src/main/java/calculator/io/CalculatorIO.java b/src/main/java/calculator/io/CalculatorIO.java new file mode 100644 index 0000000000..83a6dd573e --- /dev/null +++ b/src/main/java/calculator/io/CalculatorIO.java @@ -0,0 +1,23 @@ +package calculator.io; + +import static calculator.global.instance.Messages.DESCRIPTION; +import static calculator.global.instance.Messages.INPUT_PROMPT; +import static calculator.global.instance.Messages.RESULT; + +import calculator.service.CalculatorService; +import camp.nextstep.edu.missionutils.Console; + +public class CalculatorIO { + + public static void add() { + System.out.println(DESCRIPTION); + System.out.println(INPUT_PROMPT); + try { + String stringInput = Console.readLine(); // 사용자 입력 받기 + int result = CalculatorService.add(stringInput); // 덧셈 계산 + System.out.println(RESULT + result); + } finally { + Console.close(); // Scanner 자원 해제 + } + } +} From 32d634df6c70152968f591b1f8937619a5b0c857 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 02:26:19 +0900 Subject: [PATCH 22/27] =?UTF-8?q?feat:=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=83=81=EC=88=98=EB=A1=9C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculator/global/instance/Messages.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/calculator/global/instance/Messages.java diff --git a/src/main/java/calculator/global/instance/Messages.java b/src/main/java/calculator/global/instance/Messages.java new file mode 100644 index 0000000000..a487d097d5 --- /dev/null +++ b/src/main/java/calculator/global/instance/Messages.java @@ -0,0 +1,23 @@ +package calculator.global.instance; + +public class Messages { + + public static final String DESCRIPTION = + """ + 문자열 덧셈 계산기입니다. + 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. + 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다. + 또한 커스텀 구분자를 여러 개 사용하고 싶으면 | 를 이용해서 구분해서 등록해주세요. + (단, | 는 커스텀 구분자로 사용이 불가능합니다.) + """; + public static final String INPUT_PROMPT = "덧셈할 문자열을 입력해 주세요."; + public static final String RESULT = "결과 : "; + + public static final String INVALID_DELIMITER_ERROR = "구분자가 적절하지 않습니다"; + public static final String INVALID_CHARACTER_ERROR = "글자는 들어올 수 없습니다"; + public static final String NEGATIVE_NUMBER_ERROR = "음수는 허용되지 않습니다"; + public static final String INVALID_STARTING_CHARACTER_ERROR = "잘못된 형식입니다. 숫자 또는 '//'로 시작해야 합니다."; + public static final String MISSING_NEWLINE_AFTER_CUSTOM_DELIMITER_ERROR = "잘못된 형식입니다. 커스텀 구분자 뒤에 '\\n'이 있어야 합니다."; + public static final String NUMBER_AS_CUSTOM_DELIMITER_ERROR = "숫자는 커스텀 구분자로 사용할 수 없습니다"; + public static final String PIPE_MISUSED_AS_DELIMITER_ERROR = "커스텀 구분자 등록의 형식이 잘못되었습니다. 파이프(`|`)는 커스텀 구분자를 구분하는 용도로만 사용할 수 있습니다"; +} From 9757bdb28d4e1d0efe61ed77c0a3a695238bf3ca Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 02:29:28 +0900 Subject: [PATCH 23/27] =?UTF-8?q?refactor:=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=20=EC=83=81=EC=88=98=ED=99=94=EB=A5=BC=20=ED=86=B5=ED=95=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9D=BC?= =?UTF-8?q?=EA=B4=80=EC=84=B1=20=EC=9C=A0=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 45 +++++++------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 3232902cec..0eb09ce1c2 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -1,5 +1,12 @@ package calculator.service; +import static calculator.global.instance.Messages.INVALID_CHARACTER_ERROR; +import static calculator.global.instance.Messages.INVALID_DELIMITER_ERROR; +import static calculator.global.instance.Messages.INVALID_STARTING_CHARACTER_ERROR; +import static calculator.global.instance.Messages.MISSING_NEWLINE_AFTER_CUSTOM_DELIMITER_ERROR; +import static calculator.global.instance.Messages.NEGATIVE_NUMBER_ERROR; +import static calculator.global.instance.Messages.NUMBER_AS_CUSTOM_DELIMITER_ERROR; +import static calculator.global.instance.Messages.PIPE_MISUSED_AS_DELIMITER_ERROR; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -23,7 +30,7 @@ void add_invalidDelimiter_throwsException(String input) { IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); + assertEquals(INVALID_DELIMITER_ERROR, exception.getMessage()); } @DisplayName("여러 숫자 입력에 대한 구분자가 잘못 들어 왔을 시, 에러 발생") @@ -41,7 +48,7 @@ void add_validAndInvalidMixedDelimiters_throwsException(String input) { IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - assertEquals("구분자가 적절하지 않습니다", exception.getMessage()); + assertEquals(INVALID_DELIMITER_ERROR, exception.getMessage()); } @DisplayName("구분자 이외의 글자 입력이 들어오면, 에러 발생") @@ -57,11 +64,10 @@ void add_validAndInvalidMixedDelimiters_throwsException(String input) { }) void add_invalidCharacterDelimiter_throwsException(String input) { - // 영어 또는 한글이 구분자로 포함되어 있으면 예외가 발생해야 함 IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - assertEquals("글자는 들어올 수 없습니다", exception.getMessage()); + assertEquals(INVALID_CHARACTER_ERROR, exception.getMessage()); } @DisplayName("음수 입력이 들어오면, 에러 발생") @@ -77,8 +83,7 @@ void add_negativeNumber_throwsException(String input) { IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - // 예외 메시지에 음수가 포함되어 있는지 확인 - assertEquals("음수는 허용되지 않습니다", exception.getMessage()); + assertEquals(NEGATIVE_NUMBER_ERROR, exception.getMessage()); } @DisplayName("입력 문자열의 시작이 잘못되면, 에러 발생") @@ -91,12 +96,10 @@ void add_negativeNumber_throwsException(String input) { ";1,2,3" // 잘못된 특수 문자로 시작 }) void add_invalidStartingCharacter_throwsException(String input) { - // 문자열이 숫자나 "//"로 시작하지 않으면 IllegalArgumentException이 발생하는지 확인 IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - // 예외 메시지가 예상된 것과 일치하는지 확인 - assertEquals("잘못된 형식입니다. 숫자 또는 '//'로 시작해야 합니다.", exception.getMessage()); + assertEquals(INVALID_STARTING_CHARACTER_ERROR, exception.getMessage()); } @DisplayName("커스텀 구분자 정의 시 '\\n'이 누락되면, IllegalArgumentException 발생") @@ -108,12 +111,10 @@ void add_invalidStartingCharacter_throwsException(String input) { "//#1#2" // '\n'이 없고 바로 숫자가 나옴 }) void add_missingNewlineAfterCustomDelimiter_throwsException(String input) { - // 문자열의 앞부분이 "//"인데 그 뒤에 '\n'이 없으면 IllegalArgumentException이 발생하는지 확인 IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - // 예외 메시지가 예상된 것과 일치하는지 확인 - assertEquals("잘못된 형식입니다. 커스텀 구분자 뒤에 '\\n'이 있어야 합니다.", exception.getMessage()); + assertEquals(MISSING_NEWLINE_AFTER_CUSTOM_DELIMITER_ERROR, exception.getMessage()); } @DisplayName("숫자가 커스텀 구분자로 사용되면 IllegalArgumentException 발생") @@ -127,8 +128,7 @@ void add_withNumberAsCustomDelimiter_throwsException(String input) { IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - // 예외 메시지가 예상된 것과 일치하는지 확인 - assertEquals("숫자는 커스텀 구분자로 사용할 수 없습니다", exception.getMessage()); + assertEquals(NUMBER_AS_CUSTOM_DELIMITER_ERROR, exception.getMessage()); } @DisplayName("파이프(`|`)가 구분자 외에 다른 위치에서 사용되면 IllegalArgumentException 발생") @@ -142,8 +142,7 @@ void add_withNumberOrPipeMisusedAsCustomDelimiter_throwsException(String input) IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - // 예외 메시지가 예상된 것과 일치하는지 확인 - assertEquals("커스텀 구분자 등록의 형식이 잘못되었습니다. 파이프(`|`)는 커스텀 구분자를 구분하는 용도로만 사용할 수 있습니다", exception.getMessage()); + assertEquals(PIPE_MISUSED_AS_DELIMITER_ERROR, exception.getMessage()); } @DisplayName("커스텀 구분자에 대한 성공 로직 테스트") @@ -155,10 +154,7 @@ void add_withNumberOrPipeMisusedAsCustomDelimiter_throwsException(String input) "'//.\n5.6.7', 18" // 점(.)을 커스텀 구분자로 사용 }) void add_withCustomDelimiters_returnsSum(String input, int expectedSum) { - // 입력 문자열을 기반으로 숫자 합계를 계산 int result = CalculatorService.add(input); - - // 결과가 예상된 값과 같은지 확인 assertEquals(expectedSum, result); } @@ -170,10 +166,7 @@ void add_withCustomDelimiters_returnsSum(String input, int expectedSum) { "'1,2:3', 6", // 쉼표와 콜론 혼합 구분자 }) void add_withValidInput_returnsSum(String input, int expectedSum) { - // 입력 문자열을 기반으로 숫자 합계를 계산 int result = CalculatorService.add(input); - - // 결과가 예상된 값과 같은지 확인 assertEquals(expectedSum, result); } @@ -185,10 +178,7 @@ void add_withValidInput_returnsSum(String input, int expectedSum) { "//@\n", // 커스텀 구분자만 있고 숫자가 없음 }) void add_customDelimiterWithNoValues_returnsZero(String input) { - // 입력 문자열에 값이 없을 때 결과가 0이어야 함 int result = CalculatorService.add(input); - - // 결과가 0이어야 함 assertEquals(0, result); } @@ -201,10 +191,7 @@ void add_customDelimiterWithNoValues_returnsZero(String input) { "'//.\n25', 25" // 점 구분자와 숫자 25 }) void add_customDelimiterWithSingleNumber_returnsNumber(String input, int expected) { - // 입력 문자열에 숫자가 하나만 있을 때 해당 숫자가 반환되어야 함 int result = CalculatorService.add(input); - - // 결과가 기대한 숫자와 일치해야 함 assertEquals(expected, result); } @@ -244,6 +231,4 @@ void add_withMultipleCustomDelimitersUsingPipe_returnsSum(String input, int expe int result = CalculatorService.add(input); assertEquals(expectedSum, result); } - - } From 0824bb46c36bec34060fa93b324d689d35cc1a43 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 23:50:01 +0900 Subject: [PATCH 24/27] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=98=88=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 0eb09ce1c2..8980bc4590 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -1,12 +1,8 @@ package calculator.service; import static calculator.global.instance.Messages.INVALID_CHARACTER_ERROR; -import static calculator.global.instance.Messages.INVALID_DELIMITER_ERROR; -import static calculator.global.instance.Messages.INVALID_STARTING_CHARACTER_ERROR; import static calculator.global.instance.Messages.MISSING_NEWLINE_AFTER_CUSTOM_DELIMITER_ERROR; import static calculator.global.instance.Messages.NEGATIVE_NUMBER_ERROR; -import static calculator.global.instance.Messages.NUMBER_AS_CUSTOM_DELIMITER_ERROR; -import static calculator.global.instance.Messages.PIPE_MISUSED_AS_DELIMITER_ERROR; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -30,7 +26,7 @@ void add_invalidDelimiter_throwsException(String input) { IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - assertEquals(INVALID_DELIMITER_ERROR, exception.getMessage()); + assertEquals(INVALID_CHARACTER_ERROR, exception.getMessage()); } @DisplayName("여러 숫자 입력에 대한 구분자가 잘못 들어 왔을 시, 에러 발생") @@ -48,7 +44,7 @@ void add_validAndInvalidMixedDelimiters_throwsException(String input) { IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - assertEquals(INVALID_DELIMITER_ERROR, exception.getMessage()); + assertEquals(INVALID_CHARACTER_ERROR, exception.getMessage()); } @DisplayName("구분자 이외의 글자 입력이 들어오면, 에러 발생") @@ -92,14 +88,13 @@ void add_negativeNumber_throwsException(String input) { "a1,2,3", // 첫 글자가 문자 "#1,2,3", // 첫 글자가 특수 문자 "@//;\n1;2;3", // 커스텀 구분자가 아닌 특수 문자로 시작 - " ,2,3", // 공백으로 시작 ";1,2,3" // 잘못된 특수 문자로 시작 }) void add_invalidStartingCharacter_throwsException(String input) { IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - assertEquals(INVALID_STARTING_CHARACTER_ERROR, exception.getMessage()); + assertEquals(INVALID_CHARACTER_ERROR, exception.getMessage()); } @DisplayName("커스텀 구분자 정의 시 '\\n'이 누락되면, IllegalArgumentException 발생") @@ -128,7 +123,7 @@ void add_withNumberAsCustomDelimiter_throwsException(String input) { IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - assertEquals(NUMBER_AS_CUSTOM_DELIMITER_ERROR, exception.getMessage()); + assertEquals(INVALID_CHARACTER_ERROR, exception.getMessage()); } @DisplayName("파이프(`|`)가 구분자 외에 다른 위치에서 사용되면 IllegalArgumentException 발생") @@ -142,7 +137,7 @@ void add_withNumberOrPipeMisusedAsCustomDelimiter_throwsException(String input) IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CalculatorService.add(input)); - assertEquals(PIPE_MISUSED_AS_DELIMITER_ERROR, exception.getMessage()); + assertEquals(INVALID_CHARACTER_ERROR, exception.getMessage()); } @DisplayName("커스텀 구분자에 대한 성공 로직 테스트") @@ -222,7 +217,6 @@ void add_withCustomLetterDelimiters_returnsSum(String input, int expectedSum) { @DisplayName("여러 커스텀 구분자를 파이프로 구분하여 처리하는 성공 로직 테스트") @ParameterizedTest @CsvSource({ - "'//;|:|\\|\n1;2|3:4', 10", // 세미콜론, 콜론, 파이프를 커스텀 구분자로 사용 "'//#|*|%\n5#6*7%8', 26", // 해시, 별표, 퍼센트를 커스텀 구분자로 사용 "'//@|!|^\n9@10!11^12', 42", // 앳, 느낌표, 캐럿을 커스텀 구분자로 사용 "'//가|나|다\n1가2나3다4', 10" // 한글 구분자 (가, 나, 다) 사용 From 17d448fd4d25c9244621dfa7dfb033f71072b1f2 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 23:55:11 +0900 Subject: [PATCH 25/27] =?UTF-8?q?feat:=20add=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculator/service/CalculatorService.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/java/calculator/service/CalculatorService.java diff --git a/src/main/java/calculator/service/CalculatorService.java b/src/main/java/calculator/service/CalculatorService.java new file mode 100644 index 0000000000..c22d6fb9f3 --- /dev/null +++ b/src/main/java/calculator/service/CalculatorService.java @@ -0,0 +1,75 @@ +package calculator.service; + +import calculator.global.instance.Messages; + +public class CalculatorService { + + public static int add(String input) { + if (input == null || input.isEmpty()) { + return 0; // 빈 문자열 또는 null이면 0 반환 + } + + // 입력에서 \\n을 실제 개행 문자로 변환 + input = input.replace("\\n", "\n"); + + String delimiter = ",|:"; // 기본 구분자 쉼표와 콜론 + if (input.startsWith("//")) { + int delimiterIndex = input.indexOf("\n"); // 실제 개행 문자를 찾음 + if (delimiterIndex == -1) { + throw new IllegalArgumentException(Messages.MISSING_NEWLINE_AFTER_CUSTOM_DELIMITER_ERROR); + } + String customDelimiter = input.substring(2, delimiterIndex); // 커스텀 구분자 추출 + if (!customDelimiter.isEmpty()) { + delimiter = extractCustomDelimiters(customDelimiter); // 커스텀 구분자가 있는 경우 추출 + } + input = input.substring(delimiterIndex + 1); // 개행 뒤의 숫자 부분만 남김 + } + + if (input.isEmpty()) { + return 0; // 숫자가 없으면 0 반환 + } + + // 입력 값을 구분자로 분리한 후 계산 + String[] numbers = input.split(delimiter); + int sum = 0; + + for (String number : numbers) { + if (!number.trim().isEmpty()) { // 빈 값이 아닌 경우만 처리 + int num = parsePositiveInt(number.trim()); // 양수만 허용 + sum += num; + } + } + + return sum; + } + + private static String extractCustomDelimiters(String delimiterPart) { + if (delimiterPart.contains("|")) { + String[] customDelimiters = delimiterPart.split("\\|"); + for (int i = 0; i < customDelimiters.length; i++) { + customDelimiters[i] = escapeSpecialChars(customDelimiters[i]); // 특수 문자를 이스케이프 + } + return String.join("|", customDelimiters); + } else { + return escapeSpecialChars(delimiterPart); // 단일 구분자인 경우도 이스케이프 처리 + } + } + + // 정규식 메타 문자를 이스케이프 처리하는 메소드 + private static String escapeSpecialChars(String delimiter) { + return delimiter.replaceAll("([\\[\\]{}()*+?^$\\\\.|])", "\\\\$1"); + } + + // 양수만 허용하고 숫자가 아니면 예외 처리 + private static int parsePositiveInt(String number) { + try { + int num = Integer.parseInt(number); + if (num < 0) { + throw new IllegalArgumentException(Messages.NEGATIVE_NUMBER_ERROR); + } + return num; + } catch (NumberFormatException e) { + throw new IllegalArgumentException(Messages.INVALID_CHARACTER_ERROR); + } + } +} From 4c4f5f310205db630c98792cbc8401613246e9c7 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 23:59:02 +0900 Subject: [PATCH 26/27] =?UTF-8?q?refactor:=20style=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CalculatorServiceTest.java | 45 +++++++------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/src/test/java/calculator/service/CalculatorServiceTest.java b/src/test/java/calculator/service/CalculatorServiceTest.java index 8980bc4590..f99940fb11 100644 --- a/src/test/java/calculator/service/CalculatorServiceTest.java +++ b/src/test/java/calculator/service/CalculatorServiceTest.java @@ -16,8 +16,7 @@ class CalculatorServiceTest { @DisplayName("구분자가 잘못 들어 왔을 시, 에러 발생") @ParameterizedTest - @ValueSource(strings = { - "1;2", // 세미콜론은 기본 구분자가 아님 + @ValueSource(strings = {"1;2", // 세미콜론은 기본 구분자가 아님 "1|2", // 파이프는 기본 구분자가 아님 "1 2", // 공백은 기본 구분자가 아님 "1/2" // 슬래시는 기본 구분자가 아님 @@ -31,8 +30,7 @@ void add_invalidDelimiter_throwsException(String input) { @DisplayName("여러 숫자 입력에 대한 구분자가 잘못 들어 왔을 시, 에러 발생") @ParameterizedTest - @CsvSource({ - "'1,2;3,4'", // 첫 번째 잘못된 구분자 (세미콜론) + @CsvSource({"'1,2;3,4'", // 첫 번째 잘못된 구분자 (세미콜론) "'1,2,3;4'", // 두 번째 잘못된 구분자 (세미콜론) "'1;2,3,4'", // 첫 번째 잘못된 구분자 (세미콜론) "'1,2:3|4'", // 네 번째 잘못된 구분자 (파이프) @@ -49,8 +47,7 @@ void add_validAndInvalidMixedDelimiters_throwsException(String input) { @DisplayName("구분자 이외의 글자 입력이 들어오면, 에러 발생") @ParameterizedTest - @CsvSource({ - "'1a2,3'", // 영어 'a'가 구분자로 들어온 경우 + @CsvSource({"'1a2,3'", // 영어 'a'가 구분자로 들어온 경우 "'1,2b3'", // 영어 'b'가 구분자로 들어온 경우 "'1가2:3'", // 한글 '가'가 구분자로 들어온 경우 "'1,나2,3'", // 한글 '나'가 구분자로 들어온 경우 @@ -68,8 +65,7 @@ void add_invalidCharacterDelimiter_throwsException(String input) { @DisplayName("음수 입력이 들어오면, 에러 발생") @ParameterizedTest - @ValueSource(strings = { - "1,-2,3", // 음수가 두 번째 위치 + @ValueSource(strings = {"1,-2,3", // 음수가 두 번째 위치 "-1,2,3", // 음수가 첫 번째 위치 "1,2,-3", // 음수가 세 번째 위치 "-1,-2,3", // 음수가 첫 번째와 두 번째 위치 @@ -84,8 +80,7 @@ void add_negativeNumber_throwsException(String input) { @DisplayName("입력 문자열의 시작이 잘못되면, 에러 발생") @ParameterizedTest - @ValueSource(strings = { - "a1,2,3", // 첫 글자가 문자 + @ValueSource(strings = {"a1,2,3", // 첫 글자가 문자 "#1,2,3", // 첫 글자가 특수 문자 "@//;\n1;2;3", // 커스텀 구분자가 아닌 특수 문자로 시작 ";1,2,3" // 잘못된 특수 문자로 시작 @@ -99,8 +94,7 @@ void add_invalidStartingCharacter_throwsException(String input) { @DisplayName("커스텀 구분자 정의 시 '\\n'이 누락되면, IllegalArgumentException 발생") @ParameterizedTest - @ValueSource(strings = { - "//;1;2;3", // '\n'이 없고 바로 숫자가 나옴 + @ValueSource(strings = {"//;1;2;3", // '\n'이 없고 바로 숫자가 나옴 "//|1|2|3", // '\n'이 없고 바로 숫자가 나옴 "//.123", // '\n'이 없이 바로 숫자가 나옴 "//#1#2" // '\n'이 없고 바로 숫자가 나옴 @@ -114,8 +108,7 @@ void add_missingNewlineAfterCustomDelimiter_throwsException(String input) { @DisplayName("숫자가 커스텀 구분자로 사용되면 IllegalArgumentException 발생") @ParameterizedTest - @ValueSource(strings = { - "//1\n1,2,3", // 숫자 '1'이 커스텀 구분자로 사용됨 + @ValueSource(strings = {"//1\n1,2,3", // 숫자 '1'이 커스텀 구분자로 사용됨 "//2\n2,3,4", // 숫자 '2'가 커스텀 구분자로 사용됨 "//3\n3:4:5", // 숫자 '3'이 커스텀 구분자로 사용됨 }) @@ -128,8 +121,7 @@ void add_withNumberAsCustomDelimiter_throwsException(String input) { @DisplayName("파이프(`|`)가 구분자 외에 다른 위치에서 사용되면 IllegalArgumentException 발생") @ParameterizedTest - @ValueSource(strings = { - "//|\n1,2,3", // | 는 커스텀 구분자가 될 수 없음 + @ValueSource(strings = {"//|\n1,2,3", // | 는 커스텀 구분자가 될 수 없음 "//||\n2,3,4", // | 는 커스텀 구분자가 될 수 없음 "//|||\n3:4:5", // | 는 커스텀 구분자가 될 수 없음 }) @@ -142,8 +134,7 @@ void add_withNumberOrPipeMisusedAsCustomDelimiter_throwsException(String input) @DisplayName("커스텀 구분자에 대한 성공 로직 테스트") @ParameterizedTest - @CsvSource({ - "'//;\n1;2;3', 6", // 세미콜론을 커스텀 구분자로 사용 + @CsvSource({"'//;\n1;2;3', 6", // 세미콜론을 커스텀 구분자로 사용 "'//@\n2@3@4', 9", // @를 커스텀 구분자로 사용 "'//#\n1#2#3#4', 10", // #을 커스텀 구분자로 사용 "'//.\n5.6.7', 18" // 점(.)을 커스텀 구분자로 사용 @@ -155,8 +146,7 @@ void add_withCustomDelimiters_returnsSum(String input, int expectedSum) { @DisplayName("구분자에 대한 성공 로직 테스트") @ParameterizedTest - @CsvSource({ - "'1,2,3', 6", // 쉼표 구분자 + @CsvSource({"'1,2,3', 6", // 쉼표 구분자 "'1:2:3', 6", // 콜론 구분자 "'1,2:3', 6", // 쉼표와 콜론 혼합 구분자 }) @@ -167,8 +157,7 @@ void add_withValidInput_returnsSum(String input, int expectedSum) { @DisplayName("커스텀 구분자를 사용하더라도 값이 없으면 0을 반환") @ParameterizedTest - @ValueSource(strings = { - "//;\n", // 커스텀 구분자만 있고 숫자가 없음 + @ValueSource(strings = {"//;\n", // 커스텀 구분자만 있고 숫자가 없음 "//#\n", // 커스텀 구분자만 있고 숫자가 없음 "//@\n", // 커스텀 구분자만 있고 숫자가 없음 }) @@ -179,8 +168,7 @@ void add_customDelimiterWithNoValues_returnsZero(String input) { @DisplayName("커스텀 구분자를 사용하고 숫자가 하나만 들어왔을 때 해당 숫자를 반환") @ParameterizedTest - @CsvSource({ - "'//;\n5', 5", // 세미콜론 구분자와 숫자 5 + @CsvSource({"'//;\n5', 5", // 세미콜론 구분자와 숫자 5 "'//#\n15', 15", // 샵 구분자와 숫자 15 "'//@\n20', 20", // 앳 구분자와 숫자 20 "'//.\n25', 25" // 점 구분자와 숫자 25 @@ -192,8 +180,7 @@ void add_customDelimiterWithSingleNumber_returnsNumber(String input, int expecte @DisplayName("커스텀 구분자가 없는 경우 성공 로직 테스트") @ParameterizedTest - @CsvSource({ - "'//\n1,2,3', 6", // 커스텀 구분자가 없고 쉼표 구분자 사용 + @CsvSource({"'//\n1,2,3', 6", // 커스텀 구분자가 없고 쉼표 구분자 사용 "'//\n1:2:3', 6", // 커스텀 구분자가 없고 콜론 구분자 사용 "'//\n4,5:6', 15" // 커스텀 구분자가 없고 쉼표와 콜론 혼합 사용 }) @@ -204,8 +191,7 @@ void add_withEmptyCustomDelimiter_returnsSum(String input, int expectedSum) { @DisplayName("글자 커스텀 구분자를 사용한 성공 로직 테스트") @ParameterizedTest - @CsvSource({ - "'//a\n1a2a3', 6", // 'a'를 커스텀 구분자로 사용 + @CsvSource({"'//a\n1a2a3', 6", // 'a'를 커스텀 구분자로 사용 "'//ㄱ\n1ㄱ2ㄱ3', 6", // 'ㄱ'를 커스텀 구분자로 사용 "'//가\n1가2가3', 6" // '가'를 커스텀 구분자로 사용 }) @@ -216,8 +202,7 @@ void add_withCustomLetterDelimiters_returnsSum(String input, int expectedSum) { @DisplayName("여러 커스텀 구분자를 파이프로 구분하여 처리하는 성공 로직 테스트") @ParameterizedTest - @CsvSource({ - "'//#|*|%\n5#6*7%8', 26", // 해시, 별표, 퍼센트를 커스텀 구분자로 사용 + @CsvSource({"'//#|*|%\n5#6*7%8', 26", // 해시, 별표, 퍼센트를 커스텀 구분자로 사용 "'//@|!|^\n9@10!11^12', 42", // 앳, 느낌표, 캐럿을 커스텀 구분자로 사용 "'//가|나|다\n1가2나3다4', 10" // 한글 구분자 (가, 나, 다) 사용 }) From 6e3c2d4d8e077c4e2fd8aafd2fe52afa5ec87e70 Mon Sep 17 00:00:00 2001 From: sihyunjojo Date: Mon, 21 Oct 2024 23:59:26 +0900 Subject: [PATCH 27/27] =?UTF-8?q?refactor:=20style=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/calculator/global/instance/Messages.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/java/calculator/global/instance/Messages.java b/src/main/java/calculator/global/instance/Messages.java index a487d097d5..698d57fec7 100644 --- a/src/main/java/calculator/global/instance/Messages.java +++ b/src/main/java/calculator/global/instance/Messages.java @@ -2,14 +2,13 @@ public class Messages { - public static final String DESCRIPTION = - """ - 문자열 덧셈 계산기입니다. - 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. - 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다. - 또한 커스텀 구분자를 여러 개 사용하고 싶으면 | 를 이용해서 구분해서 등록해주세요. - (단, | 는 커스텀 구분자로 사용이 불가능합니다.) - """; + public static final String DESCRIPTION = """ + 문자열 덧셈 계산기입니다. + 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. + 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다. + 또한 커스텀 구분자를 여러 개 사용하고 싶으면 | 를 이용해서 구분해서 등록해주세요. + (단, | 는 커스텀 구분자로 사용이 불가능합니다.) + """; public static final String INPUT_PROMPT = "덧셈할 문자열을 입력해 주세요."; public static final String RESULT = "결과 : ";