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

[정찬욱] 자동차 경주 미션 Step2 #11

Open
wants to merge 41 commits into
base: seeyoujeong
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
5cb3142
refactor: ready 메서드 삭제하고 start 메서드에 통합
seeyoujeong Jun 26, 2024
f590336
test: ready 메서드 관련 테스트 코드 삭제하고 start 메서드 관련 테스트 코드로 수정
seeyoujeong Jun 26, 2024
ed91faf
test: 레이서 등록 관련 테스트 코드 추가
seeyoujeong Jun 27, 2024
4bf618e
test: 기존 테스트 가독성 개선
seeyoujeong Jun 27, 2024
d258028
feat: move 메서드에 distance 매개변수 추가
seeyoujeong Jun 27, 2024
f282f87
test: move 메서드 관련 테스트 코드 추가
seeyoujeong Jun 27, 2024
6c2170b
feat: RacerRegistry 클래스에 selectEntityType 메서드 추가 및 적용
seeyoujeong Jun 27, 2024
b39b88e
test: 불필요한 테스트 코드 제거
seeyoujeong Jun 27, 2024
342c447
feat: RacerRegistry 클래스의 분리 문자 설정 기능 삭제
seeyoujeong Jun 28, 2024
ab0775d
test: 분리 문자 관련 테스트 코드 삭제
seeyoujeong Jun 28, 2024
e2b4400
feat: 입력 값에 trim 적용
seeyoujeong Jun 28, 2024
524745b
feat: 잘못된 유형의 번호를 입력할 경우, 다시 입력 가능하게 수정
seeyoujeong Jun 28, 2024
9915593
refactor: InputManager 클래스에 retryScan 메서드 추가 및 적용
seeyoujeong Jun 28, 2024
cb0bb7a
refactor: retryScan 메서드 파라미터 수정
seeyoujeong Jun 28, 2024
2ae9e1f
refactor: Car 클래스를 Racer 클래스로 통합하고 적용
seeyoujeong Jun 28, 2024
297c600
test: Car 클래스 테스트 파일 삭제 및 테스트 코드 수정
seeyoujeong Jun 28, 2024
be47080
refactor: 수정된 retryScan 메서드에 맞게 수정
seeyoujeong Jun 28, 2024
04fde6d
fix: 삭제한 Car 클래스 export하는 코드 삭제
seeyoujeong Jun 28, 2024
6e9bafe
fix: Racer 이름에 trim 적용
seeyoujeong Jun 28, 2024
37e3e4e
test: 유형 선택 관련 테스트 코드 추가
seeyoujeong Jun 28, 2024
aa06869
feat: 레이스의 횟수 입력 받는 기능 임시 구현
seeyoujeong Jun 29, 2024
31ea4d9
refactor: RaceEntry로 클래스명 수정
seeyoujeong Jun 29, 2024
a943909
refactor: registerRacers로 메서드명 수정
seeyoujeong Jun 29, 2024
b4dc967
refactor: 레이스 횟수 관련 코드 setRaceLaps 메서드로 이동하고 적용
seeyoujeong Jun 29, 2024
2e9ddf9
refactor: validateTypeNumber 메서드 수정
seeyoujeong Jun 29, 2024
af4cb06
refactor: progressRacePerLap 메서드 추가 및 적용
seeyoujeong Jun 29, 2024
ed589ea
refactor: 경주 규칙을 할당할 수 있게 임시 구현
seeyoujeong Jun 29, 2024
157f033
refactor: 불필요한 코드 삭제
seeyoujeong Jun 30, 2024
1817aee
test: 불필요한 테스트 코드 삭제
seeyoujeong Jun 30, 2024
6307358
refactor: retryScan 메서드에서 불필요한 코드 삭제하고 반영
seeyoujeong Jun 30, 2024
90f13b2
test: retryScan 메서드 수정으로인한 테스트 코드 수정
seeyoujeong Jun 30, 2024
5b9d698
refactor: 기본 경주 관련 프로퍼티 추가
seeyoujeong Jun 30, 2024
5820cac
feat: Validator 클래스 추가
seeyoujeong Jun 30, 2024
7511a8a
refactor: 유효성 검사 관련 코드 수정
seeyoujeong Jun 30, 2024
02d771e
feat: 경기 규칙에 관한 유효성 검사 추가
seeyoujeong Jul 2, 2024
da98550
refactor: 정적 메서드 type을 추가하고 중복 제거
seeyoujeong Jul 2, 2024
2adfb5e
refactor: 에러 메시지 수정
seeyoujeong Jul 2, 2024
9e6c808
test: 에러 메시지 수정으로 인한 테스트 코드 수정
seeyoujeong Jul 2, 2024
609e90e
test: 레이스 규칙 관련 테스트 코드 추가
seeyoujeong Jul 2, 2024
b127b7d
test: 유형 선택과 레이스 횟수 설정 관련 테스트 추가
seeyoujeong Jul 3, 2024
bb1d975
refactor: 정수 검사 조건 수정
seeyoujeong Jul 6, 2024
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
30 changes: 0 additions & 30 deletions src/__tests__/Car.test.js

