-
Notifications
You must be signed in to change notification settings - Fork 3
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
[jwon] typescript-calculator #4
base: main
Are you sure you want to change the base?
Conversation
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.
흐흫.. 타입스크립트 처음인데 고생하셨습니다. 훨씬 코드도 전보다 깔끔해서 좋았습니다. 에러 처리 경우에도 굉장히 세세하게 처리해서 좋았습니다.
commit 메세지는 조금 더 세분화 하면 좋을것 같아요. 예를 들어서, feat: 테스트케이스 추가
는 테스트에 관한 부분이니 test: 테스트케이스 추가
로, feat: gitignore 수정
는 git 관련이니 chore: gitignore
로 바꾸는게 좋아보입니다. 링크 저는 docs를 만들어 기능 구현 정의를 해놓고 그 분기대로 commit 을 해보니 깔끔해서 저는 좋았습니다.
{
"parser": "typescript",
"singleQuote": true,
"trailingComma": "all"
}
마지막으로, prettier 설정은 singleQuote로 되어있는데 코드에는 " 로 적용돼서 prettier 가 적용이 안된것같아요. 고생하셨습니다 :)
"cypress/no-async-tests": "error", | ||
"import/extensions": "always" | ||
} | ||
} |
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.
EOL 관련 아티클 읽어보시면 좋을것 같아요 :)
@@ -1,3 +1,9 @@ | |||
package-lock.json | |||
yarn.lock |
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.
transcendence42/javascript-archive#16 (comment)
현재는 복잡도가 낮은 프로그램이여서 문제가 안될것같지만 후에 복잡도가 높아지면 같이 저장하는게 좋다고 생각합니다.! 또 package-lock.json
과 yarn.lock
이 공존하는데 , npm 과 yarn중 하나로 통일해서 사용하는게 좋을것 같아요!
cy.get('#total').should('have.text', '0'); | ||
}) | ||
|
||
it('3. 연산자는 1개만 입력 가능', () => { |
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.
it('3. 연산자는 1개만 입력 가능', () => { | |
it('3. 연산자 2개 이상 입력시, 먼저 입력한 연산자로 적용', () => { |
작성한 it의 설명은 함수 단위 테스트 설명이라고 생각합니다. BDD인 만큼 조금 더 세부적으로 행동을 중심으로 작성하면 좋을것 같아요! 아래는 Given, When, Then 에 대한 간략 설명입니댜!
Given : 시나리오 진행에 필요한 값을 설정합니다.
When : 시나리오를 진행하는데 필요한 조건을 명시합니다
Then : 시나리오를 완료했을 때 보장해야 하는 결과를 명시합니다.
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.
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.
맞아요! 제가 코멘트를 단 이유는 Given, When, Then의 느낌보다는 다음 it 설명이 유닛테스트 느낌이 더 강해서 였습니다. 조금 더 자세히 적어서 it 설명만 보아도 동작을 알 수 있어야 한다고 생각합니다.
연산자 2개 이상 입력시, 먼저 입력한 연산자로 적용
연산자 2개 이상(Given)
입력시,(When)
먼저 입력한 연산자로 적용(Then)
으로 나누어서 적었습니다!
}) | ||
|
||
it('5. 한 자릿수 사칙연산', () => { | ||
calculate([4], '+', [2], '6'); |
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.
LGTM 👍 👍
"cypress": "^7.4.0", | ||
"typescript": "^4.3.2" | ||
}, | ||
"description": "<br/> <br/> <p align=\"middle\" > <img width=\"100px;\" src=\"src/images/calculator_icon.png\"/> </p> <h2 align=\"middle\">level1 - 자바스크립트 계산기</h2> <p align=\"middle\">자바스크립트 계산기로 익혀보는 Cypress</p> <p align=\"middle\"> <img src=\"https://img.shields.io/badge/version-1.0.0-blue?style=flat-square\" alt=\"template version\"/> <img src=\"https://img.shields.io/badge/language-html-red.svg?style=flat-square\"/> <img src=\"https://img.shields.io/badge/language-css-blue.svg?style=flat-square\"/> <img src=\"https://img.shields.io/badge/language-js-yellow.svg?style=flat-square\"/> <img src=\"https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square\"/> </p>", |
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.
description에 HTML Tag를 포함하신 이유가 따로 있으신가요?
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.
이건.. 제가 한 기억이 없습니다. 초기 설정에 애를 먹어서 중복 작업이 많았었는데 어느 툴에선가 자동으로 들어갔나봅니다.
totalValue: string, | ||
clickValue: string | ||
): boolean => { | ||
const tmpValue = totalValue + clickValue; |
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.
const tmpValue = totalValue + clickValue; | |
const tmpValue: string = totalValue + clickValue; |
@@ -0,0 +1,32 @@ | |||
import { OPERATOR, REGEXP } from "../constants/index.js"; | |||
|
|||
export const calculator = (splitedTotalValue: Array<string>): number => { |
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.
저는 string[]
을 사용했는데 둘의 차이점이 궁금해서 찾아보았습니다.
What is the difference Array and string[]?
모두 다 동일한 문법인데, 차이점이 하나있다면
class MyArray extends Array<string> { ... }
확장 문법 사용할 때는 Array<string>
만 써야한다고 합니다.
import { calculator, makeFormula } from "../model/calculator.js"; | ||
|
||
export const clearTotalValue = (): void => { | ||
document.getElementById("total")!.innerText = "0"; |
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.
document.getElementById("total")!.innerText = "0"; | |
$("total")!.innerText = "0"; |
다른 코드 보니까 이렇게 간단하게 표현한 코드가 있어서 공유합니댜.
const $ = (id) => document.getElementById(id)
로 정의하면 위와같이 표현할 수 있습니다.
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.
넘 좋네요. 담 프로젝트에 한번 사용해보겠습니다.
@@ -0,0 +1,78 @@ | |||
{ | |||
"include": [ | |||
"src/**/*.ts" |
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.
"src/**/*.ts" | |
"./src/**/*.ts" |
이렇게 하면 빨간줄 사라지더라구요!
cy.get('#total').should('have.text', '1'); | ||
cy.get('.digit').contains('2').click(); | ||
cy.get('#total').should('have.text', '12'); | ||
cy.get('.digit').contains('3').click(); |
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.
위에 calculate 만들어 준 것처럼 따로 함수로 빼주면 더 깔끔해 보일 것 같아요!
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.
맞아요. 다음 과제에선 cypress 코드 작성에 조금 더 신경을 써봐야겠어요~!
const calculate = (number1, operator, number2, expectedResult) => { | ||
cy.get('.modifiers').click(); | ||
for (let index = 0 ; index < number1.length ; index += 1) { | ||
cy.get('.digit').contains(number1[index]).click(); | ||
} | ||
cy.get('.operations').contains(operator).click(); | ||
for (let index = 0 ; index < number2.length ; index += 1) { | ||
cy.get('.digit').contains(number2[index]).click(); | ||
} | ||
cy.get('.operations').contains('=').click(); | ||
cy.get('#total').should('have.text', expectedResult) | ||
} |
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.
깔끔하고 좋네요.
@@ -4,7 +4,7 @@ | |||
<meta charset="UTF-8" /> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
<title>Calculator</title> | |||
<link rel="stylesheet" type="text/css" href="src/css/index.css" /> | |||
<link rel="stylesheet" type="text/css" href="dist/css/index.css" /> |
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.
<link rel="stylesheet" type="text/css" href="dist/css/index.css" /> | |
<link rel="stylesheet" type="text/css" href="src/css/index.css" /> |
이렇게 해야 제대로 불러오네요
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.
수정하고 데모페이지 생성했습니다 :)
import { setEventListener } from "./event.js"; | ||
|
||
export const controller = (): void => { | ||
setEventListener(); |
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.
여기 바로 setEventListener의 코드 자체를 넣지 않고 함수를 넣은 이유가 있나요?
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.
이전 코드의 패턴을 그대로 복사해와서 사용해서 남은 흔적이에요. 없애고 메인에서 바로 해당 파트를 불러오는게 더 좋을 것 같습니다.
const tmpValueArray: RegExpMatchArray | null = tmpValue.match( | ||
"(" + | ||
REGEXP.NUMBERS + | ||
")?(" + | ||
REGEXP.OPERATORS + | ||
")?(" + | ||
REGEXP.NUMBERS + | ||
")?" | ||
); |
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.
match 라는 좋은 함수 배워갑니다.
str.match(regexp)
match() 메서드는 문자열이 정규식과 매치되는 부분을 검색합니다.
regexp
정규식 개체입니다. RegExp가 아닌 객체 obj가 전달되면, new RegExp(obj)를 사용하여 암묵적으로 RegExp로 변환됩니다. 매개변수를 전달하지 않고 match()를 사용하면, 빈 문자열:[""]이 있는 Array가 반환됩니다.
export const REGEXP = { | ||
// SIGN: '\\-{1}', | ||
NUMBERS: '\\-?\\d{1,3}', | ||
OPERATORS: 'X|\\-|\\+|\\/{1}' | ||
} |
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.
정규표현식도 잘 배워갑니다.
match말고 여러 함수에서 사용해볼 수 있네요.
정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다. 이 패턴들은 RegExp의 exec 메소드와 test 메소드 ,그리고 String의 match메소드 , replace메소드 , search메소드 , split 메소드와 함께 쓰입니다 .
if (!tmpValueArray[2] && tmpValueArray[3]) { | ||
return true; | ||
} | ||
if ( | ||
tmpValueArray[2] && | ||
!isNumber(totalValue.charAt(totalValue.length - 1)) && | ||
!isNumber(clickValue) | ||
) { | ||
return true; | ||
} | ||
if (tmpValueArray[3] && !isNumber(clickValue) && clickValue !== EQUAL) { | ||
return true; | ||
} | ||
if ( | ||
tmpValueArray[3] && | ||
tmpValue.length !== tmpValueArray[0].length && | ||
clickValue !== EQUAL | ||
) { | ||
return true; | ||
} |
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.
모든 if 문이 안에서 return 하고 있으니까 이렇게 바꾸면 좋겠네요 !
if (!tmpValueArray[2] && tmpValueArray[3]) { | |
return true; | |
} | |
if ( | |
tmpValueArray[2] && | |
!isNumber(totalValue.charAt(totalValue.length - 1)) && | |
!isNumber(clickValue) | |
) { | |
return true; | |
} | |
if (tmpValueArray[3] && !isNumber(clickValue) && clickValue !== EQUAL) { | |
return true; | |
} | |
if ( | |
tmpValueArray[3] && | |
tmpValue.length !== tmpValueArray[0].length && | |
clickValue !== EQUAL | |
) { | |
return true; | |
} | |
if (!tmpValueArray[2] && tmpValueArray[3]) { | |
return true; | |
} | |
else if ( | |
tmpValueArray[2] && | |
!isNumber(totalValue.charAt(totalValue.length - 1)) && | |
!isNumber(clickValue) | |
) { | |
return true; | |
} | |
else if (tmpValueArray[3] && !isNumber(clickValue) && clickValue !== EQUAL) { | |
return true; | |
} | |
else if ( | |
tmpValueArray[3] && | |
tmpValue.length !== tmpValueArray[0].length && | |
clickValue !== EQUAL | |
) { | |
return true; | |
} |
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.
그러네요. 순차적인 처리라 그게 맞는 듯 합니다.
export const parseTotalValue = (totalValue) => { | ||
let isFirstNumberMinus = false; | ||
if (totalValue[0] === "-") { | ||
totalValue = totalValue.slice(1, totalValue.length); | ||
isFirstNumberMinus = true; | ||
} | ||
const operator = totalValue.replace(/\d/g, ""); | ||
const numbers = totalValue.split(operator); | ||
if (isFirstNumberMinus) { | ||
return ["-" + numbers[0], operator, numbers[1]]; | ||
} | ||
return [numbers[0], operator, numbers[1]]; | ||
}; |
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.
로직 변경 후 사용하지 않는 파일입니다. git rm을 누락했네요.
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.
잘 봤습니다. 정규표현식 사용이랑 테스트에서 함수로 따로 빼낸 부분이 좋네요.
수고하셨습니다!
@@ -0,0 +1,23 @@ | |||
{ |
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.
파일명이 .exlintrc.json으로 되어 있는데 상관 없는건가요?
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.
아뇨.. 어쩐지 적용이 안되더라구요. 하하하하..
yarn.lock | ||
cypress/fixtures/ | ||
cypress/intergration/examples/ | ||
index.html |
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.
gitignore에 index.html 파일이 있는 이유가 궁금합니다
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.
헉
이건 마지막에 git add이후엔 gitignore 적용이 안되는 부분 테스트하면서 넣어놨었는데 제거하는걸 깜빡했네요.
cy.get('#total').should('have.text', '0'); | ||
}) | ||
|
||
it('3. 연산자는 1개만 입력 가능', () => { |
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.
import { REGEXP, EQUAL } from "../constants/index.js"; | ||
|
||
export const isNumber = (str: string): boolean => { | ||
return /^[\d.]+(?:e-?\d+)?$/.test(str); |
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.
이건 숫자만 판별하는 건가요?
(?:e-?\d+)? 부분 의미가 궁금하네요
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.
소수점, 부동소수점까지 체크하는 부분인데 이 프로그램에서는 필요가 없습니다. 예리하십니다~!
REGEXP.NUMBERS + | ||
")?" | ||
); | ||
if (tmpValueArray) { |
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.
요기는 if (!tmpValueArray) return false;
로 빼낼 수 있을 것 같아요
if (tmpValueArray) { | |
if (!tmpValueArray) return false; | |
if (!tmpValueArray[2] && tmpValueArray[3]) { | |
return true; | |
} | |
if ( | |
tmpValueArray[2] && | |
!isNumber(totalValue.charAt(totalValue.length - 1)) && | |
!isNumber(clickValue) | |
) { | |
return true; | |
} | |
if (tmpValueArray[3] && !isNumber(clickValue) && clickValue !== EQUAL) { | |
return true; | |
} | |
if ( | |
tmpValueArray[3] && | |
tmpValue.length !== tmpValueArray[0].length && | |
clickValue !== EQUAL | |
) { | |
return true; | |
} | |
return false; | |
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.
맞네요. 선 에러처리가 좋겠군요. 시간도 단축되겠습니다.
데모페이지 링크
https://jwon42.github.io/javascript-calculator/
makeFormula
, 공식을 이용해 계산하는 함수인calculator
가 위치합니다.테스트파일에서 확인 가능한 내용은 다음과 같습니다.
AC
버튼 입력 시0
으로 초기화[숫자][연산자][연산자]
불가)[숫자][연산자][숫자]
포맷 이후 연산자가 올 수 없음그 외에 문제에서 정의되지 않은 내용에 대한 처리는 다음과 같습니다.
-
의 경우 음수 입력 모드로 전환0
을 대상으로 연산 진행 모드 전환AC
버튼만 입력 가능=
버튼을 입력하는 경우0
을 출력