Skip to content

Commit

Permalink
[2단계 - 행운의 로또 미션] 곤이(김기융) 미션 제출합니다. (#40)
Browse files Browse the repository at this point in the history
* refactor: refactoring for feedbacks
- rename file (camelCase)
- dependency injection
- DOM selector (class -> id, dataset)
- form tag event
- private field

* feat: add test case
- test valid winning numbers

* docs: update function list
- check winning numbers

* docs: update function list, test cases
- render winning result
- reset

* refactor: custom DOM library
- remove Parentnode

* feat: update validator
- check winning numbers

* feat: add earning rate calculator

* feat: add render winning result

* feat: add reset

* feat: add test cases
- check modal
- check reset

* refactor: refactoring
- change earning rate

* refactor: step2 feedbacks

* fix: add 'throw new Error' in Custom DOM library

* feat: add memoize function

* refactor: delete console.log

Co-authored-by: Kyle <mkitigy@gmail.com>
  • Loading branch information
yungo1846 and igy95 authored Mar 1, 2021
1 parent e04ff2f commit 55dedb7
Show file tree
Hide file tree
Showing 22 changed files with 525 additions and 142 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ module.exports = {
require('os').EOL === '\r\n' ? 'windows' : 'unix',
],
'prettier/prettier': ['error', { endOfLine: 'auto' }],
parser: 'babel-eslint',
},
};
5 changes: 3 additions & 2 deletions .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"printWidth": 80,
"printWidth": 120,
"trailingComma": "es5",
"arrowParens": "avoid",
"bracketSpacing": true,
"endOfLine": "lf"
}
}
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@

### 🎯🎯 step2 당첨 결과 기능

- [ ] 결과 확인하기 버튼을 누르면 당첨 통계, 수익률을 모달로 확인할 수 있다.
- [ ] 로또 당첨 금액은 고정되어 있는 것으로 가정한다.
- [ ] 다시 시작하기 버튼을 누르면 초기화 되서 다시 구매를 시작할 수 있다.
- [x] 결과 확인하기 버튼을 누르면 당첨 통계, 수익률을 모달로 확인할 수 있다.
- [x] 로또 당첨 금액은 고정되어 있는 것으로 가정한다.
- [x] 다시 시작하기 버튼을 누르면 초기화 되서 다시 구매를 시작할 수 있다.

### 🎯🎯🎯 step3 수동 구매

Expand All @@ -57,15 +57,15 @@

### step2

- [ ] 당첨번호와 보너스 번호를 인풋으로 받는다.
- [ ] 당첨번호와 보너스 번호는 중복되서는 안된다.
- [ ] 당첨번호와 보너스 번호는 1 ~ 45
- [ ] 결과 확인하기 버튼을 눌렀을 때의 다음과 같은 기능을 수행한다.
- [ ] 당첨번호와 보너스 번호의 유효성을 검사한다.
- [ ] 구입한 로또 번호와 일치하는 당첨번호의 개수를 확인한다.
- [ ] 당첨금액을 합산하여 수익률을 계산한다.
- [ ] 당첨 통계, 수익률을 확인할 수 있는 모달을 띄운다.
- [ ] 다시 시작하기 버튼을 클릭한 경우 초기화 한다.
- [x] 당첨번호와 보너스 번호를 인풋으로 받는다.
- [x] 당첨번호와 보너스 번호는 중복되서는 안된다.
- [x] 당첨번호와 보너스 번호는 1 ~ 45
- [x] 결과 확인하기 버튼을 눌렀을 때의 다음과 같은 기능을 수행한다.
- [x] 당첨번호와 보너스 번호의 유효성을 검사한다.
- [x] 구입한 로또 번호와 일치하는 당첨번호의 개수를 확인한다.
- [x] 당첨금액을 합산하여 수익률을 계산한다.
- [x] 당첨 통계, 수익률을 확인할 수 있는 모달을 띄운다.
- [x] 다시 시작하기 버튼을 클릭한 경우 초기화 한다.

<br>

