From 1ec376ec51fdf432a991074b2467d8d553e82679 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Tue, 3 Mar 2020 16:08:24 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=8D=A7?= =?UTF-8?q?=EC=85=88=20=EA=B3=84=EC=82=B0=EA=B8=B0=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?1.=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=EA=B5=AC=EB=B6=84=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=EC=B0=BE=EA=B3=A0=20=EC=88=AB=EC=9E=90=20List?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC=ED=95=98=EB=8A=94=20Splitter=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84=202.=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=EB=90=9C=20=EC=88=AB=EC=9E=90=EB=A5=BC=20?= =?UTF-8?q?=EB=9E=98=ED=95=91=ED=95=98=EB=8A=94=20Number=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/calculator/CalculatorService.java | 14 +++++ src/main/java/calculator/Number.java | 30 ++++++++++ src/main/java/calculator/Splitter.java | 40 +++++++++++++ src/main/java/calculator/empty.txt | 0 .../calculator/CalculatorServiceTest.java | 60 +++++++++++++++++++ src/test/java/calculator/NumberTest.java | 31 ++++++++++ src/test/java/calculator/SplitterTest.java | 30 ++++++++++ src/test/java/calculator/empty.txt | 0 8 files changed, 205 insertions(+) create mode 100644 src/main/java/calculator/CalculatorService.java create mode 100644 src/main/java/calculator/Number.java create mode 100644 src/main/java/calculator/Splitter.java delete mode 100644 src/main/java/calculator/empty.txt create mode 100644 src/test/java/calculator/CalculatorServiceTest.java create mode 100644 src/test/java/calculator/NumberTest.java create mode 100644 src/test/java/calculator/SplitterTest.java delete mode 100644 src/test/java/calculator/empty.txt diff --git a/src/main/java/calculator/CalculatorService.java b/src/main/java/calculator/CalculatorService.java new file mode 100644 index 0000000..8e216b9 --- /dev/null +++ b/src/main/java/calculator/CalculatorService.java @@ -0,0 +1,14 @@ +package calculator; + +import java.util.List; + +public class CalculatorService { + + public int calculate(String expression) { + List numbers = Splitter.getSplittedNumbers(expression); + + return numbers.stream() + .mapToInt(Number::getValue) + .sum(); + } +} diff --git a/src/main/java/calculator/Number.java b/src/main/java/calculator/Number.java new file mode 100644 index 0000000..7d7c6e6 --- /dev/null +++ b/src/main/java/calculator/Number.java @@ -0,0 +1,30 @@ +package calculator; + +public class Number { + private final int value; + + public Number(String value) { + this.value = parseString(value); + } + + public int getValue() { + return value; + } + + private int parseString(String value) { + validateNumber(value); + int result = Integer.parseInt(value); + + if (result < 0) { + throw new RuntimeException(String.format("음수가 입력되었습니다. : %s ", result)); + } + + return result; + } + + private void validateNumber(String value) { + if (value == null || value.isEmpty()) { + throw new RuntimeException("빈 문자열 입니다."); + } + } +} diff --git a/src/main/java/calculator/Splitter.java b/src/main/java/calculator/Splitter.java new file mode 100644 index 0000000..c348ac9 --- /dev/null +++ b/src/main/java/calculator/Splitter.java @@ -0,0 +1,40 @@ +package calculator; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class Splitter { + private static final String COMMON_DELIMITER = ",|:"; + private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.)\n(.*)"); + private static final String DEFAULT_NUMBER = "0"; + + public static List getSplittedNumbers(String expression) { + if (expression == null || expression.isEmpty()) { + return commonSplit(DEFAULT_NUMBER); + } + + Matcher matcher = CUSTOM_DELIMITER_PATTERN.matcher(expression); + if (matcher.find()) { + return customSplit(matcher); + } + + return commonSplit(expression); + } + + private static List customSplit(Matcher matcher) { + String delimiter = matcher.group(1); + String formula = matcher.group(2); + return Arrays.stream(formula.split(delimiter)) + .map(Number::new) + .collect(Collectors.toList()); + } + + private static List commonSplit(String expression) { + return Arrays.stream(expression.split(COMMON_DELIMITER)) + .map(Number::new) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/calculator/empty.txt b/src/main/java/calculator/empty.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/java/calculator/CalculatorServiceTest.java b/src/test/java/calculator/CalculatorServiceTest.java new file mode 100644 index 0000000..c4d8705 --- /dev/null +++ b/src/test/java/calculator/CalculatorServiceTest.java @@ -0,0 +1,60 @@ +package calculator; + +import org.assertj.core.api.ThrowableAssert; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class CalculatorServiceTest { + + @DisplayName("기본 구분자로 식 입력시 결과 반환") + @Test + void name() { + String expression = "1,2:3"; + CalculatorService calculatorService = new CalculatorService(); + int result = calculatorService.calculate(expression); + assertThat(result).isEqualTo(6); + } + + @DisplayName("커스텀 구분자로 식 입력시 결과 반환") + @Test + void name1() { + String expression = "//h\n1h2h3"; + CalculatorService calculatorService = new CalculatorService(); + int result = calculatorService.calculate(expression); + assertThat(result).isEqualTo(6); + } + + @DisplayName("1 입력시 1 반환") + @Test + void name4() { + String expression = "1"; + CalculatorService calculatorService = new CalculatorService(); + int result = calculatorService.calculate(expression); + assertThat(result).isEqualTo(1); + } + + @DisplayName("빈 문자열, null 입력시 0") + @ParameterizedTest + @NullAndEmptySource + void name2(String expression) { + CalculatorService calculatorService = new CalculatorService(); + int result = calculatorService.calculate(expression); + assertThat(result).isEqualTo(0); + } + + @DisplayName("음수 값 있을때 RuntimeExcetion Throw") + @Test + void name3() { + String expression = "1,-2:3"; + CalculatorService calculatorService = new CalculatorService(); + assertThatThrownBy(() -> calculatorService.calculate(expression)) + .isInstanceOf(RuntimeException.class) + .hasMessage(String.format("음수가 입력되었습니다. : %s ", -2)); + } +} \ No newline at end of file diff --git a/src/test/java/calculator/NumberTest.java b/src/test/java/calculator/NumberTest.java new file mode 100644 index 0000000..f80a798 --- /dev/null +++ b/src/test/java/calculator/NumberTest.java @@ -0,0 +1,31 @@ +package calculator; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.EmptySource; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class NumberTest { + @DisplayName("빈 문자열 또는 null일시 RuntimeException Throw") + @ParameterizedTest + @NullAndEmptySource + void name1(String expression) { + assertThatThrownBy(() -> new Number(expression)) + .isInstanceOf(RuntimeException.class) + .hasMessage("빈 문자열 입니다."); + } + + @DisplayName("음수일시 RuntimeException Throw") + @Test + void name() { + assertThatThrownBy(() -> new Number("-1")) + .isInstanceOf(RuntimeException.class) + .hasMessage(String.format("음수가 입력되었습니다. : %s ", -1)); + } +} \ No newline at end of file diff --git a/src/test/java/calculator/SplitterTest.java b/src/test/java/calculator/SplitterTest.java new file mode 100644 index 0000000..97e0e66 --- /dev/null +++ b/src/test/java/calculator/SplitterTest.java @@ -0,0 +1,30 @@ +package calculator; + +import jdk.nashorn.internal.ir.annotations.Ignore; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class SplitterTest { + + @Ignore + @DisplayName("일반적인 식 입력시 분리된 숫자 List가 반환") + @Test + void name() { + String expression = "1,2:3,4"; + List numbers = Splitter.getSplittedNumbers(expression); + assertThat(numbers.size()).isEqualTo(4); + } + + @Ignore + @DisplayName("커스텀 구분자로 입력시 분리된 숫자 List가 반환") + @Test + void name1() { + String expression = "///\n1/2/3/6"; + List numbers = Splitter.getSplittedNumbers(expression); + assertThat(numbers.size()).isEqualTo(4); + } +} \ No newline at end of file diff --git a/src/test/java/calculator/empty.txt b/src/test/java/calculator/empty.txt deleted file mode 100644 index e69de29..0000000 From a77e48b1bf25fe6ea843d442638e2f5c1ba48026 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Tue, 3 Mar 2020 16:13:33 +0900 Subject: [PATCH 2/3] =?UTF-8?q?1.=20getSplittedNumbers=20->=20getSplitNumb?= =?UTF-8?q?ers=202.=20=EA=B8=B0=EB=B3=B8=20=EA=B5=AC=EB=B6=84=EC=9E=90=20?= =?UTF-8?q?=EC=83=81=EC=88=98=20[,:]=20=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/CalculatorService.java | 2 +- src/main/java/calculator/Splitter.java | 4 ++-- src/test/java/calculator/SplitterTest.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/calculator/CalculatorService.java b/src/main/java/calculator/CalculatorService.java index 8e216b9..141461c 100644 --- a/src/main/java/calculator/CalculatorService.java +++ b/src/main/java/calculator/CalculatorService.java @@ -5,7 +5,7 @@ public class CalculatorService { public int calculate(String expression) { - List numbers = Splitter.getSplittedNumbers(expression); + List numbers = Splitter.getSplitNumbers(expression); return numbers.stream() .mapToInt(Number::getValue) diff --git a/src/main/java/calculator/Splitter.java b/src/main/java/calculator/Splitter.java index c348ac9..27aa613 100644 --- a/src/main/java/calculator/Splitter.java +++ b/src/main/java/calculator/Splitter.java @@ -7,11 +7,11 @@ import java.util.stream.Collectors; public class Splitter { - private static final String COMMON_DELIMITER = ",|:"; + private static final String COMMON_DELIMITER = "[,:]"; private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.)\n(.*)"); private static final String DEFAULT_NUMBER = "0"; - public static List getSplittedNumbers(String expression) { + public static List getSplitNumbers(String expression) { if (expression == null || expression.isEmpty()) { return commonSplit(DEFAULT_NUMBER); } diff --git a/src/test/java/calculator/SplitterTest.java b/src/test/java/calculator/SplitterTest.java index 97e0e66..9a9c451 100644 --- a/src/test/java/calculator/SplitterTest.java +++ b/src/test/java/calculator/SplitterTest.java @@ -15,7 +15,7 @@ class SplitterTest { @Test void name() { String expression = "1,2:3,4"; - List numbers = Splitter.getSplittedNumbers(expression); + List numbers = Splitter.getSplitNumbers(expression); assertThat(numbers.size()).isEqualTo(4); } @@ -24,7 +24,7 @@ void name() { @Test void name1() { String expression = "///\n1/2/3/6"; - List numbers = Splitter.getSplittedNumbers(expression); + List numbers = Splitter.getSplitNumbers(expression); assertThat(numbers.size()).isEqualTo(4); } } \ No newline at end of file From 436cd46f7bc269cbfd097ba44e53c652c523b42b Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Wed, 4 Mar 2020 15:14:02 +0900 Subject: [PATCH 3/3] =?UTF-8?q?1.=20Number=EC=97=90=20sum=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80=ED=95=B4=EC=84=9C=20?= =?UTF-8?q?=EC=B4=9D=ED=95=A9=EC=9D=84=20=EA=B5=AC=ED=95=A0=EB=96=84=20red?= =?UTF-8?q?uce=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=202.=20Splitter=EC=97=90=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=EC=9E=90=20=EA=B7=B8=EB=A3=B9=EA=B3=BC=20?= =?UTF-8?q?=EC=8B=A4=EC=A0=9C=20=EC=88=98=EC=8B=9D=20=EA=B7=B8=EB=A3=B9=20?= =?UTF-8?q?=EC=83=81=EC=88=98=20=EC=B6=94=EA=B0=80=203.=20SplitterTest?= =?UTF-8?q?=EC=97=90=20Ignore=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/CalculatorService.java | 8 +++++--- src/main/java/calculator/Number.java | 8 ++++++++ src/main/java/calculator/Splitter.java | 6 ++++-- src/test/java/calculator/SplitterTest.java | 2 -- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/calculator/CalculatorService.java b/src/main/java/calculator/CalculatorService.java index 141461c..f6fe63a 100644 --- a/src/main/java/calculator/CalculatorService.java +++ b/src/main/java/calculator/CalculatorService.java @@ -7,8 +7,10 @@ public class CalculatorService { public int calculate(String expression) { List numbers = Splitter.getSplitNumbers(expression); - return numbers.stream() - .mapToInt(Number::getValue) - .sum(); + Number result = numbers.stream() + .reduce(Number::sum) + .orElseThrow(() -> new ArithmeticException()); + + return result.getValue(); } } diff --git a/src/main/java/calculator/Number.java b/src/main/java/calculator/Number.java index 7d7c6e6..b00f99a 100644 --- a/src/main/java/calculator/Number.java +++ b/src/main/java/calculator/Number.java @@ -7,10 +7,18 @@ public Number(String value) { this.value = parseString(value); } + public Number(int value) { + this.value = value; + } + public int getValue() { return value; } + public static Number sum(Number a, Number b) { + return new Number(a.getValue() + b.getValue()); + } + private int parseString(String value) { validateNumber(value); int result = Integer.parseInt(value); diff --git a/src/main/java/calculator/Splitter.java b/src/main/java/calculator/Splitter.java index 27aa613..8b4b45c 100644 --- a/src/main/java/calculator/Splitter.java +++ b/src/main/java/calculator/Splitter.java @@ -10,6 +10,8 @@ public class Splitter { private static final String COMMON_DELIMITER = "[,:]"; private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.)\n(.*)"); private static final String DEFAULT_NUMBER = "0"; + private static final int DELIMITER_GROUP = 1; + private static final int FORMULA_GROUP = 2; public static List getSplitNumbers(String expression) { if (expression == null || expression.isEmpty()) { @@ -25,8 +27,8 @@ public static List getSplitNumbers(String expression) { } private static List customSplit(Matcher matcher) { - String delimiter = matcher.group(1); - String formula = matcher.group(2); + String delimiter = matcher.group(DELIMITER_GROUP); + String formula = matcher.group(FORMULA_GROUP); return Arrays.stream(formula.split(delimiter)) .map(Number::new) .collect(Collectors.toList()); diff --git a/src/test/java/calculator/SplitterTest.java b/src/test/java/calculator/SplitterTest.java index 9a9c451..cac39bf 100644 --- a/src/test/java/calculator/SplitterTest.java +++ b/src/test/java/calculator/SplitterTest.java @@ -10,7 +10,6 @@ class SplitterTest { - @Ignore @DisplayName("일반적인 식 입력시 분리된 숫자 List가 반환") @Test void name() { @@ -19,7 +18,6 @@ void name() { assertThat(numbers.size()).isEqualTo(4); } - @Ignore @DisplayName("커스텀 구분자로 입력시 분리된 숫자 List가 반환") @Test void name1() {