Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3단계 - 테스트를 통한 코드 보호 #844

Merged
merged 86 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
b031e18
feat(racingcar): carNameRuleTest01-이름5글자
Dongock Jan 21, 2025
c3c20fd
feat(racingcar) : stop&movingTest
Dongock Jan 21, 2025
4406d32
feat(racingcar) : movingStrategyTest
Dongock Jan 21, 2025
840ad93
feat(cal): nullCheckTest
Jan 22, 2025
b204e91
refactor(cal): beforeEach add
Jan 22, 2025
64a8142
feat(cal): onlyNumberCheck
Dongock Jan 22, 2025
c146750
docs(cal) : README 요구사항 1번 정리
Dongock Jan 27, 2025
db97850
docs(cal) : README 요구사항 1번 정리(내용추가)
Dongock Jan 27, 2025
ffb2f89
refactor(cal) : StringUtils 제거
Dongock Jan 27, 2025
f99307c
refactor(cal) : `NullAndEmptySource`로 변경
Dongock Jan 27, 2025
1cc4d8c
feat(cal) : 숫자로 변환 가능하지 않은 문자 입력 시 예외 발생
Dongock Jan 27, 2025
199cd05
doc(cal) : 예외사항 추가
Dongock Jan 27, 2025
3fa268c
test(cal) : 구분자 검증 테스트 코드 추가
Dongock Jan 27, 2025
89fa384
feat(cal) : 구분자를 컴마(,) 이외에 콜론(:)을 사용할 수 있다.
Dongock Jan 27, 2025
881ba69
feat(cal) : "//"와 "\n" 문자 사이에 커스텀 구분자를 지정할 수 있다.
Dongock Jan 27, 2025
504f6b2
feat(cal) : 음수를 전달할 경우 RuntimeException 예외가 발생해야 한다.
Dongock Jan 27, 2025
9e4a0d5
refactor(cal) : 패턴 재사용 가능하게 축출 및 요구사항 정리
Dongock Jan 27, 2025
75b5ff4
refactor(cal) : Empty 체크 리팩토링
Dongock Jan 27, 2025
15f8e09
doc(cal) : 리팩토링을 위한 필요 정리 추가
Dongock Jan 27, 2025
572c43b
doc(cal) : 리팩토링을 위한 필요 정리 추가(Front Controller)
Dongock Jan 27, 2025
dc7a993
feat(cal) : EmptyCalculator 클래스 및 Test 추가
Dongock Jan 27, 2025
9d80278
feat(cal) : CustomCalculator 클래스 및 Test 추가
Dongock Jan 27, 2025
3800b42
feat(cal) : DefaultCalculator 클래스 및 Test 추가
Dongock Jan 27, 2025
c1b0273
refactor(cal) : frontController 패턴 적용
Dongock Jan 27, 2025
eb118f0
refactor(cal) : 클래스 이름 변경
Dongock Jan 27, 2025
3da5a4f
refactor(cal) : FeedBack 받은 부분 수정
Dongock Jan 29, 2025
bacb407
doc(force) : Product 요구사항 등록
Dongock Jan 29, 2025
c6aefa6
doc(force) : MenuGroup 요구사항 등록
Dongock Jan 29, 2025
b51a7e6
doc(force) : Menu 요구사항 등록
Dongock Jan 29, 2025
71cf69e
doc(force) : Order 요구사항 등록
Dongock Jan 29, 2025
845f4e1
doc(force) : OrderTable 요구사항 등록
Dongock Jan 29, 2025
59c6019
doc(force) : ERD 추가
Dongock Jan 29, 2025
4b51e15
doc(force) : 명칭 통일화_`정보` 제거
Dongock Jan 31, 2025
2238762
doc(force) : 상품 요구사항 구체적으로 변경
Dongock Jan 31, 2025
98b0fbd
doc(force) : 메뉴 모음 요구사항 구체적으로 변경
Dongock Jan 31, 2025
9fa2336
doc(force) : 메뉴 요구사항 구체적으로 변경
Dongock Jan 31, 2025
26a71b6
doc(force) : 주문 요구사항 구체적으로 변경
Dongock Jan 31, 2025
9e5d029
doc(force) : 매장 테이블 요구사항 구체적으로 변경
Dongock Jan 31, 2025
6579386
test(force) : ProductService Test 작성_create()
Dongock Feb 2, 2025
fc0e788
test(force) : ProductService Test 작성_minusPrice()
Dongock Feb 2, 2025
7d532c1
test(force) : ProductService Test 작성_nullName()
Dongock Feb 2, 2025
a2336cc
test(force) : ProductService Test 작성_nullPrice()
Dongock Feb 2, 2025
b284778
test(force) : ProductService Test 작성_hasProfanity()
Dongock Feb 2, 2025
7c1af64
test(force) : ProductService Test 작성_changePrice() & makeTestProduct …
Dongock Feb 2, 2025
11c0ee2
test(pos) : ProductService Test 작성_compareMenuPrice() & makeTestMenu …
Dongock Feb 5, 2025
dbefacc
refactor(pos) : TextFixture 구조 생성 및 테스트 객체 생성 메소드 위치 변경
Dongock Feb 5, 2025
3c4cdf7
test(pos) : MenuGroupServiceTest 생성 - create() 생성
Dongock Feb 5, 2025
267b08f
test(pos) : MenuGroupServiceTest - nullName() 생성
Dongock Feb 5, 2025
b1e5b41
test(pos) : MenuServiceTest - create() 생성
Dongock Feb 6, 2025
1b66912
test(pos) : MenuServiceTest - minusPrice() & noMenuInMenuGroup() 생성
Dongock Feb 6, 2025
3277f12
test(pos) : MenuServiceTest - noProductInMenu()
Dongock Feb 6, 2025
69ddc06
test(pos) : MenuServiceTest - noMenuProduct() 생성
Dongock Feb 6, 2025
f48490f
test(pos) : MenuServiceTest - hasProfanity() 생성
Dongock Feb 6, 2025
b26a63b
test(pos) : MenuServiceTest - changePrice() 생성
Dongock Feb 6, 2025
b41dc89
test(pos) : MenuServiceTest - compareMenuPrice() 생성
Dongock Feb 6, 2025
891c839
test(pos) : MenuServiceTest - display() 생성
Dongock Feb 6, 2025
be9745a
test(pos) : MenuServiceTest - hide() 생성
Dongock Feb 6, 2025
e7a2a43
refactor(pos) : ProductServiceTest - findAll() 제거
Dongock Feb 6, 2025
0915537
test(pos) : TextFixture - makeTestOrderTable() 생성
Dongock Feb 6, 2025
169dbe5
refactor(pos) : TextFixture - name 매개변수로 변경
Dongock Feb 6, 2025
0e8783e
test(pos) : OrderTableServiceTest - create() 생성
Dongock Feb 6, 2025
4058c3d
test(pos) : OrderTableServiceTest - nullName() 생성
Dongock Feb 6, 2025
788b51c
test(pos) : OrderTableServiceTest - sit() 생성
Dongock Feb 6, 2025
969689c
test(pos) : OrderTableServiceTest - clear() 생성
Dongock Feb 6, 2025
926b39f
refactor(pos) : TextFixture - makeTestOrderTable() 매개변수에 고객수 추가
Dongock Feb 6, 2025
47e6451
test(pos) : OrderTableServiceTest - changeNumberOfGuests() 생성
Dongock Feb 6, 2025
d02cb1a
test(pos) : TestFixture - makeTestEatInOrder() & makeTestTakeOutOrder…
Dongock Feb 6, 2025
fa4e993
test(pos) : TestFixture - makeTestOrderLineItem() 생성
Dongock Feb 6, 2025
f1fcef2
test(pos) : OrderServiceTest - OrderServiceTest 테스트 및createEatInOrder…
Dongock Feb 6, 2025
4252fe8
test(pos) : OrderServiceTest - createTakeOutOrder() 생성
Dongock Feb 6, 2025
17ec2b7
test(pos) : OrderServiceTest - createDeliveryOrder() 생성
Dongock Feb 6, 2025
678f914
test(pos) : OrderServiceTest - acceptEatInOrder() 생성
Dongock Feb 6, 2025
a6339fd
test(pos) : OrderServiceTest - acceptTakeOutOrder() 생성
Dongock Feb 6, 2025
01e69f7
test(pos) : OrderServiceTest - acceptDeliveryOrder() 생성
Dongock Feb 6, 2025
fd55e81
test(pos) : OrderServiceTest - serveEatInOrder() 생성
Dongock Feb 6, 2025
363a8a5
test(pos) : OrderServiceTest - serveTakeOutOrder() 생성
Dongock Feb 6, 2025
2fb4b30
test(pos) : OrderServiceTest - serveDeliveryOrder() 생성
Dongock Feb 6, 2025
ad32cdf
test(pos) : OrderServiceTest - startDelivery() 생성
Dongock Feb 6, 2025
b5517eb
test(pos) : OrderServiceTest - completeDelivery() 생성
Dongock Feb 6, 2025
afb1747
test(pos) : OrderServiceTest - completeEatInOrder() 생성
Dongock Feb 6, 2025
cec4f6e
test(pos) : OrderServiceTest - completeTakeOutOrder() 생성
Dongock Feb 6, 2025
5563b36
test(pos) : OrderServiceTest - completeDeliveryOrder() 생성
Dongock Feb 6, 2025
772cc02
refactor(pos) : MenuServiceTest - minusPrice() 경계값 테스트
Dongock Feb 9, 2025
d91afb6
refactor(pos) : MenuGroupServiceTest - nullName() Emtpy 추가
Dongock Feb 9, 2025
644d6c5
refactor(pos) : MenuGroupServiceTest - findAll 제거
Dongock Feb 9, 2025
621183d
refactor(pos) : MenuGroupServiceTest - hasProfanity() / FakePurgomalu…
Dongock Feb 9, 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
134 changes: 130 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,136 @@ docker compose -p kitchenpos up -d