Expand All @@ -75,9 +75,9 @@
- [x] 몫은 양의 정수값, 나머지는 0인 값을 받는다.
- [x] 구입 금액을 입력한 뒤 버튼을 클릭했을 때, 알맞은 개수의 로또를 렌더링한다.
- [x] 토글 버튼을 클릭했을 때, 모든 복권 번호를 렌더링한다.
- [ ] 적절한 당첨 번호를 입력 받는다.
- [ ] 중복된 숫자를 입력받지 않는다.
- [ ] 1 ~ 45의 숫자를 입력 받는다.
- [ ] 결과 확인하기 버튼을 누르면 모달을 확인할 수 있다.
- [x] 적절한 당첨 번호를 입력 받는다.
- [x] 중복된 숫자를 입력받지 않는다.
- [x] 1 ~ 45의 숫자를 입력 받는다.
- [x] 결과 확인하기 버튼을 누르면 모달을 확인할 수 있다.
- [ ] 당첨 통계가 정확한지 확인한다. (TDD)
- [ ] 다시 시작하기 버튼을 누르면 초기화 된다.
- [x] 다시 시작하기 버튼을 누르면 초기화 된다.
56 changes: 46 additions & 10 deletions cypress/integration/lotto.spec.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
import { testInputValue } from '../utils/index.js';
import { MSG_INVALID_PURCHASE_AMOUNT } from '../../src/js/constants/index.js';
import {
MSG_INVALID_PURCHASE_AMOUNT,
MSG_DUPLICATED_LOTTO_NUMBERS,
MSG_OUT_RANGED_LOTTO_NUMBERS,
MSG_BLANK_INPUT,
} from '../../src/js/constants/index.js';
import { typeInputValue } from '../utils/testInputValue.js';

describe('Lotto test', () => {
before(() => {
cy.visit('http://127.0.0.1:5500');
});

it('구입 금액은 단위 금액의 양의 배수 값을 갖는다.', () => {
const invalidValues = ['-1000', '0', '1500', '1000.1'];
const invalidValues = ['-1000', '0', '1500', '1000.1', ''];
const input = '#purchase-amount-input';
const button = '#purchase-amount-submit';

invalidValues.forEach(invalidValue => {
testInputValue(
'#purchase-amount-input',
'#purchase-amount-submit',
invalidValue,
MSG_INVALID_PURCHASE_AMOUNT
);
typeInputValue(input, invalidValue);
testInputValue(button, MSG_INVALID_PURCHASE_AMOUNT);
});
testInputValue('#purchase-amount-input', '#purchase-amount-submit', '5000');
typeInputValue(input, '5000');
testInputValue(button);
});

it('구입 금액 입력 뒤 버튼을 클릭했을 때, 알맞은 개수의 로또를 렌더링한다.', () => {
Expand All @@ -35,9 +40,40 @@ describe('Lotto test', () => {
for (let idx = 0; idx < count; idx++) {
cy.get('.lotto-wrapper') //
.eq(idx)
.children('.lotto-numbers')
.children('span[data-lotto-numbers]')
.should(toggleOption === 'on' ? 'be.visible' : 'not.be.visible');
}
}
});

it('부적절한 당첨 번호를 검사한다. (중복)', () => {
testWinnigNumbers(['1', '2', '3', '4', '5', '5', '45'], MSG_DUPLICATED_LOTTO_NUMBERS);
});

it('부적절한 당첨 번호를 검사한다. (범위 밖)', () => {
testWinnigNumbers(['0', '2', '3', '4', '5', '6', '46'], MSG_OUT_RANGED_LOTTO_NUMBERS);
});

it('부적절한 당첨 번호를 검사한다. (미입력)', () => {
testWinnigNumbers(['1', '2', '3', '', '5', '6', '45'], MSG_BLANK_INPUT);
});

it('적절한 당첨 번호를 입력 받아 결과를 모달창으로 띄운다.', () => {
testWinnigNumbers(['1', '2', '3', '4', '5', '6', '45']);
cy.get('#modal').should('be.visible');
});

function testWinnigNumbers(numbers, alertMessage = '') {
numbers.forEach((number, idx) => {
typeInputValue(`[data-winning-number=${idx}]`, number);
});
testInputValue('#result-submit', alertMessage);
}

it('다시 시작하기 버튼을 누르면 초기화 된다.', () => {
cy.get('#reset-button').click();
typeInputValue('#purchase-amount-input', '5000');
testInputValue('#purchase-amount-submit');
testWinnigNumbers(['1', '2', '3', '4', '5', '6', '45']);
});
});
2 changes: 1 addition & 1 deletion cypress/utils/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { testInputValue } from './testInputValue.js';
export { testInputValue, checkAlert } from './testInputValue.js';
18 changes: 5 additions & 13 deletions cypress/utils/testInputValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,12 @@ export const checkAlert = alertMessage => {
});
};

const resetInputValue = input => cy.get(input).then($input => $input.val(''));

