-
Notifications
You must be signed in to change notification settings - Fork 231
[2단계 - 웹 기반 로또 게임] 안톨리니 미션 제출합니다. #462
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
Merged
Merged
Changes from 71 commits
Commits
Show all changes
83 commits
Select commit
Hold shift + click to select a range
ecc4b89
feat: 네비게이션바 추가
Antoliny0919 c89d296
style: 네비게이션바 스타일 추가
Antoliny0919 744492e
feat: 컨텐츠 블록 추가
Antoliny0919 85450e8
feat: 컨텐츠 타이틀 추가
Antoliny0919 f4a962e
feat: 로또 구입할 금액 입력 레이아웃 추가
Antoliny0919 99611f0
feat: 구입한 로또들을 보여주는 레이아웃 추가
Antoliny0919 f35153b
feat: 우승로또 번호 레이아웃 추가
Antoliny0919 8130f88
style: 버튼 호버 효과 추가
Antoliny0919 81a5d32
style: input border 기본 너비 추가
Antoliny0919 d1bd970
style: 메인 컨텐트 border 스타일 추가
Antoliny0919 fff8912
style: 보너스 번호 라벨 for 속성을 통해 input과 연결
Antoliny0919 4f39173
feat: footer 영역 레이아웃 추가
Antoliny0919 350def2
style: content요소가 화면 높이를 사용하고 중앙에 위치하도록 수정
Antoliny0919 5486170
style: 반응형 CSS 추가
Antoliny0919 b715062
style: 폰트 유틸 추가
Antoliny0919 abba122
style: 중복되는 font-system, font-title 변수 제거
Antoliny0919 ef85491
style: 중복되는 padding, margin 값 제거
Antoliny0919 fb7ecf4
style: CSS 선택자에서 id가 적용된 태그를 더 인식하기 쉽게 태그명 추가
Antoliny0919 4377d7a
style: Roboto 폰트를 최우선으로 사용하도록 수정
Antoliny0919 5955dd6
style: text-base가 적용된 태그에 마진 추가
Antoliny0919 ac71900
chore: css 주석 포맷 수정
Antoliny0919 f08a617
style: id를 통해 컨텐츠 영역을 분리
Antoliny0919 4f90977
fix: input태그에 required 속성 추가
Antoliny0919 4a93a06
feat: 로또 구입할 금액 입력 검증 추가, 검증에 따른 렌더링 추가
Antoliny0919 c7196bf
feat: 로또 구입한 갯수 메시지 노드를 동적으로 추가
Antoliny0919 824f523
feat: 구매한 로또 번호를 동적으로 추가
Antoliny0919 91b52e0
fix: 오타 수정
Antoliny0919 5cc47b3
docs: 기능 요구 사항 추가, 현재까지 구현한 기능 체크
Antoliny0919 462daf7
docs: 기능 요구 사항 추가
Antoliny0919 6dbb226
feat: 당첨, 보너스 번호 입력 검증 추가
Antoliny0919 83ed175
fix: 잘못된 인덴트 수정
Antoliny0919 9421271
fix: 구매한 로또 번호, 당첨번호 & 보너스 번호 입력이 선택적으로 보이게 하도록 수정
Antoliny0919 1cec585
style: 가려진 요소가 보여질때 자연스럽게 보여지도록 수정
Antoliny0919 252ada0
feat: dialog를 닫는 요소 추가
Antoliny0919 d0ae0d2
feat: 당첨통계 타이틀 추가
Antoliny0919 4dcf4ef
feat: 당첨통계 결과 다이얼로그 레이아웃 추가
Antoliny0919 e1390c4
feat: 당첨금액 & 보너스번호 전달시 당첨통계 다이얼로그가 나타나도록 추가
Antoliny0919 6c4113d
feat: 당첨 통계 다이얼로그 닫는 기능 추가
Antoliny0919 13d3746
feat: 당첨 로또 객체 생성 추가
Antoliny0919 5b02a82
feat: 로또 당첨 결과 테이블 렌더링 기능 추가
Antoliny0919 c66b674
feat: 총 수익률 렌더 기능 추가
Antoliny0919 b0ddfe8
feat: 재시작 버튼 레이아웃 추가
Antoliny0919 6abd9fd
docs: 기능 요구 완료사항 체크
Antoliny0919 7448e83
docs: 리팩토링 사항 추가
Antoliny0919 9dbd076
refactor: 로또 구매 갯수, 구매한 로또 번호 컴포넌트화
Antoliny0919 13a3280
refactor: 로또 당첨 통계 모달 컴포넌트화
Antoliny0919 0a641dd
refactor: 에러메시지 컴포넌트화
Antoliny0919 041e304
refactor: 에러메시지 상태를 제거하는 유틸을 View로 전환
Antoliny0919 9ca223e
refactor: hidden 클래스를 추가, 제거하는 방식을 toggle로 전환
Antoliny0919 602da50
style: fade 이펙트 제거
Antoliny0919 4a4cbdc
refactor: 모달 close / open 을 View로 분리
Antoliny0919 0ae67f8
refactor: 로또 구입금액 입력값 처리에 대한 로직 Controller로 분리
Antoliny0919 98e435c
refactor: 당첨번호, 보너스번호 입력값 처리 로직을 Controller에 분리
Antoliny0919 156ec4a
refactor: 재시작 로직을 controller로 분리
Antoliny0919 4305516
refactor: 당첨 통계 모달 닫는 방식을 전환
Antoliny0919 db05eff
fix: 다이얼로그를 닫는 버튼의 type을 수정
Antoliny0919 114b430
refactor: index.js에서 필요하지 않은 즉시실행 함수 제거
Antoliny0919 0674847
style: 사용하지 않은 CSS 제거
Antoliny0919 e8ca74f
style: 구간별 주석 추가
Antoliny0919 9f1f365
style: 사용하지 않은 색상 제거
Antoliny0919 bebf9c2
style: 구입한 로또 컨텐츠의 높이를 고정
Antoliny0919 117ea2a
fix: 당첨번호 입력 에러시 form이 사라지는 문제 해결
Antoliny0919 66718bd
fix: 잘못된 속성명 수정
Antoliny0919 5a3376a
fix: readLine이 WebApp에서 사용되지 않도록 분리
Antoliny0919 313e6e4
fix: 로또 매치 결과 테이블 라벨값을 요구사항에 맞도록 수정
Antoliny0919 c84567b
test: 검증기 테스트 추가
Antoliny0919 7ef505c
fix: 매치결과 계산시 matchResult를 다시 생성하도록 수정
Antoliny0919 295b27e
fix: 구입버튼을 누를시 로또가 계속 사지는 현상 수정
Antoliny0919 bbd308b
fix: 배포 url 수정
Antoliny0919 48e5777
refactor: View에서 Dom에 접근하는 로직을 속성으로 분리
Antoliny0919 85f2d0b
fix: 입력성공시 에러메시지가 제거되도록 수정
Antoliny0919 7345821
fix: hidden 요소를 적용하는 방식을 visibility: hidden 으로 수정
Antoliny0919 591a9db
fix: 당첨 번호 제출시에도 LottoMachine이 존재하는지 확인
Antoliny0919 ab91e98
refactor: 명시적인 show, hide를 사용하도록 변경
Antoliny0919 a55bbab
fix: 중복되는 title 제거
Antoliny0919 2040b0f
refactor: Dom 로딩을 메서드로 분리
Antoliny0919 2fccd37
fix: th 태그 상위에 tr태그가 렌더링 되도록 수정
Antoliny0919 d5c26b2
fix: 로또 구매 금액 입력란에 타입 추가
Antoliny0919 a191519
fix: 잘못된 클래스명 수정
Antoliny0919 1faef65
style: overflow가 적용될 범위 수정
Antoliny0919 e990f40
feat: 폼 제출 이후 disabled 속성 추가
Antoliny0919 1747356
fix: 중복적인 innerHTML 초기화 제거
Antoliny0919 9001af1
style: 구매한 로또가 존재하지 않을때도 고정적인 높이가 제공되도록 수정
Antoliny0919 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import Component from '../src/step2/Component.js'; | ||
|
|
||
|
|
||
| describe('컴포넌트 테스트', () => { | ||
| test('에러메시지 컴포넌트', () => { | ||
| const errorMessageComponent = Component.errorMessage('잘못된 입력입니다!'); | ||
|
|
||
| expect(errorMessageComponent).toEqual('<p class="text-body error-message">잘못된 입력입니다!</p>'); | ||
| }); | ||
|
|
||
| test('lottos 배열로 로또 리스트 컴포넌트 반한', () => { | ||
| const lottoListComponent = Component.lottoList([[1, 2, 3, 4, 5, 6], [10, 11, 12, 13, 14, 15]]); | ||
| const expected = '<ul id="purchase-lotto-list">' | ||
| + '<li><span>🎟️</span>1, 2, 3, 4, 5, 6</li>' | ||
| + '<li><span>🎟️</span>10, 11, 12, 13, 14, 15</li>' | ||
| + '</ul>' | ||
|
|
||
| expect(lottoListComponent).toEqual(expected); | ||
| }); | ||
|
|
||
| test('로또 매치 결과 테이블 컴포넌트', () => { | ||
| const summary = [ | ||
| { label: '3개 일치', prize: '500', result: 3 }, | ||
| { label: '4개 일치', prize: '1,000', result: 100 }, | ||
| ] | ||
|
|
||
| const lottoMatchResultComponent = Component.lottoMatchResultTable(summary); | ||
| const expected = '<table id="lotto-match-result">' | ||
| + '<thead><th>일치 갯수</th><th>당첨금</th><th>당첨 갯수</th></thead>' | ||
| + '<tbody><tr><td>3개 일치</td><td>500</td><td>3</td></tr>' | ||
| + '<tr><td>4개 일치</td><td>1,000</td><td>100</td></tr>' | ||
| + '</tbody></table>' | ||
| expect(lottoMatchResultComponent).toEqual(expected); | ||
| }); | ||
|
|
||
| test('로또 수익률 컴포넌트', () => { | ||
| const rateOfReturnComponent = Component.rateOfReturnMessage('12345.0'); | ||
| expect(rateOfReturnComponent).toEqual('<p id="lotto-rate-of-return">당신의 총 수익률은 12345.0%입니다.</p>'); | ||
| }); | ||
|
|
||
| test('재시작 버튼 컴포넌트', () => { | ||
| const restartButton = Component.restartButton(); | ||
| expect(restartButton).toEqual('<button type="button" id="restart-button">다시 시작하기</button>'); | ||
| }); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import Converter from '../src/step2/Converter.js'; | ||
|
|
||
| describe('데이터 전환 테스트', () => { | ||
| test('matchResultSummary 데이터 label의 일치를 제거', () => { | ||
| const summary = [ | ||
| { label: '3개 일치', prize: 1000, result: 3 }, | ||
| { label: '5개 일치, 보너스 볼 일치', prize: 2000, result: 5 }, | ||
| ] | ||
| const expected = [ | ||
| { label: '3개 ', prize: 1000, result: 3 }, | ||
| { label: '5개 , 보너스 볼 ', prize: 2000, result: 5 }, | ||
| ] | ||
| expect(Converter.matchResultSummary(summary)).toEqual(expected); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import Validator from '../src/step1/Validator.js'; | ||
|
|
||
| describe('구입금액 검증 테스트', () => { | ||
| test('1000원 단위가 아닐때 예외 발생', () => { | ||
| expect(() => Validator.validatePurchaseAmount('1234')).toThrow('1000원 단위만 입력 가능합니다.'); | ||
| }); | ||
|
|
||
| test('정수가 아닐때 예외 발생', () => { | ||
| expect(() => Validator.validatePurchaseAmount('aaaa')).toThrow('숫자만 입력해 주세요.'); | ||
| }); | ||
| }); | ||
|
|
||
| describe('당첨 번호 검증 테스트', () => { | ||
| test.each([ | ||
| ['1'], | ||
| [''], | ||
| ['1', '2', '3', '4', '5', '6', '7'], | ||
| ])('당첨 번호가 6개가 아닐때 예외 발생', (value) => { | ||
| expect(() => Validator.validateLottoNumber(value)).toThrow('당첨 로또 번호는 숫자 6개여야 합니다.'); | ||
| }); | ||
|
|
||
| test('중복되는 당첨 번호가 존재할때 예외 발생', () => { | ||
| expect( | ||
| () => Validator.validateLottoNumber(['1', '2', '3', '4', '5', '1']) | ||
| ).toThrow('중복되는 당첨 번호는 사용할 수 없습니다.'); | ||
| }); | ||
|
|
||
| test('정수가 아닌 당첨 번호가 존재할때 예외 발생', () => { | ||
| expect( | ||
| () => Validator.validateLottoNumber(['1', '2', 'z', 'd', '!', '\\']) | ||
| ).toThrow('당첨 번호는 숫자만 입력 가능합니다.'); | ||
| }); | ||
|
|
||
| test.each([ | ||
| [['1', '2', '3', '4', '5', '46'], ['0', '1', '2', '3', '4', '5']] | ||
| ])('당첨 번호가 6개가 아닐때 예외 발생', (value) => { | ||
| expect(() => Validator.validateLottoNumber(value)).toThrow('당첨 번호는 1 ~ 45 이내 숫자만 입력 가능합니다.'); | ||
| }); | ||
| }); | ||
|
|
||
| describe('보너스 번호 검증 테스트', () => { | ||
| test('정수가 아닐때 예외 발생', () => { | ||
| expect( | ||
| () => Validator.validateBonusNumber(['1', '2', '3', '4', '5', '6'], 'z') | ||
| ).toThrow('보너스 번호는 숫자만 입력 가능합니다.'); | ||
| }); | ||
|
|
||
| test.each([ | ||
| ['0'], ['46'] | ||
| ])('1 ~ 45 이내 숫자가 아닐때 예외 발생', (value) => { | ||
| expect(() => Validator.validateBonusNumber( | ||
| ['1', '2', '3', '4', '5', '6'], value) | ||
| ).toThrow('보너스 번호는 1 ~ 45 이내 숫자만 입력 가능합니다.'); | ||
| }); | ||
|
|
||
| test('당첨 번호와 동일한 숫자일때 예외 발생', () => { | ||
| expect(() => Validator.validateBonusNumber( | ||
| ['1', '2', '3', '4', '5', '6'], '6' | ||
| )).toThrow('보너스 번호는 당첨번호와 중복될 수 없습니다.'); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import readline from 'readline'; | ||
|
|
||
| export const read = readline.createInterface({ | ||
| input: process.stdin, | ||
| output: process.stdout, | ||
| }); | ||
|
|
||
| export function readLine(query) { | ||
| return new Promise((resolve) => { | ||
| read.question(query, (answer) => { | ||
| resolve(answer); | ||
| }); | ||
| }); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
꼼꼼하게 테스트 코드를 추가해주셨네요 좋습니다! 다만 문자열 완전일치만 검증해서 리팩토링 내성이 낮은데요. 테스트하는 주요 DOM 구조 중심 검증으로 바꾸면 유지보수성이 좋아질 것 같은데 어떻게 생각하세요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금 현재 컴포넌트 규모에서는 적절하다고 생각합니다.
오히려 HTML 구조가 변경되었을때 테스트가 깨지는 상태가 되는게 좋다고 생각합니다.
아무래도 class의 변경같은 사소한 부분에서 깨지는게 좋지 않다는건 공감되지만 지금 상태에서는 유지해도 괜찮지 않을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어떤 마음으로 꼼꼼하게 검증하려 하셨는지 의도는 충분히 이해했습니다! 하지만 class 변경 같은 시각적, 구조적 변경을 단위 테스트에서 문자열로 잡으려고 하면, 나중에 사소한 디자인 수정만 발생해도 테스트가 전부 터져서 유지보수하기 너무 힘들어질 수 있어요ㅜㅜ
디자인이나 마크업 구조가 의도치 않게 깨지는 것을 막는 역할은 시각적 회귀 테스트에게 맡기는 것이 일반적인 방향성이에요! 이번 테스트 코드는 전체 문자열 비교 대신, 해당 컴포넌트가 반드시 가져야 하는 핵심 기능과 주요 요소만 검증하도록 의도를 명확히 드러내주시면 좋을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
동의합니다. Contains를 사용했으면 더 좋았겠네요.
보통 변경되지 않을 가능성이 높은 부분들에 대해서는 HTML 구조 전부를 검사하는 편입니다.
하지만 현재 구조에서 ComponentTest는 전체 문자열을 테스트하기 때문에 약간의 변경만 포함되더라도 유지보수 비용이 높을거라는 예상이 됩니다.
보통 시각적 회귀 테스트를 디자인적인 부분에서만 고려해서 작성해봤던거 같은데 마크업 구조는 처음 알았네요.
저는 주로 E2E 툴을 통해 Screenshot을 찍어 이전 이후를 비교하며 시각적회귀 테스트를 했었는데 현업에서는 어떤식으로 진행하나요 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
한 가지 예시를 들자면 이런식으로 전환하는게 좋았을까요?
class 부분에 대한 테스트도 해야할까요 🤔