Skip to content

Commit

Permalink
[1단계 - 콘솔 기반 로또 게임] 윤생(이윤성) 미션 제출합니다. (#173)
Browse files Browse the repository at this point in the history
* docs: 요구사항 목록 작성

Co-authored-by: 2yunseong<dbsdltjd3701@naver.com>

* feat: 콘솔 인터페이스 구현

Co-authored-by: 2yunseong<dbsdltjd3701@naver.com>

* feat: 입/출력 UI 로직 작성

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* test: Lotto 클래스 테스트 추가

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: Lotto 클래스 구현

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* test: validation 유틸 함수 테스트 추가

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: validation 유틸 함수 구현

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: RandomGenerator 구현

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: WinningLotto 클래스 구현

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: LottoMachine 클래스 구현

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: LottoController 클래스 구현

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: App 구현

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: validation 추가

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* test: 메서드 변경에 따른 테스트 수정

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* feat: 도메인 로직 변경에 따른 OutputView 수정

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* docs: 완료한 기능 체크

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* chore: eslint 및 prettier 설정

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: validation 메서드 추출

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: 에러 메세지 상수화

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: 매직넘버 제거

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: 당첨 통계 계산 책임을 LottoMachine에게 위임

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: 재사용을 위해 static 메서드로 변경

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: 등수 판별 로직 추출

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: OutputView 리터럴 상수화

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: 커맨드 상수화

Co-authored-by: 2yunseong <dbsdltjd3701@naver.com>

* refactor: 에러 메세지 상수화

* refactor: 에러 출력 부분 메서드로 분리

* refactor: 사용하지 않는 변수 제거

* refactor: 리터럴 변수 상수화

* fix: 잘못된 파라미터 사용 변경

* test: jest에서 제공하는 메서드 이용

- toBe => toBeTruthy, toBeFalsy

* chore: 주석 변경

* refactor: random Generator 범용성을 위한 로또만을 위한 로직 분리

* refactor: 범용적으로 쓰이는 상수 static에서 분리

* refactor: 매직넘버 상수화

* refactor: 범용적으로 쓰이는 상수 static에서 분리

* refactor: 메서드 축약 및 일부 로직 메서드로 분리

* refactor: InputView 에러 핸들링 변경

* refactor: 필요없는 로직 제거

---------

Co-authored-by: cruelladevil <dev.timetravel@gmail.com>
  • Loading branch information
2yunseong and cruelladevil authored Feb 19, 2023
1 parent 0f097b0 commit 0980cd3
Show file tree
Hide file tree
Showing 20 changed files with 7,839 additions and 3,415 deletions.
28 changes: 24 additions & 4 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
{
"rules": {},
"env": {
"es6": true,
"node": true
"node": true,
"jest": true
},
"extends": [
"eslint:recommended",
"airbnb-base",
"plugin:prettier/recommended",
"eslint-config-prettier"
],
"parserOptions": {
"ecmaVersion": "latest"
"ecmaVersion": "latest",
"sourceType": "module"
},
"extends": ["eslint:recommended", "plugin:prettier/recommended"]
"rules": {
"max-depth": ["error", 1],
"max-params": ["error", 2],
"max-lines-per-function": ["error", 10],
"lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }]
},
"overrides": [
{
"files": ["__tests__/**/*.js"],
"rules": {
"max-lines-per-function": "off"
}
}
]
}
10 changes: 9 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
{
"endOfLine": "auto"
"endOfLine": "auto",
"semi": true,
"bracketSpacing": true,
"trailingComma": "all",
"useTabs": false,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"arrowParens": "always"
}
38 changes: 38 additions & 0 deletions __tests__/Lotto.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Lotto from '../src/domain/Lotto';

describe('Lotto 클래스 입니다.', () => {
test.each([
[
[6, 5, 4, 3, 2, 1],
[1, 2, 3, 4, 5, 6],
],
[
[7, 6, 5, 3, 2, 1],
[1, 2, 3, 5, 6, 7],
],
])('로또 배열을 정렬한다.', (numbers, expected) => {
const lotto = new Lotto(numbers);
expect(lotto.getNumbers()).toEqual(expected);
});

test('보너스 번호를 가지고 있으면 true를 반환한다.', () => {
const lotto = new Lotto([1, 2, 3, 4, 5, 6]);
const bonusBall = 5;

expect(lotto.hasBonus(bonusBall)).toBeTruthy();
});

test('보너스 번호를 가지고 있지 않으면 false를 반환한다.', () => {
const lotto = new Lotto([1, 2, 3, 4, 5, 6]);
const bonusBall = 10;

expect(lotto.hasBonus(bonusBall)).toBeFalsy();
});

test('로또 번호가 당첨 번호와 비교해 일치하는 갯수를 반환한다.', () => {
const lotto = new Lotto([1, 2, 3, 4, 5, 6]);
const winLotto = new Lotto([4, 5, 6, 9, 10, 11]);

expect(lotto.countMatch(winLotto)).toBe(3);
});
});
18 changes: 18 additions & 0 deletions __tests__/validation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { isPositiveInteger, isValidRestartCommand } from '../src/validation';

describe('유효성 검증 테스트입니다.', () => {
test.each([1.11, null, undefined, 'string', {}])(
'양의 정수가 아니면 false를 반환한다.',
(value) => {
expect(isPositiveInteger(Number(value))).toBeFalsy();
},
);

test.each(['y', 'n'])('재시작 입력에서 y와 n를 받으면 true를 반환한다.', (input) => {
expect(isValidRestartCommand(input)).toBeTruthy();
});

test.each([1, '1'])('재시작 입력에서 y와 n인 아닌 입력을 받으면 false를 반환한다.', (input) => {
expect(isValidRestartCommand(input)).toBeFalsy();
});
});
54 changes: 54 additions & 0 deletions docs/REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## 기능 요구 사항

- [x] 구입 금액을 입력 받는다. - view
- [x] 구입 금액 유효성 검사 - domain
- [x] 로또를 발행한다. - domain
- [x] 한 장당 가격 - domain
- [x] 구매한 갯수 출력 - view
- [x] 구매한 로또들을 오름차순 정렬한다. - domain
- [x] 구매한 로또들을 출력한다. - view
- [x] 당첨 번호를 입력 받는다. - view
- [x] 당첨 번호 유효성 검사(중복, 범위) - domain
- [x] 보너스 번호를 입력 받는다. - view
- [x] 당첨 번호를 포함하여 유효성을 검사한다. - domain
- [x] 로또 당첨 통계를 계산한다. - domain
- [x] 로또 당첨 등수를 계산한다. - domain
- [ ] 당첨 등수에 따른 당첨금을 계산한다. - domain
- [ ] 수익률을 계산한다. - domain
- [x] 재시작 여부를 입력 받는다. - view
- [x] 재시작 입력에 대한 유효성을 검사한다. - view? controller? 등 domain 외부
- [x] 재시작할 경우 구입 금액 입력부터 게임을 다시 시작한다. - domain
- [x] 종료하는 경우 그대로 프로그램을 종료시킨다. - domain
- [x] 사용자가 잘못된 값을 입력한 경우 throw문을 사용해 예외를 발생시킨다. - domain/view 나뉨
- [x] 에러 메시지를 출력한다. - view
- [x] 해당 부분부터 입력을 다시 받는다. - ?

## 프로그래밍 요구 사항

### 로또 미션 프로그래밍 요구 사항

- 변수 선언시 const 만 사용한다.
- 함수(또는 메서드)의 들여쓰기 depth는 1단계까지만 허용한다.
- 함수의 매개변수는 2개 이하여야 한다.
- 함수에서 부수 효과를 분리하고, 가능한 순수 함수를 많이 활용한다.
- 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.
- 모든 기능을 TDD로 구현하는 것을 시도하여, 테스트 할 수 있는 도메인 로직에 대해서는 모두 단위 테스트가 존재해야 한다. (단, UI 로직은 제외)
- 로또 번호와 당첨 로또 번호의 유효성 검사시 발생하는 중복 코드를 제거해야 한다.
- 클래스(또는 객체)를 사용하는 경우, 프로퍼티를 외부에서 직접 꺼내지 않는다. 객체에 메시지를 보내도록 한다.

### 자동차 경주 미션 프로그래밍 요구 사항을 포함

- 코드 스타일 가이드(airbnb)에 따라 컨벤션을 준수하며 개발한다.
- ~~변수 선언시 var를 사용하지 않는다. let, const를 사용한다.~~
- 전역 변수를 만들지 않는다.
- 축약하지 않는다.
- 하드 코딩된 값 대신에 의미 있는 상수를 활용한다.
- 동등 연산자는 === 로만 사용한다.
- 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다.
- 함수(또는 메서드)가 한 가지 일만 하도록 만든다.
- ~~함수(또는 메서드)의 들여쓰기 depth는 2단계까지만 허용한다.~~
- ~~예를 들어 while문 안에 if문이 있으면 depth는 2단계 이다.~~
- 힌트) 함수(또는 메서드) 분리는 들여쓰기 depth를 줄이는 좋은 방법이다.
- else 예약어를 쓰지 않는다.
- 도메인 로직과 UI 로직을 분리한다.
- 모든 도메인 로직에 단위 테스트를 구현한다. (UI 로직은 제외)
Loading

0 comments on commit 0980cd3

Please sign in to comment.