Skip to content

Commit 9163fca

Browse files
authored
고생하셨습니다.
🎉 PR 머지 완료! 🎉
1 parent 7807734 commit 9163fca

File tree

4 files changed

+107
-77
lines changed

4 files changed

+107
-77
lines changed

src/main/java/SimpleCalculator.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
public class SimpleCalculator {
2-
public int add(int firstNum, int secondNum){
3-
return firstNum + secondNum;
2+
public int add(int a, int b) {
3+
return Math.addExact(a, b);
44
}
5-
public int multiply(int firstNum, int secondNum){
6-
return firstNum * secondNum;
7-
}
8-
public int divide(int firstNum, int secondNum){
9-
return firstNum / secondNum;
5+
6+
public int minus(int a, int b) {
7+
return Math.subtractExact(a, b);
108
}
11-
public int minus(int firstNum, int secondNum){
12-
return firstNum - secondNum;
9+
10+
public int multiply(int a, int b) {
11+
return Math.multiplyExact(a, b);
1312
}
1413

14+
public int divide(int a, int b) {
15+
if (b == 0) {
16+
throw new ArithmeticException("0으로 나눌 수 없습니다.");
17+
}
18+
if (a == Integer.MIN_VALUE && b == -1) {
19+
throw new ArithmeticException("정수 범위를 벗어났습니다.");
20+
}
21+
return a / b;
22+
}
1523
}

src/main/java/StringCalculator.java

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,64 @@
1-
/*
2-
input을 받고 빈문자열인지 null인지 체크
3-
구분자 체크 -> 구분자 예외 체크
4-
구분자 대로 문자열 계산기 구현
5-
*/
6-
71
import java.util.regex.Pattern;
82

93
public class StringCalculator {
104

11-
//입력 문자열이 null인지 확인
12-
public String checkInput(String input){
13-
if(input == null) throw new RuntimeException("null은 허용되지 않습니다.");
14-
return input;
5+
private void validateInput(String input){
6+
if (input == null){
7+
throw new RuntimeException("null은 허용되지 않습니다.");
8+
}
159
}
1610

17-
//커스텀 구분자가 있는지 확인
18-
public int checkDelimiter(String checkedInput) {
19-
if(checkedInput.isEmpty()) return -2; //문자열이 빈 경우
20-
21-
22-
if (checkedInput.startsWith("//")) { //커스텀 구분자를 설정하는가?
23-
int idx = checkedInput.indexOf("\n"); //제대로된 형식인가?
24-
if (idx == -1) throw new RuntimeException("잘못된 커스텀 구분자 형식입니다.");
25-
return idx; //구분자 위치 전달
11+
private int getDelimiterIndex(String input) {
12+
if (input.startsWith("//")) {
13+
int delimiterIdx = input.indexOf("\n");
14+
if (delimiterIdx == -1){
15+
throw new RuntimeException("잘못된 커스텀 구분자 형식입니다.");
16+
}
17+
return delimiterIdx;
2618
}
27-
2819
return -1; //기본 구분자대로 문자열을 나눔
2920
}
3021

31-
private String[] splitInput(String checkedInput, int idx){
32-
if(idx == -1){
22+
private String[] splitInput(String checkedInput, int delimiterIdx){
23+
if (delimiterIdx == -1){
3324
String delimiter = "[,:]";
34-
return checkedInput.split(delimiter); //기본 구분자대로 나누기
35-
}
36-
else if(idx == -2){
37-
return new String[0]; //빈 문자열인 경우
25+
return checkedInput.split(delimiter);
3826
}
3927
else{
40-
String delimiter = checkedInput.substring(2, idx); //구분자 나누기
41-
String regex = Pattern.quote(delimiter); //정규표현식에 사용되는 문자가 커스텀 구분자일 경우를 위해 설정
42-
return checkedInput.substring(idx + 1).split(regex); //커스텀 구분자대로 문자열을 나눔
28+
String delimiter = checkedInput.substring(2, delimiterIdx);
29+
String regex = Pattern.quote(delimiter);
30+
return checkedInput.substring(delimiterIdx + 1).split(regex);
4331
}
4432
}
4533

46-
//문자열 덧셈 실행
47-
public int sum(String[] strings){
48-
if(strings.length == 0) return 0;
34+
private int sum(String[] strings){
35+
if (strings.length == 0){
36+
return 0;
37+
}
4938

5039
int sum = 0;
5140

5241
for(var n : strings){
53-
if(n.isEmpty()) throw new RuntimeException("빈 문자열입니다.");
42+
if (n.isEmpty()){
43+
throw new RuntimeException("빈 문자열입니다.");
44+
}
5445

55-
int num = checkException(n);
46+
int num = validateNumbers(n);
5647

57-
//예외 처리
58-
if(sum > Integer.MAX_VALUE - num || sum < Integer.MIN_VALUE + num) throw new RuntimeException("int 범위를 벗어났습니다.");
48+
if (sum > Integer.MAX_VALUE - num || sum < Integer.MIN_VALUE + num) throw new RuntimeException("int 범위를 벗어났습니다.");
5949

6050
sum += num;
6151
}
6252
return sum;
6353
}
6454

65-
private int checkException(String n){
55+
private int validateNumbers(String n){
6656
int num;
6757
try{
6858
num = Integer.parseInt(n);
69-
if(num < 0) throw new RuntimeException("음수는 입력이 불가합니다.");
59+
if (num < 0){
60+
throw new RuntimeException("음수는 입력이 불가합니다.");
61+
}
7062
}
7163
catch(NumberFormatException msg){
7264
throw new RuntimeException("int 값을 벗어났거나 잘못된 숫자 형식입니다.");
@@ -75,9 +67,12 @@ private int checkException(String n){
7567
}
7668

7769
public int calculate(String input){
78-
String checkedInput = checkInput(input);
79-
int idx = checkDelimiter(checkedInput);
80-
String[] strings = splitInput(checkedInput, idx);
70+
validateInput(input);
71+
if (input.isEmpty()){
72+
return 0;
73+
}
74+
int delimiterIndex = getDelimiterIndex(input);
75+
String[] strings = splitInput(input, delimiterIndex);
8176
return sum(strings);
8277
}
8378
}
Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,64 @@
11
import org.junit.jupiter.api.Nested;
22
import org.junit.jupiter.api.Test;
3+
4+
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
35
import static org.junit.jupiter.api.Assertions.assertEquals;
6+
import static org.assertj.core.api.Assertions.assertThat;
47

58
public class SimpleCalculatorTest {
9+
10+
private final SimpleCalculator calc = new SimpleCalculator();
11+
612
@Nested
7-
class SimpleTest {
13+
class TestWithJunit5 {
814

915
@Test
10-
void addTest(){
11-
SimpleCalculator calc = new SimpleCalculator();
16+
void addTest() {
1217
assertEquals(3, calc.add(1, 2));
1318
assertEquals(5, calc.add(3, 2));
1419
}
1520

1621
@Test
17-
void minusTest(){
18-
SimpleCalculator calc = new SimpleCalculator();
22+
void minusTest() {
1923
assertEquals(3, calc.minus(5, 2));
2024
assertEquals(-2, calc.minus(3, 5));
2125
}
2226

2327
@Test
24-
void multiply(){
25-
SimpleCalculator calc = new SimpleCalculator();
28+
void multiply() {
2629
assertEquals(10, calc.multiply(5, 2));
2730
assertEquals(15, calc.multiply(3, 5));
2831
}
2932

3033
@Test
31-
void divide(){
32-
SimpleCalculator calc = new SimpleCalculator();
34+
void divide() {
3335
assertEquals(5, calc.divide(10, 2));
3436
assertEquals(30, calc.divide(180, 6));
3537
}
3638
}
39+
40+
@Nested
41+
class TestWithAssertJ {
42+
43+
@Test
44+
void simpleCalcTest(){
45+
assertThat(calc.add(1, 2)).isEqualTo(3);
46+
assertThat(calc.minus(1,2)).isEqualTo(-1);
47+
assertThat(calc.divide(4, 2)).isEqualTo(2);
48+
assertThat(calc.multiply(3,2)).isEqualTo(6);
49+
}
50+
51+
@Test
52+
void errorTestDivideZero() {
53+
assertThatThrownBy(() -> calc.divide(2, 0)).isInstanceOf(ArithmeticException.class);
54+
}
55+
56+
@Test
57+
void errorTestOverFlow() {
58+
assertThatThrownBy(() -> calc.add(Integer.MAX_VALUE, 1)).isInstanceOf(ArithmeticException.class);
59+
assertThatThrownBy(() -> calc.minus(Integer.MAX_VALUE, -3)).isInstanceOf(ArithmeticException.class);
60+
assertThatThrownBy(() -> calc.multiply(Integer.MAX_VALUE, 3)).isInstanceOf(ArithmeticException.class);
61+
assertThatThrownBy(() -> calc.divide(Integer.MIN_VALUE, -1)).isInstanceOf(ArithmeticException.class);
62+
}
63+
}
3764
}
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
import org.junit.jupiter.api.Nested;
22
import org.junit.jupiter.api.Test;
33

4+
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
45
import static org.junit.jupiter.api.Assertions.assertEquals;
5-
import static org.junit.jupiter.api.Assertions.assertThrows;
66

77
public class StringCalculatorTest {
8+
9+
private final StringCalculator calc = new StringCalculator();
10+
811
@Nested
912
class StringTest{
13+
1014
@Test
11-
void default_delimiter_Test(){
12-
StringCalculator calc = new StringCalculator();
15+
void defaultDelimiterTest(){
1316
assertEquals(3, calc.calculate("1,2"));
1417
assertEquals(6, calc.calculate("1,2,3"));
1518
assertEquals(3, calc.calculate("1:2"));
1619
assertEquals(38, calc.calculate("1:2,3:4,5:6:7:10"));
17-
assertEquals(0, calc.calculate(""));
1820
}
1921

2022
@Test
21-
void custom_delimiter_Test(){
22-
StringCalculator calc = new StringCalculator();
23+
void customDelimiterTest(){
2324
assertEquals(6, calc.calculate("//;\n1;2;3"));
2425
assertEquals(5, calc.calculate("//;;\n1;;1;;2;;1"));
2526
assertEquals(6, calc.calculate("//.\n1.2.3"));
@@ -29,19 +30,18 @@ void custom_delimiter_Test(){
2930

3031
@Test
3132
void exceptionTest(){
32-
StringCalculator calc = new StringCalculator();
33-
34-
RuntimeException exception = assertThrows(RuntimeException.class, () ->
35-
calc.calculate("-1,2")
36-
);
37-
38-
assertEquals("음수는 입력이 불가합니다.", exception.getMessage());
39-
40-
RuntimeException exception2 = assertThrows(RuntimeException.class, () ->
41-
calc.calculate("2147483647,10")
42-
);
33+
assertThatThrownBy(() -> calc.calculate("-1,2")).isInstanceOf(RuntimeException.class).
34+
hasMessageContaining("음수는 입력이 불가합니다.");
35+
assertThatThrownBy(() -> calc.calculate("2147483647,10")).isInstanceOf(RuntimeException.class).
36+
hasMessageContaining("int 범위를 벗어났습니다.");
37+
assertThatThrownBy(() -> calc.calculate("hello")).isInstanceOf(RuntimeException.class).
38+
hasMessageContaining("int 값을 벗어났거나 잘못된 숫자 형식입니다.");
39+
}
4340

44-
assertEquals("int 범위를 벗어났습니다.", exception2.getMessage());
41+
@Test
42+
void blankTest(){
43+
assertEquals(0, calc.calculate(""));
44+
assertThatThrownBy(() -> calc.calculate(" ")).isInstanceOf(RuntimeException.class);
4545
}
4646
}
4747
}

0 commit comments

Comments
 (0)