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

[jwon] typescript-calculator #4

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions .exlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
Copy link

Choose a reason for hiding this comment

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

파일명이 .exlintrc.json으로 되어 있는데 상관 없는건가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

아뇨.. 어쩐지 적용이 안되더라구요. 하하하하..

"env": {
"browser": true,
"es2021": true,
"cypress/globals": true
},
"extends": ["airbnb-base", "plugin:cypress/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "cypress"],
"ignorePatterns": ["dist/", "node_modules/"],
"rules": {
"cypress/no-assigning-return-values": "error",
"cypress/no-unnecessary-waiting": "error",
"cypress/assertion-before-screenshot": "warn",
"cypress/no-force": "warn",
"cypress/no-async-tests": "error",
"import/extensions": "always"
}
}
Copy link
Member

Choose a reason for hiding this comment

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

EOL 관련 아티클 읽어보시면 좋을것 같아요 :)

8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
package-lock.json
yarn.lock
Copy link
Member

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.jsonyarn.lock이 공존하는데 , npm 과 yarn중 하나로 통일해서 사용하는게 좋을것 같아요!

cypress/fixtures/
cypress/intergration/examples/
index.html
Copy link

Choose a reason for hiding this comment

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

gitignore에 index.html 파일이 있는 이유가 궁금합니다

Copy link
Member Author

Choose a reason for hiding this comment

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


이건 마지막에 git add이후엔 gitignore 적용이 안되는 부분 테스트하면서 넣어놨었는데 제거하는걸 깜빡했네요.



# Created by https://www.toptal.com/developers/gitignore/api/vscode,node,intellij
# Edit at https://www.toptal.com/developers/gitignore?templates=vscode,node,intellij
Expand Down Expand Up @@ -249,7 +255,7 @@ typings/

# Nuxt.js build / generate output
.nuxt
dist
# dist

# Gatsby files
.cache/
Expand Down
5 changes: 5 additions & 0 deletions .prettierc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"parser": "typescript",
"singleQuote": true,
"trailingComma": "all"
}
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
- **데모페이지**
https://jwon42.github.io/javascript-calculator/

- **PR**
https://github.com/transcendence42/javascript-calculator/pull/4

<br/>
<br/>
<p align="middle" >
Expand Down
1 change: 1 addition & 0 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
79 changes: 79 additions & 0 deletions cypress/integration/calculator.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
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)
}
Comment on lines +1 to +12
Copy link
Member

Choose a reason for hiding this comment

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

깔끔하고 좋네요.


describe('계산기 테스트', () => {
beforeEach(() => {
cy.visit('/');
});

it('1. 숫자 입력 시 3자리까지만 결과창에 표시', () => {
cy.get('.digit').contains('1').click();
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();
Copy link
Member

Choose a reason for hiding this comment

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

위에 calculate 만들어 준 것처럼 따로 함수로 빼주면 더 깔끔해 보일 것 같아요!

Copy link
Member Author

Choose a reason for hiding this comment

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

맞아요. 다음 과제에선 cypress 코드 작성에 조금 더 신경을 써봐야겠어요~!

cy.get('#total').should('have.text', '123');
cy.get('.digit').contains('4').click();
cy.get('#total').should('have.text', '123');
cy.get('.digit').contains('5').click();
cy.get('#total').should('have.text', '123');
});

it('2. [AC] 입력 시 0으로 초기화', () => {
cy.get('.digit').contains('4').click();
cy.get('.digit').contains('2').click();
cy.get('.modifiers').click();
cy.get('#total').should('have.text', '0');
})

it('3. 연산자는 1개만 입력 가능', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
it('3. 연산자는 1개만 입력 가능', () => {
it('3. 연산자 2개 이상 입력시, 먼저 입력한 연산자로 적용', () => {

작성한 it의 설명은 함수 단위 테스트 설명이라고 생각합니다. BDD인 만큼 조금 더 세부적으로 행동을 중심으로 작성하면 좋을것 같아요! 아래는 Given, When, Then 에 대한 간략 설명입니댜!

Given : 시나리오 진행에 필요한 값을 설정합니다.
When : 시나리오를 진행하는데 필요한 조건을 명시합니다
Then : 시나리오를 완료했을 때 보장해야 하는 결과를 명시합니다.

Copy link

Choose a reason for hiding this comment

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

@hochan222

그러면 여기서는

  • Given: 연산자 2개(+, -),
  • When: 입력(클릭),
  • Then: 먼저 입력한 연산자 적용

이 되는 건가요?

Copy link
Member

@hochan222 hochan222 Jun 4, 2021

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)

으로 나누어서 적었습니다!

cy.get('.digit').contains('4').click();
cy.get('.digit').contains('2').click();
cy.get('.operations').contains('+').click();
cy.get('.operations').contains('-').click();
cy.get('#total').should('have.text', '42+');
cy.get('.modifiers').click();
})

it('4. [숫자][연산자][숫자] 포맷 이후 연산자가 올 수 없음', () => {
cy.get('.digit').contains('4').click();
cy.get('.digit').contains('2').click();
cy.get('.operations').contains('+').click();
cy.get('.digit').contains('4').click();
cy.get('.digit').contains('2').click();
cy.get('.operations').contains('-').click();
cy.get('#total').should('have.text', '42+42');
cy.get('.modifiers').click();
})

it('5. 한 자릿수 사칙연산', () => {
calculate([4], '+', [2], '6');
Copy link
Member

Choose a reason for hiding this comment

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

LGTM 👍 👍

calculate([4], '-', [2], '2');
calculate([4], 'X', [2], '8');
calculate([4], '/', [2], '2');
})

it('6. 두 자릿수 사칙연산', () => {
calculate([4, 2], '+', [2, 4], '66');
calculate([4, 2], '-', [2, 4], '18');
calculate([4, 2], 'X', [2, 4], '1008');
calculate([4, 2], '/', [2, 4], '1');
})

it('7. 세 자릿수 사칙연산', () => {
calculate([1, 2, 3], '+', [3, 2, 1], '444');
calculate([1, 2, 3], '-', [3, 2, 1], '-198');
calculate([1, 2, 3], 'X', [3, 2, 1], '39483');
calculate([1, 2, 3], '/', [3, 2, 1], '0');
})
});
22 changes: 22 additions & 0 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
* @type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
25 changes: 25 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
20 changes: 20 additions & 0 deletions cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')
87 changes: 87 additions & 0 deletions dist/css/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
html,
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}

#app {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}

.calculator {
width: 300px;
display: grid;
grid-template-areas:
'total total total total'
'modif modif modif oper'
'digit digit digit oper'
'digit digit digit oper'
'digit digit digit oper'
'digit digit digit oper';
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
height: 500px;
}

button {
font-size: 2rem;
border: 0.5px solid #98999b;
}

.modifiers button {
background-color: #ccc;
}

.operations button {
background-color: orange;
}

.digits button {
background-color: #efefef;
}

#total {
grid-area: total;
background-color: #333;
color: white;
margin: 0;
padding: 1rem;
display: flex;
justify-content: flex-end;
align-items: flex-end;
font-size: 4rem;
}

