From 27f97311f4c208a8994f772772d725c972fe88b4 Mon Sep 17 00:00:00 2001 From: JunhoLee <121706341+Lanvizu@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:07:54 +0900 Subject: [PATCH 01/19] docs: Update README.md --- README.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd90ef0247..40d7173046 100644 --- a/README.md +++ b/README.md @@ -1 +1,32 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse + +## 구현할 기능 목록 + +1. 초기 구분자 설정 + ``` + - Default Setting : (쉼표, 콜론)을 구분자로 설정 + ``` + +2. 사용자에게 문자열 입력 받음 + ``` + - 입력받은 input이 비어있는 경우 예외 처리 + - 입력받은 input이 "//"와 "\n" 으로 구분자를 설정하지 않은 경우 예외 처리 + - 입력받은 input이 숫자 이외에 다른 문자가 입력된 경우 예외 처리 + - 입력받은 input이 정해진 구분자 외의 문자로 구분되어 있는 경우 예외 처리 + ``` + +3. 커스텀 구분자의 유무 판단 + ``` + - 커스텀 구분자 있는 경우 + - 새로운 커스텀 구분자로 설정 + + - 커스텀 구분자 없는 경우 + - 기존 구분자로 유지 + ``` + +4. 문자열을 구분자로 구분 하여 덧셈 + +5. 계산된 결과를 아래의 양식으로 출력한다 + ``` + 결과 : n + ``` From 18cd8c9fbdf439be1d0eaf8814516ac5767c6cc4 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Fri, 18 Oct 2024 15:24:39 +0900 Subject: [PATCH 02/19] =?UTF-8?q?feat:=20=EA=B3=84=EC=82=B0,=20=EA=B5=AC?= =?UTF-8?q?=EB=B6=84=EC=9E=90=20=EA=B5=AC=EB=B3=84,=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=20=EB=B6=84=ED=95=A0=20=ED=95=98=EB=8A=94=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/domain/Calculator.java | 17 +++++++++++++++++ .../java/calculator/domain/DelimiterParser.java | 9 +++++++++ .../java/calculator/domain/StringSplitter.java | 7 +++++++ 3 files changed, 33 insertions(+) create mode 100644 src/main/java/calculator/domain/Calculator.java create mode 100644 src/main/java/calculator/domain/DelimiterParser.java create mode 100644 src/main/java/calculator/domain/StringSplitter.java diff --git a/src/main/java/calculator/domain/Calculator.java b/src/main/java/calculator/domain/Calculator.java new file mode 100644 index 0000000000..0a1d474a57 --- /dev/null +++ b/src/main/java/calculator/domain/Calculator.java @@ -0,0 +1,17 @@ +package calculator.domain; + +public class Calculator { + private final DelimiterParser delimiterParser; + private final StringSplitter stringSplitter; + + public Calculator(DelimiterParser delimiterParser, StringSplitter stringSplitter) { + this.delimiterParser = delimiterParser; + this.stringSplitter = stringSplitter; + } + +// public int calculate(String input) { +// String delimiter = delimiterParser.parse(input); +// String[] numbers = stringSplitter.split(input, delimiter); +// return sum(numbers); +// } +} diff --git a/src/main/java/calculator/domain/DelimiterParser.java b/src/main/java/calculator/domain/DelimiterParser.java new file mode 100644 index 0000000000..97babd51b3 --- /dev/null +++ b/src/main/java/calculator/domain/DelimiterParser.java @@ -0,0 +1,9 @@ +package calculator.domain; + +public class DelimiterParser { + private static final String DEFAULT_DELIMITER = ",|:"; + +// public String parse(String input) { +// // 커스텀 구분자 파싱 로직 구현 +// } +} diff --git a/src/main/java/calculator/domain/StringSplitter.java b/src/main/java/calculator/domain/StringSplitter.java new file mode 100644 index 0000000000..f2a361f19a --- /dev/null +++ b/src/main/java/calculator/domain/StringSplitter.java @@ -0,0 +1,7 @@ +package calculator.domain; + +public class StringSplitter { +// public String[] split(String input, String delimiter) { +// // 문자열 분할 로직 구현 +// } +} From 431dc61f2f1ea8dc0a5b9656dfa34cf3631e3ed5 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Fri, 18 Oct 2024 15:25:46 +0900 Subject: [PATCH 03/19] =?UTF-8?q?feat:=20view=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/view/InputView.java | 4 ++++ src/main/java/calculator/view/OutputView.java | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 src/main/java/calculator/view/InputView.java create mode 100644 src/main/java/calculator/view/OutputView.java diff --git a/src/main/java/calculator/view/InputView.java b/src/main/java/calculator/view/InputView.java new file mode 100644 index 0000000000..75f4ceb10d --- /dev/null +++ b/src/main/java/calculator/view/InputView.java @@ -0,0 +1,4 @@ +package calculator.view; + +public class InputView { +} diff --git a/src/main/java/calculator/view/OutputView.java b/src/main/java/calculator/view/OutputView.java new file mode 100644 index 0000000000..4a2a4b0b17 --- /dev/null +++ b/src/main/java/calculator/view/OutputView.java @@ -0,0 +1,4 @@ +package calculator.view; + +public class OutputView { +} From 898a130dd66a78505f0cd34080472f9fc81f5eee Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Mon, 21 Oct 2024 17:14:44 +0900 Subject: [PATCH 04/19] =?UTF-8?q?feat:=20Enum=20=ED=83=80=EC=9E=85=20Error?= =?UTF-8?q?Message=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/exception/ErrorMessage.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/calculator/global/exception/ErrorMessage.java diff --git a/src/main/java/calculator/global/exception/ErrorMessage.java b/src/main/java/calculator/global/exception/ErrorMessage.java new file mode 100644 index 0000000000..4de7a473dd --- /dev/null +++ b/src/main/java/calculator/global/exception/ErrorMessage.java @@ -0,0 +1,18 @@ +package calculator.global.exception; + +public enum ErrorMessage { + + INVALID_DELIMITER_START("The input must start with '//' for custom delimiter."), + EMPTY_CUSTOM_DELIMITER("Custom delimiter cannot be empty after '//'."); + + + private final String message; + + ErrorMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} From d5b952b5219223581d9539eed8bc11de044a7f3f Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Mon, 21 Oct 2024 17:15:29 +0900 Subject: [PATCH 05/19] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=20=EC=B6=9C=EB=A0=A5=EA=B3=BC=20IllegalArgum?= =?UTF-8?q?entException=20=EC=B2=98=EB=A6=AC=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 --- .../global/exception/CalculatorException.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/calculator/global/exception/CalculatorException.java diff --git a/src/main/java/calculator/global/exception/CalculatorException.java b/src/main/java/calculator/global/exception/CalculatorException.java new file mode 100644 index 0000000000..f9a6ab4ea2 --- /dev/null +++ b/src/main/java/calculator/global/exception/CalculatorException.java @@ -0,0 +1,11 @@ +package calculator.global.exception; + +public class CalculatorException extends IllegalArgumentException { + private CalculatorException(ErrorMessage errorMessage) { + super(errorMessage.getMessage()); + } + + public static CalculatorException of(ErrorMessage errorMessage) { + return new CalculatorException(errorMessage); + } +} From d2d196a3a1c59098a2f5718adac22511aa54dbc6 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Mon, 21 Oct 2024 17:17:09 +0900 Subject: [PATCH 06/19] =?UTF-8?q?feat:=20=EA=B5=AC=EB=B6=84=EC=9E=90=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=20=EA=B2=80=EC=82=AC=EC=99=80=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculator/domain/DelimiterParser.java | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/main/java/calculator/domain/DelimiterParser.java b/src/main/java/calculator/domain/DelimiterParser.java index 97babd51b3..247d556f12 100644 --- a/src/main/java/calculator/domain/DelimiterParser.java +++ b/src/main/java/calculator/domain/DelimiterParser.java @@ -1,9 +1,42 @@ package calculator.domain; +import static calculator.global.exception.ErrorMessage.EMPTY_CUSTOM_DELIMITER; +import static calculator.global.exception.ErrorMessage.INVALID_DELIMITER_START; + +import calculator.global.exception.CalculatorException; + public class DelimiterParser { - private static final String DEFAULT_DELIMITER = ",|:"; + private String delimiter; + + public DelimiterParser() { + this.delimiter = ",|:"; + } + + // 새로운 구분자 설정 + /*결과적으로 "//"로 시작하지 않는 경우 , "//"로 시작하더라도 구분자가 없는 경우*/ + public String parse(String input) { + validateCustomDelimiterInput(input); + String customDelimiter = extractCustomDelimiter(input); + this.delimiter = customDelimiter; + return customDelimiter; + } + + // 입력된 구분자 형식 검사 ("//"로 시작 + "//" 제외 문자가 있는지 확인) + private void validateCustomDelimiterInput(String input) { + if (!input.startsWith("//")) { + throw CalculatorException.of(INVALID_DELIMITER_START); + } + if (input.length() == 2) { + throw CalculatorException.of(EMPTY_CUSTOM_DELIMITER); + } + } + + // 입력에서 구분자 추출 + private String extractCustomDelimiter(String input) { + return input.substring(2); + } -// public String parse(String input) { -// // 커스텀 구분자 파싱 로직 구현 -// } + public String getDelimiter() { + return delimiter; + } } From 7d8afb4466174a763bd114e0c4e51049a6f97d4a Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Mon, 21 Oct 2024 17:17:39 +0900 Subject: [PATCH 07/19] =?UTF-8?q?test:=20DelimiterParser=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=9D=98=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=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 --- .../domain/DelimiterParserTest.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/test/java/calculator/domain/DelimiterParserTest.java diff --git a/src/test/java/calculator/domain/DelimiterParserTest.java b/src/test/java/calculator/domain/DelimiterParserTest.java new file mode 100644 index 0000000000..cc6779192f --- /dev/null +++ b/src/test/java/calculator/domain/DelimiterParserTest.java @@ -0,0 +1,58 @@ +package calculator.domain; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import calculator.global.exception.CalculatorException; +import calculator.global.exception.ErrorMessage; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class DelimiterParserTest { + + private DelimiterParser delimiterParser; + + @BeforeEach + void setUp() { + delimiterParser = new DelimiterParser(); + } + + @Test + @DisplayName("기본 구분자 테스트") + void testDefaultDelimiter() { + assertEquals(",|:", delimiterParser.getDelimiter()); + } + + @Test + @DisplayName("커스텀 구분자 파싱 테스트") + void testParseCustomDelimiter() { + String result = delimiterParser.parse("//;"); + assertEquals(";", result); + assertEquals(";", delimiterParser.getDelimiter()); + } + + @Test + @DisplayName("잘못된 커스텀 구분자 형식 테스트 - '//'로 시작하지 않음") + void testInvalidCustomDelimiterStart() { + CalculatorException exception = assertThrows(CalculatorException.class, + () -> delimiterParser.parse(";")); + assertEquals(ErrorMessage.INVALID_DELIMITER_START.getMessage(), exception.getMessage()); + } + + @Test + @DisplayName("잘못된 커스텀 구분자 형식 테스트 - 빈 구분자") + void testEmptyCustomDelimiter() { + CalculatorException exception = assertThrows(CalculatorException.class, + () -> delimiterParser.parse("//")); + assertEquals(ErrorMessage.EMPTY_CUSTOM_DELIMITER.getMessage(), exception.getMessage()); + } + + @Test + @DisplayName("복잡한 커스텀 구분자 테스트") + void testComplexCustomDelimiter() { + String result = delimiterParser.parse("//[***]"); + assertEquals("[***]", result); + assertEquals("[***]", delimiterParser.getDelimiter()); + } +} \ No newline at end of file From ed288ee05ae142b0b2a224da5a2d6e4ffec8d43f Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:29:20 +0900 Subject: [PATCH 08/19] =?UTF-8?q?feat:=20parse=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20void=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/domain/DelimiterParser.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/calculator/domain/DelimiterParser.java b/src/main/java/calculator/domain/DelimiterParser.java index 247d556f12..a1c6ed4050 100644 --- a/src/main/java/calculator/domain/DelimiterParser.java +++ b/src/main/java/calculator/domain/DelimiterParser.java @@ -14,11 +14,13 @@ public DelimiterParser() { // 새로운 구분자 설정 /*결과적으로 "//"로 시작하지 않는 경우 , "//"로 시작하더라도 구분자가 없는 경우*/ - public String parse(String input) { + /*빈 값이 들어올 경우 디폴트 구분자로 유지*/ + public void parse(String input) { + if (input == null || input.isEmpty()) { + return; // 빈 입력일 경우 기존 구분자 + } validateCustomDelimiterInput(input); - String customDelimiter = extractCustomDelimiter(input); - this.delimiter = customDelimiter; - return customDelimiter; + this.delimiter = extractCustomDelimiter(input); } // 입력된 구분자 형식 검사 ("//"로 시작 + "//" 제외 문자가 있는지 확인) From 5dde8c15b24bf3bfaf6e31a4890d58e52479f63d Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:29:37 +0900 Subject: [PATCH 09/19] =?UTF-8?q?test:=20parse=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20void=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/calculator/domain/DelimiterParserTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/calculator/domain/DelimiterParserTest.java b/src/test/java/calculator/domain/DelimiterParserTest.java index cc6779192f..eddf77672c 100644 --- a/src/test/java/calculator/domain/DelimiterParserTest.java +++ b/src/test/java/calculator/domain/DelimiterParserTest.java @@ -27,8 +27,7 @@ void testDefaultDelimiter() { @Test @DisplayName("커스텀 구분자 파싱 테스트") void testParseCustomDelimiter() { - String result = delimiterParser.parse("//;"); - assertEquals(";", result); + delimiterParser.parse("//;"); assertEquals(";", delimiterParser.getDelimiter()); } @@ -51,8 +50,7 @@ void testEmptyCustomDelimiter() { @Test @DisplayName("복잡한 커스텀 구분자 테스트") void testComplexCustomDelimiter() { - String result = delimiterParser.parse("//[***]"); - assertEquals("[***]", result); + delimiterParser.parse("//[***]"); assertEquals("[***]", delimiterParser.getDelimiter()); } } \ No newline at end of file From 943669a481bb08846639a1098757a4638479f0b4 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:30:32 +0900 Subject: [PATCH 10/19] =?UTF-8?q?feat:=20=EC=B4=88=EA=B8=B0=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=9D=84=20"\n"=EC=9D=84=20=EA=B8=B0=EC=A4=80?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=82=98=EB=88=84=EA=B8=B0=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 --- .../java/calculator/domain/InputParser.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/calculator/domain/InputParser.java diff --git a/src/main/java/calculator/domain/InputParser.java b/src/main/java/calculator/domain/InputParser.java new file mode 100644 index 0000000000..5283d98004 --- /dev/null +++ b/src/main/java/calculator/domain/InputParser.java @@ -0,0 +1,39 @@ +package calculator.domain; + +import static calculator.global.exception.ErrorMessage.EMPTY_INPUT; + +import calculator.global.exception.CalculatorException; + +public class InputParser { + private String delimiterString; + private String inputString; + + /*"\\n"을 기준으로 구분자 설정 입력과 문자열 입력을 나눠주는 메서드 + * 빈 값이 들어오는 경우 예외 처리 + * "\\n"이 포함되지 않는 경우 구분자 빈 값으로 저장*/ + public void parse(String input) { + validateInput(input); + String[] parts = input.split("\\\\n", 2); + if (parts.length == 2) { + delimiterString = parts[0]; + inputString = parts[1]; + } else { + delimiterString = ""; + inputString = input; + } + } + + private void validateInput(String input) { + if (input == null || input.isEmpty()) { + throw CalculatorException.of(EMPTY_INPUT); + } + } + + public String getDelimiterString() { + return delimiterString; + } + + public String getInputString() { + return inputString; + } +} From a75fc404fa0660c08aeba701b66c8d03d9bbec35 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:30:56 +0900 Subject: [PATCH 11/19] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=EA=B3=BC=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=94=B0?= =?UTF-8?q?=EB=A1=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/view/InputView.java | 8 ++++++++ src/main/java/calculator/view/OutputView.java | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/calculator/view/InputView.java b/src/main/java/calculator/view/InputView.java index 75f4ceb10d..280c840c65 100644 --- a/src/main/java/calculator/view/InputView.java +++ b/src/main/java/calculator/view/InputView.java @@ -1,4 +1,12 @@ package calculator.view; +import camp.nextstep.edu.missionutils.Console; + public class InputView { + private InputView() { + } + + public static String input() { + return Console.readLine(); + } } diff --git a/src/main/java/calculator/view/OutputView.java b/src/main/java/calculator/view/OutputView.java index 4a2a4b0b17..920172bb55 100644 --- a/src/main/java/calculator/view/OutputView.java +++ b/src/main/java/calculator/view/OutputView.java @@ -1,4 +1,16 @@ package calculator.view; +import calculator.view.constants.OutputType; + public class OutputView { + private OutputView() { + } + + public static void commonOutputLine(String output) { + System.out.println(output); + } + + public static void totalOutputLine(String output) { + System.out.println(OutputType.RESULT_TYPE.getMessage() + output); + } } From 0a7d9a6986bd7b5b39a291439343e0d933319059 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:32:36 +0900 Subject: [PATCH 12/19] =?UTF-8?q?feat:=20=EC=84=A4=EC=A0=95=EB=90=9C=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=EB=A1=9C=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=90=9C=20=EB=AC=B8=EC=9E=A5=20=EB=82=98=EB=88=84=EA=B8=B0=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 --- .../calculator/domain/StringSplitter.java | 75 ++++++++++++++++++- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/src/main/java/calculator/domain/StringSplitter.java b/src/main/java/calculator/domain/StringSplitter.java index f2a361f19a..e5d473bf05 100644 --- a/src/main/java/calculator/domain/StringSplitter.java +++ b/src/main/java/calculator/domain/StringSplitter.java @@ -1,7 +1,76 @@ package calculator.domain; +import static calculator.global.exception.ErrorMessage.EMPTY_NUMBER_INPUT; +import static calculator.global.exception.ErrorMessage.INVALID_DELIMITER_INPUT; +import static calculator.global.exception.ErrorMessage.INVALID_STRING_END; +import static calculator.global.exception.ErrorMessage.INVALID_STRING_START; + +import calculator.global.exception.CalculatorException; +import java.util.ArrayList; +import java.util.List; + public class StringSplitter { -// public String[] split(String input, String delimiter) { -// // 문자열 분할 로직 구현 -// } + + /*구분자는 에러 없이 들어온다고 가정 + * input 즉 /n 이후의 문자열에 대한 예외 처리 진행 + * 이후 문자열을 정해진 구분자로 나눠주는 과정 진행*/ + /*예외 처리 + * 숫자로 시작하지 않는 경우 + * 숫자로 끝나지 않는 경우 + * 정해진 구분자가 아닌 문자가 들어간 경우*/ + + public String[] split(String input, String delimiter) { + validateInput(input, delimiter); + return input.split(delimiter); + } + + // 빈 값, 숫자로 시작, 숫자로 끝나는 지 검증 + private void validateInput(String input, String delimiter) { + if (input == null || input.isEmpty()) { + throw CalculatorException.of(EMPTY_NUMBER_INPUT); + } + + List parts = splitIntoParts(input); + if (!isValidStart(parts)) { + throw CalculatorException.of(INVALID_STRING_START); + } + + if (!isValidEnd(parts)) { + throw CalculatorException.of(INVALID_STRING_END); + } + + if (!containsOnlyValidCharacters(parts, delimiter)) { + throw CalculatorException.of(INVALID_DELIMITER_INPUT); + } + } + + // 입력을 모든 문자로 쪼개는 메서드 + private List splitIntoParts(String input) { + List parts = new ArrayList<>(); + for (char c : input.toCharArray()) { + parts.add(String.valueOf(c)); + } + return parts; + } + + // 숫자로 시작하는지 체크 + private boolean isValidStart(List parts) { + return Character.isDigit(parts.getFirst().charAt(0)); + } + + // 숫자로 끝나는지 체크 + private boolean isValidEnd(List parts) { + return Character.isDigit(parts.getLast().charAt(0)); + } + + // 유효한 구분자만 포함되는지 체크 + private boolean containsOnlyValidCharacters(List parts, String delimiter) { + for (String part : parts) { + char ch = part.charAt(0); + if (!Character.isDigit(ch) && !delimiter.contains(part)) { + return false; + } + } + return true; + } } From 5f6de44a2761167d6d97d4ca70c143fb6d9a77f0 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:32:51 +0900 Subject: [PATCH 13/19] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=20=EC=B6=94=EA=B0=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/calculator/global/exception/ErrorMessage.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/calculator/global/exception/ErrorMessage.java b/src/main/java/calculator/global/exception/ErrorMessage.java index 4de7a473dd..019bc0334a 100644 --- a/src/main/java/calculator/global/exception/ErrorMessage.java +++ b/src/main/java/calculator/global/exception/ErrorMessage.java @@ -2,9 +2,14 @@ public enum ErrorMessage { + EMPTY_INPUT("The input is empty."), INVALID_DELIMITER_START("The input must start with '//' for custom delimiter."), - EMPTY_CUSTOM_DELIMITER("Custom delimiter cannot be empty after '//'."); - + EMPTY_CUSTOM_DELIMITER("Custom delimiter cannot be empty after '//'."), + EMPTY_NUMBER_INPUT("The number cannot be empty."), + INVALID_STRING_START("The input must start with number"), + INVALID_STRING_END("The input must end with number"), + INVALID_DELIMITER_INPUT("The String currently has an incorrect delimiter."), + EMPTY_NUMBERS_INPUT("The numbers cannot be empty."); private final String message; From 8ccdfe439705fcabe72759004c60d37a98b36294 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:33:00 +0900 Subject: [PATCH 14/19] =?UTF-8?q?feat:=20=EC=B6=9C=EB=A0=A5=20=ED=98=95?= =?UTF-8?q?=ED=83=9C=20=EB=A9=94=EC=84=B8=EC=A7=80=EB=A1=9C=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 --- .../calculator/view/constants/OutputType.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/calculator/view/constants/OutputType.java diff --git a/src/main/java/calculator/view/constants/OutputType.java b/src/main/java/calculator/view/constants/OutputType.java new file mode 100644 index 0000000000..69946efbdc --- /dev/null +++ b/src/main/java/calculator/view/constants/OutputType.java @@ -0,0 +1,15 @@ +package calculator.view.constants; + +public enum OutputType { + RESULT_TYPE("결과 : "); + + private final String message; + + OutputType(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} From bc7e72698b1cd41550026922a71e153f8cf6f44a Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:33:23 +0900 Subject: [PATCH 15/19] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=EB=B0=9B?= =?UTF-8?q?=EC=95=84=20=EA=B3=84=EC=82=B0=ED=95=98=EB=8A=94=20Controller?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CalculatorController.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/calculator/domain/controller/CalculatorController.java diff --git a/src/main/java/calculator/domain/controller/CalculatorController.java b/src/main/java/calculator/domain/controller/CalculatorController.java new file mode 100644 index 0000000000..0e8de309ba --- /dev/null +++ b/src/main/java/calculator/domain/controller/CalculatorController.java @@ -0,0 +1,43 @@ +package calculator.domain.controller; + +import calculator.domain.DelimiterParser; +import calculator.domain.InputParser; +import calculator.domain.StringSplitter; +import calculator.domain.SumCalculator; +import calculator.view.OutputView; + + +public class CalculatorController { + + private final InputParser inputParser; + private final DelimiterParser delimiterParser; + private final StringSplitter stringSplitter; + private final SumCalculator sumCalculator; + + public CalculatorController(InputParser inputParser, DelimiterParser delimiterParser, + StringSplitter stringSplitter, SumCalculator sumCalculator) { + this.inputParser = inputParser; + this.delimiterParser = delimiterParser; + this.stringSplitter = stringSplitter; + this.sumCalculator = sumCalculator; + } + + public int processInput(String input) { + + inputParser.parse(input); + String delimiterString = inputParser.getDelimiterString(); + String inputString = inputParser.getInputString(); + + delimiterParser.parse(delimiterString); + String delimiter = delimiterParser.getDelimiter(); + + String[] numbers = stringSplitter.split(inputString, delimiter); + + return sumCalculator.calculateSum(numbers); + } + + public void run(String input) { + int totalSum = processInput(input); + OutputView.totalOutputLine(String.valueOf(totalSum)); + } +} From 3ad961f5e8b460a855526b05fc0727f80c729762 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:33:49 +0900 Subject: [PATCH 16/19] =?UTF-8?q?feat:=20=EB=82=98=EB=88=A0=EC=A7=84=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=9E=85=EB=A0=A5=EB=B0=9B?= =?UTF-8?q?=EC=95=84=20=EB=8D=94=ED=95=98=EB=8A=94=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 --- .../java/calculator/domain/SumCalculator.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/calculator/domain/SumCalculator.java diff --git a/src/main/java/calculator/domain/SumCalculator.java b/src/main/java/calculator/domain/SumCalculator.java new file mode 100644 index 0000000000..a7cc671ca2 --- /dev/null +++ b/src/main/java/calculator/domain/SumCalculator.java @@ -0,0 +1,24 @@ +package calculator.domain; + +import static calculator.global.exception.ErrorMessage.EMPTY_NUMBERS_INPUT; + +import calculator.global.exception.CalculatorException; + +public class SumCalculator { + public int calculateSum(String[] numbers) { + int sum = 0; + for (String number : numbers) { + validateNumbers(number); + sum += Integer.parseInt(number); + } + return sum; + } + + // 빈 값 처리 + private void validateNumbers(String number) { + if (number == null || number.isEmpty()) { + throw CalculatorException.of(EMPTY_NUMBERS_INPUT); + } + } + +} From cdbc291451be9130172a7817a4bbd89798e8231b Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:34:15 +0900 Subject: [PATCH 17/19] =?UTF-8?q?test:=20InputParser,=20StringSplitter=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=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 --- .../calculator/domain/InputParserTest.java | 71 ++++++++++++ .../calculator/domain/StringSplitterTest.java | 107 ++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 src/test/java/calculator/domain/InputParserTest.java create mode 100644 src/test/java/calculator/domain/StringSplitterTest.java diff --git a/src/test/java/calculator/domain/InputParserTest.java b/src/test/java/calculator/domain/InputParserTest.java new file mode 100644 index 0000000000..6de28195eb --- /dev/null +++ b/src/test/java/calculator/domain/InputParserTest.java @@ -0,0 +1,71 @@ +package calculator.domain; + +import static calculator.global.exception.ErrorMessage.EMPTY_INPUT; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import calculator.global.exception.CalculatorException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class InputParserTest { + + private InputParser inputParser; + + @BeforeEach + void setUp() { + inputParser = new InputParser(); + } + + @Test + @DisplayName("유효한 입력 테스트") + void testValidInput() { + inputParser.parse("//,\\n1,2,3"); + + assertEquals("//,", inputParser.getDelimiterString()); + assertEquals("1,2,3", inputParser.getInputString()); + } + + @Test + @DisplayName("유효한 입력 테스트") + void testValidInputOne() { + inputParser.parse("//;\\n1"); + + assertEquals("//;", inputParser.getDelimiterString()); + assertEquals("1", inputParser.getInputString()); + } + + @Test + @DisplayName("유효한 입력 테스트 - 구분자 빈 값") + void testValidInputNoDelimiter() { + inputParser.parse("1,2,3"); + + assertEquals("", inputParser.getDelimiterString()); + assertEquals("1,2,3", inputParser.getInputString()); + } + + @Test + @DisplayName("잘못된 입력 테스트 - 빈 입력") + public void testInvalidNoInputString() { + String input = ""; + + CalculatorException exception = assertThrows(CalculatorException.class, () -> { + inputParser.parse(input); + }); + + assertEquals(EMPTY_INPUT.getMessage(), exception.getMessage()); + } + + @Test + @DisplayName("잘못된 입력 테스트 - NULL 입력") + public void testInvalidNullInputString() { + String input = null; + + CalculatorException exception = assertThrows(CalculatorException.class, () -> { + inputParser.parse(input); + }); + + assertEquals(EMPTY_INPUT.getMessage(), exception.getMessage()); + } +} \ No newline at end of file diff --git a/src/test/java/calculator/domain/StringSplitterTest.java b/src/test/java/calculator/domain/StringSplitterTest.java new file mode 100644 index 0000000000..f9bf785ce7 --- /dev/null +++ b/src/test/java/calculator/domain/StringSplitterTest.java @@ -0,0 +1,107 @@ +package calculator.domain; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import calculator.global.exception.CalculatorException; +import calculator.global.exception.ErrorMessage; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class StringSplitterTest { + private StringSplitter stringSplitter; + + @BeforeEach + void setUp() { + stringSplitter = new StringSplitter(); + } + + @Test + @DisplayName("유효한 구분자와 문자 입력 테스트") + void testValidInput() { + String input = "1x2x3"; + String delimiter = "x"; + String[] expected = {"1", "2", "3"}; + assertArrayEquals(expected, stringSplitter.split(input, delimiter)); + } + + @Test + @DisplayName("유효한 구분자와 한 문자 테스트") + void testValidInputOne() { + String input = "1"; + String delimiter = "x"; + String[] expected = {"1"}; + assertArrayEquals(expected, stringSplitter.split(input, delimiter)); + } + + @Test + @DisplayName("잘못된 문자 입력 - 숫자로 시작하지 않는 경우") + void testInvalidStart() { + String input = "x1x2x3"; + String delimiter = "x"; + CalculatorException exception = assertThrows(CalculatorException.class, + () -> stringSplitter.split(input, delimiter)); + assertEquals(ErrorMessage.INVALID_STRING_START.getMessage(), exception.getMessage()); + } + + @Test + @DisplayName("잘못된 문자 입력 - 양수로 시작하지 않는 경우") + void testInvalidStartA() { + String input = "-1x2x3"; + String delimiter = "x"; + CalculatorException exception = assertThrows(CalculatorException.class, + () -> stringSplitter.split(input, delimiter)); + assertEquals(ErrorMessage.INVALID_STRING_START.getMessage(), exception.getMessage()); + } + + @Test + void 예외_테스트() { + String input = "-1x2x3"; + String delimiter = "x"; + assertThatThrownBy(() -> stringSplitter.split(input, delimiter)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("잘못된 문자 입력 - 숫자로 끝나지 않는 경우") + void testInvalidEnd() { + String input = "1x2x3x"; + String delimiter = "x"; + CalculatorException exception = assertThrows(CalculatorException.class, + () -> stringSplitter.split(input, delimiter)); + assertEquals(ErrorMessage.INVALID_STRING_END.getMessage(), exception.getMessage()); + } + + @Test + @DisplayName("잘못된 문자 입력 - 설정하지 않은 구분자 포함") + void testInvalidCharacters() { + String input = "1a2x3"; + String delimiter = "x"; + CalculatorException exception = assertThrows(CalculatorException.class, + () -> stringSplitter.split(input, delimiter)); + assertEquals(ErrorMessage.INVALID_DELIMITER_INPUT.getMessage(), exception.getMessage()); + } + + @Test + @DisplayName("잘못된 문자 입력 - 빈 문자열") + void testEmptyInput() { + String input = ""; + String delimiter = "x"; + CalculatorException exception = assertThrows(CalculatorException.class, + () -> stringSplitter.split(input, delimiter)); + assertEquals(ErrorMessage.EMPTY_NUMBER_INPUT.getMessage(), exception.getMessage()); + } + + @Test + @DisplayName("잘못된 문자 입력 - NULL 입력") + void testNullInput() { + String input = null; + String delimiter = "x"; + CalculatorException exception = assertThrows(CalculatorException.class, + () -> stringSplitter.split(input, delimiter)); + assertEquals(ErrorMessage.EMPTY_NUMBER_INPUT.getMessage(), exception.getMessage()); + } +} \ No newline at end of file From a9a5a5e78d7e75179b1c2d9de2aa11a9b3382de1 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:35:15 +0900 Subject: [PATCH 18/19] =?UTF-8?q?remove:=20=EA=B8=B0=EC=A1=B4=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/domain/Calculator.java | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 src/main/java/calculator/domain/Calculator.java diff --git a/src/main/java/calculator/domain/Calculator.java b/src/main/java/calculator/domain/Calculator.java deleted file mode 100644 index 0a1d474a57..0000000000 --- a/src/main/java/calculator/domain/Calculator.java +++ /dev/null @@ -1,17 +0,0 @@ -package calculator.domain; - -public class Calculator { - private final DelimiterParser delimiterParser; - private final StringSplitter stringSplitter; - - public Calculator(DelimiterParser delimiterParser, StringSplitter stringSplitter) { - this.delimiterParser = delimiterParser; - this.stringSplitter = stringSplitter; - } - -// public int calculate(String input) { -// String delimiter = delimiterParser.parse(input); -// String[] numbers = stringSplitter.split(input, delimiter); -// return sum(numbers); -// } -} From c7922165582aba998a69dabbfaf48504d044ba95 Mon Sep 17 00:00:00 2001 From: Lanvizu Date: Tue, 22 Oct 2024 11:35:35 +0900 Subject: [PATCH 19/19] =?UTF-8?q?feat:=20main=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=A0=95=EB=A6=AC=20=EB=B0=8F=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580fb40..91c1609ce6 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,7 +1,22 @@ package calculator; +import calculator.domain.DelimiterParser; +import calculator.domain.InputParser; +import calculator.domain.StringSplitter; +import calculator.domain.SumCalculator; +import calculator.domain.controller.CalculatorController; +import calculator.view.InputView; + public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + InputParser inputParser = new InputParser(); + DelimiterParser delimiterParser = new DelimiterParser(); + StringSplitter stringSplitter = new StringSplitter(); + SumCalculator sumCalculator = new SumCalculator(); + CalculatorController calculatorController = new CalculatorController(inputParser, delimiterParser, + stringSplitter, sumCalculator); + String input = InputView.input(); + calculatorController.run(input); } }