## 요구 사항

## 용어 사전
- 가게에서 상품과 메뉴를 등록하고 이를 주문하는 키친 포스 시스템을 구현합니다.

| 한글명 | 영문명 | 설명 |
| --- | --- | --- |
| | | |
1. 상품
1) 상품을 등록할 수 있다.
- 상품가격은 0원 이상이어야 한다.
- 상품명은 외부 검증을 통해 욕설이나 외설성이 있으면 안된다.
- 상품명은 1글자 이상이어야 한다.
2) 상품의 가격은 변경이 가능하다.
- 상품가격은 0원 이상이어야 한다.
- 상품은 주인이 등록한 상품만 수정 가능하다.
- 메뉴에 있는 상품들의 가격의 총합이 메뉴의 전체 가격보다 낮으면 메뉴를 노출하지 않는다.
- 메뉴에 있는 상품 A의 가격이 5000원, 상품 B의 가격이 6000원이라면 메뉴의 전체 가격은 11000원 보다 초과하면 더 이상 메뉴를 노출하지 않는다.
3) 모든 상품을 조회할 수 있다.
- 등록된 메뉴가 하나도 없다면 조회했을 때 아무 것도 뜨지 않는다.

2. 메뉴 모음
1) 메뉴 모음을 등록할 수 있다.
- 메뉴 모음의 이름은 1글자 이상이어야 한다.
2) 모든 메뉴 모음을 조회할 수 있다.
- 등록된 메뉴 모음이 하나도 없다면 조회했을 때 아무 것도 뜨지 않는다.

