-
Notifications
You must be signed in to change notification settings - Fork 6
혁 문자열 덧셈 계산기 #8
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
base: yh
Are you sure you want to change the base?
혁 문자열 덧셈 계산기 #8
Changes from all commits
ad75a8d
f84dc0f
2c5f7f1
4ddf9e0
9c180b6
3f91b18
1509f2b
96b2d84
7bf42f8
f727b04
0fffad5
9bac024
297360e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package calculator; | ||
|
|
||
| import calculator.extractor.NumbersExtractor; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class StringAddCalculator { | ||
|
|
||
| public static int calculateWith(String inputString) { | ||
| verifyInputStringNotNull(inputString); | ||
| if (inputString.isEmpty()) { | ||
| return 0; | ||
| } | ||
| List<Integer> numbers = NumbersExtractor.extract(inputString); | ||
| return numbers.stream() | ||
| .mapToInt(Integer::intValue) | ||
| .sum(); | ||
| } | ||
|
|
||
| private static void verifyInputStringNotNull(String inputString) { | ||
| if (inputString == null) { | ||
| throw new IllegalArgumentException("input string cannot be null"); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package calculator.extractor; | ||
|
|
||
| import calculator.vo.Delimiters; | ||
| import calculator.vo.NumberString; | ||
|
|
||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class NumbersExtractor { | ||
|
|
||
| public static List<Integer> extract(String inputString) { | ||
| Delimiters delimiters = new Delimiters(inputString); | ||
| NumberString numberString = new NumberString(inputString); | ||
|
|
||
| return numberString.getSplitStringNumbers(delimiters).stream() | ||
| .mapToInt(Integer::valueOf) | ||
| .boxed() | ||
| .collect(Collectors.toList()); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package calculator.vo; | ||
|
|
||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
|
|
||
| public class Delimiters { | ||
|
|
||
| public static final String BASIC_DELIMITER_REGEX = ",|:"; | ||
| public static final String CUSTOM_DELIMITER_REGEX = "//(.)\n(.*)"; | ||
|
|
||
| public static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile(CUSTOM_DELIMITER_REGEX); | ||
|
|
||
| private String delimiterRegex = BASIC_DELIMITER_REGEX; | ||
|
|
||
| public Delimiters(String inputString) { | ||
| Matcher matcher = CUSTOM_DELIMITER_PATTERN.matcher(inputString); | ||
| if (matcher.find()) { | ||
| String customDelimiter = matcher.group(1); | ||
| delimiterRegex = createDelimiterRegexWith(customDelimiter); | ||
| } | ||
| } | ||
|
|
||
| public String toRegexString() { | ||
| return delimiterRegex; | ||
| } | ||
|
|
||
| private String createDelimiterRegexWith(String customDelimiter) { | ||
| return new StringBuilder(delimiterRegex) | ||
| .append("|") | ||
| .append(customDelimiter) | ||
| .toString(); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package calculator.vo; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
|
|
||
| public class NumberString { | ||
|
|
||
| public static final String CUSTOM_DELIMITER_REGEX = "//(.)\n(.*)"; | ||
| public static final String VALID_NUMBER_STRING_REGEX = "([0-9]([,:][0-9])*)?"; | ||
|
|
||
| private final String value; | ||
|
|
||
| public NumberString(String inputString) { | ||
| Pattern customDelimiterPattern = Pattern.compile(CUSTOM_DELIMITER_REGEX); | ||
| Matcher matcher = customDelimiterPattern.matcher(inputString); | ||
| if (matcher.find()) { | ||
| String numberString = matcher.group(2); | ||
| value = numberString; | ||
| return; | ||
| } | ||
| validateString(inputString); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 위에서 matcher.find()로 통과한상태인데 만약 NumberString이 아니면 어떻게 되나요?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. find를 거쳐서 제대로 값이 들어갔다고 생각을 하는데.. 어떤 문제인지 잘 모르겠습니다. |
||
| value = inputString; | ||
| } | ||
|
|
||
| public List<String> getSplitStringNumbers(Delimiters delimiters) { | ||
| String delimiterRegex = delimiters.toRegexString(); | ||
| return Arrays.asList(value.split(delimiterRegex)); | ||
| } | ||
|
|
||
| private void validateString(String string) { | ||
| Pattern customDelimiterPattern = Pattern.compile(VALID_NUMBER_STRING_REGEX); | ||
| Matcher matcher = customDelimiterPattern.matcher(string); | ||
|
|
||
| if (!matcher.matches()) { | ||
| throw new IllegalArgumentException("invalid string"); | ||
| } | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| package calculator; | ||
|
|
||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
|
|
||
| public class StringAddCalculatorTest { | ||
|
|
||
| @DisplayName("유효한 계산식이 잘 계산 되는지 확인") | ||
| @Test | ||
| void calculateTest() { | ||
| // given | ||
| String inputString = "1,2:3"; | ||
|
|
||
| // when | ||
| int result = StringAddCalculator.calculateWith(inputString); | ||
|
|
||
| // then | ||
| assertThat(result).isEqualTo(6); | ||
| } | ||
|
|
||
| @DisplayName("커스텀 구분자 계산식이 잘 계산 되는지 확인") | ||
| @Test | ||
| void calculateWithCustomDelimiter() { | ||
| // given | ||
| String inputString = "//;\n1;2;3"; | ||
|
|
||
| // when | ||
| int result = StringAddCalculator.calculateWith(inputString); | ||
|
|
||
| // then | ||
| assertThat(result).isEqualTo(6); | ||
| } | ||
|
|
||
| @DisplayName("공백 확인") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요구사항을 다시 확인하세요 :) |
||
| @Test | ||
| void calculateWithBlank() { | ||
| // given | ||
| String inputString = ""; | ||
|
|
||
| // when | ||
| int result = StringAddCalculator.calculateWith(inputString); | ||
|
|
||
| // then | ||
| assertThat(result).isEqualTo(0); | ||
| } | ||
|
|
||
| @DisplayName("단일 숫자 확인") | ||
| @Test | ||
| void calculateWithSingleNumber() { | ||
| // given | ||
| String inputString = "6"; | ||
|
|
||
| // when | ||
| int result = StringAddCalculator.calculateWith(inputString); | ||
|
|
||
| // then | ||
| assertThat(result).isEqualTo(6); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package calculator.extractor; | ||
|
|
||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
|
|
||
| class NumbersExtractorTest { | ||
|
|
||
| @DisplayName("문자열에서 정수 리스트를 잘 추출해 내는지 테스트") | ||
| @Test | ||
| void numberExtractTest() { | ||
| // given | ||
| String inputString = "1,2:3"; | ||
|
|
||
| // when | ||
| List<Integer> extractedNumbers = NumbersExtractor.extract(inputString); | ||
|
|
||
| // then | ||
| assertThat(extractedNumbers).isEqualTo(Arrays.asList(1, 2, 3)); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package calculator.vo; | ||
|
|
||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
|
|
||
| class DelimitersTest { | ||
|
|
||
| @DisplayName("커스텀 구분자 없을 때 디폴트 구분자 regex만 존재") | ||
| @Test | ||
| void noCustomDelimiter() { | ||
| // given | ||
| String inputString = "1,2:3"; | ||
| Delimiters delimiters = new Delimiters(inputString); | ||
|
|
||
| // then | ||
| assertThat(delimiters.toRegexString()).isEqualTo(",|:"); | ||
| } | ||
|
|
||
| @DisplayName("커스텀 구분자 있을 때, 디폴트 구분자와 커스텀 구분자가 regex가 존재") | ||
| @Test | ||
| void haveCustomDelimiter() { | ||
| // given | ||
| String inputString = "//;\n1;2;3"; | ||
| Delimiters delimiters = new Delimiters(inputString); | ||
|
|
||
| // then | ||
| assertThat(delimiters.toRegexString()).isEqualTo(",|:|;"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| package calculator.vo; | ||
|
|
||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
|
||
| class NumberStringTest { | ||
|
|
||
| @DisplayName("커스텀 구분자 없을 때 분리된 문자열 숫자 가져오기") | ||
| @Test | ||
| void noCustomDelimiter() { | ||
| // given | ||
| String inputString = "1,2:3"; | ||
| NumberString numberString = new NumberString(inputString); | ||
| Delimiters delimiters = new Delimiters(inputString); | ||
|
|
||
| // then | ||
| assertThat(numberString.getSplitStringNumbers(delimiters)).isEqualTo(Arrays.asList("1", "2", "3")); | ||
| } | ||
|
|
||
| @DisplayName("유효하지 않은 문자열에 커스텀 구분자 없을 때 에러처리") | ||
| @Test | ||
| void invalidateStringWithoutCustomDelimiter() { | ||
| // given | ||
| String inputString = "/1,2:3"; | ||
|
|
||
| // then | ||
| assertThatThrownBy(() -> new NumberString(inputString)) | ||
| .isInstanceOf(IllegalArgumentException.class) | ||
| .hasMessage("invalid string"); | ||
| } | ||
|
|
||
| @DisplayName("커스텀 구분자 있을 때 분리된 문자열 숫자 가져오기") | ||
| @Test | ||
| void haveCustomDelimiter() { | ||
| // given | ||
| String inputString = "//;\n1;2;3"; | ||
| NumberString numberString = new NumberString(inputString); | ||
| Delimiters delimiters = new Delimiters(inputString); | ||
|
|
||
| // then | ||
| assertThat(numberString.getSplitStringNumbers(delimiters)).isEqualTo(Arrays.asList("1", "2", "3")); | ||
| } | ||
|
|
||
| @DisplayName("유효하지 않은 문자열에 커스텀 구분자 있을 때 에러처리") | ||
| @Test | ||
| void invalidateStringWithCustomDelimiter() { | ||
| // given | ||
| String inputString = "/;\n1;2;3"; | ||
|
|
||
| // then | ||
| assertThatThrownBy(() -> new NumberString(inputString)) | ||
| .isInstanceOf(IllegalArgumentException.class) | ||
| .hasMessage("invalid string"); | ||
| } | ||
|
|
||
| @DisplayName("공백 검사") | ||
| @Test | ||
| void blankString() { | ||
| // given | ||
| String inputString = ""; | ||
| NumberString numberString = new NumberString(inputString); | ||
| Delimiters delimiters = new Delimiters(inputString); | ||
|
|
||
| // then | ||
| assertThat(numberString.getSplitStringNumbers(delimiters)).isEqualTo(Collections.singletonList("")); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mapToInt 말고 map으로만 하면 boxed 할 필요없이 Integer 리스트로 collect 되지않나요??