From 408aeb63984dd6a66bf62fdd1b2a8724e8dce10a Mon Sep 17 00:00:00 2001
From: bo-10000 <seot100@naver.com>
Date: Mon, 24 Mar 2025 21:12:08 +0900
Subject: [PATCH] =?UTF-8?q?feat:=20step1=20=EC=9A=94=EA=B5=AC=EC=82=AC?=
 =?UTF-8?q?=ED=95=AD=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/Calculator.java     | 37 +++++++++++++++++++++
 src/main/java/Operand.java        | 42 ++++++++++++++++++++++++
 src/test/java/CalculatorTest.java | 54 +++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 src/main/java/Calculator.java
 create mode 100644 src/main/java/Operand.java
 create mode 100644 src/test/java/CalculatorTest.java

diff --git a/src/main/java/Calculator.java b/src/main/java/Calculator.java
new file mode 100644
index 00000000000..fb245c51852
--- /dev/null
+++ b/src/main/java/Calculator.java
@@ -0,0 +1,37 @@
+public class Calculator {
+    private static void validate_input(String expression) {
+        if (expression == null || expression.isBlank()) {
+            throw new IllegalArgumentException("입력 값이 null이거나 빈 공백 문자입니다.");
+        }
+    }
+
+    private static int updateResult(int result, Operand operand, int number) {
+        if (operand == null) {
+            return number;
+        } 
+        else {
+            return operand.operate(result, number);
+        }
+    }
+
+    public static int run(String expression) {
+        validate_input(expression);
+
+        int result = 0;
+        Operand operand = null;
+
+        String[] tokens = expression.split(" ");
+        for (int i = 0; i < tokens.length; i++) {
+            String t = tokens[i];
+            if (i % 2 == 0) {
+                int number = Integer.parseInt(t);
+                result = updateResult(result, operand, number);
+            }
+            else {
+                operand = new Operand(t);
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/src/main/java/Operand.java b/src/main/java/Operand.java
new file mode 100644
index 00000000000..6f826053f2b
--- /dev/null
+++ b/src/main/java/Operand.java
@@ -0,0 +1,42 @@
+class Operand {
+    private final String VALUE;
+
+    Operand(String value) {
+        this.VALUE = value;
+    }
+
+    private int sum(int num1, int num2) {
+        return num1 + num2;
+    }
+
+    private int subtract(int num1, int num2) {
+        return num1 - num2;
+    }
+
+    private int multiply(int num1, int num2) {
+        return num1 * num2;
+    }
+
+    private int divide(int num1, int num2) {
+        return num1 / num2;
+    }
+
+    int operate(int num1, int num2) {
+        if (VALUE.equals("+")) {
+            return sum(num1, num2);
+        } 
+        else if (VALUE.equals("-")) {
+            return subtract(num1, num2);
+        } 
+        else if (VALUE.equals("*")) {
+            return multiply(num1, num2);
+        } 
+        else if (VALUE.equals("/")) {
+            return divide(num1, num2);
+        } 
+        else {
+            throw new IllegalArgumentException("지원하지 않는 연산자입니다.");
+        }
+    }
+
+}
diff --git a/src/test/java/CalculatorTest.java b/src/test/java/CalculatorTest.java
new file mode 100644
index 00000000000..bc85237b630
--- /dev/null
+++ b/src/test/java/CalculatorTest.java
@@ -0,0 +1,54 @@
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+public class CalculatorTest {
+    @DisplayName("덧셈 테스트")
+    @Test
+    void addTest() {
+        int result = Calculator.run("2 + 3");
+        assertEquals(5, result);
+    }
+
+    @DisplayName("뺄셈 테스트")
+    @Test
+    void subtractTest() {
+        int result = Calculator.run("5 - 3");
+        assertEquals(2, result);
+    }
+
+    @DisplayName("곱셈 테스트")
+    @Test
+    void multiplyTest() {
+        int result = Calculator.run("2 * 3");
+        assertEquals(6, result);
+    }
+
+    @DisplayName("나눗셈 테스트")
+    @Test
+    void divideTest() {
+        int result = Calculator.run("6 / 3");
+        assertEquals(2, result);
+    }
+
+    @DisplayName("입력 값이 null이거나 빈 공백 문자일 경우")
+    @ParameterizedTest
+    @ValueSource(strings = {"", " "})
+    void nullOrEmptyTest() {
+        assertThatIllegalArgumentException().isThrownBy(() -> {
+            Calculator.run(null);
+        }).withMessage("입력 값이 null이거나 빈 공백 문자입니다.");
+    }
+
+    @DisplayName("지원하지 않는 연산자일 경우")
+    @Test
+    void invalidOperatorTest() {
+        assertThatIllegalArgumentException().isThrownBy(() -> {
+            Calculator.run("2 % 3");
+        }).withMessage("지원하지 않는 연산자입니다.");
+    }
+}