3. 메뉴
1) 메뉴를 등록할 수 있다.
- 메뉴의 가격은 0원 이상이어야 한다.
- 메뉴 모음은 하나 이상의 메뉴로 구성되어야 한다.
- 메뉴는 하나 이상의 상품으로 구성되어 있다.
- 메뉴에 등록된 모든 상품은 이미 등록이 된 상품이어야 한다.
- 메뉴를 구성하는 상품과 수량은 등록할 수 있다.
- 메뉴의 전체 가격이 메뉴의 상품들의 전체 가격보다 크면 안된다.
- 메뉴에 있는 상품 A의 가격이 5000원, 상품 B의 가격이 6000원이라면 메뉴의 전체 가격은 11000원 보다 초과하면 안된다.
- 메뉴명은 1글자 이상이어야 한다.
2) 메뉴의 가격은 변경이 가능하다.
- 메뉴의 가격은 0원 이상이어야 한다.
- 주인이 등록한 메뉴의 가격만 수정이 가능하다.
- 메뉴에 등록된 상품들의 전체가격은 변경된 메뉴의 가격보다 크면 안된다.
- 메뉴에 있는 상품 A의 가격이 5000원, 상품 B의 가격이 6000원이라면 메뉴의 전체 가격을 11000보다 적게 하면 안된다.
3) 메뉴를 노출할 수 있다.
- 주인이 등록한 메뉴만 노출할 수 있다.
- 메뉴 상품들의 가격 합보다 메뉴 가격이 크면 메뉴를 노출할 수 없다.
- 메뉴에 있는 상품 A의 가격이 5000원, 상품 B의 가격이 6000원이라면 메뉴의 전체 가격이 11000보다 적으면 메뉴를 노출할 수 없다.
4) 메뉴를 노출하지 않을 수 있다.
- 주인이 등록한 메뉴만 노출하지 않을 수 있다.
5) 모든 메뉴를 조회할 수 있다.
- 등록된 메뉴가 하나도 없다면 조회했을 때 아무 것도 뜨지 않는다.