export const setInputValue = (input, button, value) => {
resetInputValue(input);

if (value !== '') {
cy.get(input).type(value);
}

cy.get(button).click();
export const typeInputValue = (input, value) => {
cy.get(input).then($input => $input.val(''));
value !== '' && cy.get(input).type(value);
};

export const testInputValue = (input, button, value, alertMessage = '') => {
setInputValue(input, button, value);
export const testInputValue = (button, alertMessage = '') => {
cy.get(button).click();
alertMessage && checkAlert(alertMessage);
cy.get(input).should('have.value', alertMessage ? '' : value);
};
79 changes: 24 additions & 55 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,96 +12,65 @@
<div class="w-100">
<h1 class="text-center">🎱 행운의 로또</h1>
<!-- purchase amount input form -->
<form class="mt-5">
<label class="mb-2 d-inline-block"
>구입할 금액을 입력해주세요.
</label>
<form class="mt-5" id="purchase-amount-form" novalidate>
<label class="mb-2 d-inline-block">구입할 금액을 입력해주세요. </label>
<div class="d-flex">
<input
type="number"
class="w-100 mr-2 pl-2"
placeholder="구입 금액 (1000원 단위)"
id="purchase-amount-input"
/>
<button
type="button"
class="btn btn-cyan"
id="purchase-amount-submit"
>
확인
</button>
<button type="submit" class="btn btn-cyan" id="purchase-amount-submit">확인</button>
</div>
</form>
<!-- lotto section -->
<section class="mt-9 d-none" id="lotto-section">
<div class="d-flex">
<label class="flex-auto my-0"
><span id="lotto-count"></span>개를 구매하였습니다.</label
>
<label class="flex-auto my-0"><span id="lotto-count"></span>개를 구매하였습니다.</label>
<div class="flex-auto d-flex justify-end pr-1">
<label class="switch">
<input type="checkbox" class="lotto-numbers-toggle-button" />
<input type="checkbox" id="lotto-numbers-toggle-button" />
<span class="text-base font-normal">번호보기</span>
</label>
</div>
</div>
<div id="lotto-container" class="d-flex flex-wrap"></div>
</section>
<!-- lotto-result-form -->
<form class="mt-9 d-none" id="lotto-result-form">
<form class="mt-9 d-none" id="lotto-result-form" novalidate>
<label class="flex-auto d-inline-block mb-3"
>지난 주 당첨번호 6개와 보너스 넘버 1개를 입력해주세요.</label
>지난 주 당첨번호 6개와 보너스 넘버 1개를 입력해주세요. (1부터 45까지의 숫자를 입력해주세요.)</label
>
<div class="d-flex">
<div>
<h4 class="mt-0 mb-3 text-center">당첨 번호</h4>
<div>
<input
type="number"
class="winning-number mx-1 text-center"
/>
<input
type="number"
class="winning-number mx-1 text-center"
/>
<input
type="number"
class="winning-number mx-1 text-center"
/>
<input
type="number"
class="winning-number mx-1 text-center"
/>
<input
type="number"
class="winning-number mx-1 text-center"
/>
<input
type="number"
class="winning-number mx-1 text-center"
/>
<input type="text" class="winning-number mx-1 text-center" data-winning-number="0" />
<input type="text" class="winning-number mx-1 text-center" data-winning-number="1" />
<input type="text" class="winning-number mx-1 text-center" data-winning-number="2" />
<input type="text" class="winning-number mx-1 text-center" data-winning-number="3" />
<input type="text" class="winning-number mx-1 text-center" data-winning-number="4" />
<input type="text" class="winning-number mx-1 text-center" data-winning-number="5" />
</div>
</div>
<div class="bonus-number-container flex-grow">
<h4 class="mt-0 mb-3 text-center">보너스 번호</h4>
<div class="d-flex justify-center">
<input type="number" class="bonus-number text-center" />
<input type="text" class="bonus-number text-center" id="bonus-number" data-winning-number="6" />
</div>
</div>
</div>
<button
type="button"
class="open-result-modal-button mt-5 btn btn-cyan w-100"
>
<button type="submit" class="open-result-modal-button mt-5 btn btn-cyan w-100" id="result-submit">
결과 확인하기
</button>
</form>
</div>
</div>
<!-- result modal -->
<div class="modal">
<div class="modal" id="modal">
<div class="modal-inner p-10">
<div class="modal-close">
<div class="modal-close" id="modal-close">
<svg viewbox="0 0 40 40">
<path class="close-x" d="M 10,10 L 30,30 M 30,10 L 10,30" />
</svg>
Expand All @@ -121,34 +90,34 @@ <h2 class="text-center">🏆 당첨 통계 🏆</h2>
<tr class="text-center">
<td class="p-3">3개</td>
<td class="p-3">5,000</td>
<td class="p-3">n개</td>
<td data-rank="5" class="p-3"></td>
</tr>
<tr class="text-center">
<td class="p-3">4개</td>
<td class="p-3">50,000</td>
<td class="p-3">n개</td>
<td data-rank="4" class="p-3"></td>
</tr>
<tr class="text-center">
<td class="p-3">5개</td>
<td class="p-3">1,500,000</td>
<td class="p-3">n개</td>
<td data-rank="3" class="p-3"></td>
</tr>
<tr class="text-center">
<td class="p-3">5개 + 보너스볼</td>
<td class="p-3">30,000,000</td>
<td class="p-3">n개</td>
<td data-rank="2" class="p-3"></td>
</tr>
<tr class="text-center">
<td class="p-3">6개</td>
<td class="p-3">2,000,000,000</td>
<td class="p-3">n개</td>
<td data-rank="1" class="p-3"></td>
</tr>
</tbody>
</table>
</div>
<p class="text-center font-bold">당신의 총 수익률은 %입니다.</p>
<p class="text-center font-bold">당신의 총 수익률은 <span id="earning-rate"></span>%입니다.</p>
<div class="d-flex justify-center mt-5">
<button type="button" class="btn btn-cyan">다시 시작하기</button>
<button type="button" class="btn btn-cyan" id="reset-button">다시 시작하기</button>
</div>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"author": "Kyle <mkitigy@gmail.com>",
"license": "MIT",
"devDependencies": {
"babel-eslint": "^10.1.0",
"cypress": "6.4.0",
"eslint": "^7.20.0",
"eslint-config-prettier": "^7.2.0",
Expand Down
3 changes: 3 additions & 0 deletions src/js/constants/alertMessage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { UNIT_AMOUNT } from './standard.js';

export const MSG_INVALID_PURCHASE_AMOUNT = `금액을 ${UNIT_AMOUNT}원 단위로 입력해주세요!`;
export const MSG_DUPLICATED_LOTTO_NUMBERS = `중복된 숫자를 입력하셨습니다. 다시 입력해주세요!`;
export const MSG_OUT_RANGED_LOTTO_NUMBERS = `범위 밖의 숫자를 입력하셨습니다. 1부터 45 사이의 숫자를 입력해주세요!`;
export const MSG_BLANK_INPUT = `빈 칸을 입력하셨습니다. 다시 입력해주세요!`;
10 changes: 9 additions & 1 deletion src/js/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,13 @@ export {
MIN_LOTTO_NUMBER,
MAX_LOTTO_NUMBER,
LOTTO_NUMBER_COUNT,
BONUS_NUMBER_COUNT,
WINNING_NUMBER_COUNT,
PRIZE_MONEY,
} from './standard.js';
export { MSG_INVALID_PURCHASE_AMOUNT } from './alertMessage.js';
export {
MSG_INVALID_PURCHASE_AMOUNT,
MSG_BLANK_INPUT,
MSG_OUT_RANGED_LOTTO_NUMBERS,
MSG_DUPLICATED_LOTTO_NUMBERS,
} from './alertMessage.js';
16 changes: 16 additions & 0 deletions src/js/constants/standard.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,19 @@ export const UNIT_AMOUNT = 1000;
export const MIN_LOTTO_NUMBER = 1;
export const MAX_LOTTO_NUMBER = 45;
export const LOTTO_NUMBER_COUNT = 6;
export const BONUS_NUMBER_COUNT = 1;
export const WINNING_NUMBER_COUNT = LOTTO_NUMBER_COUNT + BONUS_NUMBER_COUNT;

const PRIZE_MONEY_1ST = 2000000000;
const PRIZE_MONEY_2ND = 30000000;
const PRIZE_MONEY_3RD = 1500000;
const PRIZE_MONEY_4TH = 50000;
const PRIZE_MONEY_5TH = 5000;

export const PRIZE_MONEY = {
1: PRIZE_MONEY_1ST,
2: PRIZE_MONEY_2ND,
3: PRIZE_MONEY_3RD,
4: PRIZE_MONEY_4TH,
5: PRIZE_MONEY_5TH,
};
Loading

0 comments on commit 55dedb7

Please sign in to comment.