-
Notifications
You must be signed in to change notification settings - Fork 171
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
[2단계 - 자동차 경주 구현] 유조(조윤호) 미션 제출합니다. #25
Changes from 22 commits
a2e2b84
d0f6194
dbc866d
5d8ef99
4df4349
cb3803d
ec48997
b868476
4a58639
a3f6ec2
b4c1b7a
fba8912
cfbc0dc
5d9d3e4
2f0fc82
ff25aac
a272ee3
a19d9e8
4700ef6
2c2f7ba
4e0ca6f
0270679
b794b80
7625e7c
d6e71c1
1f5ab2f
42f041a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,8 +59,8 @@ describe('racing-game', () => { | |
it('음수와 공백을 시도 횟수로 입력 시, 경고메세지가 출력되는지 테스트 한다.', () => { | ||
const negativeRacingCount = -7; | ||
const alertStub = cy.stub(); | ||
|
||
cy.on('window:alert', alertStub); | ||
|
||
typeCarNameAndClickToSubmitButton(); | ||
typeRacingCountAndClickToSubmitButton(negativeRacingCount).then(() => { | ||
expect(alertStub.getCall(0)).to.be.calledWith( | ||
|
@@ -82,44 +82,84 @@ describe('racing-game', () => { | |
it('올바른 시도 횟수 입력 시, 화면에 자동차 경주 섹션이 표시되는지 테스트 한다.', () => { | ||
typeCarNameAndClickToSubmitButton(); | ||
typeRacingCountAndClickToSubmitButton(); | ||
|
||
cy.get('.car-player') | ||
.should('have.length', carNames.length) | ||
.each(($div, index) => cy.get($div).should('have.text', carNames[index])); | ||
cy.get('#game-process-section').should('be.visible'); | ||
}); | ||
|
||
it('랜덤 함수가 정상적으로 동작하는지 테스트 한다.', () => { | ||
const possibleScores = Array.from({ | ||
length: GAME.MAX_SCORE - GAME.MIN_SCORE + 1, | ||
}).map((v, i) => i); | ||
const randomNumbers = [...Array(100)] | ||
.map(() => getRandomNumber(GAME.MIN_SCORE, GAME.MAX_SCORE)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HoF를 이용해 chaining을 진행하니 가독성이 많이 좋아졌네요! 굿입니다! 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 감사합니다! 다른 크루의 리뷰에 달린 코멘트에서 아이디어를 얻었습니다ㅎㅎ |
||
.filter((num) => GAME.MIN_SCORE <= num && num <= GAME.MAX_SCORE); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 조건문이 가독성이 떨어지는데 validate함수를 따로 분리했으면 어땠을까 |
||
|
||
for (let i = 0; i < 100; i++) { | ||
expect(possibleScores).to.include( | ||
getRandomNumber(GAME.MIN_SCORE, GAME.MAX_SCORE), | ||
); | ||
} | ||
expect(randomNumbers.length).to.equal(100); | ||
}); | ||
|
||
it('자동차가 정상적으로 전진, 멈춤하는지 테스트한다.', () => { | ||
for (let i = GAME.MAX_SCORE; i < GAME.MAX_SCORE; i++) { | ||
for (let i = GAME.MAX_SCORE; i <= GAME.MAX_SCORE; i++) { | ||
if (i < GAME.EFFECTIVE_SCORE) { | ||
return expect(isEffectiveScore(i)).to.equal(false); | ||
} | ||
return expect(isEffectiveScore(i)).to.equal(true); | ||
} | ||
}); | ||
|
||
it('자동차 경주 진행 중 턴마다 1초의 지연시간이 생기는지 테스트 한다.', () => { | ||
cy.clock(); | ||
|
||
// 첫번째 경기 진행시간 1000ms | ||
typeCarNameAndClickToSubmitButton(); | ||
typeRacingCountAndClickToSubmitButton(1); | ||
|
||
cy.tick(500); | ||
cy.get('#game-result-section').should('not.be.visible'); | ||
cy.tick(500); | ||
cy.get('#game-result-section').should('be.visible'); | ||
|
||
// 두번째 경기 진행시간 3000ms | ||
cy.get('#game-restart-button').click(); | ||
typeCarNameAndClickToSubmitButton(); | ||
typeRacingCountAndClickToSubmitButton(3); | ||
|
||
cy.tick(1500); | ||
cy.get('#game-result-section').should('not.be.visible'); | ||
cy.tick(1500); | ||
cy.get('#game-result-section').should('be.visible'); | ||
}); | ||
|
||
it('자동차 경주 진행 중 지연시간마다 Anmiation이 출력되는지 테스트 한다.', () => { | ||
typeCarNameAndClickToSubmitButton(); | ||
typeRacingCountAndClickToSubmitButton(); | ||
|
||
cy.clock(); | ||
|
||
// 경주 진행시간 5000ms | ||
cy.get('.spinner-container').should('be.visible'); | ||
cy.wait(2000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
패턴이 반복되네요! 충분히 함수로 뺄 수 있을 것 같습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그리고, 생각보다 중첩되는 로직이 많아지므로, 인치님께 드렸던 피드백 처럼 객체화를 하여 chaining 형태로 해결하는 방법도 있습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 좋은 방법이네요! 코드에 적용해보겠습니다 감사합니다!!👍👍👍 |
||
cy.get('.spinner-container').should('be.visible'); | ||
cy.wait(2000); | ||
cy.get('.spinner-container').should('be.visible'); | ||
cy.wait(1000); | ||
cy.get('.spinner-container').should('not.be.visible'); | ||
}); | ||
|
||
it('자동차 경주가 정상적으로 진행되는지 테스트 한다.', () => { | ||
typeCarNameAndClickToSubmitButton(); | ||
typeRacingCountAndClickToSubmitButton(); | ||
|
||
cy.clock(); | ||
cy.wait(5000); | ||
|
||
cy.get('.car-player').each(($div, index) => { | ||
cy.get($div) | ||
.should('have.text', carNames[index]) | ||
.parent() | ||
.children('div') | ||
.its('length') | ||
.then((childrenNum) => { | ||
cy.get($div).should('have.data', 'forwardCount', childrenNum - 1); | ||
cy.get($div).should('have.data', 'forwardCount', childrenNum - 2); | ||
}); | ||
}); | ||
}); | ||
|
@@ -128,6 +168,9 @@ describe('racing-game', () => { | |
typeCarNameAndClickToSubmitButton(); | ||
typeRacingCountAndClickToSubmitButton(); | ||
|
||
cy.clock(); | ||
cy.wait(5000); | ||
|
||
cy.get('.car').then(($cars) => { | ||
const counts = [...$cars].map(($car) => { | ||
return $car.querySelectorAll('.forward-icon').length; | ||
|
@@ -148,9 +191,27 @@ describe('racing-game', () => { | |
}); | ||
}); | ||
|
||
it('자동차 경주가 모두 끝났을 때, 2초 후 축하의 alert메세지가 출력되는지 테스트 한다.', () => { | ||
cy.clock(); | ||
|
||
typeCarNameAndClickToSubmitButton(['yujo']); | ||
typeRacingCountAndClickToSubmitButton(); | ||
|
||
// 자동차 경주 진행시간 5000ms + alert 출력 대기시간 2000ms | ||
cy.tick(7000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 7000이라는 숫자가 나온 자동차 경주 진행시간인 5000이라는 숫자와 alert 출력 대기시간 2000을 상수화해서 사용하는게 좋아보입니다. 하단에서도 5000을 사용하는 것 같고, 위에서도 중복해서 사용하네요! 최상단에서
요런 형태로 지정하여
형태로 사용하는게 더 좋아보입니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 테스트 코드의 상수 분리에는 신경을 못 썼군요😅😅😅 놓치고 있었는데 꼼꼼하게 봐주셔서 감사합니다!👍👍👍 |
||
|
||
cy.on('window:alert', (txt) => { | ||
expect(txt).to.equal('🎉 축하드립니다! 우승자는 yujo입니다! 🎉'); | ||
}); | ||
}); | ||
|
||
it('다시 시작버튼을 눌렀을 때 화면이 초기화 되는지 테스트한다.', () => { | ||
typeCarNameAndClickToSubmitButton(); | ||
typeRacingCountAndClickToSubmitButton(); | ||
|
||
cy.clock(); | ||
cy.wait(5000); | ||
|
||
cy.get('#game-restart-button').click(); | ||
cy.get('#racing-count-section').should('not.be.visible'); | ||
cy.get('#game-process-section').should('not.be.visible'); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,18 @@ | ||
import { GAME } from '../utils/constant.js'; | ||
import { getWinners } from './getWinners.js'; | ||
import { restartGame } from './restartGame.js'; | ||
|
||
const alertGameResult = (winners) => { | ||
alert(`🎉 축하드립니다! 우승자는 ${winners}입니다! 🎉`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. winners의 값이 빈 배열이거나 undefined, null인 경우에 대한 예외처리는 없어도 될까요~? 함수를 작성하는 순서
사실 이 기법은 TDD할 때도 많이 쓰이는 기법입니다. 테스트 케이스의 base case를 정의하기 전, bad case를 정해두시면 언제나 좋습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 와 알려주신 순서대로 함수를 정의하는건 한번도 생각해보지 못 했는데 정말 좋은 방법이네요!! 좋은 습관을 들일 수 있게 앞으로 함수를 작성할 때 알려주신 순서를 지키면서 작성 해야겠습니다! 좋은 인사이트 주셔서 감사합니다!!👍👍👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넴!! 그런데 마지막 4번째 단계를 빼먹었네요 ㅋㅋ 4번째 단계는 |
||
}; | ||
|
||
export const printGameResult = () => { | ||
const $gameResultText = document.querySelector('#game-result-text'); | ||
const $gameRestartButton = document.querySelector('#game-restart-button'); | ||
const winners = getWinners(); | ||
|
||
$gameResultText.innerHTML = `🏆 최종 우승자: ${getWinners()} 🏆`; | ||
$gameResultText.innerHTML = `🏆 최종 우승자: ${winners} 🏆`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 무언가 위의 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [질문] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 요것은 패스하셔도 됩니다!!! |
||
$gameRestartButton.addEventListener('click', restartGame); | ||
|
||
setTimeout(() => alertGameResult(winners), GAME.RESULT_ALERT_DELAY); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,16 @@ | ||
import { isEffectiveScore } from './isEffectiveScore.js'; | ||
import { getRandomNumber } from '../utils/getRandomNumber.js'; | ||
import { printGameResult } from './printGameResult.js'; | ||
import { toggleVisibility } from '../utils/toggleVisibility.js'; | ||
import { GAME } from '../utils/constant.js'; | ||
import { setVisibility } from '../utils/setAttribute.js'; | ||
|
||
const setHiddenWaitRacingAnimation = () => { | ||
const $spinnerContainers = document.querySelectorAll('.spinner-container'); | ||
|
||
$spinnerContainers.forEach(($spinnerContainer) => | ||
setVisibility($spinnerContainer, false), | ||
); | ||
}; | ||
|
||
const arrowTemplate = () => { | ||
return `<div class="forward-icon mt-2">⬇️️</div>`; | ||
|
@@ -13,21 +21,28 @@ const updateRacingCount = (cars) => { | |
const isForward = isEffectiveScore( | ||
getRandomNumber(GAME.MIN_SCORE, GAME.MAX_SCORE), | ||
); | ||
|
||
if (isForward) { | ||
$car.dataset.forwardCount = Number($car.dataset.forwardCount) + 1; | ||
$car.parentNode.insertAdjacentHTML('beforeend', arrowTemplate()); | ||
$car.insertAdjacentHTML('afterend', arrowTemplate()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
} | ||
}); | ||
}; | ||
|
||
export const startGame = (racingCount) => { | ||
const cars = document.querySelectorAll('.car-player'); | ||
const $gameResultSection = document.querySelector('#game-result-section'); | ||
const totalRacingDurationTime = racingCount * GAME.RACING_TIME; | ||
|
||
for (let i = 0; i < racingCount; i++) { | ||
const gameProcess = setInterval(() => { | ||
if (racingCount-- === 1) { | ||
clearInterval(gameProcess); | ||
} | ||
Comment on lines
+36
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 가독성이 좋지 않다. 차라리 다음 처럼 작성했다면 어땠을까 const gameProcess = setInterval(() => {
if (racingCount === 상수) {
clearInterval(gameProcess);
racingCount -= 1;
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아니면 별도의 함수로 분리했어도 좋았겠다. |
||
updateRacingCount(cars); | ||
} | ||
}, GAME.RACING_TIME); | ||
|
||
toggleVisibility('$gameResultSection'); | ||
printGameResult(); | ||
setTimeout(() => { | ||
setVisibility($gameResultSection, true); | ||
setHiddenWaitRacingAnimation(); | ||
printGameResult(); | ||
}, totalRacingDurationTime); | ||
}; |
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.
stub()
을 쓰는 발상까지는 좋지만alertStub.getCall(0)
처럼 콜스택에 매직넘버로 접근하는 방법보다는 다른 방법을 더 찾아봐야겠다.