From b10cf9fc263109d4701f8892d70f0d13720e29e0 Mon Sep 17 00:00:00 2001 From: seojaeyeon Date: Wed, 26 Feb 2020 16:46:54 +0900 Subject: [PATCH 01/13] =?UTF-8?q?1st=20commit=201.=20Calculator,=20Calcula?= =?UTF-8?q?torService,=20Splitter=EB=A1=9C=20=EC=B1=85=EC=9E=84=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=202.=20TestCode=20=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Strategy.md | 16 ++++ src/main/java/Main.java | 18 ++++ src/main/java/calculator/empty.txt | 0 src/main/java/domain/Calculator.java | 14 +++ src/main/java/domain/dto/Operand.java | 29 ++++++ src/main/java/service/CalculatorService.java | 27 ++++++ src/main/java/support/Splitter.java | 52 +++++++++++ src/main/java/view/OutputView.java | 15 +++ src/test/java/domain/CalculatorTest.java | 51 ++++++++++ .../java/service/CalculatorServiceTest.java | 53 +++++++++++ src/test/java/support/SplitterTest.java | 92 +++++++++++++++++++ 11 files changed, 367 insertions(+) create mode 100644 Strategy.md create mode 100644 src/main/java/Main.java delete mode 100644 src/main/java/calculator/empty.txt create mode 100644 src/main/java/domain/Calculator.java create mode 100644 src/main/java/domain/dto/Operand.java create mode 100644 src/main/java/service/CalculatorService.java create mode 100644 src/main/java/support/Splitter.java create mode 100644 src/main/java/view/OutputView.java create mode 100644 src/test/java/domain/CalculatorTest.java create mode 100644 src/test/java/service/CalculatorServiceTest.java create mode 100644 src/test/java/support/SplitterTest.java diff --git a/Strategy.md b/Strategy.md new file mode 100644 index 0000000..ad4c690 --- /dev/null +++ b/Strategy.md @@ -0,0 +1,16 @@ + +메시지 + +1. 입력을 받아라 +2. 구분자를 뽑아내라 - inner class +3. 구분자에 따라 쪼개라 +4. 덧셈해라 + + +구분자로 쪼개는 애 > Splitter +구분자 뽑아내는 애 > Splitter.delimiter + +커스텀 구분자가 있는지 없는지 판단하는 애? 서비스레이어에서하자 + + +덧셈하는 > Calculator diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000..911644b --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,18 @@ +import domain.Calculator; +import service.CalculatorService; +import view.OutputView; + +import java.util.Scanner; + +public class Main { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + CalculatorService calculatorService = new CalculatorService(new Calculator()); + + OutputView.printRequestFormulaMessage(); + + double result = calculatorService.calculate(scanner.next()); + + OutputView.printCalculateResult(result); + } +} 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/main/java/domain/Calculator.java b/src/main/java/domain/Calculator.java new file mode 100644 index 0000000..7234c31 --- /dev/null +++ b/src/main/java/domain/Calculator.java @@ -0,0 +1,14 @@ +package domain; + +import domain.dto.Operand; + +import java.util.List; + +public class Calculator { + + public double calculate(List formula) { + return formula.stream() + .mapToDouble( o -> new Operand(o).getValue()) + .sum(); + } +} diff --git a/src/main/java/domain/dto/Operand.java b/src/main/java/domain/dto/Operand.java new file mode 100644 index 0000000..a0aa4fc --- /dev/null +++ b/src/main/java/domain/dto/Operand.java @@ -0,0 +1,29 @@ +package domain.dto; + +public class Operand { + + private final double value; + + public Operand(final String operand) { + try{ + double parsedOperand = Double.parseDouble(operand); + + checkNegative(parsedOperand); + + this.value = parsedOperand; + }catch(NumberFormatException ne){ + throw new IllegalArgumentException(String.format("%s 는 Double 형으로 파싱될 수 없습니다.", operand)); + } + } + + private void checkNegative(double parsedOperand) { + if(parsedOperand < 0 ){ + throw new IllegalArgumentException(String.format("음수인 %s 값은 들어올 수 없습니다", parsedOperand)); + } + } + + public double getValue() { + return value; + } + +} diff --git a/src/main/java/service/CalculatorService.java b/src/main/java/service/CalculatorService.java new file mode 100644 index 0000000..b263f8f --- /dev/null +++ b/src/main/java/service/CalculatorService.java @@ -0,0 +1,27 @@ +package service; + +import com.sun.nio.sctp.IllegalReceiveException; +import domain.Calculator; +import support.Splitter; + +import java.util.List; + +public class CalculatorService { + + private final Calculator calculator; + + public CalculatorService(Calculator calculator) { + this.calculator = calculator; + } + + public double calculate(final String formula) { + List splitedFormula = Splitter.split(formula.trim()); + + if (splitedFormula.size() <= 0) { + throw new IllegalReceiveException(String.format("%s 는 계산할 수 없는 수식입니다. Delimiter를 체크해주세요", formula)); + } + + return calculator.calculate(splitedFormula); + } + +} diff --git a/src/main/java/support/Splitter.java b/src/main/java/support/Splitter.java new file mode 100644 index 0000000..9843420 --- /dev/null +++ b/src/main/java/support/Splitter.java @@ -0,0 +1,52 @@ +package support; + +import java.util.Arrays; +import java.util.List; + + +public class Splitter { + + private final static String DEFAULT_DELIMITER_REGEX = "[,:]"; + + private final static String CUSTOM_DELIMITER_START_FORMAT = "//"; + private final static String CUSTOM_DELIMITER_END_FORMAT = "₩n"; + + public static List split(final String formula) { + if (notExistCustomDelimiter(formula)) { + return Arrays.asList(formula.split(DEFAULT_DELIMITER_REGEX)); + } + + String customDelimiter = DelimiterExtractor.extract(formula); + String realFormula = formula.substring(formula.indexOf(CUSTOM_DELIMITER_END_FORMAT) + CUSTOM_DELIMITER_END_FORMAT.length()); + + return Arrays.asList(realFormula.split(customDelimiter)); + } + + private static boolean notExistCustomDelimiter(final String maybeCustomDelimiter) { + return !maybeCustomDelimiter.startsWith(CUSTOM_DELIMITER_START_FORMAT); + } + + private static class DelimiterExtractor { + + private static String extract(final String maybeDelimiter) { + int endDelimiterIndex = maybeDelimiter.indexOf(CUSTOM_DELIMITER_END_FORMAT); + + if (endDelimiterIndex < 0) { + throw new IllegalArgumentException(String.format("%s는 올바르지 않은 요청 포맷입니다.", maybeDelimiter)); + } + + String customDelimiter = maybeDelimiter.substring(CUSTOM_DELIMITER_START_FORMAT.length(), endDelimiterIndex); + + if (customDelimiter.isEmpty() || isNumeric(customDelimiter)) { + throw new IllegalArgumentException(String.format("%s는 올바르지 않은 커스텀구분자입니다.", maybeDelimiter)); + } + + return customDelimiter; + } + + private static boolean isNumeric(final String customDelimiter){ + return customDelimiter.matches("-?\\d+(\\.\\d+)?"); + } + + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000..6eba647 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,15 @@ +package view; + +import java.text.DecimalFormat; + +public class OutputView { + + public static void printRequestFormulaMessage(){ + System.out.println("계산 할 수식을 입력해주세요"); + } + + public static void printCalculateResult(final double result){ + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + System.out.println("결과: "+decimalFormat.format(result)); + } +} diff --git a/src/test/java/domain/CalculatorTest.java b/src/test/java/domain/CalculatorTest.java new file mode 100644 index 0000000..2807270 --- /dev/null +++ b/src/test/java/domain/CalculatorTest.java @@ -0,0 +1,51 @@ +package domain; + +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.AssertionsForClassTypes.assertThatThrownBy; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class CalculatorTest { + + Calculator calculator = new Calculator(); + + @DisplayName("올바른 수식 덧셈") + @Test + void calculate() { + //given + List formula = Arrays.asList("1", "2", "3"); + + //when + double result = calculator.calculate(formula); + + //then + assertThat(result).isEqualTo(6); + } + + @DisplayName("숫자가 아닌 값이 들어갔을 때 에러를 던져준다") + @Test + void calculateThrow() { + //given + List formula = Arrays.asList("1", "@", "3"); + + //when + //then + assertThatThrownBy(() -> calculator.calculate(formula)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(String.format("%s 는 Double 형으로 파싱될 수 없습니다.", "@")); + } + + @DisplayName("음수가 나오면 에러를 던진다") + @Test + void negative(){ + List formula = Arrays.asList("1", "-2", "3"); + + assertThatThrownBy(() -> calculator.calculate(formula)) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/service/CalculatorServiceTest.java b/src/test/java/service/CalculatorServiceTest.java new file mode 100644 index 0000000..e1fd3fd --- /dev/null +++ b/src/test/java/service/CalculatorServiceTest.java @@ -0,0 +1,53 @@ +package service; + +import domain.Calculator; +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.stream.Stream; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +class CalculatorServiceTest { + + CalculatorService calculatorService = new CalculatorService(new Calculator()); + + @DisplayName("올바른 수식 계산 테스트") + @MethodSource("validFormula") + @ParameterizedTest + void invalidFormula(String formula, double expectedValue){ + assertThat(calculatorService.calculate(formula)).isEqualTo(expectedValue); + } + + static Stream validFormula() { + return Stream.of( + Arguments.of("//o₩n1o2o3", 6d), + Arguments.of("//abc₩n1abc2abc3abc", 6d), + Arguments.of("//@₩n3@1@7@1", 12d), + Arguments.of("1,2:3", 6d) + ); + } + + + @DisplayName("올바르지 않은 수식 테스트") + @MethodSource("invalidFormula") + @ParameterizedTest + void inValidFormula(String formula){ + assertThatThrownBy(() -> calculatorService.calculate(formula)) + .isInstanceOf(IllegalArgumentException.class); + } + + static Stream invalidFormula() { + return Stream.of( + Arguments.of("//₩n1o2o3"), + Arguments.of("//abc"), + Arguments.of("1abc2abc3abc"), + Arguments.of("//o₩n1*2") + ); + } + + +} diff --git a/src/test/java/support/SplitterTest.java b/src/test/java/support/SplitterTest.java new file mode 100644 index 0000000..af82568 --- /dev/null +++ b/src/test/java/support/SplitterTest.java @@ -0,0 +1,92 @@ +package support; + +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.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +class SplitterTest { + + @DisplayName("커스텀 구분자가 없을 때 제대로 쪼개지는 지") + @CsvSource({"'1,2,3'", "'1:2:3'", "'1,2:3'"}) + @ParameterizedTest + void split(String formula) { + //given + //when + List splitedFormula = Splitter.split(formula); + + //then + assertThat(splitedFormula).isEqualTo(Arrays.asList(formula.split("[,:]"))); + } + + + @DisplayName("커스텀 구분자가 있을 때 제대로 쪼개지는 지") + @MethodSource("customDelimiterFormat") + @ParameterizedTest + void splitByCustomDelimiter(String formula, List expectedValue) { + //given + //when + List splitedFormula = Splitter.split(formula); + + //then + assertThat(splitedFormula).isEqualTo(expectedValue); + } + + static Stream customDelimiterFormat() { + return Stream.of( + Arguments.of("//o₩n1o2o3", Arrays.asList("1", "2", "3")), + Arguments.of("//abc₩n1abc2abc3abc", Arrays.asList("1", "2", "3")) + ); + } + + + + @DisplayName("// \n 사이에 구분자가 없을 때 에러를 던져주는 지") + @Test + void splitCustomDelimiterThrow(){ + //given + String formula = "//₩n1o2o3"; + + //when + //then + assertThatThrownBy(() -> Splitter.split(formula)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(String.format("%s는 올바르지 않은 커스텀구분자입니다.", formula)); + } + + @DisplayName("// \n 사이에 구분자가 숫자일 때 에러를 던져주는 지") + @Test + void splitCustomDelimiterThrowIfNumeric(){ + //given + String formula = "//1₩n11213"; + + //when + //then + assertThatThrownBy(() -> Splitter.split(formula)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(String.format("%s는 올바르지 않은 커스텀구분자입니다.", formula)); + } + + @DisplayName("//는 있는데 ₩n 없으면 에러를 던져주는지") + @Test + void invalidCustomDeliment(){ + //given + String formula = "//abcd"; + + //when + //then + assertThatThrownBy(() -> Splitter.split(formula)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(String.format("%s는 올바르지 않은 요청 포맷입니다.", formula)); + } + +} From 7ec8ac0305b97db8a27fb218611f17ab0a3419c0 Mon Sep 17 00:00:00 2001 From: seojaeyeon Date: Thu, 27 Feb 2020 10:01:00 +0900 Subject: [PATCH 02/13] =?UTF-8?q?[2nd=20Commit]=201.=20Split=20Class=20Mat?= =?UTF-8?q?cher=20=EB=A1=9C=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD=202.?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=203.=20Pattern=20=EC=B2=98=EB=9F=BC=20=EC=8A=A4?= =?UTF-8?q?=EB=A0=88=EB=93=9C=EC=84=B8=EC=9D=B4=ED=94=84=ED=95=9C=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EC=9D=98=20=EC=83=81=EC=88=98=ED=99=94.=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=EC=9D=80=20=EB=8C=80=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=3F=20=EC=86=8C=EB=AC=B8=EC=9E=90=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Main.java | 18 ------- src/main/java/domain/Calculator.java | 2 +- src/main/java/domain/dto/Operand.java | 10 ++-- src/main/java/support/Splitter.java | 53 ++++++++----------- src/main/java/view/OutputView.java | 15 ------ .../java/service/CalculatorServiceTest.java | 8 +-- src/test/java/support/SplitterTest.java | 16 +----- 7 files changed, 34 insertions(+), 88 deletions(-) delete mode 100644 src/main/java/Main.java delete mode 100644 src/main/java/view/OutputView.java diff --git a/src/main/java/Main.java b/src/main/java/Main.java deleted file mode 100644 index 911644b..0000000 --- a/src/main/java/Main.java +++ /dev/null @@ -1,18 +0,0 @@ -import domain.Calculator; -import service.CalculatorService; -import view.OutputView; - -import java.util.Scanner; - -public class Main { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - CalculatorService calculatorService = new CalculatorService(new Calculator()); - - OutputView.printRequestFormulaMessage(); - - double result = calculatorService.calculate(scanner.next()); - - OutputView.printCalculateResult(result); - } -} diff --git a/src/main/java/domain/Calculator.java b/src/main/java/domain/Calculator.java index 7234c31..074262a 100644 --- a/src/main/java/domain/Calculator.java +++ b/src/main/java/domain/Calculator.java @@ -8,7 +8,7 @@ public class Calculator { public double calculate(List formula) { return formula.stream() - .mapToDouble( o -> new Operand(o).getValue()) + .mapToDouble(o -> new Operand(o).getValue()) .sum(); } } diff --git a/src/main/java/domain/dto/Operand.java b/src/main/java/domain/dto/Operand.java index a0aa4fc..dd74627 100644 --- a/src/main/java/domain/dto/Operand.java +++ b/src/main/java/domain/dto/Operand.java @@ -2,22 +2,22 @@ public class Operand { - private final double value; + private final long value; public Operand(final String operand) { - try{ - double parsedOperand = Double.parseDouble(operand); + try { + long parsedOperand = Long.parseLong(operand); checkNegative(parsedOperand); this.value = parsedOperand; - }catch(NumberFormatException ne){ + } catch (NumberFormatException ne) { throw new IllegalArgumentException(String.format("%s 는 Double 형으로 파싱될 수 없습니다.", operand)); } } private void checkNegative(double parsedOperand) { - if(parsedOperand < 0 ){ + if (parsedOperand < 0) { throw new IllegalArgumentException(String.format("음수인 %s 값은 들어올 수 없습니다", parsedOperand)); } } diff --git a/src/main/java/support/Splitter.java b/src/main/java/support/Splitter.java index 9843420..fbd1f4e 100644 --- a/src/main/java/support/Splitter.java +++ b/src/main/java/support/Splitter.java @@ -2,51 +2,42 @@ import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class Splitter { private final static String DEFAULT_DELIMITER_REGEX = "[,:]"; + private final static String NUMERIC_REGEX = "-?\\d+(\\.\\d+)?"; - private final static String CUSTOM_DELIMITER_START_FORMAT = "//"; - private final static String CUSTOM_DELIMITER_END_FORMAT = "₩n"; + private final static int CUSTOM_DELIMITER_INDEX = 1; + private final static int REAL_FORMULA_INDEX = 2; - public static List split(final String formula) { - if (notExistCustomDelimiter(formula)) { - return Arrays.asList(formula.split(DEFAULT_DELIMITER_REGEX)); - } + private final static Pattern customDelimiterPattern = Pattern.compile("//(.*)₩n(.*)"); - String customDelimiter = DelimiterExtractor.extract(formula); - String realFormula = formula.substring(formula.indexOf(CUSTOM_DELIMITER_END_FORMAT) + CUSTOM_DELIMITER_END_FORMAT.length()); - - return Arrays.asList(realFormula.split(customDelimiter)); - } + public static List split(final String formula) { + Matcher customDelimiterMatcher = customDelimiterPattern.matcher(formula); - private static boolean notExistCustomDelimiter(final String maybeCustomDelimiter) { - return !maybeCustomDelimiter.startsWith(CUSTOM_DELIMITER_START_FORMAT); + if (customDelimiterMatcher.find()) { + return split(customDelimiterMatcher); + } + return Arrays.asList(formula.split(DEFAULT_DELIMITER_REGEX)); } - private static class DelimiterExtractor { - - private static String extract(final String maybeDelimiter) { - int endDelimiterIndex = maybeDelimiter.indexOf(CUSTOM_DELIMITER_END_FORMAT); + private static List split(Matcher customDelimiterMatcher) { + String realFormula = customDelimiterMatcher.group(REAL_FORMULA_INDEX); + String customDelimiter = customDelimiterMatcher.group(CUSTOM_DELIMITER_INDEX); - if (endDelimiterIndex < 0) { - throw new IllegalArgumentException(String.format("%s는 올바르지 않은 요청 포맷입니다.", maybeDelimiter)); - } + validateDelimiter(customDelimiter); - String customDelimiter = maybeDelimiter.substring(CUSTOM_DELIMITER_START_FORMAT.length(), endDelimiterIndex); - - if (customDelimiter.isEmpty() || isNumeric(customDelimiter)) { - throw new IllegalArgumentException(String.format("%s는 올바르지 않은 커스텀구분자입니다.", maybeDelimiter)); - } - - return customDelimiter; - } + return Arrays.asList(realFormula.split(customDelimiter)); + } - private static boolean isNumeric(final String customDelimiter){ - return customDelimiter.matches("-?\\d+(\\.\\d+)?"); + private static void validateDelimiter(final String customDelimiter) { + if (customDelimiter.matches(NUMERIC_REGEX) || customDelimiter.isEmpty()) { + throw new IllegalArgumentException(String.format("%s 는(은) 올바르지 않은 커스텀구분자입니다.", customDelimiter)); } - } + } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java deleted file mode 100644 index 6eba647..0000000 --- a/src/main/java/view/OutputView.java +++ /dev/null @@ -1,15 +0,0 @@ -package view; - -import java.text.DecimalFormat; - -public class OutputView { - - public static void printRequestFormulaMessage(){ - System.out.println("계산 할 수식을 입력해주세요"); - } - - public static void printCalculateResult(final double result){ - DecimalFormat decimalFormat = new DecimalFormat("#.##"); - System.out.println("결과: "+decimalFormat.format(result)); - } -} diff --git a/src/test/java/service/CalculatorServiceTest.java b/src/test/java/service/CalculatorServiceTest.java index e1fd3fd..ec9a6d8 100644 --- a/src/test/java/service/CalculatorServiceTest.java +++ b/src/test/java/service/CalculatorServiceTest.java @@ -24,10 +24,10 @@ void invalidFormula(String formula, double expectedValue){ static Stream validFormula() { return Stream.of( - Arguments.of("//o₩n1o2o3", 6d), - Arguments.of("//abc₩n1abc2abc3abc", 6d), - Arguments.of("//@₩n3@1@7@1", 12d), - Arguments.of("1,2:3", 6d) + Arguments.of("//o₩n1o2o3", 6l), + Arguments.of("//abc₩n1abc2abc3abc", 6l), + Arguments.of("//@₩n3@1@7@1", 12l), + Arguments.of("1,2:3", 6l) ); } diff --git a/src/test/java/support/SplitterTest.java b/src/test/java/support/SplitterTest.java index af82568..c221795 100644 --- a/src/test/java/support/SplitterTest.java +++ b/src/test/java/support/SplitterTest.java @@ -60,7 +60,7 @@ void splitCustomDelimiterThrow(){ //then assertThatThrownBy(() -> Splitter.split(formula)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage(String.format("%s는 올바르지 않은 커스텀구분자입니다.", formula)); + .hasMessage(String.format("%s 는(은) 올바르지 않은 커스텀구분자입니다.", "")); } @DisplayName("// \n 사이에 구분자가 숫자일 때 에러를 던져주는 지") @@ -73,20 +73,8 @@ void splitCustomDelimiterThrowIfNumeric(){ //then assertThatThrownBy(() -> Splitter.split(formula)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage(String.format("%s는 올바르지 않은 커스텀구분자입니다.", formula)); + .hasMessage(String.format("%s 는(은) 올바르지 않은 커스텀구분자입니다.", 1)); } - @DisplayName("//는 있는데 ₩n 없으면 에러를 던져주는지") - @Test - void invalidCustomDeliment(){ - //given - String formula = "//abcd"; - - //when - //then - assertThatThrownBy(() -> Splitter.split(formula)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(String.format("%s는 올바르지 않은 요청 포맷입니다.", formula)); - } } From f9e658be12bdc3b296ca388f88e18c7fedd6ee33 Mon Sep 17 00:00:00 2001 From: seojaeyeon Date: Thu, 27 Feb 2020 10:14:30 +0900 Subject: [PATCH 03/13] =?UTF-8?q?[3rd=20commit]=201.=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20validation?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/service/CalculatorService.java | 4 ---- src/main/java/support/Splitter.java | 1 + src/test/java/service/CalculatorServiceTest.java | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/service/CalculatorService.java b/src/main/java/service/CalculatorService.java index b263f8f..91bdd69 100644 --- a/src/main/java/service/CalculatorService.java +++ b/src/main/java/service/CalculatorService.java @@ -17,10 +17,6 @@ public CalculatorService(Calculator calculator) { public double calculate(final String formula) { List splitedFormula = Splitter.split(formula.trim()); - if (splitedFormula.size() <= 0) { - throw new IllegalReceiveException(String.format("%s 는 계산할 수 없는 수식입니다. Delimiter를 체크해주세요", formula)); - } - return calculator.calculate(splitedFormula); } diff --git a/src/main/java/support/Splitter.java b/src/main/java/support/Splitter.java index fbd1f4e..e85bcf1 100644 --- a/src/main/java/support/Splitter.java +++ b/src/main/java/support/Splitter.java @@ -22,6 +22,7 @@ public static List split(final String formula) { if (customDelimiterMatcher.find()) { return split(customDelimiterMatcher); } + return Arrays.asList(formula.split(DEFAULT_DELIMITER_REGEX)); } diff --git a/src/test/java/service/CalculatorServiceTest.java b/src/test/java/service/CalculatorServiceTest.java index ec9a6d8..d6e6feb 100644 --- a/src/test/java/service/CalculatorServiceTest.java +++ b/src/test/java/service/CalculatorServiceTest.java @@ -49,5 +49,19 @@ static Stream invalidFormula() { ); } + @DisplayName("구분자가 없는 경우 그대로반환하는지 테스트") + @MethodSource("formulaWithoutDelimiter") + @ParameterizedTest + void formulaWithoutDelimiter(String formula, long expected){ + assertThat(calculatorService.calculate(formula)).isEqualTo(expected); + } + + static Stream formulaWithoutDelimiter() { + return Stream.of( + Arguments.of("//;₩n123", 123l), + Arguments.of("12345", 12345l) + ); + } + } From 59af19809ac9dc1508759e06a9cbcabae55ee58f Mon Sep 17 00:00:00 2001 From: seojaeyeon Date: Thu, 27 Feb 2020 13:28:24 +0900 Subject: [PATCH 04/13] codeconvention --- src/main/java/domain/Calculator.java | 1 - src/main/java/domain/dto/Operand.java | 1 - src/main/java/service/CalculatorService.java | 1 - src/main/java/support/Splitter.java | 1 - 4 files changed, 4 deletions(-) diff --git a/src/main/java/domain/Calculator.java b/src/main/java/domain/Calculator.java index 074262a..3ebd493 100644 --- a/src/main/java/domain/Calculator.java +++ b/src/main/java/domain/Calculator.java @@ -5,7 +5,6 @@ import java.util.List; public class Calculator { - public double calculate(List formula) { return formula.stream() .mapToDouble(o -> new Operand(o).getValue()) diff --git a/src/main/java/domain/dto/Operand.java b/src/main/java/domain/dto/Operand.java index dd74627..8533cd9 100644 --- a/src/main/java/domain/dto/Operand.java +++ b/src/main/java/domain/dto/Operand.java @@ -1,7 +1,6 @@ package domain.dto; public class Operand { - private final long value; public Operand(final String operand) { diff --git a/src/main/java/service/CalculatorService.java b/src/main/java/service/CalculatorService.java index 91bdd69..1cf25b7 100644 --- a/src/main/java/service/CalculatorService.java +++ b/src/main/java/service/CalculatorService.java @@ -7,7 +7,6 @@ import java.util.List; public class CalculatorService { - private final Calculator calculator; public CalculatorService(Calculator calculator) { diff --git a/src/main/java/support/Splitter.java b/src/main/java/support/Splitter.java index e85bcf1..8c903b2 100644 --- a/src/main/java/support/Splitter.java +++ b/src/main/java/support/Splitter.java @@ -7,7 +7,6 @@ public class Splitter { - private final static String DEFAULT_DELIMITER_REGEX = "[,:]"; private final static String NUMERIC_REGEX = "-?\\d+(\\.\\d+)?"; From 55d923c4d5c6553b9fb0060fd0648dfd0a6df9ea Mon Sep 17 00:00:00 2001 From: seojaeyeon Date: Thu, 27 Feb 2020 15:32:29 +0900 Subject: [PATCH 05/13] =?UTF-8?q?Codeconvention,=20double=20>=20long=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Double > Long 안바뀌어있던 것 수정 --- src/main/java/domain/Calculator.java | 7 ++++--- src/main/java/domain/dto/Operand.java | 8 +++----- src/main/java/service/CalculatorService.java | 2 +- src/test/java/domain/CalculatorTest.java | 2 +- src/test/java/service/CalculatorServiceTest.java | 2 +- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/domain/Calculator.java b/src/main/java/domain/Calculator.java index 3ebd493..75b30fd 100644 --- a/src/main/java/domain/Calculator.java +++ b/src/main/java/domain/Calculator.java @@ -5,9 +5,10 @@ import java.util.List; public class Calculator { - public double calculate(List formula) { - return formula.stream() - .mapToDouble(o -> new Operand(o).getValue()) + public long calculate(List operands) { + return operands.stream() + .map(Operand::new) + .mapToLong(Operand::getValue) .sum(); } } diff --git a/src/main/java/domain/dto/Operand.java b/src/main/java/domain/dto/Operand.java index 8533cd9..65ba1dd 100644 --- a/src/main/java/domain/dto/Operand.java +++ b/src/main/java/domain/dto/Operand.java @@ -6,22 +6,20 @@ public class Operand { public Operand(final String operand) { try { long parsedOperand = Long.parseLong(operand); - checkNegative(parsedOperand); - this.value = parsedOperand; } catch (NumberFormatException ne) { - throw new IllegalArgumentException(String.format("%s 는 Double 형으로 파싱될 수 없습니다.", operand)); + throw new IllegalArgumentException(String.format("%s 는 Long 형으로 파싱될 수 없습니다.", operand)); } } - private void checkNegative(double parsedOperand) { + private void checkNegative(long parsedOperand) { if (parsedOperand < 0) { throw new IllegalArgumentException(String.format("음수인 %s 값은 들어올 수 없습니다", parsedOperand)); } } - public double getValue() { + public long getValue() { return value; } diff --git a/src/main/java/service/CalculatorService.java b/src/main/java/service/CalculatorService.java index 1cf25b7..56ce375 100644 --- a/src/main/java/service/CalculatorService.java +++ b/src/main/java/service/CalculatorService.java @@ -13,7 +13,7 @@ public CalculatorService(Calculator calculator) { this.calculator = calculator; } - public double calculate(final String formula) { + public long calculate(final String formula) { List splitedFormula = Splitter.split(formula.trim()); return calculator.calculate(splitedFormula); diff --git a/src/test/java/domain/CalculatorTest.java b/src/test/java/domain/CalculatorTest.java index 2807270..970e448 100644 --- a/src/test/java/domain/CalculatorTest.java +++ b/src/test/java/domain/CalculatorTest.java @@ -37,7 +37,7 @@ void calculateThrow() { //then assertThatThrownBy(() -> calculator.calculate(formula)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage(String.format("%s 는 Double 형으로 파싱될 수 없습니다.", "@")); + .hasMessage(String.format("%s 는 Long 형으로 파싱될 수 없습니다.", "@")); } @DisplayName("음수가 나오면 에러를 던진다") diff --git a/src/test/java/service/CalculatorServiceTest.java b/src/test/java/service/CalculatorServiceTest.java index d6e6feb..ed2c87a 100644 --- a/src/test/java/service/CalculatorServiceTest.java +++ b/src/test/java/service/CalculatorServiceTest.java @@ -18,7 +18,7 @@ class CalculatorServiceTest { @DisplayName("올바른 수식 계산 테스트") @MethodSource("validFormula") @ParameterizedTest - void invalidFormula(String formula, double expectedValue){ + void invalidFormula(String formula, long expectedValue){ assertThat(calculatorService.calculate(formula)).isEqualTo(expectedValue); } From e3309b57674dd4c9233f1c1455d8fd6023b53622 Mon Sep 17 00:00:00 2001 From: csbsjy Date: Sat, 29 Feb 2020 22:07:43 +0900 Subject: [PATCH 06/13] =?UTF-8?q?1.=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=202.=20Calculator=20logic=20reduce?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20->=20=EC=A7=88=EB=AC=B8=203.?= =?UTF-8?q?=20testcode=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operand::sum 오타수정 Pattern convention --- src/main/java/domain/Calculator.java | 5 +- src/main/java/domain/dto/Operand.java | 11 +++- src/main/java/service/CalculatorService.java | 7 +++ src/main/java/support/Splitter.java | 4 +- src/test/java/domain/CalculatorTest.java | 31 +++++------ .../java/service/CalculatorServiceTest.java | 52 ++++++++++--------- 6 files changed, 65 insertions(+), 45 deletions(-) diff --git a/src/main/java/domain/Calculator.java b/src/main/java/domain/Calculator.java index 75b30fd..bc9aafd 100644 --- a/src/main/java/domain/Calculator.java +++ b/src/main/java/domain/Calculator.java @@ -8,7 +8,8 @@ public class Calculator { public long calculate(List operands) { return operands.stream() .map(Operand::new) - .mapToLong(Operand::getValue) - .sum(); + .reduce(Operand::sum) + .orElseThrow(() -> new IllegalArgumentException("sum 할 수 있는 operand가 없습니다")) + .getValue(); } } diff --git a/src/main/java/domain/dto/Operand.java b/src/main/java/domain/dto/Operand.java index 65ba1dd..beb2dd1 100644 --- a/src/main/java/domain/dto/Operand.java +++ b/src/main/java/domain/dto/Operand.java @@ -13,14 +13,21 @@ public Operand(final String operand) { } } + Operand(long value) { + this.value = value; + } + private void checkNegative(long parsedOperand) { if (parsedOperand < 0) { - throw new IllegalArgumentException(String.format("음수인 %s 값은 들어올 수 없습니다", parsedOperand)); + throw new IllegalArgumentException(String.format("음수인 %d 값은 들어올 수 없습니다", parsedOperand)); } } public long getValue() { - return value; + return this.value; } + public Operand sum(Operand operand) { + return new Operand(this.value + operand.value); + } } diff --git a/src/main/java/service/CalculatorService.java b/src/main/java/service/CalculatorService.java index 56ce375..e49b74e 100644 --- a/src/main/java/service/CalculatorService.java +++ b/src/main/java/service/CalculatorService.java @@ -14,9 +14,16 @@ public CalculatorService(Calculator calculator) { } public long calculate(final String formula) { + if (isNullOrEmpty(formula)) { + return 0; + } List splitedFormula = Splitter.split(formula.trim()); return calculator.calculate(splitedFormula); } + private boolean isNullOrEmpty(String formula) { + return formula == null || formula.isEmpty(); + } + } diff --git a/src/main/java/support/Splitter.java b/src/main/java/support/Splitter.java index 8c903b2..48ab8f0 100644 --- a/src/main/java/support/Splitter.java +++ b/src/main/java/support/Splitter.java @@ -13,10 +13,10 @@ public class Splitter { private final static int CUSTOM_DELIMITER_INDEX = 1; private final static int REAL_FORMULA_INDEX = 2; - private final static Pattern customDelimiterPattern = Pattern.compile("//(.*)₩n(.*)"); + private final static Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.*)₩n(.*)"); public static List split(final String formula) { - Matcher customDelimiterMatcher = customDelimiterPattern.matcher(formula); + Matcher customDelimiterMatcher = CUSTOM_DELIMITER_PATTERN.matcher(formula); if (customDelimiterMatcher.find()) { return split(customDelimiterMatcher); diff --git a/src/test/java/domain/CalculatorTest.java b/src/test/java/domain/CalculatorTest.java index 970e448..70e47d6 100644 --- a/src/test/java/domain/CalculatorTest.java +++ b/src/test/java/domain/CalculatorTest.java @@ -2,19 +2,22 @@ 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.Arrays; import java.util.List; +import java.util.stream.Stream; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; -import static org.junit.jupiter.api.Assertions.*; class CalculatorTest { Calculator calculator = new Calculator(); - @DisplayName("올바른 수식 덧셈") + @DisplayName("calculator에 음수가 아닌 숫자가 들어가면 정상적으로 더해서 반환한다.") @Test void calculate() { //given @@ -27,25 +30,23 @@ void calculate() { assertThat(result).isEqualTo(6); } - @DisplayName("숫자가 아닌 값이 들어갔을 때 에러를 던져준다") - @Test - void calculateThrow() { + @DisplayName("숫자가 아닌 값이나 음수가 들어가면 Exception이 발생한다") + @MethodSource("exceptionCase") + @ParameterizedTest + void calculateThrow(List formula, String exceptionMessage) { //given - List formula = Arrays.asList("1", "@", "3"); - //when //then assertThatThrownBy(() -> calculator.calculate(formula)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage(String.format("%s 는 Long 형으로 파싱될 수 없습니다.", "@")); + .hasMessage(exceptionMessage); } - @DisplayName("음수가 나오면 에러를 던진다") - @Test - void negative(){ - List formula = Arrays.asList("1", "-2", "3"); - - assertThatThrownBy(() -> calculator.calculate(formula)) - .isInstanceOf(IllegalArgumentException.class); + static Stream exceptionCase() { + return Stream.of( + Arguments.of(Arrays.asList("1", "@", "3"), String.format("%s 는 Long 형으로 파싱될 수 없습니다.", "@")), + Arguments.of(Arrays.asList("1", "-2", "3"), String.format("음수인 %d 값은 들어올 수 없습니다", -2)) + ); } + } diff --git a/src/test/java/service/CalculatorServiceTest.java b/src/test/java/service/CalculatorServiceTest.java index ed2c87a..2e73b2d 100644 --- a/src/test/java/service/CalculatorServiceTest.java +++ b/src/test/java/service/CalculatorServiceTest.java @@ -2,6 +2,7 @@ import domain.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.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -10,58 +11,61 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; class CalculatorServiceTest { CalculatorService calculatorService = new CalculatorService(new Calculator()); - @DisplayName("올바른 수식 계산 테스트") + @DisplayName(",과 : 로 구분하거나 커스텀 구분자를 설정한 정상계산 테스트") @MethodSource("validFormula") @ParameterizedTest - void invalidFormula(String formula, long expectedValue){ + void validFormula(String formula, long expectedValue) { assertThat(calculatorService.calculate(formula)).isEqualTo(expectedValue); } static Stream validFormula() { return Stream.of( - Arguments.of("//o₩n1o2o3", 6l), - Arguments.of("//abc₩n1abc2abc3abc", 6l), - Arguments.of("//@₩n3@1@7@1", 12l), - Arguments.of("1,2:3", 6l) + Arguments.of("//o₩n1o2o3", 6L), + Arguments.of("//abc₩n1abc2abc3abc", 6L), + Arguments.of("//@₩n3@1@7@1", 12L), + Arguments.of("1,2:3", 6L) ); } + @DisplayName("숫자 하나를 문자열로 입력할 경우 해당 숫자를 반환한다.") + @Test + void formulaWithoutDelimiter() { + String formula = "12345"; + + assertThat(calculatorService.calculate(formula)).isEqualTo(Long.parseLong(formula)); + } @DisplayName("올바르지 않은 수식 테스트") @MethodSource("invalidFormula") @ParameterizedTest - void inValidFormula(String formula){ + void inValidFormula(String formula, String exceptionMessage) { assertThatThrownBy(() -> calculatorService.calculate(formula)) - .isInstanceOf(IllegalArgumentException.class); + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(exceptionMessage); } static Stream invalidFormula() { return Stream.of( - Arguments.of("//₩n1o2o3"), - Arguments.of("//abc"), - Arguments.of("1abc2abc3abc"), - Arguments.of("//o₩n1*2") + Arguments.of("//₩n1o2o3", " 는(은) 올바르지 않은 커스텀구분자입니다."), + Arguments.of("//abc", "//abc 는 Long 형으로 파싱될 수 없습니다."), + Arguments.of("1abc2abc3abc", "1abc2abc3abc 는 Long 형으로 파싱될 수 없습니다."), + Arguments.of("//o₩n1*2", "1*2 는 Long 형으로 파싱될 수 없습니다.") ); } - @DisplayName("구분자가 없는 경우 그대로반환하는지 테스트") - @MethodSource("formulaWithoutDelimiter") - @ParameterizedTest - void formulaWithoutDelimiter(String formula, long expected){ - assertThat(calculatorService.calculate(formula)).isEqualTo(expected); - } - - static Stream formulaWithoutDelimiter() { - return Stream.of( - Arguments.of("//;₩n123", 123l), - Arguments.of("12345", 12345l) + @DisplayName("빈 문자열 또는 null 값이 들어가면 0 을 반환해야 한다.") + @Test + void emptyNull() { + assertAll( + () -> assertThat(calculatorService.calculate("")).isEqualTo(0), + () -> assertThat(calculatorService.calculate(null)).isEqualTo(0) ); } - } From 7cbb28ef8a1596e8258bc720aa02a68ca51d1605 Mon Sep 17 00:00:00 2001 From: csbsjy Date: Sat, 29 Feb 2020 22:41:02 +0900 Subject: [PATCH 07/13] =?UTF-8?q?Operand=20=EC=83=9D=EC=84=B1=EC=9E=90=20p?= =?UTF-8?q?rivate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/dto/Operand.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/domain/dto/Operand.java b/src/main/java/domain/dto/Operand.java index beb2dd1..31b4dc8 100644 --- a/src/main/java/domain/dto/Operand.java +++ b/src/main/java/domain/dto/Operand.java @@ -13,15 +13,10 @@ public Operand(final String operand) { } } - Operand(long value) { + private Operand(long value) { this.value = value; } - private void checkNegative(long parsedOperand) { - if (parsedOperand < 0) { - throw new IllegalArgumentException(String.format("음수인 %d 값은 들어올 수 없습니다", parsedOperand)); - } - } public long getValue() { return this.value; @@ -30,4 +25,10 @@ public long getValue() { public Operand sum(Operand operand) { return new Operand(this.value + operand.value); } + + private void checkNegative(long parsedOperand) { + if (parsedOperand < 0) { + throw new IllegalArgumentException(String.format("음수인 %d 값은 들어올 수 없습니다", parsedOperand)); + } + } } From e22bf1e27c3f410720ec5a269a5a7a492a560350 Mon Sep 17 00:00:00 2001 From: csbsjy Date: Sat, 29 Feb 2020 22:50:55 +0900 Subject: [PATCH 08/13] =?UTF-8?q?Operand=20Test=20=EC=BD=94=EB=93=9C=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 --- src/main/java/domain/dto/Operand.java | 15 +++++++ src/main/java/service/CalculatorService.java | 1 - src/test/java/domain/dto/OperandTest.java | 42 ++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/test/java/domain/dto/OperandTest.java diff --git a/src/main/java/domain/dto/Operand.java b/src/main/java/domain/dto/Operand.java index 31b4dc8..d9291e7 100644 --- a/src/main/java/domain/dto/Operand.java +++ b/src/main/java/domain/dto/Operand.java @@ -31,4 +31,19 @@ private void checkNegative(long parsedOperand) { throw new IllegalArgumentException(String.format("음수인 %d 값은 들어올 수 없습니다", parsedOperand)); } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Operand operand = (Operand) o; + + return value == operand.value; + } + + @Override + public int hashCode() { + return (int) (value ^ (value >>> 32)); + } } diff --git a/src/main/java/service/CalculatorService.java b/src/main/java/service/CalculatorService.java index e49b74e..99e2303 100644 --- a/src/main/java/service/CalculatorService.java +++ b/src/main/java/service/CalculatorService.java @@ -1,6 +1,5 @@ package service; -import com.sun.nio.sctp.IllegalReceiveException; import domain.Calculator; import support.Splitter; diff --git a/src/test/java/domain/dto/OperandTest.java b/src/test/java/domain/dto/OperandTest.java new file mode 100644 index 0000000..9edbde6 --- /dev/null +++ b/src/test/java/domain/dto/OperandTest.java @@ -0,0 +1,42 @@ +package domain.dto; + +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.stream.Stream; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +class OperandTest { + + @DisplayName("음수가 들어가면 익셉션을 던져준다") + @MethodSource("negativeAndString") + @ParameterizedTest + void negative(String input, String exceptionMessage){ + assertThatThrownBy(() -> new Operand(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(exceptionMessage); + } + + static Stream negativeAndString(){ + return Stream.of( + Arguments.of("-5", "음수인 -5 값은 들어올 수 없습니다"), + Arguments.of("abc", "abc 는 Long 형으로 파싱될 수 없습니다.") + ); + } + + @DisplayName("Operand 끼리 sum 정상 동작 수행 확인") + @Test + void sum(){ + Operand operand = new Operand("5"); + Operand operand1 = new Operand("1"); + + assertThat(operand.sum(operand1)).isEqualTo(new Operand("6")); + } + + +} \ No newline at end of file From 10cab209c56d52c315bb9d3e9635fffc1a607006 Mon Sep 17 00:00:00 2001 From: csbsjy Date: Sun, 1 Mar 2020 00:21:40 +0900 Subject: [PATCH 09/13] =?UTF-8?q?SplitTest=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/dto/OperandTest.java | 2 +- src/test/java/support/SplitterTest.java | 25 ++++++++--------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/test/java/domain/dto/OperandTest.java b/src/test/java/domain/dto/OperandTest.java index 9edbde6..9a73fdd 100644 --- a/src/test/java/domain/dto/OperandTest.java +++ b/src/test/java/domain/dto/OperandTest.java @@ -13,7 +13,7 @@ class OperandTest { - @DisplayName("음수가 들어가면 익셉션을 던져준다") + @DisplayName("음수나 문자가 들어가면 익셉션을 던져준다") @MethodSource("negativeAndString") @ParameterizedTest void negative(String input, String exceptionMessage){ diff --git a/src/test/java/support/SplitterTest.java b/src/test/java/support/SplitterTest.java index c221795..b77e209 100644 --- a/src/test/java/support/SplitterTest.java +++ b/src/test/java/support/SplitterTest.java @@ -51,29 +51,22 @@ static Stream customDelimiterFormat() { @DisplayName("// \n 사이에 구분자가 없을 때 에러를 던져주는 지") - @Test - void splitCustomDelimiterThrow(){ + @MethodSource("exceptionCase") + @ParameterizedTest + void splitCustomDelimiterThrow(String formula, String exceptionMessage){ //given - String formula = "//₩n1o2o3"; - //when //then assertThatThrownBy(() -> Splitter.split(formula)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage(String.format("%s 는(은) 올바르지 않은 커스텀구분자입니다.", "")); + .hasMessage(exceptionMessage); } - @DisplayName("// \n 사이에 구분자가 숫자일 때 에러를 던져주는 지") - @Test - void splitCustomDelimiterThrowIfNumeric(){ - //given - String formula = "//1₩n11213"; - - //when - //then - assertThatThrownBy(() -> Splitter.split(formula)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(String.format("%s 는(은) 올바르지 않은 커스텀구분자입니다.", 1)); + static Stream exceptionCase(){ + return Stream.of( + Arguments.of("//₩n1o2o3", " 는(은) 올바르지 않은 커스텀구분자입니다."), + Arguments.of("//1₩n11213", "1 는(은) 올바르지 않은 커스텀구분자입니다.") + ); } From 54ae35e0cd720587418a146a114f4244f0485e01 Mon Sep 17 00:00:00 2001 From: csbsjy Date: Mon, 2 Mar 2020 21:41:42 +0900 Subject: [PATCH 10/13] =?UTF-8?q?=EC=A0=95=EC=A0=81=20Util=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EB=8A=94=20=EA=B8=B0=EB=B3=B8=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=EB=A5=BC=20private=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=A7=89=EC=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/support/Splitter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/support/Splitter.java b/src/main/java/support/Splitter.java index 48ab8f0..b5a742c 100644 --- a/src/main/java/support/Splitter.java +++ b/src/main/java/support/Splitter.java @@ -15,6 +15,9 @@ public class Splitter { private final static Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.*)₩n(.*)"); + private Splitter() { + } + public static List split(final String formula) { Matcher customDelimiterMatcher = CUSTOM_DELIMITER_PATTERN.matcher(formula); From d14692392b81a1b1da8ded0b8bf4e50d75e9864c Mon Sep 17 00:00:00 2001 From: seojaeyeon Date: Wed, 4 Mar 2020 08:25:59 +0900 Subject: [PATCH 11/13] =?UTF-8?q?Splitter.split=20=EC=9D=84=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=A1=9C=20=EB=B9=BC=EC=A7=80=20=EC=95=8A=EC=95=84?= =?UTF-8?q?=EB=B3=B4=EC=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/service/CalculatorService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/service/CalculatorService.java b/src/main/java/service/CalculatorService.java index 99e2303..9516027 100644 --- a/src/main/java/service/CalculatorService.java +++ b/src/main/java/service/CalculatorService.java @@ -16,9 +16,8 @@ public long calculate(final String formula) { if (isNullOrEmpty(formula)) { return 0; } - List splitedFormula = Splitter.split(formula.trim()); - return calculator.calculate(splitedFormula); + return calculator.calculate(Splitter.split(formula.trim())); } private boolean isNullOrEmpty(String formula) { From 6070a64915095c4165eb376912ecbd9ace8b08cb Mon Sep 17 00:00:00 2001 From: seojaeyeon Date: Wed, 4 Mar 2020 14:26:57 +0900 Subject: [PATCH 12/13] =?UTF-8?q?1.=20Operand=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80,=20reduce=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=202.=20final=20static=20->=20static=20final?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Calculator.java | 3 +-- src/main/java/domain/dto/Operand.java | 15 +++++++++------ src/main/java/support/Splitter.java | 10 +++++----- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/java/domain/Calculator.java b/src/main/java/domain/Calculator.java index bc9aafd..838ad08 100644 --- a/src/main/java/domain/Calculator.java +++ b/src/main/java/domain/Calculator.java @@ -8,8 +8,7 @@ public class Calculator { public long calculate(List operands) { return operands.stream() .map(Operand::new) - .reduce(Operand::sum) - .orElseThrow(() -> new IllegalArgumentException("sum 할 수 있는 operand가 없습니다")) + .reduce(new Operand(), Operand::sum) .getValue(); } } diff --git a/src/main/java/domain/dto/Operand.java b/src/main/java/domain/dto/Operand.java index d9291e7..6c40d23 100644 --- a/src/main/java/domain/dto/Operand.java +++ b/src/main/java/domain/dto/Operand.java @@ -3,6 +3,10 @@ public class Operand { private final long value; + public Operand(){ + this.value = 0; + } + public Operand(final String operand) { try { long parsedOperand = Long.parseLong(operand); @@ -17,6 +21,11 @@ private Operand(long value) { this.value = value; } + private void checkNegative(long parsedOperand) { + if (parsedOperand < 0) { + throw new IllegalArgumentException(String.format("음수인 %d 값은 들어올 수 없습니다", parsedOperand)); + } + } public long getValue() { return this.value; @@ -26,12 +35,6 @@ public Operand sum(Operand operand) { return new Operand(this.value + operand.value); } - private void checkNegative(long parsedOperand) { - if (parsedOperand < 0) { - throw new IllegalArgumentException(String.format("음수인 %d 값은 들어올 수 없습니다", parsedOperand)); - } - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/support/Splitter.java b/src/main/java/support/Splitter.java index b5a742c..7cc4f58 100644 --- a/src/main/java/support/Splitter.java +++ b/src/main/java/support/Splitter.java @@ -7,13 +7,13 @@ public class Splitter { - private final static String DEFAULT_DELIMITER_REGEX = "[,:]"; - private final static String NUMERIC_REGEX = "-?\\d+(\\.\\d+)?"; + private static final String DEFAULT_DELIMITER_REGEX = "[,:]"; + private static final String NUMERIC_REGEX = "-?\\d+(\\.\\d+)?"; - private final static int CUSTOM_DELIMITER_INDEX = 1; - private final static int REAL_FORMULA_INDEX = 2; + private static final int CUSTOM_DELIMITER_INDEX = 1; + private static final int REAL_FORMULA_INDEX = 2; - private final static Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.*)₩n(.*)"); + private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.*)₩n(.*)"); private Splitter() { } From dfcaa891d7f19f6c4bc7a918791103082ca8bea1 Mon Sep 17 00:00:00 2001 From: seojaeyeon Date: Wed, 4 Mar 2020 15:59:54 +0900 Subject: [PATCH 13/13] =?UTF-8?q?@NullAndEmptySource=20=EB=A5=BC=20?= =?UTF-8?q?=EC=95=8C=EC=95=98=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/service/CalculatorServiceTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/test/java/service/CalculatorServiceTest.java b/src/test/java/service/CalculatorServiceTest.java index 2e73b2d..47cdb37 100644 --- a/src/test/java/service/CalculatorServiceTest.java +++ b/src/test/java/service/CalculatorServiceTest.java @@ -6,6 +6,7 @@ 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; @@ -60,12 +61,10 @@ static Stream invalidFormula() { } @DisplayName("빈 문자열 또는 null 값이 들어가면 0 을 반환해야 한다.") - @Test - void emptyNull() { - assertAll( - () -> assertThat(calculatorService.calculate("")).isEqualTo(0), - () -> assertThat(calculatorService.calculate(null)).isEqualTo(0) - ); + @ParameterizedTest + @NullAndEmptySource + void emptyNull(String formula) { + assertThat(calculatorService.calculate((formula))).isEqualTo(0); } }