This file was deleted.

137 changes: 93 additions & 44 deletions src/__tests__/Race.test.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import { describe, expect, test } from "vitest";
import { Car, Race } from "../domain/index.js";
import { Racer, Race } from "../domain/index.js";

describe("Race 클래스 테스트", () => {
test("레이서가 Racer 클래스의 자식 클래스가 아니면 오류가 발생한다.", () => {
expect(() => new Race({}, 1)).toThrowError();
});

test("레이서가 Racer 클래스의 자식 클래스면 오류가 발생하지 않는다.", () => {
expect(() => new Race(Car, 1)).not.toThrowError();
});

test.each([
{ value: "1" },
{ value: true },
Expand All @@ -20,21 +12,21 @@ describe("Race 클래스 테스트", () => {
])(
"레이스 횟수로 숫자가 아닌 값($value)을 할당하면 오류가 발생한다.",
({ value }) => {
expect(() => new Race(Car, value)).toThrowError();
expect(() => new Race(value)).toThrowError();
}
);

test("레이스 횟수로 숫자를 할당하면 오류가 발생하지 않는다.", () => {
expect(() => new Race(Car, 1)).not.toThrowError();
expect(() => new Race(1)).not.toThrowError();
});

test("레이스 횟수가 0이하면 오류가 발생한다.", () => {
expect(() => new Race(Car, 0)).toThrowError();
expect(() => new Race(Car, -1)).toThrowError();
expect(() => new Race(0)).toThrowError();
expect(() => new Race(-1)).toThrowError();
});

test("레이스 횟수가 1이상이면 오류가 발생하지 않는다.", () => {
expect(() => new Race(Car, 1)).not.toThrowError();
expect(() => new Race(1)).not.toThrowError();
});

test.each([
Expand All @@ -45,67 +37,124 @@ describe("Race 클래스 테스트", () => {
{ value: null },
{ value: {} },
])(
"레이스 준비시 배열이 아닌 값($value)을 할당하면 오류가 발생한다.",
"레이스 시작시 배열이 아닌 값($value)을 할당하면 오류가 발생한다.",
({ value }) => {
const race = createCarRaceWith5Laps();
const race = createRaceWith5Laps();

expect(() => race.ready(value)).toThrowError(
"경기 준비에 적합하지 않은 입력값입니다."
expect(() => race.start(value)).toThrowError(
"레이스 시작에 적합하지 않은 입력값입니다."
);
}
);

test("레이스 준비시 배열을 할당하면 오류가 발생하지 않는다.", () => {
const race = createCarRaceWith5Laps();

expect(() => race.ready(["1", "2"])).not.toThrowError();
});
test("레이스 시작의 입력값이 0개 이하면 오류가 발생한다.", () => {
const race = createRaceWith5Laps();

test("레이스 준비의 입력값이 0개 이하면 오류가 발생한다.", () => {
const race = createCarRaceWith5Laps();

expect(() => race.ready([])).toThrowError(
"경기를 준비하기엔 레이서가 부족합니다."
expect(() => race.start([])).toThrowError(
"레이스를 시작하기엔 레이서가 부족합니다."
);
});

test("레이스 준비의 입력값이 1개 이상이면 오류가 발생하지 않는다.", () => {
const race = createCarRaceWith5Laps();
test("레이스 시작의 입력값이 레이서들이면 오류가 발생하지 않는다.", () => {
const race = createRaceWith5Laps();

expect(() => race.ready(["1"])).not.toThrowError();
expect(() => race.start([new Racer("1")])).not.toThrowError();
});

test("레이스 시작전에 기록을 가져오면 빈배열입니다.", () => {
const race = createCarRaceWith5Laps();
race.ready(["1", "2"]);
const race = createRaceWith5Laps();

expect(race.records).toEqual([]);
});

test("레이스 시작후에 기록을 알 수 있습니다.", () => {
const race = createCarRaceWith5Laps();
race.ready(["1", "2"]);
race.start();
const race = createRaceWith5Laps();
race.start([new Racer("1"), new Racer("2")]);

expect(race.records).toHaveLength(5);
});

test("레이스 시작전에 우승자를 가져오면 빈배열입니다.", () => {
const race = createCarRaceWith5Laps();
race.ready(["1", "2"]);
const race = createRaceWith5Laps();

expect(race.winners).toEqual([]);
});

test("레이스 우승자는 1이상입니다..", () => {
const race = createCarRaceWith5Laps();
race.ready(["1", "2"]);
race.start();
test("레이스 우승자는 1이상입니다.", () => {
const race = createRaceWith5Laps();
race.start([new Racer("1"), new Racer("2")]);

expect(race.winners.length).toBeGreaterThanOrEqual(1);
});

test.each([
{ value: 1 },
{ value: "str" },
{ value: true },
{ value: null },
{ value: {} },
])(
"레이스 규칙에 적합하지 않은 입력값($value)이면 오류가 발생합니다.",
({ value }) => {
const race = createRaceWith5Laps();

expect(() =>
race.start([new Racer("1"), new Racer("2")], value)
).toThrowError("레이스 규칙에 적합하지 않은 입력값입니다.");
}
);

test("레이스 규칙이 1개미만이면 오류가 발생한다.", () => {
const race = createRaceWith5Laps();

expect(() => race.start([new Racer("1"), new Racer("2")], [])).toThrowError(
"레이스를 시작하기엔 규칙이 부족합니다."
);
});

test.each([
{ value: 1 },
{ value: "str" },
{ value: true },
{ value: undefined },
{ value: null },
{ value: [] },
{ value: {} },
])(
"레이스 규칙이 함수가 아닌 값($value)이면 오류가 발생한다.",
({ value }) => {
const race = createRaceWith5Laps();

expect(() =>
race.start([new Racer("1"), new Racer("2")], [value])
).toThrowError("레이스 규칙은 함수여야 합니다.");
}
);

test.each([
{ fn: () => 1 },
{ fn: () => "str" },
{ fn: () => undefined },
{ fn: () => null },
{ fn: () => [] },
{ fn: () => {} },
])("레이스 규칙의 반환값이 불린값이 아니면 오류가 발생한다.", ({ fn }) => {
const race = createRaceWith5Laps();

expect(() =>
race.start([new Racer("1"), new Racer("2")], [fn])
).toThrowError("레이스 규칙의 반환값으로 적합하지 않습니다.");
});

test("레이스 규칙이 불린값을 반환하는 함수이면 오류가 발생하지 않는다.", () => {
const race = createRaceWith5Laps();

expect(() =>
race.start([new Racer("1"), new Racer("2")], [() => true])
).not.toThrowError();
});
});

function createCarRaceWith5Laps() {
return new Race(Car, 5);
function createRaceWith5Laps() {
return new Race(5);
}
68 changes: 68 additions & 0 deletions src/__tests__/RaceEntry.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { describe, expect, test, vi } from "vitest";
import { Race, RaceEntry } from "../domain/index.js";
import { inputManager } from "../service/index.js";

vi.mock("../service/index.js");

function retryScanMock(inputValue) {
inputManager.retryScan.mockImplementationOnce(async (_, processFn) => {
return processFn(inputValue);
});
}

describe("RaceEntry 클래스 테스트", () => {
test("올바른 유형을 선택하지 않으면 오류가 발생한다.", async () => {
retryScanMock("5");

Choose a reason for hiding this comment

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

추후에 유형이 늘어날 경우를 대비하기 위해선 어떻게 해야할까요?

Copy link
Author

Choose a reason for hiding this comment

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

테스트 코드가 아니었다면 유형이 늘어날 경우를 대비해서 상수로 빼거나 했을 것 같습니다.
하지만 테스트 코드이기 때문에, 가장 예외가 없고 확실한 방법인 하드 코딩을 선택했습니다!


const register = new RaceEntry();

await expect(register.selectEntityType()).rejects.toThrowError(
"올바른 유형의 번호가 아닙니다."
);
});

test("올바른 유형을 선택하면 오류가 발생하지 않는다.", async () => {
retryScanMock("1");

const register = new RaceEntry();

await expect(register.selectEntityType()).resolves.not.toThrowError();
});

test("레이스 횟수로 정수가 아닌 값을 입력하면 오류가 발생한다.", async () => {
retryScanMock("a");

const register = new RaceEntry();

await expect(register.setRaceLaps()).rejects.toThrowError(
"시도할 횟수로 정수를 입력해야 합니다."
);
});

test("레이스 횟수로 0이하를 입력하면 오류가 발생한다.", async () => {
retryScanMock("0");

const register = new RaceEntry();

await expect(register.setRaceLaps()).rejects.toThrowError(
"시도할 횟수는 1이상이어야 합니다."
);
});

test("레이스 횟수로 1이상을 입력하면 오류가 발생하지 않는다.", async () => {
retryScanMock("1");

const register = new RaceEntry();

await expect(register.setRaceLaps()).resolves.not.toThrowError();
});

test("레이스 횟수를 설정하면 Race 클래스 인스턴스를 반환받는다.", async () => {
retryScanMock("1");
const register = new RaceEntry();

const race = await register.setRaceLaps();

expect(race).toEqual(new Race(1));
});
});
8 changes: 4 additions & 4 deletions src/__tests__/RaceScoreboard.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, test } from "vitest";
import { Car, Race, RaceScoreboard } from "../domain/index.js";
import { Race, RaceScoreboard } from "../domain/index.js";

describe("RaceScoreboard 클래스 테스트", () => {
test("Race 클래스의 인스턴스를 할당하지 않으면 오류가 발생한다.", () => {
Expand All @@ -10,9 +10,9 @@ describe("RaceScoreboard 클래스 테스트", () => {
expect(() => new RaceScoreboard(person)).toThrowError();
});

test("Race 클래스의 인스턴스를 할당하면 오류가 발생한다.", () => {
const carRace = new Race(Car, 5);
test("Race 클래스의 인스턴스를 할당하면 오류가 발생하지 않는다.", () => {
const race = new Race(5);

expect(() => new RaceScoreboard(carRace)).not.toThrowError();
expect(() => new RaceScoreboard(race)).not.toThrowError();
});
});
52 changes: 40 additions & 12 deletions src/__tests__/Racer.test.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,55 @@
import { beforeEach, describe, expect, test } from "vitest";
import { describe, expect, test } from "vitest";
import { Racer } from "../domain/index.js";

describe("Racer 클래스 테스트", () => {
let racer;

beforeEach(() => {
racer = new Racer(" jeong ");
});

test("레이서의 이름 앞뒤 공백은 제거된다.", () => {
expect(racer.name).toHaveLength(5);
});

test("레이서에 이름을 지어줄 수 있다.", () => {
expect(racer.name).toBe("jeong");
const racer = new Racer("tom");

expect(racer.name).toBe("tom");
});

test("레이서는 움직일 수 있다.", () => {
const racer = createRacerWithName();

racer.move();

expect(racer.position).toBe(1);
});

test.each([
{ value: 1.1 },
{ value: "1" },
{ value: true },
{ value: null },
{ value: {} },
])(
"레이서의 이동 거리로 정수가 아닌 값($value)을 할당하면 오류가 발생한다.",
({ value }) => {
const racer = createRacerWithName();

expect(() => racer.move(value)).toThrowError();
}
);

test.each([2, 3, 4, 5])(
"레이서의 이동 거리(%i)를 지정할 수 있다.",
(distance) => {
const racer = createRacerWithName();

racer.move(distance);

expect(racer.position).toBe(distance);
}
);

test("레이서의 위치는 0미만이 될 수 없다.", () => {
const racer = createRacerWithName();

racer.move(-1);

expect(racer.position).toBe(0);
});

test("레이서의 이름을 수정하려고 하면 오류가 발생한다.", () => {
const racer = createRacerWithName();

Expand Down
Loading