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

[로또] 박진효 미션 제출합니다. #646

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
dba0ed5
docs: README.md 생성
jinmidnight01 Nov 8, 2023
faad6d9
style: eslint(airbnb), prettier 설치 및 적용
jinmidnight01 Nov 8, 2023
8d8126b
feat(views): 구입금액 입력
jinmidnight01 Nov 8, 2023
fa9526b
docs: README.md에서 '사용자'를 '구매자'로 변경
jinmidnight01 Nov 8, 2023
08195b5
feat(models): 구매자 정보 class에 '구입 금액' 필드 구현
jinmidnight01 Nov 8, 2023
c4ef024
refactor(views): getLottoPrice 함수에 개행문자 추가
jinmidnight01 Nov 8, 2023
c7c7bd5
docs: README에 테스트 목록 추가
jinmidnight01 Nov 8, 2023
acb8d82
refactor(views): InputView 클래스에서 객체리터럴 방식으로 재구조화
jinmidnight01 Nov 8, 2023
c357414
test: 구입 금액에 공백이 없는지
jinmidnight01 Nov 8, 2023
dcc00f0
feat(constants): 구입 금액 공백이 있는 경우 예외처리
jinmidnight01 Nov 8, 2023
e4bdcf5
test(LottoPrice): 구입 금액이 숫자 타입이 맞는지
jinmidnight01 Nov 8, 2023
1795c7a
feat(validations): 구입 금액이 숫자가 아닌 경우 예외 처리
jinmidnight01 Nov 8, 2023
f273978
test: 구입 금액이 0원보다 큰 금액인지
jinmidnight01 Nov 8, 2023
525e5d7
feat(validations): 구입 금액이 0원 이하일 경우 예외 처리
jinmidnight01 Nov 8, 2023
add7431
test: 구입 금액이 1000원 단위인지
jinmidnight01 Nov 8, 2023
09a8640
feat(validations): 구입 금액이 1000원 단위가 아닐 경우 예외 처리
jinmidnight01 Nov 8, 2023
cf3f8b1
feat(views): OutputView에서 로또 개수 출력 구현
jinmidnight01 Nov 8, 2023
dce8024
feat(controllers): 구매자가 소유할 로또 번호 목록 생성
jinmidnight01 Nov 8, 2023
9693137
feat(models): 구매자 정보에서 소유한 로또 번호 목록 필드 추가
jinmidnight01 Nov 8, 2023
5789b19
feat(views): 출력창에 구매자 로또 번호 출력
jinmidnight01 Nov 8, 2023
52925a9
test: 사용자 로또 번호 목록이 전부 숫자가 맞는지
jinmidnight01 Nov 8, 2023
ba0d318
test: 사용자 로또 번호 목록이 전부 1~45 사이의 숫자인지
jinmidnight01 Nov 8, 2023
87d48fb
feat(validations): 숫자가 1~45 사이의 숫자가 아닐 경우 예외처리
jinmidnight01 Nov 8, 2023
de2d4ed
test: 사용자 로또 번호가 소수점이 없는지
jinmidnight01 Nov 8, 2023
dff1739
test: 사용자 로또 번호 목록 테스트
jinmidnight01 Nov 8, 2023
a1bbf14
feat(develop): 최종 커밋
jinmidnight01 Nov 8, 2023
302c9e3
test: 사용자 로또 번호 목록이 랜덤으로 생성되는지
jinmidnight01 Nov 9, 2023
ee3c0c6
feat(views): 입력창에서 당첨번호/보너스 번호 입력 기능 추가
jinmidnight01 Nov 9, 2023
432355f
feat(models): 사용자 로또 번호 목록 예외처리
jinmidnight01 Nov 9, 2023
2c25433
feat(Lotto): 로또 당첨 번호 예외처리 기능 구현
jinmidnight01 Nov 9, 2023
9c35508
test: 당첨 번호 테스트 구현 완료
jinmidnight01 Nov 9, 2023
4037b4c
feat(models): 로또 정보 class에 보너스 번호 필드와 예외처리 기능 추가
jinmidnight01 Nov 9, 2023
d67f313
test: 보너스 번호 테스트
jinmidnight01 Nov 9, 2023
4ac54dc
feat: Error 발생시 직전 입력창으로 이동
jinmidnight01 Nov 9, 2023
03f66d5
feat(controllers): 당첨 내역 연산 기능 구현
jinmidnight01 Nov 9, 2023
e11a094
test: 로또 개수 테스트
jinmidnight01 Nov 9, 2023
7544a44
feat(views): OutputView에서 당첨 통계 제목 및 내역 출력
jinmidnight01 Nov 9, 2023
c3c0a14
feat(controllers): 당첨 결과(수익률) 계산 기능 구현
jinmidnight01 Nov 9, 2023
1f5383c
test: 수익률 테스트
jinmidnight01 Nov 9, 2023
0bf449b
feat(views): OutputView 수익률 출력 기능 구현
jinmidnight01 Nov 9, 2023
4f0422a
docs: 주석 추가
jinmidnight01 Nov 9, 2023
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
35 changes: 35 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module.exports = {
env: {
browser: true,
commonjs: true,
es2021: true,
node: true,
jest: true,
},
extends: ['airbnb-base', 'prettier'],
overrides: [
{
env: {
node: true,
},
files: [
'.eslintrc.{js,cjs}',
],
parserOptions: {
sourceType: 'script',
},
},
],
parserOptions: {
ecmaVersion: 'latest',
},
rules: {
'import/prefer-default-export': 'off',
'import/extensions': ['off'],
'class-methods-use-this': 'off',
'no-unused-vars': 'off',
'no-await-in-loop': 'off',
'no-constant-condition': 'off',
'no-param-reassign': 'off',
},
};
12 changes: 12 additions & 0 deletions .prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: 'all',
bracketSpacing: true,
arrowParens: 'avoid',
proseWrap: 'never',
endOfLine: 'auto',
};
42 changes: 42 additions & 0 deletions __tests__/BonusNumberTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Validations from '../src/Validations.js';
import Lotto from '../src/Lotto.js';
import LottoTotal from '../src/models/LottoTotal.js';

