Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
fd88d68
docs: README.md에 구현할 기능 목록 추가
hj-66 Oct 18, 2025
c7e5709
feat: 문자열 입/출력 문구 생성
hj-66 Oct 18, 2025
8ea8e00
feat: 문자열 입력 기능 추가
hj-66 Oct 18, 2025
4f132da
feat: 기본 구분자와 커스텀 구분자를 이용한 문자열 분리
hj-66 Oct 18, 2025
affc0b7
feat: 문자열이 비어있을 시 0을 출력시키기 위해 빈 배열 반환
hj-66 Oct 18, 2025
2205a10
feat: 'reduce'를 사용하여 분리된 숫자들을 모두 더함
hj-66 Oct 18, 2025
4535006
feat: 'Console.print()'로 결과 출력 기능 추가
hj-66 Oct 18, 2025
b9f39c3
docs: README.md에 ERROR 검출 상황 추가
hj-66 Oct 19, 2025
39ccac2
feat: 에러 메시지 상수 추가
hj-66 Oct 19, 2025
92f12eb
feat: Error 구분 함수 추가
hj-66 Oct 19, 2025
7cf9a47
feat: 에러 처리 함수 적용
hj-66 Oct 20, 2025
7f54ea1
feat: 구분자를 여러글자로 설정 가능하도록 함수 변경
hj-66 Oct 20, 2025
3bfebe8
refactor: import 부분 따옴표, 줄바꿈 수정
hj-66 Oct 20, 2025
9b86442
refactor: 결과 출력 부분 템플릿 리터럴 사용
hj-66 Oct 20, 2025
9a41e45
refactor: calculateSum() 함수 간결화와 중간변수 제거
hj-66 Oct 20, 2025
23c2f88
refactor: 함수명 변경 및 공통기능을 새 함수로 묶음
hj-66 Oct 20, 2025
7410a6d
refactor: 함수 선언방식 변경
hj-66 Oct 20, 2025
4493446
refactor: 불필요한 변수 제거
hj-66 Oct 20, 2025
8efb93d
refactor: validateIsNumber if문 변수로 할당
hj-66 Oct 20, 2025
c55ed7f
refactor: validateCustomDelimiterSyntax if문 구조 변경
hj-66 Oct 20, 2025
b08492e
refactor: constants.js 메시지 변수 이름 변경 및 적용
hj-66 Oct 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,38 @@
# javascript-calculator-precourse
# javascript-calculator-precourse

# 구현할 기능 목록

## 문자 입력받기

- `Console.readLineAsync("문자열을 입력해 주세요")`로 문자열 받기
- 문자열이 비어있을 시 0 반환

<br>

## 숫자 추출을 위한 문자열 분리

- `,`와 `:`을 이용하여 문자열을 분리
- `//`와 `\n` 사이의 문자를 커스텀 구분자로 지정
- 커스텀 구분자를 이용하여 문자열을 분리

<br>

## 덧셈 하기

- `reduce`를 이용하여 분리된 숫자들을 모두 더함

<br>

## 결과 반환

- `Console.print()`로 결과 출력

<br>

## ERROR 검출

- `[ERROR]`로 시작하는 메시지와 함께 Error 발생 후 애플리케이션 종료
- 구분자가 아닌 다른 문자가 있는 경우 Error 발생
- 분리된 문자열의 문자가 숫자가 아닌경우 Error 발생
- 커스텀 구분자 지정 시 `\n`이 빠진 경우 Error 발생
- 커스텀 구분자 지정 시 문자가 아닌 경우 Error 발생
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 48 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,52 @@
import { Console } from '@woowacourse/mission-utils';
import { MESSAGES } from './constants.js';
import {
validateAllowedCharacters,
validateCustomDelimiterSyntax,
validateIsNumber,
} from './validation.js';

class App {
async run() {}
async run() {
try {
await this.getInput();
const numbers = this.parseInputToNumbers();
const sum = this.calculateSum(numbers);
Console.print(`${MESSAGES.OUTPUT.OUTPUT_RESULT}${sum}`);
} catch (error) {
throw error;
}
}

async getInput() {
this.input = await Console.readLineAsync(MESSAGES.INPUT.INPUT_STRING);
}

parseInputToNumbers() {
if (!this.input) return [];

const customDelimiter = validateCustomDelimiterSyntax(this.input);

if (customDelimiter) {
const numbersPart = this.input.split('\\n')[1];
validateAllowedCharacters(numbersPart, customDelimiter);
return this.convertToNumberArray(numbersPart.split(customDelimiter));
}

validateAllowedCharacters(this.input);
return this.convertToNumberArray(this.input.split(/,|:/));
}

convertToNumberArray(values) {
return values.map((value) => {
validateIsNumber(value);
return parseInt(value, 10);
});
}

calculateSum(numbers) {
return numbers.reduce((sum, value) => sum + value, 0);
}
}

export default App;
16 changes: 16 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const MESSAGES = {
INPUT: {
INPUT_STRING: `덧셈할 문자열을 입력해 주세요.\n`,
},

OUTPUT: {
OUTPUT_RESULT: `결과 : `,
},

ERROR: {
CUSTOM_ERROR_MESSAGE: `[ERROR] 커스텀 구분자 지정에 실패했습니다.`,
CUSTOM_SETTING_ERROR_MESSAGE: `[ERROR] 커스텀 구분자 지정 형식이 잘못되었습니다.`,
CHARACTER_ERROR_MESSAGE: `[ERROR] 구분자가 아닌 다른 문자가 있습니다.`,
NUMBER_ERROR_MESSAGE: `[ERROR] 숫자를 입력해 주세요.`,
},
};
44 changes: 44 additions & 0 deletions src/validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { MESSAGES } from './constants.js';

export const validateAllowedCharacters = (numbersPart, customDelimiter) => {
const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const pattern = customDelimiter
? new RegExp(`[^0-9${escapeRegex(customDelimiter)}]`)
: /[^0-9,:]/;

if (pattern.test(numbersPart)) {
throw new Error(MESSAGES.ERROR.CHARACTER_ERROR_MESSAGE);
}
}

export const validateIsNumber = (str) => {
const isValidNumber = /^\d+$/.test(str);
if (!isValidNumber) {
throw new Error(MESSAGES.ERROR.NUMBER_ERROR_MESSAGE);
}
}

export const validateCustomDelimiterSyntax = (input) => {
const hasCustomDelimiter = input.startsWith("//");
if (!hasCustomDelimiter) return null;

const hasNewLine = input.includes("\\n");
if (!hasNewLine) {
throw new Error(MESSAGES.ERROR.CUSTOM_SETTING_ERROR_MESSAGE);
}

const [delimiterPart] = input.split("\\n");
const match = /^\/\/(.+)$/.exec(delimiterPart);

if (!match) {
throw new Error(MESSAGES.ERROR.CUSTOM_SETTING_ERROR_MESSAGE);
}

const delimiter = match[1];

if (/^\d+$/.test(delimiter)) {
throw new Error(MESSAGES.ERROR.CUSTOM_ERROR_MESSAGE);
}

return delimiter;
}