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

[1단계 - 음식점 목록] 윤생(이윤성) 미션 제출합니다. #8

Merged
merged 48 commits into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3aa6c25
docs(REQUIREMENTS): 구현할 기능 목록 작성
bassyu Feb 28, 2023
8216494
feat(prettierrc): 프리티어 설정 변경
bassyu Feb 28, 2023
b9195da
docs(REQUIREMENTS): 컴포넌트 상세 추가
bassyu Mar 2, 2023
e0dec9a
feat(type): 컴포넌트, 데이터 모델 타입 선언
bassyu Mar 2, 2023
f1bafd3
feat(index): 기본 템플릿 구현
bassyu Mar 2, 2023
7669e32
feat(Header): Header 컴포넌트 추가
bassyu Mar 2, 2023
1750178
feat(RestaurantListItem): RestaurantListItem 컴포넌트 구현
bassyu Mar 2, 2023
eaf9941
feat(component): 필요한 컴포넌트 구현 및 연결
bassyu Mar 2, 2023
d6478f2
feat(Modal): 취소버튼에 toggleModal 등록
bassyu Mar 2, 2023
f7288c6
feat(Modal): 음식점 추가 기능 구현
bassyu Mar 2, 2023
d180301
feat(RestaurantListItem): RestaurantListItem 랜더링 구현
bassyu Mar 2, 2023
8e6ba2d
feat(asset/icons): 이미지 파일 추가 및 타입 적용
bassyu Mar 2, 2023
b29892c
feat(RestaurantListItem): 정적 이미지 적용
bassyu Mar 2, 2023
9d9c4bd
feat(RestaurantList): 랜더링 및 정렬 기능 구현
bassyu Mar 2, 2023
be705b2
feat(RestaurantListHeader): 카테고리, 정렬 옵션 동적 랜더링 구현
bassyu Mar 2, 2023
e7bcb45
feat(RestaurantListPage): 랜더링, 옵션 핸들러 구현
bassyu Mar 2, 2023
0bc0a89
feat(Header): 추가 버튼 이미지 적용
bassyu Mar 2, 2023
cdad33f
feat(index): fragment document 적용
bassyu Mar 2, 2023
f69fb73
refactor(MainTemplate): state 초기화 통일
bassyu Mar 2, 2023
7e5ed0f
refactor(image): 이미지 import 경로 변경
bassyu Mar 2, 2023
87c5fa4
refactor(component): 화살표 함수로 변경
bassyu Mar 2, 2023
cb3dae2
test(render): 각 컴포넌트 랜더링 테스트 작성
bassyu Mar 3, 2023
c7c3538
test(unit): RestaurantList 컴포넌트 기능 테스트 작성
bassyu Mar 3, 2023
d37dbef
docs(README): 환경 설정 및 실행 방법 작성
bassyu Mar 3, 2023
ed25001
chore(tsconfig): typeRoots 제거
bassyu Mar 3, 2023
a5a82f2
refactor(utils/constants): 상수 정의 및 컴포넌트 매직넘버 상수화
bassyu Mar 3, 2023
ce7a852
refactor: truly/falsy 사용
2yunseong Mar 6, 2023
5676a74
refactor: 타입 전용 import 사용
2yunseong Mar 6, 2023
4a149b7
refactor: 매직넘버 상수화
2yunseong Mar 6, 2023
158586d
refactor: 가독성 개선을 위한 공백 추가
2yunseong Mar 6, 2023
ccd446e
refactor: 화살표 함수 메서드로 변경
2yunseong Mar 6, 2023
3fcdb9e
refactor: DOM 직접 접근 대신 Form 접근 및 조작
2yunseong Mar 6, 2023
c3fcca8
refactor: 메서드 네이밍 변경
2yunseong Mar 6, 2023
881e2bc
refactor: 일반적인 네이밍 구체화
2yunseong Mar 6, 2023
6b4fc28
refactor: 불필요한 페이지 컴포넌트 제거
2yunseong Mar 6, 2023
0e2761e
refactor: 디렉토리 구조 변경
2yunseong Mar 6, 2023
7e1126a
refactor: 컴포넌트 명 변경
2yunseong Mar 6, 2023
b85ceec
refactor: 핸들러 컴포넌트의 state로 관리
2yunseong Mar 6, 2023
da16185
refactor: Component interface 타입 분리
2yunseong Mar 6, 2023
90f3856
refactor: 필드 네이밍 변경
2yunseong Mar 6, 2023
fe989cf
test: 테스트 코드 네이밍 구체적으로 변경
2yunseong Mar 6, 2023
ef145e8
test: 기능 테스트 DOM 접근 로직 제거
2yunseong Mar 6, 2023
8cd394a
refactor: 컴포넌트 네이밍 변경
2yunseong Mar 7, 2023
d722844
refactor: 디렉터리 구조 변경
2yunseong Mar 7, 2023
ca1752b
refactor: 잘못된 네이밍 정정
2yunseong Mar 7, 2023
a88be2d
refactor: 네이밍 변경에 따른 import 문 변경
2yunseong Mar 7, 2023
e737c90
refactor: 설게한 구조에 맞게 변경
2yunseong Mar 7, 2023
f67fbbc
refactor: drop down 재사용 컴포넌트로 분리
2yunseong Mar 7, 2023
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
4 changes: 3 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"endOfLine": "auto"
"endOfLine": "auto",
"singleQuote": true,
"printWidth": 100
}
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,42 @@
# javascript-lunch

