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
16 changes: 16 additions & 0 deletions README-HS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## 구현해야할 기능

**1. 입력값 검증**
- 빈값 입력 ("" 또는 null) : 0 반환

**2. 쉼표(,) 또는 콜론(:) 구분자 기준으로 문자열 분리**
- 숫자 하나 입력 : 해당 숫자 반환
- 숫자 이외의 값 : RuntimeException throw
- 음수 : RuntimeException throw

**3. // 와 \\n 위치한 문자 구분자로 사용해 문자열 분리**
- 예를 들면 //;\n1;2;3

**4. 덧셈 계산**

**5. 계산 결과**
27 changes: 27 additions & 0 deletions src/main/java/calculator/AddCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package calculator;

import calculator.utils.ValidationUtils;

import java.util.Arrays;

public class AddCalculator {
private final String[] numbers;

public AddCalculator(String[] numbers) {
this.numbers = numbers;
}

public int add() {
return Arrays.stream(numbers)
.mapToInt(this::validateAndConvert)
.sum();
}

public int validateAndConvert(String number){
int num = ValidationUtils.stringToInt(number);
ValidationUtils.isPositiveNumber(num);

return num;
}

}
22 changes: 22 additions & 0 deletions src/main/java/calculator/StringAddCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package calculator;

import calculator.utils.ValidationUtils;

public class StringAddCalculator {
public static int splitAndSum(String input) {
if (ValidationUtils.isEmptyOrNull(input)) return 0;

String[] numbers = inputSplit(input);

if (ValidationUtils.isSingleNumber(numbers)) {
return ValidationUtils.stringToInt(numbers[0]);
}

return new AddCalculator(numbers).add();
}

public static String[] inputSplit(String input){
return new StringSplitter(input).split();
}

}
43 changes: 43 additions & 0 deletions src/main/java/calculator/StringSplitter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package calculator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringSplitter {
private final String input;
private Matcher m;

public StringSplitter(String input) {
this.input = input;
}

public String[] split() {
if (isContainsCustomDelimiter()) {
return splitCustomDelimiter();
}
if (isContainsDelimiter()) {
return splitDelimiter();
}

return new String[]{input};
}

public boolean isContainsCustomDelimiter(){
m = Pattern.compile("//(.)\n(.*)").matcher(input);
return m.find();
}

public String[] splitCustomDelimiter() {
String customDelimiter = m.group(1);
return m.group(2).split(customDelimiter);
}

public String[] splitDelimiter() {
return input.split("[,:]");
}

public boolean isContainsDelimiter() {
return (input.contains(",") || input.contains(":"));
}

}
6 changes: 6 additions & 0 deletions src/main/java/calculator/message/ErrorMessages.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package calculator.message;

public class ErrorMessages {
public static final String INVALID_INPUT = "구분자, 숫자 이외의 값은 입력 불가합니다.";
public static final String INVALID_NEGATIVE_NUMBER_INPUT = "음수는 입력 불가합니다.";
}
31 changes: 31 additions & 0 deletions src/main/java/calculator/utils/ValidationUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package calculator.utils;

import calculator.message.ErrorMessages;

public class ValidationUtils {
private static final int NEGATIVE_LIMIT = 0;
private static final int SINGLE_NUMBER_LENGTH = 1;

public static boolean isEmptyOrNull(String input) {
return input == null || input.isEmpty();
}

public static int stringToInt(String input) {
try {
return Integer.parseInt(input);
} catch (RuntimeException ex){
throw new RuntimeException(ErrorMessages.INVALID_INPUT);
}
}

public static void isPositiveNumber(int number){
if (number < NEGATIVE_LIMIT){
throw new RuntimeException(ErrorMessages.INVALID_NEGATIVE_NUMBER_INPUT);
}
}

public static boolean isSingleNumber(String[] numbers){
return numbers.length == SINGLE_NUMBER_LENGTH;
}

}
104 changes: 104 additions & 0 deletions src/test/java/calculator/AddCalculatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package calculator;

import calculator.message.ErrorMessages;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.in;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class AddCalculatorTest {

@Test
@DisplayName("덧셈 계산")
void add(){
// given, when
AddCalculator addCalculator = new AddCalculator(new String[]{"1", "2", "3"});

// when
int response = addCalculator.add();

// then
assertThat(response).isEqualTo(6);
}

@Test
@DisplayName("덧셈 계산 시 숫자 하나 입력한 경우")
void add_singleNumber(){
// given
AddCalculator addCalculator = new AddCalculator(new String[]{"1"});

// when
int response = addCalculator.add();

// then
assertThat(response).isEqualTo(1);
}

@Test
@DisplayName("덧셈 계산 시 음수가 포함된 경우")
void add_inputNegativeNumber(){
// given
AddCalculator addCalculator = new AddCalculator(new String[]{"1", "-2", "3"});

// when
RuntimeException fail = assertThrows(RuntimeException.class, addCalculator::add);

// then
assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_NEGATIVE_NUMBER_INPUT);
}

