Skip to content

[BCSD Lab] 박태진, 1차시 미션 제출합니다. #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Aug 3, 2025
Merged
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
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ repositories {
dependencies {
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation('org.assertj:assertj-core:3.24.2')
}

test {
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/Calc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
public class Calc {
public int add(int a, int b) {
int res = a + b;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래처럼 한번에 리턴하지 않고 변수에 저장해서 리턴하는 이유가 있을까요?

return a + b;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

결과 값을 res 변수에 저장하는 것이 습관이 되어서 해당 형식으로 작성했습니다!

return res;
}

public int minus(int a, int b) {
int res = a - b;
return res;
}

public int times(int a, int b) {
int res = a * b;
return res;
}

public int divide(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("0 으로 나눌 수 없습니다.");
}
int res = a / b;
return res;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파일 끝에 개행 문자가 없어서 EOF 문제가 발생하고있습니다.
EOF에 대해 찾아 보시면 좋을것같습니다.

78 changes: 78 additions & 0 deletions src/main/java/StringCalc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringCalc {

private static final String DEFAULT_DELIMITERS = "[,:]";

public int add(String text) {
if (isNullOrEmpty(text)) {
return 0;
}

DelimiterInfo delimiterInfo = parseDelimiterInfo(text);
String[] numbersAsString = splitByDelimiter(delimiterInfo.textToParse, delimiterInfo.delimiter);

return calculateSum(numbersAsString);
}

private boolean isNullOrEmpty(String text) {
return text == null || text.isEmpty();
}

private DelimiterInfo parseDelimiterInfo(String text) {
Pattern customDelimiterPattern = Pattern.compile("//(.)\n(.*)");
Matcher matcher = customDelimiterPattern.matcher(text);
Comment on lines +24 to +25
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자바에서 제공하는 정규표현식 패키지를 사용하셨네요 👍


if (matcher.find()) {
String customDelimiter = Pattern.quote(matcher.group(1));
String actualTextToParse = matcher.group(2);
// 커스텀 구분자와 기본 구분자를 모두 포함
String combinedDelimiters = DEFAULT_DELIMITERS + "|" + customDelimiter;
return new DelimiterInfo(combinedDelimiters, actualTextToParse);
}

return new DelimiterInfo(DEFAULT_DELIMITERS, text);
}

private String[] splitByDelimiter(String text, String delimiter) {
return text.split(delimiter);
}

private int calculateSum(String[] numbersAsString) {
int sum = 0;
for (String numStr : numbersAsString) {
if (numStr.isEmpty()) {
continue;
}
sum += parseAndValidateNumber(numStr);
}
return sum;
}

private int parseAndValidateNumber(String numStr) {
try {
int number = Integer.parseInt(numStr);
validateNumber(number);
return number;
} catch (NumberFormatException e) {
throw new RuntimeException("숫자 이외의 값이 포함되어 있습니다.");
}
}

private void validateNumber(int number) {
if (number < 0) {
throw new RuntimeException("음수는 입력할 수 없습니다.");
}
}

private static class DelimiterInfo {
final String delimiter;
final String textToParse;

DelimiterInfo(String delimiter, String textToParse) {
this.delimiter = delimiter;
this.textToParse = textToParse;
}
}
}
60 changes: 60 additions & 0 deletions src/test/java/CalcTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;

@DisplayName("계산기 작동 테스트")
public class CalcTest {
private final Calc calc = new Calc();

@Test
@DisplayName("더하기 테스트")
void add() {
final var a = 1;
final var b = 2;
final var actual = calc.add(a, b);

assertThat(actual).isEqualTo(3);
}

@Test
@DisplayName("빼기 테스트")
void minus() {
final var a = 3;
final var b = 1;
final var actual = calc.minus(a, b);

assertThat(actual).isEqualTo(2);
}

@Test
@DisplayName("곱하기 테스트")
void times() {
final var a = 2;
final var b = 3;
final var actual = calc.times(a, b);

assertThat(actual).isEqualTo(6);
}

@Test
@DisplayName("나누기 테스트")
void divide() {
final var a = 10;
final var b = 5;
final var actual = calc.divide(a, b);

assertThat(actual).isEqualTo(2);
}

@Test
@DisplayName("0으로 나누기 예외 테스트")
void divideByZeroThrowsException() {
final var a = 10;
final var b = 0;

assertThatThrownBy(() -> calc.divide(a, b))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("0 으로 나눌 수 없습니다.");
}
}
92 changes: 92 additions & 0 deletions src/test/java/StringCalcTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;

@DisplayName("문자열 계산기 테스트")
class StringCalcTest {
private final StringCalc stringCalc = new StringCalc();

@Test
@DisplayName("쉼표 구분자 문자열 계산 테스트")
void addWithComma() {
final var input = "1,2,3";
final var actual = stringCalc.add(input);

assertThat(actual).isEqualTo(6);
}

@Test
@DisplayName("콜론 구분자 문자열 계산 테스트")
void addWithColon() {
final var input = "1:2:3";
final var actual = stringCalc.add(input);

assertThat(actual).isEqualTo(6);
}

@Test
@DisplayName("쉼표와 콜론 혼합 구분자 테스트")
void addWithMixedDelimiters() {
final var input = "1,2:3";
final var actual = stringCalc.add(input);

assertThat(actual).isEqualTo(6);
}

@Test
@DisplayName("빈 문자열 테스트")
void addEmptyString() {
final var input = "";
final var actual = stringCalc.add(input);

assertThat(actual).isEqualTo(0);
}

@Test
@DisplayName("null 입력 테스트")
void addNullInput() {
final String input = null;
final var actual = stringCalc.add(input);

assertThat(actual).isEqualTo(0);
}

@Test
@DisplayName("커스텀 구분자 테스트")
void addWithCustomDelimiter() {
final var input = "//;\n1;2;3";
final var actual = stringCalc.add(input);

assertThat(actual).isEqualTo(6);
}

@Test
@DisplayName("음수 입력 예외 테스트")
void addNegativeNumberThrowsException() {
final var input = "1,-2,3";

assertThatThrownBy(() -> stringCalc.add(input))
.isInstanceOf(RuntimeException.class)
.hasMessage("음수는 입력할 수 없습니다.");
}

@Test
@DisplayName("숫자가 아닌 값 입력 예외 테스트")
void addNonNumericValueThrowsException() {
final var input = "1,a,3";

assertThatThrownBy(() -> stringCalc.add(input))
.isInstanceOf(RuntimeException.class)
.hasMessage("숫자 이외의 값이 포함되어 있습니다.");
}

@Test
@DisplayName("커스텀 구분자와 기본 구분자 혼합 테스트")
void addWithCustomAndDefaultDelimiters() {
final var input = "//@\n1@2,3:4";
final var actual = stringCalc.add(input);

assertThat(actual).isEqualTo(10);
}
}