책/자바 웹 프로그래밍 next step

실습 1 문자열 계산기

함께자라기 2022. 3. 22. 21:08

실습 1 문자열 계산기


요구사항

  • 쉼표 또는 콜론을 구분자로 가지는 문자열을 전달 받으면 구분자를 기준으로 분리한 각 숫자의 합을 반환한다
ex) "1,2" = 3 , "1,2,3" = 6 ...
  • 공백이 들어오면 0이 반환 되어야 한다
ex) "" = 0
  • 커스텀 구분자를 지정 가능하다(//와\n 사이의 문자) 커스텀 구분자를 기준으로 분리한 각 숫자의 합도 반환 가능해야한다
ex) "//;\n1;2;3" = 6
  • 음수가 입력되는 경우 RuntimeException으로 예외 처리

추가 요구사항

  • 메서드가 한 가지 책임만을 가지도록 한다
  • 인덴트(indent , 들여쓰기) 깊이를 1단계로 유지한다
while 문과 if문을 사용할 경우 인덴트 깊이가 1씩 증가한다

아래 예제는 인덴트가 2다

while (true) {
    if (true) {

    }
}
  • else를 사용하지 마라

프로덕션 코드


public class StringCalculator {

    //string 배열을 int 배열로 변환
    int[] stringArrayConvertIntArray(String[] strArray) {
        return Arrays.stream(strArray).mapToInt(Integer::parseInt).toArray();
    }

    //더하기
    int sum(int[] intArray) {
        return Arrays.stream(intArray).sum();
    }

    //음수 체크
    void chkNegativeNumber(int intVal) {
        if (intVal < 0) {
            throw new RuntimeException("Runtime Exception");
        }
    }

    //공백 체크
    boolean emptyChk(String str) {
        String inputStr = str.replace(" ","");
        if ("".equals(inputStr) || inputStr.isEmpty()) {
            return true;
        }
        return false;
    }

    //문자열 자르기
    String[] stringSplit(String str) {
        Pattern pattern = Pattern.compile("[/][/](.*?)[\n]");
        Matcher matcher = pattern.matcher(str);

        // 커스텀 태그
        while (matcher.find()) {
            return str.replaceAll("[/][/](.*?)[\n]","").split(matcher.group(1));
        }

        return str.split(",|:");
    }

    //문자열 더하기
    int stringCalAdd(String str) {
        if (emptyChk(str)) {
            return 0;
        }

        String[] resultArray = stringSplit(str);
        int[] intArray = stringArrayConvertIntArray(resultArray);

        for (int val : intArray) {
            chkNegativeNumber(val);
        }

        return sum(intArray);
    }
}

테스트 코드


public class StringCalculatorTest {

    private StringCalculator stringCalculator;

    @BeforeEach
    void setUp() {
        stringCalculator = new StringCalculator();
    }

    @Test
    void emptyChk() {
        assertTrue(stringCalculator.emptyChk(""),"Exception");
        assertTrue(stringCalculator.emptyChk(" "),"Exception");
        assertFalse(stringCalculator.emptyChk("1"),"Exception");
    }

    @Test
    void stringSplit() {
        String[] strArray = new String[3];
        strArray[0] = "1";
        strArray[1] = "2";
        strArray[2] = "3";

        assertArrayEquals(strArray,stringCalculator.stringSplit("1,2:3"));
        assertArrayEquals(strArray,stringCalculator.stringSplit("//;\n1;2;3"));
    }

    @Test
    void stringArrayConvertIntArray() {
        int[] intArray = new int[3];
        intArray[0] = 1;
        intArray[1] = 2;
        intArray[2] = 3;

        String[] strArray = new String[3];
        strArray[0] = "1";
        strArray[1] = "2";
        strArray[2] = "3";

        assertArrayEquals(intArray, stringCalculator.stringArrayConvertIntArray(strArray));
    }

    @Test
    void chkNegativeNumber() {
        Exception exception = assertThrows(RuntimeException.class, () -> {
            stringCalculator.chkNegativeNumber(-10);
        });

        String exceptionMsg = exception.getMessage();

        assertTrue(exceptionMsg.contains("Runtime Exception"));
    }

    @Test
    void sum() {
        int[] intArray = new int[2];
        intArray[0] = 1;
        intArray[1] = 2;
        assertEquals(3,stringCalculator.sum(intArray));
    }

    @Test
    void stringCalAdd() {
        assertEquals(6,stringCalculator.stringCalAdd("1,2:3"));
        assertEquals(0,stringCalculator.stringCalAdd(""));
        assertEquals(0,stringCalculator.stringCalAdd(" "));
        assertEquals(6,stringCalculator.stringCalAdd("//;\n1;2;3"));
    }
}

간단한 요구 사항이었지만 테스트 코드를 짜는게 익숙하지 않아 생각보다 시간이 많이 걸렸다
음수를 체크하는 부분은 더 개선 할 수 있을거 같은데 아직 잘 모르겠다