4. 주문
1) 매장 주문일 때
1. 주문을 등록할 수 있다.
- 주문 유형은 배달, 테이크아웃, 매장으로 세가지가 존재한다.
- 주문에는 구체적인 주문 항목들이 존재해야 한다.
- 주문 항목들에 있는 메뉴는 등록된 메뉴여야 한다.
- 메뉴의 전체 가격은 주문 항목들의 가격의 합과 같아야 한다.
- 1000원 짜리 상품 A를 2개, 2000원 짜리 상품 B로 구성된 메뉴를 주문했다면 가격은 4000원이어야 한다.
- 주문이 들어오면 주문은 대기상태이다.
- 주문 시간은 주문이 들어온 현재시간으로 한다.
- 매장에 사용 가능한 매장 테이블이 존재해야 한다.
2. 주문이 들어오면 주문을 수락할 수 있다.
- 주문이 들어와야 주문을 수락할 수 있다.
- 대기 상태인 주문만 수락이 가능하다.
3. 주문을 들어왔다면 메뉴를 준비한다.
- 주문이 들어와야 메뉴 준비가 가능하다.
- 주문이 수락됐다면 메뉴 준비 중으로 주문 상태가 변경된다.
4. 메뉴 준비가 끝나면 주문을 완료할 수 있다.
- 주문을 완료하고 매장 테이블이 사용 중이라면 테이블을 청소하고(사용 인원 초기화) 테이블을 사용 가능하도록 등록한다.
5. 모든 주문을 조회할 수 있다.
- 등록된 주문이 하나도 없다면 조회했을 때 아무 것도 뜨지 않는다.
2) 테이크 아웃 주문일 때
1. 주문을 등록할 수 있다.
- 주문 유형은 배달, 테이크아웃, 매장으로 세가지가 존재한다.
- 주문에는 구체적인 주문 항목들이 존재해야 한다.
- 주문 항목들에 있는 메뉴는 등록된 메뉴여야 한다.
- 메뉴의 전체 가격은 주문 항목들의 가격의 합과 같아야 한다.
- 1000원 짜리 상품 A를 2개, 2000원 짜리 상품 B로 구성된 메뉴를 주문했다면 가격은 4000원이어야 한다.
- 주문이 들어오면 주문은 대기상태이다.
- 주문 항목이 없으면 안된다.
2. 주문이 들어오면 주문을 수락할 수 있다.
- 주문이 들어와야 주문을 수락할 수 있다.
- 대기 상태인 주문만 수락이 가능하다.
3. 주문을 들어왔다면 메뉴를 준비한다.
- 주문이 들어와야 메뉴 준비가 가능하다.
- 주문이 수락됐다면 메뉴 준비 중으로 주문 상태가 변경된다.
4. 메뉴 준비가 끝나면 주문을 완료할 수 있다.
- 메뉴 준비가 끝났을 때 주문을 완료한다.
5. 모든 주문을 조회할 수 있다.
- 등록된 주문이 하나도 없다면 조회했을 때 아무 것도 뜨지 않는다.
3) 배달 주문일 때
1. 주문을 등록할 수 있다.
- 주문 유형은 배달, 테이크아웃, 매장으로 세가지가 존재한다.
- 주문에는 구체적인 주문 항목들이 존재해야 한다.
- 주문 항목들에 있는 메뉴는 등록된 메뉴여야 한다.
- 메뉴의 전체 가격은 주문 항목들의 가격의 합과 같아야 한다.
- 1000원 짜리 상품 A를 2개, 2000원 짜리 상품 B로 구성된 메뉴를 주문했다면 가격은 4000원이어야 한다.
- 주문이 들어오면 주문은 대기상태이다.
- 주문 항목이 없으면 안된다.
- 배달 주소가 없으면 배달을 할 수 없다.
2. 주문이 들어오면 주문을 수락할 수 있다.
- 주문이 들어와야 주문을 수락할 수 있다.
- 대기 상태인 주문만 수락이 가능하다.
- 배달 기사에게 배달을 요청하려면 배달 주소와 주문 항목들의 총 가격 등의 주문 정보가 필요하다.
- 배달 요청에 성공하면 주문 상태는 수락으로 변경된다.
3. 주문을 들어왔다면 메뉴를 준비한다.
- 주문이 들어와야 메뉴 준비가 가능하다.
- 주문이 수락됐다면 메뉴 준비 중으로 주문 상태가 변경된다.
4. 메뉴 준비가 끝나면 배달을 시작한다.
- 메뉴 준비가 끝나면 배달 중으로 주문 상태가 변경된다.
5. 배달 기사가 주문한 주소로 도착하면 배달이 완료된다.
- 배달 중에 배달이 완료됐다면 배달 완료됨으로 주문 상태가 변경된다.
6. 배달이 완료 됐다면 주문을 완료할 수 있다.
- 배달이 완료되면 주문을 완료한다.
7. 모든 주문을 조회할 수 있다.
- 등록된 주문이 하나도 없다면 조회했을 때 아무 것도 뜨지 않는다.