@Test
@DisplayName("덧셈 계산 시 숫자 이외의 값이 입력된 경우")
void add_inputInvalidDelimiter(){
// given
AddCalculator addCalculator = new AddCalculator(new String[]{"1", "문", "3"});

// when
RuntimeException fail = assertThrows(RuntimeException.class, addCalculator::add);

// then
assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_INPUT);
}

@Test
@DisplayName("문자열 검증 및 숫자로 변환")
void validateAndConvert(){
// given
AddCalculator addCalculator = new AddCalculator(new String[]{});

// when
int response = addCalculator.validateAndConvert("122222");

// then
assertThat(response).isEqualTo(122222);
}

@Test
@DisplayName("문자열 검증 및 숫자로 변환 시 숫자 이외의 문자열 포함되어 예외 발생")
void validateAndConvert_inputNotNumber(){
// given
AddCalculator addCalculator = new AddCalculator(new String[]{});

// when
RuntimeException fail = assertThrows(RuntimeException.class, () -> addCalculator.validateAndConvert("1&2"));

// then
assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_INPUT);
}

@Test
@DisplayName("문자열 검증 및 숫자로 변환 시 음수 입력으로 예외 발생")
void validateAndConvert_inputNegativeNumber(){
// given
AddCalculator addCalculator = new AddCalculator(new String[]{});

// when
RuntimeException fail = assertThrows(RuntimeException.class, () -> addCalculator.validateAndConvert("-20"));

// then
assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_NEGATIVE_NUMBER_INPUT);
}

}
111 changes: 111 additions & 0 deletions src/test/java/calculator/StringAddCalculatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package calculator;

import calculator.message.ErrorMessages;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class StringAddCalculatorTest {

@Test
@DisplayName("뮨자열 덧셈 계산기 빈값 입력")
void splitAndSum_inputEmpty(){
// given, when
int response = StringAddCalculator.splitAndSum("");

// then
assertThat(response).isEqualTo(0);
}

@Test
@DisplayName("뮨자열 덧셈 계산기 빈값 입력")
void splitAndSum_inputNull(){
// given, when
int response = StringAddCalculator.splitAndSum(null);

// then
assertThat(response).isEqualTo(0);
}

@Test
@DisplayName("문자열 덧셈 계산기 콤마 입력")
void splitAndSum_comma(){
// given, when
int response = StringAddCalculator.splitAndSum("1,2");

// then
assertThat(response).isEqualTo(3);
}

@Test
@DisplayName("문자열 덧셈 계산기 콜론 입력")
void splitAndSum_colon(){
// given, when
int response = StringAddCalculator.splitAndSum("1:2");

// then
assertThat(response).isEqualTo(3);
}

@Test
@DisplayName("문자열 덧셈 계산기 사용자 지정 구분자 입력")
void splitAndSum_customDelimiter(){
// given, when
int response = StringAddCalculator.splitAndSum("//;\n1;2;3");

// then
assertThat(response).isEqualTo(6);
}

@Test
@DisplayName("문자열 덧셈 계산 숫자 하나 입력한 경우")
void splitAndSum_singleNumber(){
// given, when
int response = StringAddCalculator.splitAndSum("13");

// then
assertThat(response).isEqualTo(13);
}

@Test
@DisplayName("문자열 덧셈 계산기 숫자 이외의 값 입력")
void splitAndSum_inputNotNumber(){
// given, when
RuntimeException fail = assertThrows(RuntimeException.class, () -> StringAddCalculator.splitAndSum("문자열"));

// then
assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_INPUT);
}

@Test
@DisplayName("문자열 덧셈 계산기 지정되어 있지 않은 구분자 입력")
void splitAndSum_inputInvalidDelimiter(){
// given, when
RuntimeException fail = assertThrows(RuntimeException.class, () -> StringAddCalculator.splitAndSum("1;2;3;"));

// then
assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_INPUT);
}

@Test
@DisplayName("문자열 덧셈 계산기 음수 입력")
void splitAndSum_inputNegativeNumber(){
// given, when
RuntimeException fail = assertThrows(RuntimeException.class, () -> StringAddCalculator.splitAndSum("1,-2,3"));

// then
assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_NEGATIVE_NUMBER_INPUT);
}

@Test
public void splitAndSum_negative() throws Exception {
assertThatThrownBy(() -> StringAddCalculator.splitAndSum("-1,2,3"))
.isInstanceOf(RuntimeException.class);
}



}
Loading