Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/main/java/CalculatorException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public class CalculatorException {

// 음수 또는 0이 입력될 때 사용하는 예외 클래스
public static class InvalidInputException extends RuntimeException {
public InvalidInputException(int value) {
super("음수 또는 0은 입력할 수 없습니다. 입력된 값: " + value);
}
}
}
36 changes: 36 additions & 0 deletions src/main/java/InputParser.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
12 changes: 12 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -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());
}
}
}
40 changes: 40 additions & 0 deletions src/main/java/StringCalculator.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
22 changes: 22 additions & 0 deletions src/test/java/CalculatorExceptionTest.java
Original file line number Diff line number Diff line change
@@ -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());
}
}
38 changes: 38 additions & 0 deletions src/test/java/InputParserTest.java
Original file line number Diff line number Diff line change
@@ -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"));
}
}
31 changes: 31 additions & 0 deletions src/test/java/MainTest.java
Original file line number Diff line number Diff line change
@@ -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());
}
}
58 changes: 58 additions & 0 deletions src/test/java/StringCalculatorTest.java
Original file line number Diff line number Diff line change
@@ -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());
}
}