5. 매장 테이블
1) 매장 테이블은 등록이 가능하다.
- 매장 테이블의 이름은 1글자 이상이어야 한다.
- 매장 테이블의 사용 인원은 0명으로 등록한다.
- 매장 테이블은 등록할 때 사용이 가능한 상태이다.
2) 매장 테이블은 매장 방문 고객이 착석이 가능하다.
- 착석하고자 하는 매장 테이블은 등록이 된 테이블이어야 한다.
- 테이블에 고객이 착석한다면 사용 중으로 상태가 변경된다.
3) 매장 테이블은 청소가 가능하다.
- 청소하고자 하는 매장 테이블은 등록이 된 테이블이어야 한다.
- 고객이 주문을 완료했다면 매장 테이블을 청소하고(인원 초기화) 테이블 사용가능 상태로 변경한다.
4) 매장 테이블을 사용하는 인원은 늘어나거나 줄어들 수 있다.
- 매장 테이블을 이용하는 고객은 최소 1명 이상이어야 한다.
- 매장 테이블은 등록이 된 테이블이어야 한다.
- 이미 고객이 사용 중인 테이블은 고객이 늘어나거나 줄어들면 테이블의 사용 인원을 변경할 수 있다.
5) 모든 매장 테이블은 조회할 수 있다.
- 등록된 매장 테이블이 하나도 없다면 조회했을 때 아무 것도 뜨지 않는다.

## 모델링

![ERD_force.png](docs/ERD_force.png)
Binary file added docs/ERD_force.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 문자열 계산기 요구사항 분석