const mockLotto = new Lotto([1,2,3,4,5,6])

describe('보너스 번호 테스트', () => {
test.each([['10 00', ' 2000 ', ' 30 000']])('공백이 없는지', bonusNumber => {
expect(() => {
// eslint-disable-next-line no-new
new LottoTotal(mockLotto, bonusNumber);
}).toThrow('[ERROR] 공백 없이 입력해 주세요.');
});

test.each([['1000s', '2s000', 's30000', '']])('숫자가 맞는지', bonusNumber => {
expect(() => {
// eslint-disable-next-line no-new
new LottoTotal(mockLotto, bonusNumber);
}).toThrow('[ERROR] 숫자만 입력해 주세요.');
});

test.each([['0', '-10', '455']])('1~45 사이의 숫자가 맞는지', bonusNumber => {
expect(() => {
// eslint-disable-next-line no-new
new LottoTotal(mockLotto, bonusNumber);
}).toThrow('[ERROR] 1~45 사이의 숫자만 입력해주세요.');
});

test.each([['15.1', '12.2', '6.3']])('소수점이 없는지', bonusNumber => {
expect(() => {
// eslint-disable-next-line no-new
new LottoTotal(mockLotto, bonusNumber);
}).toThrow('[ERROR] 정수만 입력해주세요.');
});

test.each([['1', '2', '3']])('당첨 번호와 중복되지 않는지', bonusNumber => {
expect(() => {
// eslint-disable-next-line no-new
new LottoTotal(mockLotto, bonusNumber);
}).toThrow('[ERROR] 보너스 번호는 당첨 번호와 중복될 수 없습니다.');
});
});
124 changes: 124 additions & 0 deletions __tests__/CustomerNumbersTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { MissionUtils } from '@woowacourse/mission-utils';
import Validations from '../src/Validations.js';
import LottoGameController from '../src/controllers/LottoGameController.js';

const mockRandoms = numbers => {
MissionUtils.Random.pickUniqueNumbersInRange = jest.fn();
numbers.reduce(
(acc, number) => acc.mockReturnValueOnce(number),
MissionUtils.Random.pickUniqueNumbersInRange,
);
};

