From ddd83b739845bd32bab68501b2182fac9093725b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8C=E1=85=A9=E1=84=89=E1=85=A6=E1=84=8B=E1=85=B3?= =?UTF-8?q?=E1=86=AB?= Date: Fri, 1 Nov 2024 21:47:51 +0900 Subject: [PATCH] =?UTF-8?q?Feat:=20=EB=AD=87=EC=9E=90=EC=97=B4=20=EB=8D=A7?= =?UTF-8?q?=EC=85=88=20=EA=B3=84=EC=82=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/CalculatorException.java | 9 ++++ src/main/java/InputParser.java | 36 ++++++++++++++ src/main/java/Main.java | 12 +++++ src/main/java/StringCalculator.java | 40 +++++++++++++++ src/test/java/CalculatorExceptionTest.java | 22 ++++++++ src/test/java/InputParserTest.java | 38 ++++++++++++++ src/test/java/MainTest.java | 31 ++++++++++++ src/test/java/StringCalculatorTest.java | 58 ++++++++++++++++++++++ 8 files changed, 246 insertions(+) create mode 100644 src/main/java/CalculatorException.java create mode 100644 src/main/java/InputParser.java create mode 100644 src/main/java/Main.java create mode 100644 src/main/java/StringCalculator.java create mode 100644 src/test/java/CalculatorExceptionTest.java create mode 100644 src/test/java/InputParserTest.java create mode 100644 src/test/java/MainTest.java create mode 100644 src/test/java/StringCalculatorTest.java diff --git a/src/main/java/CalculatorException.java b/src/main/java/CalculatorException.java new file mode 100644 index 0000000..b7fffb2 --- /dev/null +++ b/src/main/java/CalculatorException.java @@ -0,0 +1,9 @@ +public class CalculatorException { + + // 음수 또는 0이 입력될 때 사용하는 예외 클래스 + public static class InvalidInputException extends RuntimeException { + public InvalidInputException(int value) { + super("음수 또는 0은 입력할 수 없습니다. 입력된 값: " + value); + } + } +} diff --git a/src/main/java/InputParser.java b/src/main/java/InputParser.java new file mode 100644 index 0000000..1cde3c1 --- /dev/null +++ b/src/main/java/InputParser.java @@ -0,0 +1,36 @@ +import java.util.Arrays; + +public class InputParser { + + public String[] parseInput(String input) { + if (isEmpty(input)) { + return new String[]{"0"}; // 빈 문자열일 때 0 반환을 위해 기본값 설정 + } + + String numbersOnly = removeDelimiterPrefix(input); + String delimiter = getDelimiter(input); + return splitByDelimiter(numbersOnly, delimiter); + } + + private boolean isEmpty(String input) { + return input == null || input.isEmpty(); + } + + private String getDelimiter(String input) { + return input.startsWith("//") ? extractCustomDelimiter(input) : ",|:"; + } + + private String extractCustomDelimiter(String input) { + return input.substring(2, input.indexOf("\n")); + } + + private String removeDelimiterPrefix(String input) { + return input.startsWith("//") ? input.substring(input.indexOf("\n") + 1) : input; + } + + private String[] splitByDelimiter(String input, String delimiter) { + return Arrays.stream(input.split(delimiter)) + .filter(num -> !num.isBlank()) + .toArray(String[]::new); + } +} diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000..70f8c12 --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,12 @@ +public class Main { + public static void main(String[] args) { + StringCalculator calculator = new StringCalculator(); + + try { + int result = calculator.calculate("//;\n1;3;3"); + System.out.println("계산 결과: " + result); + } catch (CalculatorException.InvalidInputException e) { + System.out.println("예외 발생: " + e.getMessage()); + } + } +} diff --git a/src/main/java/StringCalculator.java b/src/main/java/StringCalculator.java new file mode 100644 index 0000000..e290dc0 --- /dev/null +++ b/src/main/java/StringCalculator.java @@ -0,0 +1,40 @@ +import java.util.Arrays; + +public class StringCalculator { + + public int calculate(String input) { + if (isEmpty(input)) { + return 0; + } + + String[] numbers = parseNumbers(input); + validateNonNegativeAndNonZero(numbers); // 메소드 이름을 수정하여 0도 포함하도록 명확히 함 + + return sum(numbers); + } + + private boolean isEmpty(String input) { + return input == null || input.isEmpty(); + } + + private String[] parseNumbers(String input) { + InputParser parser = new InputParser(); + return parser.parseInput(input); + } + + private void validateNonNegativeAndNonZero(String[] numbers) { + Arrays.stream(numbers) + .mapToInt(Integer::parseInt) + .filter(num -> num <= 0) // 0과 음수를 모두 예외로 처리 + .findFirst() + .ifPresent(num -> { + throw new CalculatorException.InvalidInputException(num); + }); + } + + private int sum(String[] numbers) { + return Arrays.stream(numbers) + .mapToInt(Integer::parseInt) + .sum(); + } +} diff --git a/src/test/java/CalculatorExceptionTest.java b/src/test/java/CalculatorExceptionTest.java new file mode 100644 index 0000000..65cf077 --- /dev/null +++ b/src/test/java/CalculatorExceptionTest.java @@ -0,0 +1,22 @@ +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class CalculatorExceptionTest { + + @Test + @DisplayName("음수 값 입력 시 InvalidInputException 예외 메시지 확인함") + public void testInvalidInputExceptionWithNegativeNumber() { + CalculatorException.InvalidInputException exception = + new CalculatorException.InvalidInputException(-3); + assertEquals("음수 또는 0은 입력할 수 없습니다. 입력된 값: -3", exception.getMessage()); + } + + @Test + @DisplayName("0 입력 시 InvalidInputException 예외 메시지 확인함") + public void testInvalidInputExceptionWithZero() { + CalculatorException.InvalidInputException exception = + new CalculatorException.InvalidInputException(0); + assertEquals("음수 또는 0은 입력할 수 없습니다. 입력된 값: 0", exception.getMessage()); + } +} diff --git a/src/test/java/InputParserTest.java b/src/test/java/InputParserTest.java new file mode 100644 index 0000000..b7d7c75 --- /dev/null +++ b/src/test/java/InputParserTest.java @@ -0,0 +1,38 @@ +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class InputParserTest { + + private final InputParser parser = new InputParser(); + + @Test + @DisplayName("빈 문자열 입력 시 '0'을 기본값으로 반환함") + public void testParseEmptyInput() { + assertArrayEquals(new String[]{"0"}, parser.parseInput("")); + } + + @Test + @DisplayName("숫자 하나만 입력했을 때 배열로 반환함") + public void testParseSingleNumber() { + assertArrayEquals(new String[]{"5"}, parser.parseInput("5")); + } + + @Test + @DisplayName("쉼표로 구분된 숫자를 배열로 변환함") + public void testParseCommaSeparatedNumbers() { + assertArrayEquals(new String[]{"1", "2", "3"}, parser.parseInput("1,2,3")); + } + + @Test + @DisplayName("콜론으로 구분된 숫자를 배열로 변환함") + public void testParseColonSeparatedNumbers() { + assertArrayEquals(new String[]{"4", "5", "6"}, parser.parseInput("4:5:6")); + } + + @Test + @DisplayName("커스텀 구분자가 있는 경우 해당 구분자로 숫자 분리함") + public void testParseCustomDelimiter() { + assertArrayEquals(new String[]{"1", "2", "3"}, parser.parseInput("//;\n1;2;3")); + } +} diff --git a/src/test/java/MainTest.java b/src/test/java/MainTest.java new file mode 100644 index 0000000..6a4b3e1 --- /dev/null +++ b/src/test/java/MainTest.java @@ -0,0 +1,31 @@ +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class MainTest { + + @Test + @DisplayName("정상 입력에 대해 예외 없이 결과 반환됨") + public void testMainCalculation() { + StringCalculator calculator = new StringCalculator(); + + try { + int result = calculator.calculate("//;\n1;2;3"); + assertEquals(6, result); + } catch (CalculatorException.InvalidInputException e) { + fail("예외가 발생하지 않아야 함"); + } + } + + @Test + @DisplayName("음수 입력 시 예외 발생 확인함") + public void testMainCalculationWithException() { + StringCalculator calculator = new StringCalculator(); + + CalculatorException.InvalidInputException exception = assertThrows( + CalculatorException.InvalidInputException.class, + () -> calculator.calculate("-1,2,3") + ); + assertEquals("음수 또는 0은 입력할 수 없습니다. 입력된 값: -1", exception.getMessage()); + } +} diff --git a/src/test/java/StringCalculatorTest.java b/src/test/java/StringCalculatorTest.java new file mode 100644 index 0000000..d77d41c --- /dev/null +++ b/src/test/java/StringCalculatorTest.java @@ -0,0 +1,58 @@ +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class StringCalculatorTest { + + private final StringCalculator calculator = new StringCalculator(); + + @Test + @DisplayName("빈 문자열 입력 시 0 반환함") + public void testCalculateEmptyInput() { + assertEquals(0, calculator.calculate("")); + } + + @Test + @DisplayName("숫자 하나만 입력 시 해당 숫자 반환함") + public void testCalculateSingleNumber() { + assertEquals(7, calculator.calculate("7")); + } + + @Test + @DisplayName("쉼표로 구분된 숫자들의 합 반환함") + public void testCalculateCommaSeparatedNumbers() { + assertEquals(6, calculator.calculate("1,2,3")); + } + + @Test + @DisplayName("콜론으로 구분된 숫자들의 합 반환함") + public void testCalculateColonSeparatedNumbers() { + assertEquals(15, calculator.calculate("5:5:5")); + } + + @Test + @DisplayName("커스텀 구분자로 구분된 숫자들의 합 반환함") + public void testCalculateCustomDelimiter() { + assertEquals(10, calculator.calculate("//;\n2;3;5")); + } + + @Test + @DisplayName("음수 포함 시 예외 발생 확인함") + public void testCalculateWithNegativeNumber() { + CalculatorException.InvalidInputException exception = assertThrows( + CalculatorException.InvalidInputException.class, + () -> calculator.calculate("-1,2,3") + ); + assertEquals("음수 또는 0은 입력할 수 없습니다. 입력된 값: -1", exception.getMessage()); + } + + @Test + @DisplayName("0 포함 시 예외 발생 확인함") + public void testCalculateWithZero() { + CalculatorException.InvalidInputException exception = assertThrows( + CalculatorException.InvalidInputException.class, + () -> calculator.calculate("0,1,2") + ); + assertEquals("음수 또는 0은 입력할 수 없습니다. 입력된 값: 0", exception.getMessage()); + } +}