1. 문자열이 들어왔을 때 형식에 맞는지 확인
1) 문자열 : String, 외부에서 입력된 글자
2) 형식 : 구분자를 기준으로 양쪽에 숫자로 변환이 가능한 글자가 있는지
- 예외1 : 빈 문자나 Null 입력 시 0 반환
- 예외2 : 구분자가 없이 숫자 하나만 들어왔을 경우 숫자를 반환
- 예외3 : 숫자로 변환 가능하지 않은 문자가 들어왔을 시 예외 발생
- 예외4 : 시작과 마지막이 숫자가 아니라면 예외 발생
3) 구분자 : 현재는 ,와 :인데 특정 상황에서 커스터마이징한 구분자 추가가 가능함
- 문제 : 구분자가 한개가 아니라면 그 사이 빈문자는 0으로 처리
4) 특정 상황 : 구분자로 정의한 문자 앞뒤에 `//`와 `\n`가 붙어 있음`
- 예외 : 음수가 들어온다면 예외처리

2. 객체지향 필요 정리
1) Pattern은 무거우므로 재사용 가능하게 축출
2) 계산기의 역할이 너무 다양해지므로 관심사의 분리가 필요
- 구분자로 값을 처리하는 부분을 클래스 분리
- 예외 상황의 초기값이 들어왔을 때 처리를 클래스 분리
※ Front Controller
- input이 들어왔을 때 어떤 계산 방법을 선택해야 하는지 확인하고(canCalculate)
맞는 조건일 때 계산을 진행(sum)
47 changes: 47 additions & 0 deletions src/main/java/calculator/BaseSeparatorStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package calculator;

import java.util.Arrays;
import java.util.regex.Pattern;

public class BaseSeparatorStrategy implements CalculateStrategy {
private static final Pattern CUSTOM_SEPARATOR_PATTERN = Pattern.compile("//(.)\\\\n(.*)");
private static final String SEPARATOR = "[,:]";

// 이 클래스가 과연 필요한가?
@Override
public int calculate(String input) {
String[] splitInput = input.split(SEPARATOR);
return sum(splitInput);
}

@Override
public boolean canCalculate(String input) {
return !CUSTOM_SEPARATOR_PATTERN.matcher(input).find() && !input.isEmpty();
}

private int sum(String[] splitInput) {
return Arrays.stream(splitInput)
.mapToInt(this::convertToInt)
.sum();
}

private int convertToInt(String a) {
if (a.isEmpty()) {
return 0;
}
try {
return convertToPositiveNumber(a);
} catch (NumberFormatException e) {
throw new RuntimeException("숫자의 형태가 아닙니다.", e);
}

}

private int convertToPositiveNumber(String a) {
int number = Integer.parseInt(a);
if (number < 0) {
throw new IllegalArgumentException("음수는 들어올 수 없습니다.");
}
return number;
}
}
6 changes: 6 additions & 0 deletions src/main/java/calculator/CalculateStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package calculator;

public interface CalculateStrategy {
int calculate(String input);
boolean canCalculate(String input);
}
24 changes: 24 additions & 0 deletions src/main/java/calculator/Calculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package calculator;

import java.util.List;

public class Calculator {

private final List<CalculateStrategy> calculationStrategies;

public Calculator() {
this.calculationStrategies = List.of(
new NoSeparatorStrategy(),
new CustomSeparatorStrategy(),
new BaseSeparatorStrategy()
);
}

public int calculate(String input) {
return calculationStrategies.stream()
.filter(calculationStrategy -> calculationStrategy.canCalculate(input))
.findFirst()
.map(calculationStrategy -> calculationStrategy.calculate(input))
.orElseThrow(() -> new RuntimeException("알맞는 계산기를 찾지 못했습니다."));
}
}
53 changes: 53 additions & 0 deletions src/main/java/calculator/CustomSeparatorStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package calculator;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CustomSeparatorStrategy implements CalculateStrategy {
private static final Pattern CUSTOM_SEPARATOR_PATTERN = Pattern.compile("//(.)\\\\n(.*)");

@Override
public int calculate(String input) {
Matcher m = CUSTOM_SEPARATOR_PATTERN.matcher(input);

if (m.find()) { // find를 공통을 빼는 것?
String customDelimiter = m.group(1);
String[] splitInput = m.group(2).split(customDelimiter);
return sum(splitInput);
} else {
throw new RuntimeException("커스텀 구분자가 들어오지 않았습니다.");
}
}

@Override
public boolean canCalculate(String input) {
return CUSTOM_SEPARATOR_PATTERN.matcher(input).find();
}

private int sum(String[] splitInput) {
return Arrays.stream(splitInput)
.mapToInt(this::convertToInt)
.sum();
}

private int convertToInt(String a) {
if (a.isEmpty()) {
return 0;
}
try {
return convertToPositiveNumber(a);
} catch (NumberFormatException e) {
throw new RuntimeException("숫자의 형태가 아닙니다.", e);
}

}

private int convertToPositiveNumber(String a) {
int number = Integer.parseInt(a);
if (number < 0) {
throw new IllegalArgumentException("음수는 들어올 수 없습니다.");
}
return number;
}
}
17 changes: 17 additions & 0 deletions src/main/java/calculator/NoSeparatorStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package calculator;

public class NoSeparatorStrategy implements CalculateStrategy {
@Override
public int calculate(String input) {
return 0;
}

@Override
public boolean canCalculate(String input) {
return isEmpty(input);
}

private boolean isEmpty(String input) {
return input == null || input.isBlank();
}
}
19 changes: 19 additions & 0 deletions src/main/java/kitchenpos/infra/FakePurgomalumClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kitchenpos.infra;

import org.springframework.boot.web.client.RestTemplateBuilder;

import java.util.List;

public class FakePurgomalumClient extends PurgomalumClient {

private static final List<String> profanities = List.of("fuck", "shit");

public FakePurgomalumClient() {
super(new RestTemplateBuilder());
}

@Override
public boolean containsProfanity(final String text) {
return profanities.contains(text);
}
Comment on lines +7 to +18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍 💯

}
25 changes: 25 additions & 0 deletions src/main/java/racingcar/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package racingcar;

import java.util.Random;

public class Car {
private final String name;
private int position;

public Car(final String name) {
if (name.length() > 5) {
throw new IllegalArgumentException();
}
this.name = name;
}

public int getPosition() {
return position;
}

public void move(MovingStrategy movingStrategy) {
if (movingStrategy.movable()) {
position++;
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/racingcar/MovingStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package racingcar;

public interface MovingStrategy {
boolean movable();
}
Loading