describe('사용자 로또 번호 목록 테스트', () => {
test.each([
[[1, 2, 'e', 4, 5, 6]],
[['s', 3, 5, 7, 8]],
[['', ' ', '', ' ', '', 'ff']],
])('숫자가 맞는지', lottoNumbers => {
mockRandoms(lottoNumbers);

LottoGameController.generateCustomerNumbers(lottoNumbers).forEach(
lottoNumber => {
expect(() => {
lottoNumber.forEach(number => {
Validations.isNumber(number);
});
}).toThrow('[ERROR] 숫자만 입력해 주세요.');
},
);
});

test.each([[[1, 2, 3, 4, 5, 6, 56]], [[60, 59, 58, 57]], [[0, 3, 5]]])(
'1~45 사이의 숫자가 맞는지',
lottoNumbers => {
mockRandoms(lottoNumbers);

LottoGameController.generateCustomerNumbers(lottoNumbers).forEach(
lottoNumber => {
expect(() => {
lottoNumber.forEach(number => {
Validations.isInRange(number);
});
}).toThrow('[ERROR] 1~45 사이의 숫자만 입력해주세요.');
},
);
},
);

test.each([[[1, 2, 3, 4.5, 33]], [[40, 39.1, 43]], [[2, 3, 5.3]]])(
'소수점이 없는지',
lottoNumbers => {
mockRandoms(lottoNumbers);

LottoGameController.generateCustomerNumbers(lottoNumbers).forEach(
lottoNumber => {
expect(() => {
lottoNumber.forEach(number => {
Validations.isInteger(number);
});
}).toThrow('[ERROR] 정수만 입력해주세요.');
},
);
},
);

test.each([[[1, 2, 3, 3, 4]], [[40, 39, 39]], [[1, 5, 5]]])(
'중복된 숫자가 없는지',
lottoNumbers => {
mockRandoms(lottoNumbers);

LottoGameController.generateCustomerNumbers(lottoNumbers).forEach(
lottoNumber => {
expect(() => {
Validations.isNotDuplicated(lottoNumber);
}).toThrow('[ERROR] 중복된 숫자가 없이 입력해주세요.');
},
);
},
);

test.each([[[1, 2, 3, 3, 4]], [[40, 39, 38]], [[1, 5, 4]]])(
'6개인지',
lottoNumbers => {
mockRandoms(lottoNumbers);

LottoGameController.generateCustomerNumbers(lottoNumbers).forEach(
lottoNumber => {
expect(() => {
Validations.isProperLength(lottoNumber);
}).toThrow('[ERROR] 길이가 6이어야 합니다.');
},
);
},
);

test.each([[[1, 2, 3, 5, 4]], [[40, 39, 38, 37, 36]], [[1, 5, 4, 3, 6]]])(
'오름차순으로 정렬되어 있는지',
lottoNumbers => {
mockRandoms(lottoNumbers);

LottoGameController.generateCustomerNumbers(lottoNumbers).forEach(
lottoNumber => {
expect(() => {
Validations.isSorted(lottoNumber);
}).toThrow('ERROR] 오름차순으로 정렬되어 있어야 합니다.');
},
);
},
);

test.each([
[[1, 2, 3, 5, 6, 9]],
[[5, 7, 9, 11, 13, 17]],
[[7, 8, 40, 41, 42, 43]],
])('랜덤으로 생성되는지', lottoNumbers => {
mockRandoms(lottoNumbers);

LottoGameController.generateCustomerNumbers(lottoNumbers).forEach(
lottoNumber => {
expect(lottoNumber).toEqual(lottoNumbers);
},
);
});
});
27 changes: 27 additions & 0 deletions __tests__/LottoPriceTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Validations from '../src/Validations.js';

