From f524d9d288d7b0a691f86c54d1229d13edcd7866 Mon Sep 17 00:00:00 2001 From: chanin Date: Tue, 3 Mar 2020 22:35:17 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat=20:=20=EB=B6=84=EB=A6=AC=20=EC=A0=84?= =?UTF-8?q?=EB=9E=B5=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/splitter/CustomSplitStrategy.java | 28 +++++++++++ .../domain/splitter/DefaultSplitStrategy.java | 27 ++++++++++ .../domain/splitter/SplitStrategy.java | 9 ++++ src/main/java/calculator/empty.txt | 0 .../splitter/CustomSplitStrategyTest.java | 50 +++++++++++++++++++ .../splitter/DefaultSplitStrategyTest.java | 45 +++++++++++++++++ src/test/java/calculator/empty.txt | 0 7 files changed, 159 insertions(+) create mode 100644 src/main/java/calculator/domain/splitter/CustomSplitStrategy.java create mode 100644 src/main/java/calculator/domain/splitter/DefaultSplitStrategy.java create mode 100644 src/main/java/calculator/domain/splitter/SplitStrategy.java delete mode 100644 src/main/java/calculator/empty.txt create mode 100644 src/test/java/calculator/domain/splitter/CustomSplitStrategyTest.java create mode 100644 src/test/java/calculator/domain/splitter/DefaultSplitStrategyTest.java delete mode 100644 src/test/java/calculator/empty.txt diff --git a/src/main/java/calculator/domain/splitter/CustomSplitStrategy.java b/src/main/java/calculator/domain/splitter/CustomSplitStrategy.java new file mode 100644 index 0000000..a2cd5df --- /dev/null +++ b/src/main/java/calculator/domain/splitter/CustomSplitStrategy.java @@ -0,0 +1,28 @@ +package calculator.domain.splitter; + +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 CustomSplitStrategy implements SplitStrategy { + private static final Pattern CUSTOM_PATTERN = Pattern.compile("//(.)\n(.*)"); + + @Override + public boolean support(String expression) { + return CUSTOM_PATTERN.matcher(expression) + .find(); + } + + @Override + public List split(String expression) { + Matcher matcher = CUSTOM_PATTERN.matcher(expression); + matcher.find(); + + String customDelimiter = matcher.group(1); + String target = matcher.group(2); + return Arrays.stream(target.split(customDelimiter)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/calculator/domain/splitter/DefaultSplitStrategy.java b/src/main/java/calculator/domain/splitter/DefaultSplitStrategy.java new file mode 100644 index 0000000..0622f15 --- /dev/null +++ b/src/main/java/calculator/domain/splitter/DefaultSplitStrategy.java @@ -0,0 +1,27 @@ +package calculator.domain.splitter; + +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 DefaultSplitStrategy implements SplitStrategy { + private static final Pattern DEFAULT_PATTERN = Pattern.compile("(.*)"); + private static final String COMMA_AND_SEMICOLON = "[,|:]"; + + @Override + public boolean support(String expression) { + return DEFAULT_PATTERN.matcher(expression) + .find(); + } + + @Override + public List split(String expression) { + Matcher matcher = DEFAULT_PATTERN.matcher(expression); + matcher.find(); + String target = matcher.group(0); + return Arrays.stream(target.split(COMMA_AND_SEMICOLON)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/calculator/domain/splitter/SplitStrategy.java b/src/main/java/calculator/domain/splitter/SplitStrategy.java new file mode 100644 index 0000000..f785bf0 --- /dev/null +++ b/src/main/java/calculator/domain/splitter/SplitStrategy.java @@ -0,0 +1,9 @@ +package calculator.domain.splitter; + +import java.util.List; + +public interface SplitStrategy { + boolean support(String expression); + + List split(String expression); +} 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/domain/splitter/CustomSplitStrategyTest.java b/src/test/java/calculator/domain/splitter/CustomSplitStrategyTest.java new file mode 100644 index 0000000..67aae30 --- /dev/null +++ b/src/test/java/calculator/domain/splitter/CustomSplitStrategyTest.java @@ -0,0 +1,50 @@ +package calculator.domain.splitter; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.List; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +class CustomSplitStrategyTest { + + private static Stream customSupportProvider() { + return Stream.of( + Arguments.of("//?\n1?2?3", true), + Arguments.of("1?2?3", false) + ); + } + + @DisplayName("커스텀식을 나타내는 (// \\n)이 존재해야 지원한다.") + @ParameterizedTest + @MethodSource("customSupportProvider") + void support(String expression, boolean result) { + //given + CustomSplitStrategy customSplitStrategy = new CustomSplitStrategy(); + + //when + boolean expect = customSplitStrategy.support(expression); + + //then + assertThat(expect).isEqualTo(result); + } + + @DisplayName("커스텀식은 커스텀 구분자로 구분한다.") + @Test + void split() { + //given + CustomSplitStrategy customSplitStrategy = new CustomSplitStrategy(); + String expression = "//#\n1#2#3"; + + //when + List expect = customSplitStrategy.split(expression); + + //then + assertThat(expect).containsExactly("1", "2", "3"); + } +} \ No newline at end of file diff --git a/src/test/java/calculator/domain/splitter/DefaultSplitStrategyTest.java b/src/test/java/calculator/domain/splitter/DefaultSplitStrategyTest.java new file mode 100644 index 0000000..a9cfb4a --- /dev/null +++ b/src/test/java/calculator/domain/splitter/DefaultSplitStrategyTest.java @@ -0,0 +1,45 @@ +package calculator.domain.splitter; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class DefaultSplitStrategyTest { + + @DisplayName("기본전략은 모든 식을 수용한다.") + @ParameterizedTest + @CsvSource(value = { + "1,2:3", + "1", + "1 2"}, delimiter = '|') + void support(String expression) { + //given + DefaultSplitStrategy defaultSplitStrategy = new DefaultSplitStrategy(); + + //then + assertThat(defaultSplitStrategy.support(expression)).isTrue(); + } + + @DisplayName("기본전략은 연산자로 ,와 ;를 이용한여 식을 분리한다.") + @ParameterizedTest + @CsvSource(value = { + "1,2,3", + "1:2:3", + "1,2:3", + }, delimiter = '|') + void split(String expression) { + //given + DefaultSplitStrategy defaultSplitStrategy = new DefaultSplitStrategy(); + + //when + List split = defaultSplitStrategy.split(expression); + + //then + assertThat(split).containsExactly("1", "2", "3"); + } + +} \ 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 cb6cd6a6666be10d62a86d9ebf75407795effbd2 Mon Sep 17 00:00:00 2001 From: chanin Date: Tue, 3 Mar 2020 22:46:02 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat=20:=20=EB=B6=84=EB=A6=AC=20=EC=A0=84?= =?UTF-8?q?=EB=9E=B5=20=EA=B7=B8=EB=A3=B9=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/splitter/SplitterGroup.java | 26 ++++++++++++ .../domain/splitter/SplitterGroupTest.java | 41 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/main/java/calculator/domain/splitter/SplitterGroup.java create mode 100644 src/test/java/calculator/domain/splitter/SplitterGroupTest.java diff --git a/src/main/java/calculator/domain/splitter/SplitterGroup.java b/src/main/java/calculator/domain/splitter/SplitterGroup.java new file mode 100644 index 0000000..54083bb --- /dev/null +++ b/src/main/java/calculator/domain/splitter/SplitterGroup.java @@ -0,0 +1,26 @@ +package calculator.domain.splitter; + +import java.util.Arrays; +import java.util.List; + +public enum SplitterGroup { + CUSTOM(new CustomSplitStrategy()), + DEFAULT(new DefaultSplitStrategy()); + + private final SplitStrategy splitStrategy; + + SplitterGroup(SplitStrategy splitStrategy) { + this.splitStrategy = splitStrategy; + } + + public static SplitterGroup findStrategyByExpression(String expression) { + return Arrays.stream(values()) + .filter(aSplitter -> aSplitter.splitStrategy.support(expression)) + .findFirst() + .orElseThrow(AssertionError::new); + } + + public List split(String expression) { + return this.splitStrategy.split(expression); + } +} diff --git a/src/test/java/calculator/domain/splitter/SplitterGroupTest.java b/src/test/java/calculator/domain/splitter/SplitterGroupTest.java new file mode 100644 index 0000000..53d24a6 --- /dev/null +++ b/src/test/java/calculator/domain/splitter/SplitterGroupTest.java @@ -0,0 +1,41 @@ +package calculator.domain.splitter; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.List; +import java.util.stream.Stream; + +import static calculator.domain.splitter.SplitterGroup.CUSTOM; +import static calculator.domain.splitter.SplitterGroup.DEFAULT; +import static org.assertj.core.api.Assertions.assertThat; + +class SplitterGroupTest { + + private static Stream expressionProvider() { + return Stream.of( + Arguments.of("//#\n1#2#3", CUSTOM), + Arguments.of("1,2,3", DEFAULT) + ); + } + + @DisplayName("입력식이 커스텀 구분자를 가지고 있으면 커스텀전략을 아니면 기본전략을 반환한다.") + @ParameterizedTest + @MethodSource("expressionProvider") + void findStrategyByExpression(String expression, SplitterGroup result) { + SplitterGroup strategyByExpression = SplitterGroup.findStrategyByExpression(expression); + + assertThat(strategyByExpression).isEqualTo(result); + } + + @DisplayName("해당하는 전략이 식을 분리한다.") + @ParameterizedTest + @MethodSource("expressionProvider") + void split(String expression, SplitterGroup splitterGroup) { + List expect = splitterGroup.split(expression); + + assertThat(expect).containsExactly("1", "2", "3"); + } +} \ No newline at end of file From d288c4589ed8e784f5f41cf88939fbf3f7a8bd0a Mon Sep 17 00:00:00 2001 From: chanin Date: Tue, 3 Mar 2020 23:00:36 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat=20:=20=EC=88=AB=EC=9E=90=20=EC=9D=BC?= =?UTF-8?q?=EA=B8=89=EC=BB=AC=EB=A0=89=EC=85=98=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/domain/Numbers.java | 47 +++++++++++++++++++ .../domain/splitter/SplitterGroup.java | 7 +-- .../java/calculator/domain/NumbersTest.java | 40 ++++++++++++++++ .../domain/splitter/SplitterGroupTest.java | 13 +++-- 4 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 src/main/java/calculator/domain/Numbers.java create mode 100644 src/test/java/calculator/domain/NumbersTest.java diff --git a/src/main/java/calculator/domain/Numbers.java b/src/main/java/calculator/domain/Numbers.java new file mode 100644 index 0000000..4904c8a --- /dev/null +++ b/src/main/java/calculator/domain/Numbers.java @@ -0,0 +1,47 @@ +package calculator.domain; + +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class Numbers { + private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+"); + private final List numbers; + + public Numbers(List numbers) { + validate(numbers); + this.numbers = numbers.stream() + .map(Integer::parseInt) + .collect(Collectors.toList()); + } + + private void validate(List numbers) { + boolean canParse = numbers.stream() + .map(NUMBER_PATTERN::matcher) + .allMatch(Matcher::find); + + if (!canParse) { + throw new IllegalArgumentException(numbers + "숫자가 아닌 입력값이 존재합니다."); + } + } + + public int sum() { + return numbers.stream() + .reduce(0, Integer::sum); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Numbers numbers1 = (Numbers) o; + return Objects.equals(numbers, numbers1.numbers); + } + + @Override + public int hashCode() { + return Objects.hash(numbers); + } +} diff --git a/src/main/java/calculator/domain/splitter/SplitterGroup.java b/src/main/java/calculator/domain/splitter/SplitterGroup.java index 54083bb..c2fac73 100644 --- a/src/main/java/calculator/domain/splitter/SplitterGroup.java +++ b/src/main/java/calculator/domain/splitter/SplitterGroup.java @@ -1,7 +1,8 @@ package calculator.domain.splitter; +import calculator.domain.Numbers; + import java.util.Arrays; -import java.util.List; public enum SplitterGroup { CUSTOM(new CustomSplitStrategy()), @@ -20,7 +21,7 @@ public static SplitterGroup findStrategyByExpression(String expression) { .orElseThrow(AssertionError::new); } - public List split(String expression) { - return this.splitStrategy.split(expression); + public Numbers split(String expression) { + return new Numbers(this.splitStrategy.split(expression)); } } diff --git a/src/test/java/calculator/domain/NumbersTest.java b/src/test/java/calculator/domain/NumbersTest.java new file mode 100644 index 0000000..3dd4101 --- /dev/null +++ b/src/test/java/calculator/domain/NumbersTest.java @@ -0,0 +1,40 @@ +package calculator.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class NumbersTest { + + @DisplayName("숫자가 아닌 문자를 입력받으면 exception 발생") + @Test + void parseException() { + assertThatThrownBy(() -> new Numbers(Arrays.asList("1", "22", "2a"))) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("입력받은 값으로 합을 출력한다.") + @Test + void sum() { + //given + Numbers numbers = new Numbers(Arrays.asList("1", "2", "3")); + + //when + int sum = numbers.sum(); + + //then + assertThat(sum).isEqualTo(6); + } + + @DisplayName("숫자 일급 컬렉션 생성 테스트") + @Test + void equals() { + Numbers numbers = new Numbers(Arrays.asList("1", "2", "3")); + + assertThat(numbers).isEqualTo(new Numbers(Arrays.asList("1", "2", "3"))); + } +} \ No newline at end of file diff --git a/src/test/java/calculator/domain/splitter/SplitterGroupTest.java b/src/test/java/calculator/domain/splitter/SplitterGroupTest.java index 53d24a6..3b86e4d 100644 --- a/src/test/java/calculator/domain/splitter/SplitterGroupTest.java +++ b/src/test/java/calculator/domain/splitter/SplitterGroupTest.java @@ -1,11 +1,12 @@ package calculator.domain.splitter; +import calculator.domain.Numbers; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.util.List; +import java.util.Arrays; import java.util.stream.Stream; import static calculator.domain.splitter.SplitterGroup.CUSTOM; @@ -34,8 +35,14 @@ void findStrategyByExpression(String expression, SplitterGroup result) { @ParameterizedTest @MethodSource("expressionProvider") void split(String expression, SplitterGroup splitterGroup) { - List expect = splitterGroup.split(expression); + //given + Numbers result = new Numbers(Arrays.asList("1", "2", "3")); - assertThat(expect).containsExactly("1", "2", "3"); + //when + Numbers expect = splitterGroup.split(expression); + + + //then + assertThat(expect).isEqualTo(result); } } \ No newline at end of file From 44720b4152c2bdd555ea04b18a29a65110ff29ec Mon Sep 17 00:00:00 2001 From: chanin Date: Tue, 3 Mar 2020 23:18:30 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat=20:=20=EA=B3=84=EC=82=B0=EA=B8=B0=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/calculator/domain/Calculator.java | 16 ++++++++ src/main/java/calculator/domain/Numbers.java | 4 +- .../calculator/domain/CalculatorTest.java | 40 +++++++++++++++++++ .../java/calculator/domain/NumbersTest.java | 2 +- .../splitter/DefaultSplitStrategyTest.java | 2 +- 5 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/main/java/calculator/domain/Calculator.java create mode 100644 src/test/java/calculator/domain/CalculatorTest.java diff --git a/src/main/java/calculator/domain/Calculator.java b/src/main/java/calculator/domain/Calculator.java new file mode 100644 index 0000000..ba98104 --- /dev/null +++ b/src/main/java/calculator/domain/Calculator.java @@ -0,0 +1,16 @@ +package calculator.domain; + +import calculator.domain.splitter.SplitterGroup; + +public class Calculator { + + public static int calculate(String expression) { + if (expression == null || expression.trim().isEmpty()) { + return 0; + } + SplitterGroup strategyByExpression = SplitterGroup.findStrategyByExpression(expression); + Numbers numbers = strategyByExpression.split(expression); + + return numbers.sum(); + } +} diff --git a/src/main/java/calculator/domain/Numbers.java b/src/main/java/calculator/domain/Numbers.java index 4904c8a..c025d89 100644 --- a/src/main/java/calculator/domain/Numbers.java +++ b/src/main/java/calculator/domain/Numbers.java @@ -7,7 +7,7 @@ import java.util.stream.Collectors; public class Numbers { - private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+"); + private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+)"); private final List numbers; public Numbers(List numbers) { @@ -20,7 +20,7 @@ public Numbers(List numbers) { private void validate(List numbers) { boolean canParse = numbers.stream() .map(NUMBER_PATTERN::matcher) - .allMatch(Matcher::find); + .allMatch(Matcher::matches); if (!canParse) { throw new IllegalArgumentException(numbers + "숫자가 아닌 입력값이 존재합니다."); diff --git a/src/test/java/calculator/domain/CalculatorTest.java b/src/test/java/calculator/domain/CalculatorTest.java new file mode 100644 index 0000000..d2e4951 --- /dev/null +++ b/src/test/java/calculator/domain/CalculatorTest.java @@ -0,0 +1,40 @@ +package calculator.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +class CalculatorTest { + + private static Stream expressionProvider() { + return Stream.of( + Arguments.of("1,2:3", 6), + Arguments.of("//#\n1#4#10", 15), + Arguments.of("1", 1) + ); + } + + @DisplayName("null 또는 공백을 입력할 경우 0을 반환") + @ParameterizedTest + @NullAndEmptySource + void calculateNullAndEmpty(String expression) { + int expect = Calculator.calculate(expression); + + assertThat(expect).isEqualTo(0); + } + + @DisplayName("입력식에 따른 결과 반환") + @ParameterizedTest + @MethodSource("expressionProvider") + void calculate(String expression, int result) { + int expect = Calculator.calculate(expression); + + assertThat(expect).isEqualTo(result); + } +} \ No newline at end of file diff --git a/src/test/java/calculator/domain/NumbersTest.java b/src/test/java/calculator/domain/NumbersTest.java index 3dd4101..cd05cfb 100644 --- a/src/test/java/calculator/domain/NumbersTest.java +++ b/src/test/java/calculator/domain/NumbersTest.java @@ -13,7 +13,7 @@ class NumbersTest { @DisplayName("숫자가 아닌 문자를 입력받으면 exception 발생") @Test void parseException() { - assertThatThrownBy(() -> new Numbers(Arrays.asList("1", "22", "2a"))) + assertThatThrownBy(() -> new Numbers(Arrays.asList("1", "22", "2;"))) .isInstanceOf(IllegalArgumentException.class); } diff --git a/src/test/java/calculator/domain/splitter/DefaultSplitStrategyTest.java b/src/test/java/calculator/domain/splitter/DefaultSplitStrategyTest.java index a9cfb4a..8ef2639 100644 --- a/src/test/java/calculator/domain/splitter/DefaultSplitStrategyTest.java +++ b/src/test/java/calculator/domain/splitter/DefaultSplitStrategyTest.java @@ -24,7 +24,7 @@ void support(String expression) { assertThat(defaultSplitStrategy.support(expression)).isTrue(); } - @DisplayName("기본전략은 연산자로 ,와 ;를 이용한여 식을 분리한다.") + @DisplayName("기본전략은 연산자로 ,와 :를 이용한여 식을 분리한다.") @ParameterizedTest @CsvSource(value = { "1,2,3", From d9466e8b2940a4202406aef11c022cd11de02509 Mon Sep 17 00:00:00 2001 From: chanin Date: Tue, 3 Mar 2020 23:22:29 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor=20:=20=EC=96=91=EC=88=98=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/calculator/domain/Calculator.java | 4 ++-- .../{Numbers.java => PositiveNumbers.java} | 10 +++++----- .../domain/splitter/SplitterGroup.java | 6 +++--- ...bersTest.java => PositiveNumbersTest.java} | 19 +++++++++++++------ .../domain/splitter/SplitterGroupTest.java | 6 +++--- 5 files changed, 26 insertions(+), 19 deletions(-) rename src/main/java/calculator/domain/{Numbers.java => PositiveNumbers.java} (79%) rename src/test/java/calculator/domain/{NumbersTest.java => PositiveNumbersTest.java} (51%) diff --git a/src/main/java/calculator/domain/Calculator.java b/src/main/java/calculator/domain/Calculator.java index ba98104..2854fbc 100644 --- a/src/main/java/calculator/domain/Calculator.java +++ b/src/main/java/calculator/domain/Calculator.java @@ -9,8 +9,8 @@ public static int calculate(String expression) { return 0; } SplitterGroup strategyByExpression = SplitterGroup.findStrategyByExpression(expression); - Numbers numbers = strategyByExpression.split(expression); + PositiveNumbers positiveNumbers = strategyByExpression.split(expression); - return numbers.sum(); + return positiveNumbers.sum(); } } diff --git a/src/main/java/calculator/domain/Numbers.java b/src/main/java/calculator/domain/PositiveNumbers.java similarity index 79% rename from src/main/java/calculator/domain/Numbers.java rename to src/main/java/calculator/domain/PositiveNumbers.java index c025d89..be2910d 100644 --- a/src/main/java/calculator/domain/Numbers.java +++ b/src/main/java/calculator/domain/PositiveNumbers.java @@ -6,11 +6,11 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -public class Numbers { +public class PositiveNumbers { private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+)"); private final List numbers; - public Numbers(List numbers) { + public PositiveNumbers(List numbers) { validate(numbers); this.numbers = numbers.stream() .map(Integer::parseInt) @@ -23,7 +23,7 @@ private void validate(List numbers) { .allMatch(Matcher::matches); if (!canParse) { - throw new IllegalArgumentException(numbers + "숫자가 아닌 입력값이 존재합니다."); + throw new IllegalArgumentException(numbers + "양수가 아닌 입력값이 존재합니다."); } } @@ -36,8 +36,8 @@ public int sum() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - Numbers numbers1 = (Numbers) o; - return Objects.equals(numbers, numbers1.numbers); + PositiveNumbers positiveNumbers = (PositiveNumbers) o; + return Objects.equals(numbers, positiveNumbers.numbers); } @Override diff --git a/src/main/java/calculator/domain/splitter/SplitterGroup.java b/src/main/java/calculator/domain/splitter/SplitterGroup.java index c2fac73..7df0e90 100644 --- a/src/main/java/calculator/domain/splitter/SplitterGroup.java +++ b/src/main/java/calculator/domain/splitter/SplitterGroup.java @@ -1,6 +1,6 @@ package calculator.domain.splitter; -import calculator.domain.Numbers; +import calculator.domain.PositiveNumbers; import java.util.Arrays; @@ -21,7 +21,7 @@ public static SplitterGroup findStrategyByExpression(String expression) { .orElseThrow(AssertionError::new); } - public Numbers split(String expression) { - return new Numbers(this.splitStrategy.split(expression)); + public PositiveNumbers split(String expression) { + return new PositiveNumbers(this.splitStrategy.split(expression)); } } diff --git a/src/test/java/calculator/domain/NumbersTest.java b/src/test/java/calculator/domain/PositiveNumbersTest.java similarity index 51% rename from src/test/java/calculator/domain/NumbersTest.java rename to src/test/java/calculator/domain/PositiveNumbersTest.java index cd05cfb..bebeb5c 100644 --- a/src/test/java/calculator/domain/NumbersTest.java +++ b/src/test/java/calculator/domain/PositiveNumbersTest.java @@ -8,12 +8,19 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -class NumbersTest { +class PositiveNumbersTest { + + @DisplayName("음수 입력시 exception 발생") + @Test + void negativeNumber() { + assertThatThrownBy(() -> new PositiveNumbers(Arrays.asList("1", "22", "-1"))) + .isInstanceOf(IllegalArgumentException.class); + } @DisplayName("숫자가 아닌 문자를 입력받으면 exception 발생") @Test void parseException() { - assertThatThrownBy(() -> new Numbers(Arrays.asList("1", "22", "2;"))) + assertThatThrownBy(() -> new PositiveNumbers(Arrays.asList("1", "22", "2;"))) .isInstanceOf(IllegalArgumentException.class); } @@ -21,10 +28,10 @@ void parseException() { @Test void sum() { //given - Numbers numbers = new Numbers(Arrays.asList("1", "2", "3")); + PositiveNumbers positiveNumbers = new PositiveNumbers(Arrays.asList("1", "2", "3")); //when - int sum = numbers.sum(); + int sum = positiveNumbers.sum(); //then assertThat(sum).isEqualTo(6); @@ -33,8 +40,8 @@ void sum() { @DisplayName("숫자 일급 컬렉션 생성 테스트") @Test void equals() { - Numbers numbers = new Numbers(Arrays.asList("1", "2", "3")); + PositiveNumbers positiveNumbers = new PositiveNumbers(Arrays.asList("1", "2", "3")); - assertThat(numbers).isEqualTo(new Numbers(Arrays.asList("1", "2", "3"))); + assertThat(positiveNumbers).isEqualTo(new PositiveNumbers(Arrays.asList("1", "2", "3"))); } } \ No newline at end of file diff --git a/src/test/java/calculator/domain/splitter/SplitterGroupTest.java b/src/test/java/calculator/domain/splitter/SplitterGroupTest.java index 3b86e4d..c53a7c9 100644 --- a/src/test/java/calculator/domain/splitter/SplitterGroupTest.java +++ b/src/test/java/calculator/domain/splitter/SplitterGroupTest.java @@ -1,6 +1,6 @@ package calculator.domain.splitter; -import calculator.domain.Numbers; +import calculator.domain.PositiveNumbers; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -36,10 +36,10 @@ void findStrategyByExpression(String expression, SplitterGroup result) { @MethodSource("expressionProvider") void split(String expression, SplitterGroup splitterGroup) { //given - Numbers result = new Numbers(Arrays.asList("1", "2", "3")); + PositiveNumbers result = new PositiveNumbers(Arrays.asList("1", "2", "3")); //when - Numbers expect = splitterGroup.split(expression); + PositiveNumbers expect = splitterGroup.split(expression); //then From e8c99258583890d2d3a21566e79195978704b1c0 Mon Sep 17 00:00:00 2001 From: chanin Date: Tue, 3 Mar 2020 23:24:39 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor=20:=20=EB=B9=88=EA=B0=92=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=8B=9C=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=EB=A1=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/domain/Calculator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/calculator/domain/Calculator.java b/src/main/java/calculator/domain/Calculator.java index 2854fbc..621334b 100644 --- a/src/main/java/calculator/domain/Calculator.java +++ b/src/main/java/calculator/domain/Calculator.java @@ -5,7 +5,7 @@ public class Calculator { public static int calculate(String expression) { - if (expression == null || expression.trim().isEmpty()) { + if (isEmpty(expression)) { return 0; } SplitterGroup strategyByExpression = SplitterGroup.findStrategyByExpression(expression); @@ -13,4 +13,8 @@ public static int calculate(String expression) { return positiveNumbers.sum(); } + + private static boolean isEmpty(String expression) { + return expression == null || expression.trim().isEmpty(); + } } From c5666dd658c1c145b8404f49423f2eefa738aa13 Mon Sep 17 00:00:00 2001 From: chanin Date: Wed, 4 Mar 2020 12:49:22 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor=20:=20=EA=B5=AC=EB=B6=84=EC=9E=90?= =?UTF-8?q?=EB=A1=9C=20=EC=B0=A9=EA=B0=81=ED=95=9C=20=EB=AC=B8=EC=9E=90=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/calculator/domain/splitter/DefaultSplitStrategy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/calculator/domain/splitter/DefaultSplitStrategy.java b/src/main/java/calculator/domain/splitter/DefaultSplitStrategy.java index 0622f15..12b3e57 100644 --- a/src/main/java/calculator/domain/splitter/DefaultSplitStrategy.java +++ b/src/main/java/calculator/domain/splitter/DefaultSplitStrategy.java @@ -8,7 +8,7 @@ public class DefaultSplitStrategy implements SplitStrategy { private static final Pattern DEFAULT_PATTERN = Pattern.compile("(.*)"); - private static final String COMMA_AND_SEMICOLON = "[,|:]"; + private static final String COMMA_AND_SEMICOLON = "[,:]"; @Override public boolean support(String expression) { From 6cb55d4846d1497b75e9da9fa44d1831d831bad3 Mon Sep 17 00:00:00 2001 From: chanin Date: Wed, 4 Mar 2020 13:55:45 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor=20:=20=EC=9D=B8=EC=8A=A4=ED=84=B4?= =?UTF-8?q?=EC=8A=A4=ED=99=94=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/domain/Calculator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/calculator/domain/Calculator.java b/src/main/java/calculator/domain/Calculator.java index 621334b..30f59f8 100644 --- a/src/main/java/calculator/domain/Calculator.java +++ b/src/main/java/calculator/domain/Calculator.java @@ -4,6 +4,9 @@ public class Calculator { + private Calculator() { + } + public static int calculate(String expression) { if (isEmpty(expression)) { return 0;