๊ตฌํ์ ์ํ MEMO
index.html์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์คํฌ๋ฆฝํธ๋ก ์ด๋ฏธ ํฌํจ๋์ด ์๊ธฐ์ ์ ์ญ ๊ฐ์ฒด๋ก ์ถ๊ฐ๋์ด ์์
- ๋ฐ๋ก import ํ์ง ์์๋ ์ฌ์ฉ ๊ฐ๋ฅ
// ex)
const randomNumber = Random.pickNumberInRange(1, 9);
import
๋ชจ๋์์ ์ฌ๋ฌ ๋ฉค๋ฒ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. ์๋์ import๋ก ํ์ฌ ๋ฒ์ ๋ด์ foo, bar ๋ฉค๋ฒ๋ฅผ ํฌํจ์ํฌ ์ ์๋ค.
import { foo, bar } from "my-module.js";
commit message convention(Angular JS)
- ์ปค๋ฐ ์ ์ ํ์ธํ๊ธฐ!!
Subject line
Subject line contains succinct description of the change.
- feat (feature)
- fix (bug fix)
- docs (documentation)
- style (formatting, missing semi colons, …)
- refactor
- test (when adding missing tests)
- chore (maintain)
Scope could be anything specifying place of the commit change. For example $location, $browser, $compile, $rootScope, ngHref, ngClick, ngView, etc...
- use imperative, present tense: “change” not “changed” nor “changes”
- don't capitalize first letter
- no dot (.) at the end
- just as in use imperative, present tense: “change” not “changed” nor “changes”
- includes motivation for the change and contrasts with previous behavior
๊ตฌํ์ฌํญ
- index.html์์ ์ซ์๋ฅผ ์ ๋ ฅ๋ฐ๊ณ , ๋ฒํผ์ ๋๋ฅด๋ฉด xxx.js ํ์ผ์์ ์ด ๊ฐ์ด ์ฒ๋ฆฌ๋๋๋ก ํด์ผ ํจ
- id๊ฐ result์ธ div ํ๊ทธ์ ํํธ(1์คํธ๋ผ์ดํฌ, 1๋ณผ 1์คํธ๋ผ์ดํฌ, ๋ซ์ฑ)๋ฅผ ๋ฐ์์ ํ์ํด์ผ ํจ
index.js
export default class BaseballGame {
play(computerInputNumbers, userInputNumbers) {
return "๊ฒฐ๊ณผ ๊ฐ String";
}
}
// ์์
play(123, 456); // '๋ซ์ฑ'
play(123, 345); // '1๋ณผ'
play(123, 432); // '2๋ณผ'
play(123, 312); // '3๋ณผ'
play(123, 145); // '1์คํธ๋ผ์ดํฌ'
play(123, 134); // '1๋ณผ 1์คํธ๋ผ์ดํฌ'
play(123, 132); // '2๋ณผ 1์คํธ๋ผ์ดํฌ'
play(123, 124); // '2์คํธ๋ผ์ดํฌ'
BaseballGame ํด๋์ค์ play ํจ์๋ฅผ ์ด์ฉํด์ return ๊ฐ์ด ์์์ ๊ฐ์ด ๋์ฌ ์ ์๊ฒ ๋ด๋ถ ๋ก์ง ์กฐ์
-> ๊ฒฐ๊ณผ ๊ฐ์ ์คํธ๋ง์ผ๋ก ๋ฆฌํดํ๊ณ , alert๊ฐ ๋์ค๋๋ก ํด์ผํจ.
๊ธฐ๋ฅ ๊ตฌํ
ํจ์์ ์ฌ๋ฌ ๊ฐ ๋ฐํํ๊ธฐ
์ฌ๋ฌ ๊ฐ๋ค์ ๋ฐฐ์ด ํน์ ๊ฐ์ฒด๋ก ๋ฌถ์ด์ ํ๋์ ๊ฐ์ผ๋ก ๋ง๋ ํ์ ๋ฐํํ๊ฑฐ๋, ๋ฐฐ์ด, ๊ฐ์ฒด๋ฅผ ๋ถํ ํ ๋์ ํ์ฌ ๋ฐํ์ด ํ์ํ๋ค.
- parseInputNumber() ํจ์์ return ๊ฐ์ ๊ฐ์ฒด๋ก ๋ฌถ์ด์ ๋ฐํ
- ๋ถํ ๋์ ๋ฐฉ๋ฒ์ผ๋ก ๋ณ์์ ํ ๋น
input number parsing ๋ฐ play method์ ๊ฐ์ฒด๋ก ๋ฐํ
'ํจ์(๋๋ ๋ฉ์๋)๊ฐ ํ ๊ฐ์ง ์ผ๋ง ํ๋๋ก ์ต๋ํ ์๊ฒ ๋ง๋ค๋ฉฐ, indent depth๊ฐ 3์ด ๋์ง ์๋๋ก ๊ตฌํํ๋ค'๋ ๊ณตํต ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ parsing ํ๋ ํจ์์ parsing๋ ํจ์๋ฅผ ๊ฐ์ฒด๋ก ๋ง๋ค์ด ๋ฐํํ๋ ํจ์๋ก ๋๋์ด ๊ตฌํํ๋ค.
import {parseInputNumber} from './calLogic.js';
class BaseballGame {
play(computerInputNumbers, userInputNumbers) {
let [comIn, userIN] = parseInputNumber(computerInputNumbers, userInputNumbers)
console.log(comIn, userIN);
return "๊ฒฐ๊ณผ ๊ฐ String";
}
}
function generateObj (CIN_first, CIN_second, CIN_third,UIN_first, UIN_second, UIN_third){
const comIN = new Object();
comIN['first'] = CIN_first;
comIN['second'] = CIN_second;
comIN['third'] = CIN_third;
const userIN = new Object();
userIN['first'] = UIN_first;
userIN['second'] = UIN_second;
userIN['third'] = UIN_third;
return [comIN, userIN];
}
export function parseInputNumber (computerInputNumbers, userInputNumbers){
let CIN_first, CIN_second, CIN_third;
let UIN_first, UIN_second, UIN_third;
CIN_first = Math.floor(computerInputNumbers/100);
CIN_second = Math.floor(computerInputNumbers%100/10);
CIN_third = Math.floor(computerInputNumbers%10);
UIN_first = Math.floor(userInputNumbers/100);
UIN_second = Math.floor(userInputNumbers%100/10);
UIN_third = Math.floor(userInputNumbers%10);
console.log(CIN_first, CIN_second, CIN_third);
console.log(UIN_first, UIN_second, UIN_third);
return generateObj(CIN_first, CIN_second, CIN_third,UIN_first, UIN_second, UIN_third);
}
- parseInputNumber ํจ์: ์ปดํจํฐ์์ ์์ฑํ ๋๋ค ์ซ์์ user๋ก ๋ถํฐ ์ ๋ ฅ ๋ฐ์ ์๋ฅผ ์๋ฆฟ์์ ๋ฐ๋ผ ๋๋์ด ๊ฐ๊ฐ ๊ด๋ฆฌํ๋ค.
- generateObj ํจ์: ์ด ํจ์์์ ๊ฐ๊ฐ ๊ด๋ฆฌ๋๋ ๋ณ์๋ฅผ ๊ฐ์ฒดํํ์ฌ ๋ฐํํ๋ค.
๋ณผ, ์คํธ๋ผ์ดํฌ ๊ฐ์ ์ธ๊ธฐ
parsing ํ ๊ฐ์ฒด ํํ๋ก ๊ด๋ฆฌ ํ๊ณ ์๋ input number๋ฅผ ๋น๊ตํ์ฌ ๋ณผ์ ๊ฐ์์ ์คํธ๋ผ์ดํฌ ๊ฐ์๋ฅผ ์ธ์ผํ๋ค. ์ด ํจ์๋ ๊ตฌํ ์๊ตฌ์ฌํญ์ ๋ฐ๋ผ ๋ณผ์ ๊ฐ์๋ฅผ ์ธ๋ ํจ์, ์คํธ๋ผ์ดํฌ์ ๊ฐ์๋ฅผ ์ธ๋ ํจ์ ๋๋์ด ๊ตฌํํ๋ค.
// ๋ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ ๋ฐ์์ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํ๋ main ํจ์
export function gamestart (comIN, userIN){
// i = ballCheck
let strike_cnt = strikeCheck(comIN, userIN);
let ball_cnt = ballCheck(comIN, userIN);
return [ball_cnt, strike_cnt];
}
// ball ๊ฐ์ ์ธ๊ธฐ
function ballCheck(comIN, userIN){
let com_arr = Object.values(comIN);
let user_arr = Object.values(userIN);
let temp_ball_cnt = 0;
for (let i = 0; i<3; i++){
if (user_arr.includes(com_arr[i])){
console.log(com_arr[i]);
console.log(user_arr);
temp_ball_cnt += 1
}
}
return temp_ball_cnt;
}
// strike ๊ฐ์ ์ธ๊ธฐ
function strikeCheck(comIN, userIN){
let temp_strike_cnt = 0;
if (comIN['first'] == userIN['first']){
userIN['first'] = 10;
temp_strike_cnt += 1;
}
if (comIN['second'] == userIN['second']){
userIN['second'] = 10;
temp_strike_cnt += 1;
}
if (comIN['third'] == userIN['third']){
userIN['third'] = 10;
temp_strike_cnt += 1;
}
return temp_strike_cnt;
}
- export function () ~ : export๋ฅผ ํตํด index.js ํ์ผ์์ ์ด ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
- gamestart : ๋ณธ๊ฒฉ์ ์ผ๋ก game์ด ์์๋๋ ํจ์๋ก game์ ๊ฒฐ๊ณผ๋ก ๋ณผ์ ๊ฐ์(ball_cnt), ์คํธ๋ผ์ดํฌ์ ๊ฐ์(strike_cnt)๋ฅผ returnํ๋ค.
- strikeCheck : ๋ฐ๋์ ballCheck ์ ์ strikeCheck๊ฐ ์ํ๋์ด์ผ ํ๋ค. ์๋ํ๋ฉด, strike๋ ball๋ก ์นด์ดํ ๋์ง ์๋๋ก strike์ ํด๋นํ๋ value๋ฅผ ์์ ํด๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์ด๋ค.
์ปดํจํฐ์ ๋๋ค๊ฐ ์์ฑ
index.html์ด ์ต์ด ๋ก๋ฉ๋ ๋, ๋๋ค ๋๋ฒ๋ฅผ ์์ฑํ์ฌ user๊ฐ ๋ง์ถ ์ ์๋๋ก ๊ตฌํํ๋ค. ์ ์ํ ์ ์ form tag์ button์ ํด๋ฆญํ์ฌ๋ ์ด ๋๋ค ๊ฐ์ ๋ณ๊ฒฝ๋๋ฉด ์ ๋๋ค๋ ์ ์ด๋ค. ์ด๋ฅผ ๊ณ ๋ คํ๋ฉด, ./index.js ํ์ผ์์ script๊ฐ ํ์ฑ๋ ๋ ์ต์ด ํธ์ถ๋๋๋ก ํ๋ ๊ฒ์ด ์ข์ ๋ณด์ธ๋ค.
// src/index.js
function generateRandom(){
const randomNumber1 = MissionUtils.Random.pickNumberInRange(1, 9);
const randomNumber2 = MissionUtils.Random.pickNumberInRange(1, 9);
while (randomNumber1 == randomNumber2){
randomNumber2 = MissionUtils.Random.pickNumberInRange(1, 9);
}
const randomNumber3 = MissionUtils.Random.pickNumberInRange(1, 9);
while (randomNumber1 == randomNumber3 | randomNumber2 == randomNumber3){
randomNumber3 = MissionUtils.Random.pickNumberInRange(1, 9);
}
return randomNumber1 * 100 + randomNumber2 * 10 + randomNumber3;
}
...
const randomNumber = generateRandom();
const form = document.querySelector("form");
form.addEventListener('submit', function(event) {
...
let result_str = game.play(userInput, randomNumber);
...
});
- generateRandom : ์ค๋ณต๋๋ ์ซ์๊ฐ ์์ฑ๋๋ฉด ์ ๋๊ธฐ์ ์์ฑ ์ ํ์ธํ์ฌ ์ค๋ณต๋ ๊ฒฝ์ฐ ์ฌ์์ฑ๋ ์ ์๋๋ก while ๋ฌธ์ ๊ตฌ์ฑํ๋ค.
๊ฒฐ๊ณผ ๋ฌธ์์ด ์ถ๋ ฅ ๋ฐ ํ์
๋ณผ, ์คํธ๋ผ์ดํฌ์ ๊ฐ์๋ฅผ ๋ฐ์์ผ๋ฏ๋ก ์ด์ ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ ํจ์๋ฅผ ๊ตฌํํ๋ค. ์ด๋ ๊ธฐ๋ฅ ์๊ตฌ์ฌํญ์ ๋ฐ๋ผ ์ถ๋ ฅ๋๋๋ก ํ๋ค.
export function resultStr (ball_cnt, strike_cnt){
let result;
if (ball_cnt == 0 & strike_cnt == 0){
result = '๋ซ์ฑ';
return result;
}
if (ball_cnt == 0){
result = strike_cnt + "์คํธ๋ผ์ดํฌ"
return result;
}
if (strike_cnt == 0){
result = ball_cnt + "๋ณผ"
return result;
}
result = ball_cnt + "๋ณผ" + " " + strike_cnt + "์คํธ๋ผ์ดํฌ";
return result;
}
export function displayResult(str){
document.getElementById("result").innerText=str;
}
- resultStr : ๋ณผ, ์คํธ๋ผ์ดํฌ ๊ฐ์์ ๋ฐ๋ผ์ result์ ์๋ง๋ ๋ฌธ์์ด์ ํ ๋นํ์ฌ return ํ๋ค.
- displayResult : ๋ฐํ ๋ฐ์ ๋ฌธ์์ด์ Element ID๊ฐ "result"์ธ ํ๊ทธ์ ๋ด๋ถ text ๊ฐ์ผ๋ก ํ ๋นํ๋ค. text ๊ฐ์๋ ์์ ์์ฑํ ๋ฌธ์์ด์ด ํ ๋น๋๋ค.
์ ํจํ์ง ์์ ์ ๋ ฅ์ฐฝ alert ์ฒ๋ฆฌ
//src/util.js
export function isInputValid(input_str){
if (122 < input_str & input_str < 977){
return true;
}
return false;
}
//src/index.js
form.addEventListener('submit', function(event) {
...
if (isInputValid(userInput)){
let game = new BaseballGame;
let result_str = game.play(userInput, randomNumber);
displayResult(result_str);
}
else{
window.alert("invalid input");
}
- isInputValid : input ๊ฐ์ด 123๋ถํฐ 987๊น์ง ์ ๋ ฅ๋๋ฏ๋ก ์์ ๊ฐ์ด ๋ฒ์๋ฅผ ์ฃผ์๋ค. ์ค๋ณต๊ฐ์ ๋ํ ์ฒ๋ฆฌ๊ฐ ๋ฏธํกํ์ฌ ๋ณด์ ์์ ์ด๋ค.
- ์ ํจ ํ์ง ์์ ๊ฒฝ์ฐ window.alert() ํจ์๋ก ์๋ด ์ฐฝ์ pop-up ํ๋ค.
npm run test๋ฅผ ํตํด cypress๋ฅผ ์คํ์์ผ test๊ฐ ํต๊ณผํ๋์ง ํ์ธํ ์ ์๋ค. ๋ค๋ง, ์ด๋ app.spec.js ๋ด์ ํ ์คํธ ์ผ์ด์ค๋ฅผ ํต๊ณผํ๋์ง ์ฌ๋ถ๋ง ํ์ธ ๊ฐ๋ฅํ์ฌ ์ธ๋ถ ๊ธฐ๋ฅ ๊ตฌํ์ด ์๋ฃ๋์๋ค๋ ๋ณด์ฅ์ ํ ์ ์๋ค.