우아한테크코스 레벨1 점심 뭐 먹지 미션

배포 주소 : https://bassyu.github.io/javascript-lunch/

## 시작하기

### 기본 설정

```
git clone https://github.com/bassyu/javascript-lunch.git
cd javascript-lunch
```

### step1

#### 설정

```
git checkout -b step1
git pull origin step1
npm ci
```

#### 테스트

```
npm run test-unit
```

#### 실행

```
npm run start
```

#### 빌드

```
npm run build
```
105 changes: 105 additions & 0 deletions __tests__/render.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,108 @@
/**
* @jest-environment jsdom
*/

import '@testing-library/jest-dom';
import { screen } from '@testing-library/dom';
import RestaurantListItem from '../src/components/RestaurantListItem';
import RestaurantList from '../src/pages/RestaurantListPage/RestaurantList';
import RestaurantFilterContainer from '../src/pages/RestaurantListPage/RestaurantFilterContainer';
import GNB from '../src/components/GNB';
Copy link

Choose a reason for hiding this comment

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

GNB를 Global Navigation Bar의 약자로 사용하신거 같은데요. 이런 단어는 실제 코드나 컴포넌트를 작성할 때 직접적으로 잘 사용되지 않아서 낯설게 느껴지네용

import AddRestaurantDrawer from '../src/pages/AddRestaurantDrawer';

describe('컴포넌트 랜더링 테스트', () => {
beforeEach(() => {
document.body.innerHTML = '';
});

describe('RestaurantListItem 랜더링 테스트', () => {
test('RestaurantListItem 요소가 필요한 정보를 모두 갖추었는지 테스트', () => {
const restaurant = {
category: '한식',
name: '농민백암순대',
distance: 15,
description: '선릉에서 제일 유명한 국밥집',
link: '',
};

new RestaurantListItem({ $parent: document.body, restaurant }).render();
expect(screen.getByText('농민백암순대')).toBeInTheDocument();
expect(screen.getByText('선릉에서 제일 유명한 국밥집')).toBeInTheDocument();
expect(screen.getByText('캠퍼스부터 15분 내')).toBeInTheDocument();
});
});

describe('RestaurantList 랜더링 테스트', () => {
test('음식 종류별 필터링한 결과가 잘 출력되는지 테스트', () => {
const restaurants = [
{
category: '한식',
name: '농민백암순대',
distance: 15,
description: '선릉에서 제일 유명한 국밥집',
link: '',
},
{
category: '양식',
name: '버거킹',
distance: 10,
description: '햄버거 하면 버거킹',
link: '',
},
];
const category = '양식';
const sortBy = 'name';

new RestaurantList({ $parent: document.body, restaurants, category, sortBy }).render();
expect(screen.getByText('버거킹')).toBeInTheDocument();
expect(screen.getByText('햄버거 하면 버거킹')).toBeInTheDocument();
expect(screen.getByText('캠퍼스부터 10분 내')).toBeInTheDocument();
expect(document.querySelectorAll('.restaurant').length).toBe(1);
});
});

describe('RestaurantListHeader 테스트', () => {
test('선택된 카테고리를 화면에 잘 나타내는지 테스트', () => {
const category = '한식';
const sortBy = 'distance';
new RestaurantFilterContainer({ $parent: document.body, category, sortBy }).render();
expect(document.querySelector(`option[value="${category}"]`)).toHaveAttribute('selected');
expect(document.querySelector(`option[value="${sortBy}"]`)).toHaveAttribute('selected');
});
});

describe('GNB 테스트', () => {
test('GNB를 화면에 잘 나타내는지 테스트', () => {
new GNB({ $parent: document.body, toggleAddRestaurantDrawer: () => {} }).render();
expect(screen.getByText('점심 뭐 먹지')).toBeInTheDocument();
});
});

describe('AddRestaurantDrawer 테스트', () => {
test('select 태그 렌더링 테스트: 카테고리', () => {
new AddRestaurantDrawer({
$parent: document.body,
toggleAddRestaurantDrawer: () => {},
}).render();
const categoryElement = document.getElementById('category');
const categories = ['한식', '중식', '일식', '양식', '아시안', '기타'];
categories.forEach((category) => {
expect(categoryElement).toContainHTML(`<option value="${category}">${category}</option>`);
});
});

test('select 태그 렌더링 테스트: 거리(도보 x분)', () => {
new AddRestaurantDrawer({
$parent: document.body,
toggleAddRestaurantDrawer: () => {},
}).render();
const distanceElement = document.getElementById('distance');
const distances = [5, 10, 15, 20, 30];
distances.forEach((distance) => {
expect(distanceElement).toContainHTML(
`<option value="${distance}">${distance}분 내</option>`
);
});
});
});
});
86 changes: 86 additions & 0 deletions __tests__/unit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* @jest-environment jsdom
*/

