Skip to content

Commit

Permalink
[1단계 - 행운의 로또 미션] 곤이(김기융) 미션 제출합니다. (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
goni-ssi authored Feb 21, 2021
1 parent 6958dc9 commit e04ff2f
Show file tree
Hide file tree
Showing 32 changed files with 2,400 additions and 60 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cypress
30 changes: 30 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = {
plugins: ['prettier'],
env: {
browser: true,
es2021: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module',
},
rules: {
'no-new': 'off',
'newline-before-return': 'error',
'class-methods-use-this': 'off',
'import/no-named-as-default': 'off',
'no-underscore-dangle': 'off',
'no-console': 'off',
'no-alert': 'off',
'no-prototype-builtins': 'off',
'max-depth': ['error', 2],
'max-lines-per-function': ['error', 20],
'linebreak-style': [
'error',
require('os').EOL === '\r\n' ? 'windows' : 'unix',
],
'prettier/prettier': ['error', { endOfLine: 'auto' }],
},
};
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
.DS_Store
.AppleDouble
.LSOverride
.vscode
node_modules

# Icon must end with two \r
Icon
Expand Down
10 changes: 10 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"semi": true,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"printWidth": 80,
"trailingComma": "es5",
"arrowParens": "avoid",
"endOfLine": "lf"
}
69 changes: 37 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,17 @@

### 🎯 step1 구입 기능

- [ ] 로꼬 구입 금액을 입력하면, 금액에 해당하는 로또를 발급해야 한다.
- [ ] 로또 1장의 가격은 1,000원이다.
- [ ] 소비자는 **자동 구매**를 할 수 있어야 한다.
- [ ] 복권 번호는 번호보기 토글 버튼을 클릭하면, 볼 수 있어야 한다.

- [x] 로또 구입 금액을 입력하면, 금액에 해당하는 로또를 발급해야 한다.
- [x] 로또 1장의 가격은 1,000원이다.
- [x] 소비자는 **자동 구매**를 할 수 있어야 한다.
- [x] 복권 번호는 번호보기 토글 버튼을 클릭하면, 볼 수 있어야 한다.

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

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


### 🎯🎯🎯 step3 수동 구매

- [ ] 소비자는 수동 구매(스스로 구매 번호를 입력)를 할 수 있어야 한다.
Expand All @@ -43,36 +41,43 @@

<br>

## ⚙️ Before Started

#### <img alt="Tip" src="https://img.shields.io/static/v1.svg?label=&message=Tip&style=flat-square&color=673ab8"> 로컬에서 서버 띄워서 손쉽게 static resources 변경 및 확인하는 방법

로컬에서 웹서버를 띄워 html, css, js 등을 실시간으로 손쉽게 테스트해 볼 수 있습니다. 이를 위해서는 우선 npm이 설치되어 있어야 합니다. 구글에 `npm install` 이란 키워드로 각자의 운영체제에 맞게끔 npm을 설치해주세요. 이후 아래의 명령어를 통해 실시간으로 웹페이지를 테스트해볼 수 있습니다.

```
npm install -g live-server
```

실행은 아래의 커맨드로 할 수 있습니다.

```
live-server 폴더명
```

<br>

## 👏 Contributing
### 💾 기능 목록

만약 미션 수행 중에 개선사항이 보인다면, 언제든 자유롭게 PR을 보내주세요.
### step1

<br>
- [x] 로또 구입 금액을 인풋으로 받는다.
- [x] 단위 금액 placeholder 표시 (단위 금액은 1000원으로 한다.)
- [x] 단위 금액으로 나누어지지 않을 경우 에러 핸들링
- [x] 금액을 단위 금액으로 나눈 만큼 로또를 발급한다.
- [x] 로또 번호는 1 ~ 45
- [x] 하나의 로또 안에서 각각의 번호는 중복되면 안된다.
- [x] 발급된 로또는 화면에 렌더링한다.
- [x] 토글 버튼을 눌렀을 때 로또 섹션의 레이아웃이 바뀌고 번호가 보인다.
- [x] css를 이용해 레이아웃과 디스플레이를 수정한다.

## 🐞 Bug Report
### step2

