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

[2단계 - 자동차 경주 구현] 유조(조윤호) 미션 제출합니다. #25

Merged
merged 27 commits into from
Feb 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a2e2b84
docs: 불필요한 내용 정리
yujo11 Feb 9, 2021
d0f6194
test: 자동차 경주가 진행될 때 턴마다 1초의 지연시간이 생기는지 테스트 하는 코드 작성
yujo11 Feb 10, 2021
dbc866d
test: 자동차 경주의 지연시간마다 Animation이 출력되는지 테스트하는 코드 작성
yujo11 Feb 10, 2021
5d8ef99
test: 경주를 마쳤을 때 2초 후 축하의 alert메세지가 출력되는지 확인하는 테스트 코드 작성
yujo11 Feb 10, 2021
4df4349
refactor: 전체 코드의 일관성을 위해 함수 선언식을 함수 표현식으로 변경
yujo11 Feb 10, 2021
cb3803d
feat: 자동차 경주가 진행될 때 매 턴마다 1초의 delay를 주는 기능
yujo11 Feb 10, 2021
ec48997
feat: 경주가 끝난 후 2초 후에 축하의 alert메세지를 띄우는 기능
yujo11 Feb 10, 2021
b868476
refactor: alert출력 테스트의 대기시간 수정
yujo11 Feb 10, 2021
4a58639
refactor: 역할을 확실히 할 수 있도록 constant 모듈 구성 변경
yujo11 Feb 10, 2021
a3f6ec2
refactor: 불필요한 값을 return하지 않도록 수정
yujo11 Feb 10, 2021
b4c1b7a
fix: 테스트코드가 애니메이션이 몇개 출력되는지 검증하지 못 하던 오류 수정
yujo11 Feb 10, 2021
fba8912
refactor: Error Message 변수명 직관적이게 변경
yujo11 Feb 11, 2021
cfbc0dc
feat: 경주 진행 턴 대기시간에 애니메이션을 표시하는 기능
yujo11 Feb 11, 2021
5d9d3e4
docs: 구현한 기능들 체크
yujo11 Feb 11, 2021
2f0fc82
refactor: 불필요한 requestAnimationFrame 제거
yujo11 Feb 11, 2021
ff25aac
test: Animation 출력 테스트 신뢰도를 높이기 위해 visible메서드로 변경
yujo11 Feb 11, 2021
a272ee3
test: 자동차 경주가 진행되는 테스트들에 지연시간 추가
yujo11 Feb 11, 2021
a19d9e8
test: 자동차 경주 진행 중 딜레이 검증 케이스 추가
yujo11 Feb 11, 2021
4700ef6
style: 가독성을 위한 함수, 변수 이름 변경
yujo11 Feb 11, 2021
2c2f7ba
chore: eslint config 변경
yujo11 Feb 11, 2021
4e0ca6f
refactor: toggle- 함수들을 set- 함수로 변경
yujo11 Feb 11, 2021
0270679
refactor: 반복되는 숫자 상수로 분리
yujo11 Feb 11, 2021
b794b80
refactor: winners가 없을 경우 예외처리가 가능하도록 alert 함수 수정
yujo11 Feb 15, 2021
7625e7c
refactor: 가독성을 위한 함수 이름 변경 및 분리
yujo11 Feb 15, 2021
d6e71c1
test: 반복되는 숫자 상수로 분리
yujo11 Feb 15, 2021
1f5ab2f
style: 상수 이름 변경 RACING_TIME -> RACE_TIME
yujo11 Feb 15, 2021
42f041a
test: 반복되는 테스트 내용 함수로 분리
yujo11 Feb 15, 2021
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
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
"import/extensions": "off",
"import/prefer-default-export": "off",
"max-depth": ["error", 1],
"max-lines-per-function": ["error", 15]
"max-lines-per-function": ["error", 20]
}
}
38 changes: 4 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,39 +29,9 @@

### 🎯🎯 step2