import '@testing-library/jest-dom';
import RestaurantList from '../src/pages/RestaurantListPage/RestaurantList';

describe('RestaurantList 기능 테스트', () => {
test('이름 순 정렬 기능 테스트', () => {
const restaurants = [
{
category: '한식',
name: '농민백암순대',
distance: 15,
description: '선릉에서 제일 유명한 국밥집',
link: '',
},
{
category: '양식',
name: '버거킹',
distance: 10,
description: '햄버거 하면 버거킹',
link: '',
},
{
category: '양식',
name: '맥도날드',
distance: 5,
description: '햄버거 하면 두번째는 맥도날드',
link: '',
},
];
const category = '전체';
const sortBy = 'name';

const restaurantList = new RestaurantList({
$parent: document.body,
restaurants,
category,
sortBy,
}).categorizeRestaurantByOption();

expect(restaurantList[0].name).toEqual('농민백암순대');
expect(restaurantList[1].name).toEqual('맥도날드');
expect(restaurantList[2].name).toEqual('버거킹');
});

test('거리 순 정렬 기능 테스트(거리 짧은 순)', () => {
const restaurants = [
{
category: '한식',
name: '농민백암순대',
distance: 15,
description: '선릉에서 제일 유명한 국밥집',
link: '',
},
{
category: '양식',
name: '버거킹',
distance: 10,
description: '햄버거 하면 버거킹',
link: '',
},
{
category: '양식',
name: '맥도날드',
distance: 5,
description: '햄버거 하면 두번째는 맥도날드',
link: '',
},
];
const category = '전체';
const sortBy = 'distance';

const restaurantList = new RestaurantList({
$parent: document.body,
restaurants,
category,
sortBy,
}).categorizeRestaurantByOption();

expect(restaurantList[0].name).toEqual('맥도날드');
expect(restaurantList[1].name).toEqual('버거킹');
expect(restaurantList[2].name).toEqual('농민백암순대');
});
});
Empty file removed __tests__/unit.test.ts
Empty file.
97 changes: 97 additions & 0 deletions docs/REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# 구현할 기능 목록

## 컴포넌트 구조

```
├─ 메인 템플릿
│ ├─ 헤더
│ ├─ 음식점 리스트 페이지
│ ├─ 음식점 리스트 헤더
│ │ ├─ 카테고리
│ │ ├─ 정렬
│ ├─ 음식점 리스트
│ ├─ 음식점
│ ├─ 사진
│ ├─ 이름
│ ├─ 거리
│ ├─ 설명
├─ 모달
├─ 폼
├─ 헤더
├─ 여러가지 인풋
├─ 취소/추가 버튼
```

## 컴포넌트 상세

### 앱

- 상태

1. 모달 숨김

- 핸들러

1. 모달 여닫는 기능

### 메인

- 상태

1. 모달 숨김

- 핸들러

1. 모달 여닫는 기능

### 음식점 리스트 페이지

- 상태

1. 현재 볼 카테고리
2. 정렬정보 (이름, 설명, 참고)
3. 음식점 정보 리스트

- 핸들러

1. 카테고리 핸들러
2. 정렬정보 핸들러

### 음식점 리스트 헤더

- 상태

1. 현재 볼 카테고리
2. 정렬정보 (이름, 설명, 참고)

- 핸들러

1. 카테고리 핸들러
2. 정렬정보 핸들러

### 음식점 리스트

- 상태

1. 음식점 정보 리스트

### 음식점

- 상태

1. 음식점 정보

### 모달

- 상태

1. 모달 숨김
2. 음식점 정보

- 핸들러

1. 모달 여닫는 기능
2. 음식점 추가

## 유틸
Binary file added image/add-button.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 image/category-asian.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 image/category-chinese.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 image/category-etc.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 image/category-japanese.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 image/category-korean.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 image/category-western.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 image/favorite-icon-filled.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 image/favorite-icon-lined.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 9 additions & 12 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<!DOCTYPE html>
<html lang="ko">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>점심 뭐 먹지</title>
</head>

<body>

</body>

<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>점심 뭐 먹지</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Loading