버그를 발견한다면, [Issues](https://github.com/woowacourse/javascript-lotto/issues)에 등록해주세요.
- [ ] 당첨번호와 보너스 번호를 인풋으로 받는다.
- [ ] 당첨번호와 보너스 번호는 중복되서는 안된다.
- [ ] 당첨번호와 보너스 번호는 1 ~ 45
- [ ] 결과 확인하기 버튼을 눌렀을 때의 다음과 같은 기능을 수행한다.
- [ ] 당첨번호와 보너스 번호의 유효성을 검사한다.
- [ ] 구입한 로또 번호와 일치하는 당첨번호의 개수를 확인한다.
- [ ] 당첨금액을 합산하여 수익률을 계산한다.
- [ ] 당첨 통계, 수익률을 확인할 수 있는 모달을 띄운다.
- [ ] 다시 시작하기 버튼을 클릭한 경우 초기화 한다.

<br>

## 📝 License

This project is [MIT](https://github.com/woowacourse/javascript-lotto/blob/main/LICENSE) licensed.
### 테스트 케이스

- [x] 구입 금액은 단위 금액의 양의 배수 값을 갖는다.
- [x] 몫은 양의 정수값, 나머지는 0인 값을 받는다.
- [x] 구입 금액을 입력한 뒤 버튼을 클릭했을 때, 알맞은 개수의 로또를 렌더링한다.
- [x] 토글 버튼을 클릭했을 때, 모든 복권 번호를 렌더링한다.
- [ ] 적절한 당첨 번호를 입력 받는다.
- [ ] 중복된 숫자를 입력받지 않는다.
- [ ] 1 ~ 45의 숫자를 입력 받는다.
- [ ] 결과 확인하기 버튼을 누르면 모달을 확인할 수 있다.
- [ ] 당첨 통계가 정확한지 확인한다. (TDD)
- [ ] 다시 시작하기 버튼을 누르면 초기화 된다.
1 change: 1 addition & 0 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
5 changes: 5 additions & 0 deletions cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
43 changes: 43 additions & 0 deletions cypress/integration/lotto.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { testInputValue } from '../utils/index.js';
import { MSG_INVALID_PURCHASE_AMOUNT } from '../../src/js/constants/index.js';

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

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

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

it('구입 금액 입력 뒤 버튼을 클릭했을 때, 알맞은 개수의 로또를 렌더링한다.', () => {
cy.get('#lotto-container') //
.find('.lotto-wrapper')
.should('have.length', 5);
});

it('토글 버튼을 클릭했을 때, 모든 복권 번호를 렌더링한다.', () => {
testLottoToggle(5, 'on');
testLottoToggle(5, 'off');

function testLottoToggle(count, toggleOption) {
cy.get('.switch').click();
for (let idx = 0; idx < count; idx++) {
cy.get('.lotto-wrapper') //
.eq(idx)
.children('.lotto-numbers')
.should(toggleOption === 'on' ? 'be.visible' : 'not.be.visible');
}
}
});
});
21 changes: 21 additions & 0 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
25 changes: 25 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
20 changes: 20 additions & 0 deletions cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands';

// Alternatively you can use CommonJS syntax:
// require('./commands')
1 change: 1 addition & 0 deletions cypress/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { testInputValue } from './testInputValue.js';
25 changes: 25 additions & 0 deletions cypress/utils/testInputValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const checkAlert = alertMessage => {
const alertStub = cy.stub();

cy.on('window:alert', alertStub).then(() => {
expect(alertStub.getCall(0)).to.be.calledWith(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 testInputValue = (input, button, value, alertMessage = '') => {
setInputValue(input, button, value);
alertMessage && checkAlert(alertMessage);
cy.get(input).should('have.value', alertMessage ? '' : value);
};
32 changes: 19 additions & 13 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<div class="d-flex justify-center mt-5">
<div class="w-100">
<h1 class="text-center">🎱 행운의 로또</h1>
<!-- purchase amount input form -->
<form class="mt-5">
<label class="mb-2 d-inline-block"
>구입할 금액을 입력해주세요.
Expand All @@ -19,30 +20,35 @@ <h1 class="text-center">🎱 행운의 로또</h1>
<input
type="number"
class="w-100 mr-2 pl-2"
placeholder="구입 금액"
placeholder="구입 금액 (1000원 단위)"
id="purchase-amount-input"
/>
<button type="button" class="btn btn-cyan">확인</button>
<button
type="button"
class="btn btn-cyan"
id="purchase-amount-submit"
>
확인
</button>
</div>
</form>
<section class="mt-9">
<!-- lotto section -->
<section class="mt-9 d-none" id="lotto-section">
<div class="d-flex">
<label class="flex-auto my-0">총 5개를 구매하였습니다.</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" />
<span class="text-base font-normal">번호보기</span>
</label>
</div>
</div>
<div class="d-flex flex-wrap">
<span class="mx-1 text-4xl">🎟️ </span>
<span class="mx-1 text-4xl">🎟️ </span>
<span class="mx-1 text-4xl">🎟️ </span>
<span class="mx-1 text-4xl">🎟️ </span>
<span class="mx-1 text-4xl">🎟️ </span>
</div>
<div id="lotto-container" class="d-flex flex-wrap"></div>
</section>
<form class="mt-9">
<!-- lotto-result-form -->
<form class="mt-9 d-none" id="lotto-result-form">
<label class="flex-auto d-inline-block mb-3"
>지난 주 당첨번호 6개와 보너스 넘버 1개를 입력해주세요.</label
>
Expand Down Expand Up @@ -92,7 +98,7 @@ <h4 class="mt-0 mb-3 text-center">보너스 번호</h4>
</form>
</div>
</div>

<!-- result modal -->
<div class="modal">
<div class="modal-inner p-10">
<div class="modal-close">
Expand Down
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
{
"name": "racingcar",
"name": "javascript-lotto",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/GwangYeol-Im/javascript-lotto.git",
"author": "Kyle <mkitigy@gmail.com>",
"license": "MIT",
"devDependencies": {
"cypress": "^6.3.0"
"cypress": "6.4.0",
"eslint": "^7.20.0",
"eslint-config-prettier": "^7.2.0",
"eslint-plugin-prettier": "^3.3.1",
"prettier": "2.2.1"
}
}
4 changes: 4 additions & 0 deletions src/css/shared/modules/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
display: inline-block;
}

.d-none {
display: none;
}

/* Layout - Top / Right / Bottom / Left */

.mt-2 {
Expand Down
3 changes: 3 additions & 0 deletions src/js/constants/alertMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { UNIT_AMOUNT } from './standard.js';

export const MSG_INVALID_PURCHASE_AMOUNT = `금액을 ${UNIT_AMOUNT}원 단위로 입력해주세요!`;
Loading

0 comments on commit e04ff2f

Please sign in to comment.