describe('구입 금액 테스트', () => {
test.each([['10 00', ' 2000 ', ' 30 000']])('공백이 없는지', lottoPrice => {
expect(() => {
Validations.hasSpace(lottoPrice);
}).toThrow('[ERROR] 공백 없이 입력해 주세요.');
});

test.each([['1000s', '2s000', 's30000', '']])('숫자가 맞는지', lottoPrice => {
expect(() => {
Validations.isNumber(lottoPrice);
}).toThrow('[ERROR] 숫자만 입력해 주세요.');
});

test.each([['0', '-1000', '-1']])('0원 보다 큰 금액인지', lottoPrice => {
expect(() => {
Validations.isPlus(lottoPrice);
}).toThrow('[ERROR] 양수만 입력해 주세요.');
});

test.each([['1500', '1200', '200001']])('1000원 단위인지', lottoPrice => {
expect(() => {
Validations.isThousandUnit(lottoPrice);
}).toThrow('[ERROR] 1000원 단위로만 입력해주세요.');
});
});
81 changes: 75 additions & 6 deletions __tests__/LottoTest.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,87 @@
import Lotto from "../src/Lotto.js";
import { MissionUtils } from '@woowacourse/mission-utils';
import Lotto from '../src/Lotto.js';
import Validations from '../src/Validations.js';

describe("로또 클래스 테스트", () => {
test("로또 번호의 개수가 6개가 넘어가면 예외가 발생한다.", () => {
const mockRandoms = numbers => {
MissionUtils.Random.pickUniqueNumbersInRange = jest.fn();
numbers.reduce(
(acc, number) => acc.mockReturnValueOnce(number),
MissionUtils.Random.pickUniqueNumbersInRange,
);
};

describe('로또 클래스 테스트', () => {
test('로또 번호의 개수가 6개가 넘어가면 예외가 발생한다.', () => {
expect(() => {
// eslint-disable-next-line no-new
new Lotto([1, 2, 3, 4, 5, 6, 7]);
}).toThrow("[ERROR]");
}).toThrow('[ERROR]');
});

// TODO: 이 테스트가 통과할 수 있게 구현 코드 작성
test("로또 번호에 중복된 숫자가 있으면 예외가 발생한다.", () => {
test('로또 번호에 중복된 숫자가 있으면 예외가 발생한다.', () => {
expect(() => {
// eslint-disable-next-line no-new
new Lotto([1, 2, 3, 4, 5, 5]);
}).toThrow("[ERROR]");
}).toThrow('[ERROR]');
});

// 아래에 추가 테스트 작성 가능
test.each([[['1000s', '2s000', 's30000', '']], [['s', 1, 30]]])(
'숫자가 맞는지',
winningNumbers => {
expect(() => {
// eslint-disable-next-line no-new
new Lotto(winningNumbers);
}).toThrow('[ERROR] 숫자만 입력해 주세요.');
},
);

test.each([[[1, 2, 3, 4, 5, 6, 56]], [[60, 59, 58, 57]], [[0, 3, 5]]])(
'1~45 사이의 숫자가 맞는지',
winningNumbers => {
mockRandoms(winningNumbers);

expect(() => {
// eslint-disable-next-line no-new
new Lotto(winningNumbers);
}).toThrow('[ERROR] 1~45 사이의 숫자만 입력해주세요.');
},
);

test.each([[[1, 2, 3, 4, 5, 6, 7.5]], [[44, 43, 42, 37.4]], [[2, 3, 20.1]]])(
'소수점이 없는지',
winningNumbers => {
mockRandoms(winningNumbers);

expect(() => {
// eslint-disable-next-line no-new
new Lotto(winningNumbers);
}).toThrow('[ERROR] 정수만 입력해주세요.');
},
);

test.each([[[1, 2, 3, 4, 5, 5]], [[44, 43, 42, 42]], [[2, 20, 20]]])(
'중복된 숫자가 없는지',
winningNumbers => {
mockRandoms(winningNumbers);

expect(() => {
// eslint-disable-next-line no-new
new Lotto(winningNumbers);
}).toThrow('[ERROR] 중복된 숫자가 없이 입력해주세요.');
},
);

test.each([[[1, 2, 3, 4, 5, 7, 8]], [[42, 43, 41, 4]], [[3, 33, 2, 35]]])(
'6개인지',
winningNumbers => {
mockRandoms(winningNumbers);

expect(() => {
// eslint-disable-next-line no-new
new Lotto(winningNumbers);
}).toThrow('[ERROR] 길이가 6이어야 합니다.');
},
);
});
Loading