From 81ad35febb67eecce074a48389a553568b096b11 Mon Sep 17 00:00:00 2001 From: woomin Date: Fri, 5 Jun 2020 20:56:16 +0900 Subject: [PATCH 1/2] Do Step1: method test --- src/test/java/empty.txt | 0 src/test/java/method/CharAtTest.java | 31 +++++++++++++++++ src/test/java/method/SetTest.java | 45 +++++++++++++++++++++++++ src/test/java/method/SplitTest.java | 19 +++++++++++ src/test/java/method/SubstringTest.java | 17 ++++++++++ 5 files changed, 112 insertions(+) delete mode 100644 src/test/java/empty.txt create mode 100644 src/test/java/method/CharAtTest.java create mode 100644 src/test/java/method/SetTest.java create mode 100644 src/test/java/method/SplitTest.java create mode 100644 src/test/java/method/SubstringTest.java diff --git a/src/test/java/empty.txt b/src/test/java/empty.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/java/method/CharAtTest.java b/src/test/java/method/CharAtTest.java new file mode 100644 index 0000000..671fcc4 --- /dev/null +++ b/src/test/java/method/CharAtTest.java @@ -0,0 +1,31 @@ +package method; + +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 static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CharAtTest { + @ParameterizedTest + @CsvSource(value = {"0:a", "1:b", "2:c"}, delimiter = ':') + @DisplayName("test charAt() with in of bound") + public void charAt(int input, char expected) { + String abc = "abc"; + assertEquals(expected, abc.charAt(input)); + } + + @Test + @DisplayName("test charAt() with out of bound") + public void charAtException() { + String abc = "abc"; + + assertThatThrownBy(() -> { + System.out.println(abc.charAt(3)); + }) + .isInstanceOf(IndexOutOfBoundsException.class) + .hasMessageContaining("String index out of range: 3"); + } +} diff --git a/src/test/java/method/SetTest.java b/src/test/java/method/SetTest.java new file mode 100644 index 0000000..0470634 --- /dev/null +++ b/src/test/java/method/SetTest.java @@ -0,0 +1,45 @@ +package method; + +import org.junit.jupiter.api.BeforeEach; +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 java.util.HashSet; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SetTest { + private Set numbers; + + @BeforeEach + void setUp() { + numbers = new HashSet<>(); + numbers.add(1); + numbers.add(1); + numbers.add(2); + numbers.add(3); + } + + @Test + @DisplayName("test size()") + public void size() { + assertThat(numbers.size()).isEqualTo(3); + } + + @ParameterizedTest + @CsvSource(value = { + "1:true", + "2:true", + "3:true", + "4:false", + "5:false", + }, delimiter = ':') + @DisplayName("test contains()") + public void contains(int input, boolean expected) { + assertEquals(expected, numbers.contains(input)); + } +} diff --git a/src/test/java/method/SplitTest.java b/src/test/java/method/SplitTest.java new file mode 100644 index 0000000..445538f --- /dev/null +++ b/src/test/java/method/SplitTest.java @@ -0,0 +1,19 @@ +package method; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +public class SplitTest { + @Test + @DisplayName("test split()") + public void splitTest() { + String testString = "1,2"; + String[] splitted = testString.split(","); + + assertThat(splitted).contains("1"); + assertThat(splitted).contains("2"); + assertThat(splitted).containsExactly("1", "2"); + } +} diff --git a/src/test/java/method/SubstringTest.java b/src/test/java/method/SubstringTest.java new file mode 100644 index 0000000..438b51c --- /dev/null +++ b/src/test/java/method/SubstringTest.java @@ -0,0 +1,17 @@ +package method; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SubstringTest { + @Test + @DisplayName("test substring()") + public void substringTest() { + String testString ="(1,2)"; + String testSubString = testString.substring(1, 4); + + assertThat(testSubString).isEqualTo("1,2"); + } +} From 4b97388832a59e12adef7383e3c8fb3dd4177aa4 Mon Sep 17 00:00:00 2001 From: woomin Date: Fri, 5 Jun 2020 21:06:28 +0900 Subject: [PATCH 2/2] Do Step2: calculator --- .../calculator/application/CalculatorApp.java | 25 +++++ .../java/calculator/domain/Calculator.java | 59 ++++++++++ .../java/calculator/domain/InputMachine.java | 20 ++++ .../java/calculator/domain/StringReader.java | 104 ++++++++++++++++++ .../java/calculator/view/ScreenMassage.java | 15 +++ src/main/java/empty.txt | 0 src/test/java/calculator/CalculatorTest.java | 40 +++++++ .../java/calculator/InputMachineTest.java | 28 +++++ .../java/calculator/StringReaderTest.java | 75 +++++++++++++ 9 files changed, 366 insertions(+) create mode 100644 src/main/java/calculator/application/CalculatorApp.java create mode 100644 src/main/java/calculator/domain/Calculator.java create mode 100644 src/main/java/calculator/domain/InputMachine.java create mode 100644 src/main/java/calculator/domain/StringReader.java create mode 100644 src/main/java/calculator/view/ScreenMassage.java delete mode 100644 src/main/java/empty.txt create mode 100644 src/test/java/calculator/CalculatorTest.java create mode 100644 src/test/java/calculator/InputMachineTest.java create mode 100644 src/test/java/calculator/StringReaderTest.java diff --git a/src/main/java/calculator/application/CalculatorApp.java b/src/main/java/calculator/application/CalculatorApp.java new file mode 100644 index 0000000..f70da0a --- /dev/null +++ b/src/main/java/calculator/application/CalculatorApp.java @@ -0,0 +1,25 @@ +package calculator.application; + +import calculator.domain.Calculator; +import calculator.domain.InputMachine; +import calculator.view.ScreenMassage; + +public class CalculatorApp { + public static void main(String[] args) { + InputMachine inputMachine = new InputMachine(); + Calculator calculator = new Calculator(); + ScreenMassage screen = new ScreenMassage(); + + screen.showMassage(); + + int answer = 0; + try { + String userInput = inputMachine.getUserInput(); + answer = calculator.getTotalCalculation(userInput); + } catch (Exception e) { + screen.showErrorMassage(e); + } + + screen.showResult(answer); + } +} diff --git a/src/main/java/calculator/domain/Calculator.java b/src/main/java/calculator/domain/Calculator.java new file mode 100644 index 0000000..e7baca0 --- /dev/null +++ b/src/main/java/calculator/domain/Calculator.java @@ -0,0 +1,59 @@ +package calculator.domain; + +public class Calculator { + public int getTotalCalculation(String arithmeticOperation) { + StringReader reader = new StringReader(); + + int[] numbers = reader.extractNumber(arithmeticOperation); + String[] operators = reader.extractOperator(arithmeticOperation); + + int answer = 0; + + for (int i = 0; i < operators.length; i += 1) { + if (operators[i].equals("+")) { + int value = this.add(numbers[i], numbers[i + 1]); + numbers[i + 1] = value; + answer = value; + continue; + } + + if (operators[i].equals("-")) { + int value = this.subtract(numbers[i], numbers[i + 1]); + numbers[i + 1] = value; + answer = value; + continue; + } + + if (operators[i].equals("*")) { + int value = this.multiply(numbers[i], numbers[i + 1]); + numbers[i + 1] = value; + answer = value; + continue; + } + + if (operators[i].equals("/")) { + int value = this.divide(numbers[i], numbers[i + 1]); + numbers[i + 1] = value; + answer = value; + } + } + + return answer; + } + + public int add(int a, int b) { + return a + b; + } + + public int subtract(int a, int b) { + return a - b; + } + + public int multiply(int a, int b) { + return a * b; + } + + public int divide(int a, int b) { + return a / b; + } +} diff --git a/src/main/java/calculator/domain/InputMachine.java b/src/main/java/calculator/domain/InputMachine.java new file mode 100644 index 0000000..cc9197b --- /dev/null +++ b/src/main/java/calculator/domain/InputMachine.java @@ -0,0 +1,20 @@ +package calculator.domain; + +import java.util.Scanner; + +public class InputMachine { + public String getUserInput() { + Scanner input = new Scanner(System.in); + String userInput = input.nextLine(); + + validateUserInput(userInput); + + return userInput; + } + + public void validateUserInput(String str) { + if (str == null || str == "") { + throw new IllegalArgumentException(); + } + } +} diff --git a/src/main/java/calculator/domain/StringReader.java b/src/main/java/calculator/domain/StringReader.java new file mode 100644 index 0000000..c5dc869 --- /dev/null +++ b/src/main/java/calculator/domain/StringReader.java @@ -0,0 +1,104 @@ +package calculator.domain; + +import java.util.*; +import java.util.regex.*; + +public class StringReader { + public int[] extractNumber(String str) { + if (this.checkWeird(str)) { + throw new IllegalArgumentException(); + } + + String[] arr = str.split(" "); + + removeUnnecessaryParts(arr); + ArrayList pureNumbers = convertArrayToArrayList(arr); + ArrayList result = considerBracket(pureNumbers); + + return extractNumbersFromBracket(result); + } + + public String[] extractOperator(String str) { + if (this.checkWeird(str)) { + throw new IllegalArgumentException(); + } + + String[] arr = str.split(" "); + + ArrayList pureOperators = convertArrayToArrayList(arr); + Object[] objOperators = pureOperators.stream() + .filter(v -> Pattern.matches("[\\*\\-\\+\\/]", v)) + .toArray(); + + return convertObjectArrayToStringArray(objOperators); + } + + public boolean checkWeird(String str) { + String weirds = str.replaceAll("[0-9\\+\\-\\*\\/\\' '\\(\\)]", ""); + return weirds.length() > 0; + } + + private void removeUnnecessaryParts(String[] arr) { + for (int i = 0; i < arr.length; i += 1) { + arr[i] = arr[i].replaceAll("[^0-9\\-\\(\\)]", ""); + } + } + + private ArrayList convertArrayToArrayList(String[] arr) { + ArrayList arrayList = new ArrayList<>(); + + for (String e : arr) { + arrayList.add(e); + } + + return arrayList; + } + + private String[] convertObjectArrayToStringArray(Object[] objArr) { + String[] strArr = new String[objArr.length]; + + int index = 0; + for (Object operator: objArr) { + strArr[index] = operator.toString(); + index += 1; + } + + return strArr; + } + + private ArrayList considerBracket(ArrayList arrayList) { + ArrayList result = new ArrayList<>(); + + for (int i = 0; i < arrayList.size(); i += 1) { + String e = arrayList.get(i); + if (e.length() > 0 && e.charAt(0) == '(') { + result.add(e); + continue; + } + + if (Pattern.matches("[0-9]{1,}", e)) { + result.add(e); + } + } + + return result; + } + + private int[] extractNumbersFromBracket(ArrayList arrayList) { + int[] answer = new int[arrayList.size()]; + + for (int i = 0; i < answer.length; i += 1) { + String e = arrayList.get(i); + + if (e.charAt(0) == '(') { + String substr = e.substring(1, e.length() - 1); + answer[i] = Integer.parseInt(substr); + continue; + } + + answer[i] = Integer.parseInt(e); + } + + return answer; + } +} diff --git a/src/main/java/calculator/view/ScreenMassage.java b/src/main/java/calculator/view/ScreenMassage.java new file mode 100644 index 0000000..c583175 --- /dev/null +++ b/src/main/java/calculator/view/ScreenMassage.java @@ -0,0 +1,15 @@ +package calculator.view; + +public class ScreenMassage { + public void showMassage() { + System.out.println("수식을 입력해주세요. 계산은 제가 합니다 ㅋ"); + } + + public void showResult(int result) { + System.out.printf("답은 %d 입니다.", result); + } + + public void showErrorMassage(Exception e) { + System.out.println(e); + } +} diff --git a/src/main/java/empty.txt b/src/main/java/empty.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/java/calculator/CalculatorTest.java b/src/test/java/calculator/CalculatorTest.java new file mode 100644 index 0000000..72f8b3d --- /dev/null +++ b/src/test/java/calculator/CalculatorTest.java @@ -0,0 +1,40 @@ +package calculator; + +import calculator.domain.Calculator; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("Calculator") +public class CalculatorTest { + Calculator calculator = new Calculator(); + + @Test + @DisplayName("add") + public void add() { + assertThat(calculator.add(1, 1)).isEqualTo(2); + assertThat(calculator.add(-1, 1)).isEqualTo(0); + } + + @Test + @DisplayName("subtract") + public void subtract() { + assertThat(calculator.subtract(1, 1)).isEqualTo(0); + assertThat(calculator.subtract(-1, 1)).isEqualTo(-2); + } + + @Test + @DisplayName("multiply") + public void multiply() { + assertThat(calculator.multiply(2, 2)).isEqualTo(4); + assertThat(calculator.multiply(-2, 5)).isEqualTo(-10); + } + + @Test + @DisplayName("divide") + public void divide() { + assertThat(calculator.divide(6, 2)).isEqualTo(3); + assertThat(calculator.divide(3, 2)).isEqualTo(1); + } +} diff --git a/src/test/java/calculator/InputMachineTest.java b/src/test/java/calculator/InputMachineTest.java new file mode 100644 index 0000000..5849b10 --- /dev/null +++ b/src/test/java/calculator/InputMachineTest.java @@ -0,0 +1,28 @@ +package calculator; + +import calculator.domain.InputMachine; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayName("InputMachine") +public class InputMachineTest { + @Test + @DisplayName("validateUserInput") + public void validateUserInput() { + InputMachine inputMachine = new InputMachine(); + + assertThatThrownBy(() -> { + inputMachine.validateUserInput(""); + }) + .isInstanceOf(IllegalArgumentException.class) + .hasToString("java.lang.IllegalArgumentException"); + + assertThatThrownBy(() -> { + inputMachine.validateUserInput(null); + }) + .isInstanceOf(IllegalArgumentException.class) + .hasToString("java.lang.IllegalArgumentException"); + } +} diff --git a/src/test/java/calculator/StringReaderTest.java b/src/test/java/calculator/StringReaderTest.java new file mode 100644 index 0000000..496df41 --- /dev/null +++ b/src/test/java/calculator/StringReaderTest.java @@ -0,0 +1,75 @@ +package calculator; + +import calculator.domain.StringReader; +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 static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayName("StringReader") +public class StringReaderTest { + @Test + @DisplayName("extractNumber") + public void extractNumber() { + StringReader stringReader = new StringReader(); + + String input1 = "1 + 2 * 3"; + int[] expected1= {1, 2, 3}; + assertThat(stringReader.extractNumber(input1)).isEqualTo(expected1); + + String input2 = "11 - 2 * 3 + 2"; + int[] expected2 = {11, 2, 3, 2}; + assertThat(stringReader.extractNumber(input2)).isEqualTo(expected2); + + String input3 = "(-2) * (-3) + (-10)"; + int[] expected3 = {-2, -3, -10}; + assertThat(stringReader.extractNumber(input3)).isEqualTo(expected3); + + String input4 = "1 & 3 + 5"; + assertThatThrownBy(() -> { + stringReader.extractNumber(input4); + }) + .hasToString("java.lang.IllegalArgumentException") + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("extractOperator") + public void extractOperator() { + StringReader stringReader = new StringReader(); + + String input1 = "1 + 2 * 3"; + String[] expected1= {"+", "*"}; + assertThat(stringReader.extractOperator(input1)).isEqualTo(expected1); + + String input2 = "11 - 2 * 3 + 2"; + String[] expected2 = {"-", "*", "+"}; + assertThat(stringReader.extractOperator(input2)).isEqualTo(expected2); + + String input3 = "(-2) * 3 + 4"; + String[] expected3 = {"*", "+"}; + assertThat(stringReader.extractOperator(input3)).isEqualTo(expected3); + + String input4 = "1 & 3 + 5"; + assertThatThrownBy(() -> { + stringReader.extractNumber(input4); + }) + .hasToString("java.lang.IllegalArgumentException") + .isInstanceOf(IllegalArgumentException.class); + } + + @ParameterizedTest + @CsvSource(value = { + "1 + 2 * 3, false", + "4 # 2 * 3, true", + }) + @DisplayName("checkWeird") + public void checkWeird(String input, boolean expected) { + StringReader stringReader = new StringReader(); + + assertThat(stringReader.checkWeird(input)).isEqualTo(expected); + } +}