.digits {
grid-area: digit;
display: flex;
flex-wrap: wrap;
flex-direction: row-reverse;
}

.digits button {
flex: 1 0 30%;
}

.digit.wide {
flex: 2 0 60%;
order: 1;
}

.modifiers {
grid-area: modif;
grid-auto-flow: column;
grid-auto-columns: 1fr;
}

.operations {
grid-area: oper;
}

.subgrid {
display: grid;
}
Binary file added dist/images/calculator_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dist/images/calculator_ui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions dist/ts/constants/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const OPERATOR = {
ADD: "+",
SUBSTRACT: "-",
MULTIPLY: "X",
DIVIDE: "/",
EQUAL: "=",
};
export const EQUAL = '=';
export const REGEXP = {
// SIGN: '\\-{1}',
NUMBERS: '\\-?\\d{1,3}',
OPERATORS: 'X|\\-|\\+|\\/{1}'
};
18 changes: 18 additions & 0 deletions dist/ts/controller/event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { pushTotalValue, clearTotalValue } from "../view/index.js";
export const setEventListener = () => {
document
.getElementsByClassName("digits")[0]
.addEventListener("click", (e) => {
pushTotalValue(e);
});
document
.getElementsByClassName("operations")[0]
.addEventListener("click", (e) => {
pushTotalValue(e);
});
document
.getElementsByClassName("modifier")[0]
.addEventListener("click", () => {
clearTotalValue();
});
};
4 changes: 4 additions & 0 deletions dist/ts/controller/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { setEventListener } from "./event.js";
export const controller = () => {
setEventListener();
};
13 changes: 13 additions & 0 deletions dist/ts/controller/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
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]];
};
Comment on lines +1 to +13
Copy link
Member Author

Choose a reason for hiding this comment

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

로직 변경 후 사용하지 않는 파일입니다. git rm을 누락했네요.

36 changes: 36 additions & 0 deletions dist/ts/controller/validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { REGEXP, EQUAL } from "../constants/index.js";
export const isNumber = (str) => {
return /^[\d.]+(?:e-?\d+)?$/.test(str);
};
export const checkFirstTotalValue = (totalValue, clickValue) => {
return totalValue === "0" && (isNumber(clickValue) || clickValue === "-");
};
export const checkPreventClickValue = (totalValue, clickValue) => {
const tmpValue = totalValue + clickValue;
const tmpValueArray = tmpValue.match("(" +
REGEXP.NUMBERS +
")?(" +
REGEXP.OPERATORS +
")?(" +
REGEXP.NUMBERS +
")?");
if (tmpValueArray) {
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;
};
5 changes: 5 additions & 0 deletions dist/ts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { controller } from "./controller/index.js";
const app = () => {
controller();
};
app();
Loading