- [ ] 자동차 경주 게임의 턴이 진행 될 때마다 1초의 텀(progressive 재생)을 두고 진행한다.
- [ ] 애니메이션 구현을 위해 setInterval, setTimeout, requestAnimationFrame 을 활용한다.
- [ ] 정상적으로 게임의 턴이 다 동작된 후에는 결과를 보여주고, 2초 후에 축하의 alert 메세지를 띄운다.
- [ ] 위 기능들이 정상적으로 동작하는지 Cypress를 이용해 테스트한다.
- [x] 자동차 경주 게임의 턴이 진행 될 때마다 1초의 텀(progressive 재생)을 두고 진행한다.
- [x] 애니메이션 구현을 위해 setInterval, setTimeout, requestAnimationFrame 을 활용한다.
- [x] 정상적으로 게임의 턴이 다 동작된 후에는 결과를 보여주고, 2초 후에 축하의 alert 메세지를 띄운다.
- [x] 위 기능들이 정상적으로 동작하는지 Cypress를 이용해 테스트한다.

<br>

## 📝 구현 기능 목록

- 자동차 이름 입력
- [x] 올바른 자동차 이름을 입력한 후 확인버튼을 누르면 시도횟수 입력창을 화면에 출력한다.
> - X ] 'EAST, WEST, SOUTH, NORTH'를 입력하면 화면에 시도횟수 입력창이 표시되는지 테스트를 한다.
- [x] 올바르지 않은 자동차 이름을 입력한 경우 경고메세지를 출력한다.
> - [x] 'YUJOYOONHO'을 입력한 경우 '이름은 5글자 이하로 입력해 주세요.' 경고메세지를 출력하는 테스트를 한다.
> - [x] 공백만 입력된 경우나 아무것도 입력되지 않은 경우 '공백만으로는 이름을 구성할 수 없습니다.' 경고메세지를 출력하는 테스트를 한다.
> - [x] 이 때, 자동차 이름 입력창을 초기화 하는지 테스트를 한다.
- 시도 횟수 입력
- [x] 양의 정수만을 시도횟수로 입력할 수 있다.
> - [x] '-7'을 입력한 경우 '1 이상의 숫자를 입력해주세요.' 경고메세지를 출력하는 테스트를 한다.
> - [x] 공백만 입력된 경우나 아무것도 입력되지 않은 경우 '1 이상의 숫자를 입력해주세요.' 경고메세지를 출력하는 테스트를 한다.
> - [x] 이 때, 시도횟수 입력창을 초기화 하는지 테스트를 한다.
- [x] 확인버튼을 누르면 앞서 입력된 자동차를 화면에 표시해준다.
> - [x] 입력된 자동차 대수와 화면에 보이는 자동차 대수가 일치하는지 테스트를 한다.
> - [x] 입력된 자동차 이름과 화면에 보이는 자동차 이름이 일치하는지 테스트를 한다.
- 자동자 경주 진행
- [x] 자동차 경주가 정상적으로 진행되는지 테스트 한다.
> - [x] 난수를 생성하는 함수가 0 ~ 9 사이의 정수를 반환하는지 확인하는 테스트를 한다.
> - [x] 전진횟수를 결정하는 함수가 '[1, 3, 3, 7]'을 입력받았을 때 '1'을 반환하는지 확인하는 테스트를 한다.
> - [ X 각 자동차의 이름과 화살표 갯수가 제대로 표시되는지 확인하는 테스트를 한다.
- 결과 출력
- [x] 자동차 경주 게임을 완료한 후 누가 우승했는지를 화면에 출력한다. 우승자가 여러명일 경우 ,를 이용하여 구분해서 출력한다.
> - [x] 최종 우승자가 `🏆 최종 우승자: ${쉼표로 구분된 우승자 목록} 🏆`와 일치하는지 확인하는 테스트를 한다.
- [x] 다시 시작버튼을 누르면 초기 화면을 출력해서 게임을 다시시작할 수 있도록 한다.
> - [x] '#racing-count-section', '#game-process-section', '#game-result-section'이 hidden 속성을 가지고 있는지 테스트를 한다.
> - [x] '#racing-count-section' 노드가 비어있는지 테스트를 한다.
> - [x] '#car-name-input', '#racing-count-input'의 입력창이 비어있는지 테스트를 한다.
81 changes: 66 additions & 15 deletions cypress/integration/racingGame.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ import { isEffectiveScore } from '../../src/js/game/isEffectiveScore.js';
import { GAME } from '../../src/js/utils/constant.js';

describe('racing-game', () => {
beforeEach(() => {
cy.visit('http://localhost:5500/');
});

const carNames = ['EAST', 'WEST', 'SOUTH', 'NORTH'];
const TEST_RACE_TIME = GAME.RACE_TIME * 5;

const typeCarNameAndClickToSubmitButton = (
carNames = ['EAST', 'WEST', 'SOUTH', 'NORTH'],
Expand All @@ -21,6 +18,27 @@ describe('racing-game', () => {
return cy.get('#racing-count-submit').click();
};

const waitRaceTime = (raceTime = TEST_RACE_TIME) => {
cy.clock();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반복되는 cy.clock()은 beforeEach() 구문에 넣었으면 중복을 줄일 수 있었겠다.

cy.wait(raceTime);
};

const waitTimeAndcheckElementShow = (time, element) => {
cy.clock();
cy.wait(time);
cy.get(element).should('be.visible');
};

const waitTimeAndcheckElementHide = (time, element) => {
cy.clock();
cy.wait(time);
cy.get(element).should('not.be.visible');
};

beforeEach(() => {
cy.visit('http://localhost:5500/');
});

it('자동차 이름 입력 시, 화면에 시도 횟수 입력창이 표시되는지 테스트 한다.', () => {
typeCarNameAndClickToSubmitButton();
cy.get('#racing-count-section').should('be.visible');
Expand Down Expand Up @@ -59,8 +77,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(
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stub()을 쓰는 발상까지는 좋지만 alertStub.getCall(0)처럼 콜스택에 매직넘버로 접근하는 방법보다는 다른 방법을 더 찾아봐야겠다.

Expand All @@ -82,44 +100,61 @@ 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))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HoF를 이용해 chaining을 진행하니 가독성이 많이 좋아졌네요! 굿입니다! 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다! 다른 크루의 리뷰에 달린 코멘트에서 아이디어를 얻었습니다ㅎㅎ

.filter((num) => GAME.MIN_SCORE <= num && num <= GAME.MAX_SCORE);
Copy link
Author

Choose a reason for hiding this comment

The 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초의 지연시간이 생기는지 테스트 한다.', () => {
typeCarNameAndClickToSubmitButton();
typeRacingCountAndClickToSubmitButton(5);

waitTimeAndcheckElementHide(2500, '#game-result-section');
waitTimeAndcheckElementShow(2500, '#game-result-section');
});

it('자동차 경주 진행 중 지연시간마다 Anmiation이 출력되는지 테스트 한다.', () => {
typeCarNameAndClickToSubmitButton();
typeRacingCountAndClickToSubmitButton();

waitTimeAndcheckElementShow(2000, '.spinner-container');
waitTimeAndcheckElementShow(2000, '.spinner-container');
waitTimeAndcheckElementHide(1000, '.spinner-container');
});

it('자동차 경주가 정상적으로 진행되는지 테스트 한다.', () => {
typeCarNameAndClickToSubmitButton();
typeRacingCountAndClickToSubmitButton();

waitRaceTime();

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);
});
});
});
Expand All @@ -128,6 +163,8 @@ describe('racing-game', () => {
typeCarNameAndClickToSubmitButton();
typeRacingCountAndClickToSubmitButton();

waitRaceTime();

cy.get('.car').then(($cars) => {
const counts = [...$cars].map(($car) => {
return $car.querySelectorAll('.forward-icon').length;
Expand All @@ -148,9 +185,23 @@ describe('racing-game', () => {
});
});

it('자동차 경주가 모두 끝났을 때, 2초 후 축하의 alert메세지가 출력되는지 테스트 한다.', () => {
typeCarNameAndClickToSubmitButton(['yujo']);
typeRacingCountAndClickToSubmitButton();

// 자동차 경주 진행시간 5000ms + alert 출력 대기시간 2000ms
waitRaceTime(TEST_RACE_TIME + GAME.RESULT_ALERT_DELAY);
cy.on('window:alert', (txt) => {
expect(txt).to.equal('🎉 축하드립니다! 우승자는 yujo입니다! 🎉');
});
});

it('다시 시작버튼을 눌렀을 때 화면이 초기화 되는지 테스트한다.', () => {
typeCarNameAndClickToSubmitButton();
typeRacingCountAndClickToSubmitButton();

waitRaceTime();

cy.get('#game-restart-button').click();
cy.get('#racing-count-section').should('not.be.visible');
cy.get('#game-process-section').should('not.be.visible');
Expand Down
15 changes: 14 additions & 1 deletion src/js/game/printGameResult.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
import { GAME } from '../utils/constant.js';
import { getWinners } from './getWinners.js';
import { restartGame } from './restartGame.js';

const alertGameResult = (winners) => {
if (!winners) {
alert('❌ Error : 우승자를 찾지 못 했습니다. ❌');
throw new Error('우승자를 찾지 못 했습니다.');
}

alert(`🎉 축하드립니다! 우승자는 ${winners}입니다! 🎉`);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

winners의 값이 빈 배열이거나 undefined, null인 경우에 대한 예외처리는 없어도 될까요~?
이러한 parameter에 대한 예외처리를 함수를 작성하실 때 고려하시는게 중요합니다.

함수를 작성하는 순서

  1. 먼저 한글로 어떤 행동을 하는 함수인지 정의한다.
const 게임결과에_대한_알럿을_출력하는_함수 = () => {}
  1. 해당 함수가 어떤 parameter가 필요한지 정의한다
const 게임결과에_대한_알럿을_출력하는_함수 = (winners) => {}
  1. 해당 parameter는 어떠한 예외가 있는지 bad case를 정의하여 return 구문을 작성한다.
const 게임결과에_대한_알럿을_출력하는_함수 = (winners) => {
if (!Array.isArray(winners) || winners.length === 0) return

alert(`🎉 축하드립니다! 우승자는 ${winners}입니다! 🎉`);
}

사실 이 기법은 TDD할 때도 많이 쓰이는 기법입니다. 테스트 케이스의 base case를 정의하기 전, bad case를 정해두시면 언제나 좋습니다!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • TDD 및 알고리즘을 작성할때 유용합니다

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와 알려주신 순서대로 함수를 정의하는건 한번도 생각해보지 못 했는데 정말 좋은 방법이네요!! 좋은 습관을 들일 수 있게 앞으로 함수를 작성할 때 알려주신 순서를 지키면서 작성 해야겠습니다!

좋은 인사이트 주셔서 감사합니다!!👍👍👍

Choose a reason for hiding this comment

The 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} 🏆`;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

무언가 위의 alertGameResultalert 메시지와 중복해서 써먹을 수 있을 것 같아 보이네요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[질문]
최종 우승자를 출력하는(보여주는) 텍스트와 alert를 통해 사용자에게 알려주는 텍스트에서 중복되는 부분이 winners 뿐인데 혹시 어떤식으로 중복해서 사용할 수 있을까요? 나름 생각을 해봤지만 어떤 식으로 써먹을 수 있을지 아이디어가 생각나지 않아서 질문을 남깁니다ㅠㅠ

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 요것은 패스하셔도 됩니다!!!

$gameRestartButton.addEventListener('click', restartGame);

setTimeout(() => alertGameResult(winners), GAME.RESULT_ALERT_DELAY);
};
19 changes: 12 additions & 7 deletions src/js/game/restartGame.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { toggleDisabled } from '../utils/toggleDisabled.js';
import { toggleVisibility } from '../utils/toggleVisibility.js';
import { enabledElement, hideElement } from '../utils/setAttribute.js';

const resetGame = () => {
const $carNameInput = document.querySelector('#car-name-input');
Expand All @@ -12,11 +11,17 @@ const resetGame = () => {
};

export const restartGame = () => {
toggleVisibility('$racingCountSection');
toggleVisibility('$gameProcessSection');
toggleVisibility('$gameResultSection');
toggleDisabled('$carNameSubmit');
toggleDisabled('$racingCountSubmit');
const $carNameSubmit = document.querySelector('#car-name-submit');
const $racingCountSubmit = document.querySelector('#racing-count-submit');
const $racingCountSection = document.querySelector('#racing-count-section');
const $gameProcessSection = document.querySelector('#game-process-section');
const $gameResultSection = document.querySelector('#game-result-section');

hideElement($racingCountSection);
hideElement($gameProcessSection);
hideElement($gameResultSection);
enabledElement($carNameSubmit);
enabledElement($racingCountSubmit);

resetGame();
};
29 changes: 22 additions & 7 deletions src/js/game/startGame.js
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 { hideElement, showElement } from '../utils/setAttribute.js';

const setHiddenWaitRacingAnimation = () => {
const $spinnerContainers = document.querySelectorAll('.spinner-container');

$spinnerContainers.forEach(($spinnerContainer) =>
hideElement($spinnerContainer),
);
};

const arrowTemplate = () => {
return `<div class="forward-icon mt-2">⬇️️</div>`;
Expand All @@ -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());
Copy link
Author

Choose a reason for hiding this comment

The 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.RACE_TIME;

for (let i = 0; i < racingCount; i++) {
const gameProcess = setInterval(() => {
if (racingCount-- === 1) {
clearInterval(gameProcess);
}
Comment on lines +36 to +39
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

가독성이 좋지 않다. 차라리 다음 처럼 작성했다면 어땠을까

  const gameProcess = setInterval(() => {
    if (racingCount === 상수) {
      clearInterval(gameProcess);
      racingCount -= 1;
    }

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아니면 별도의 함수로 분리했어도 좋았겠다.

updateRacingCount(cars);
}
}, GAME.RACE_TIME);

toggleVisibility('$gameResultSection');
printGameResult();
setTimeout(() => {
showElement($gameResultSection);
setHiddenWaitRacingAnimation();
printGameResult();
}, totalRacingDurationTime);
};
6 changes: 3 additions & 3 deletions src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ const init = () => {
$racingCountSubmit.addEventListener('click', handleRacingCountInput);
};

export default function RacingGame() {
export const racingGame = () => {
init();
}
};

window.onload = () => {
new RacingGame();
racingGame();
};
25 changes: 16 additions & 9 deletions src/js/input/handleCarNameInput.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { VALIDATOR, ERR_MESSAGE } from '../utils/constant.js';
import { toggleDisabled } from '../utils/toggleDisabled.js';
import { toggleVisibility } from '../utils/toggleVisibility.js';
import { GAME, ERR_MESSAGE } from '../utils/constant.js';
import { disabledElement, showElement } from '../utils/setAttribute.js';

const carTemplate = (carName) => {
return `<div class="car" data-name=${carName}>
<div class="car-player mr-2" data-forward-count="0">${carName}</div>
<div class="d-flex justify-center mt-4">
<div class="relative spinner-container">
<span class="material spinner"></span>
</div>
</div>
</div>`;
};

Expand All @@ -17,11 +21,11 @@ const createCars = (carNames) => {
};

const isValidLength = (name) => {
return name.length <= VALIDATOR.MAX_NAME_LENGTH;
return name.length <= GAME.MAX_CAR_NAME_LENGTH;
};

const isBlank = (name) => {
return name.length >= VALIDATOR.MIN_NAME_LENGTH;
return name.length >= GAME.MIN_CAR_NAME_LENGTH;
};

const isValidCarName = (carNames) => {
Expand All @@ -30,21 +34,24 @@ const isValidCarName = (carNames) => {
return false;
}
if (!carNames.every((carName) => isBlank(carName))) {
alert(ERR_MESSAGE.NAME_BLANK);
alert(ERR_MESSAGE.NAME_CANNOT_BE_BLANK);
return false;
}
return true;
};

export const handleCarNameInput = () => {
const $carNameInput = document.querySelector('#car-name-input');
const $carNameSubmit = document.querySelector('#car-name-submit');
const $racingCountSection = document.querySelector('#racing-count-section');

const carNames = $carNameInput.value.split(',').map((car) => car.trim());
if (!isValidCarName(carNames)) {
return ($carNameInput.value = '');
$carNameInput.value = '';
return;
}

toggleVisibility('$racingCountSection');
toggleDisabled('$carNameSubmit');
showElement($racingCountSection);
disabledElement($carNameSubmit);
createCars(carNames);
};
Loading