From 2d5a73e31896b31524636141e6dda99bb96b6241 Mon Sep 17 00:00:00 2001 From: o0Orangee Date: Sat, 23 Mar 2024 21:36:37 +0900 Subject: [PATCH 1/6] =?UTF-8?q?domain=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 77 ++++++++++++++++++++++++++++++ docs/README.md | 32 +++++++++++++ src/main/java/domain/Car.java | 28 +++++++++++ src/main/java/domain/CarName.java | 23 +++++++++ src/main/java/domain/Cars.java | 53 ++++++++++++++++++++ src/main/java/domain/Distance.java | 19 ++++++++ src/main/java/domain/TryCount.java | 32 +++++++++++++ 7 files changed, 264 insertions(+) create mode 100644 docs/README.md create mode 100644 src/main/java/domain/Car.java create mode 100644 src/main/java/domain/CarName.java create mode 100644 src/main/java/domain/Cars.java create mode 100644 src/main/java/domain/Distance.java create mode 100644 src/main/java/domain/TryCount.java diff --git a/README.md b/README.md index 1969313..5f3b371 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,80 @@ 자동차 경주 미션 저장소 +## 설정 사항 + +- (중요) JDK 17 버전으로 진행한다. + +## **기능 요구사항** + +- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. +- 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. +- 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. +- 전진하는 조건은 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다. +- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. + +## **실행 결과** + +- 위 요구사항에 따라 3대의 자동차가 5번 움직였을 경우 프로그램을 실행한 결과는 다음과 같다. + +``` +경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분). +kokodak,kuku,cucu +시도할 회수는 몇회인가요? +5 +실행 결과 +kokodak : - +kuku : - +cucu : - +kokodak : -- +kuku : - +cucu : -- +kokodak : --- +kuku : -- +cucu : --- +kokodak : ---- +kuku : --- +cucu : ---- +kokodak : ----- +kuku : ---- +cucu : ----- +kokodak : ----- +kuku : ---- +cucu : ----- +kokodak, cucu가 최종 우승했습니다. +``` + +## **프로그래밍 요구사항** + +- **모든 로직에 단위 테스트를 구현한다. 단, UI(System.out, System.in) 로직은 제외** +- **자바 코드 컨벤션을 지키면서 프로그래밍한다.** + - 참고문서: https://google.github.io/styleguide/javaguide.html 또는 https://myeonguni.tistory.com/1596 +- **`규칙 1: 한 메서드에 오직 한 단계의 들여쓰기(indent)만 한다.`**를 지키며 구현한다. + - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. + - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다. +- **`규칙 2: else 예약어를 쓰지 않는다.`**를 지키며 구현한다. + - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다. + - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. +- **함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.** + - 함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다. + +**MVC 패턴으로 리팩터링 후의 main 메소드 예시** + +```java +import view.InputView; +import view.ResultView; +import domain.RacingGame; + +public class RacingMain { + public static void main(final String... args) { + final var carNames = InputView.getCarNames(); + final var tryCount = InputView.getTryCount(); + + final var racingGame = new RacingGame(carNames, tryCount); + racingGame.race(); + + ResultView.printWinners(racingGame.getWinners()); + } +} +``` \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..3b7b08d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,32 @@ +# domain +- ## Car(자동차) ## + - 이름 + - 전진 거리 + +- ## CarName(자동차 이름) ## + - 미입력 or 5글자 초과 확인 + +- ## Distance(이동 거리) ## + - 정지 or 거리 증가 + +- ## Cars(자동차 리스트) ## + - 자동차들의 정보(중복 이름 X) + - 우승자 판별 + +- ## TryConut(시도 횟수) ## + - 음수 입력 X (횟수 상한은 없나??) + +# dto + +# controller + +# service + +# view +- ## InputView ## + - 자동차 이름 입력 + - 시도 횟수 입력 + +- ## OutView ## + - 실행 결과 출력 + - 우승자 출력 \ No newline at end of file diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java new file mode 100644 index 0000000..14fbac5 --- /dev/null +++ b/src/main/java/domain/Car.java @@ -0,0 +1,28 @@ +package domain; + +public class Car { + + private static final int CAN_MOVE_NUMBER = 4; + private final CarName carName; + private final Distance distance; + + + public Car(String carName) { + this.carName = new CarName(carName); + this.distance = new Distance(); + } + + public void move(int number) { + if (number >= CAN_MOVE_NUMBER) { + distance.increaseDistance(); + } + } + + public CarName getCarName() { + return carName; + } + + public int getDistance() { + return distance.getDistance(); + } +} diff --git a/src/main/java/domain/CarName.java b/src/main/java/domain/CarName.java new file mode 100644 index 0000000..1eed06b --- /dev/null +++ b/src/main/java/domain/CarName.java @@ -0,0 +1,23 @@ +package domain; + +public class CarName { + private final String carName; + + public CarName(String carName) { + validateCarName(carName); + this.carName = carName; + } + + public String getCarName() { + return carName; + } + + private void validateCarName(String carName) { //이름 글자수 확인(없거나, 5글자 초과일 시) + if (carName.isEmpty()) { + throw new IllegalArgumentException("이름이 반드시 존재해야 합니다."); + } + if (carName.length() > 5) { + throw new IllegalArgumentException("이름은 5글자 이하여야 합니다."); + } + } +} diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java new file mode 100644 index 0000000..4ac176c --- /dev/null +++ b/src/main/java/domain/Cars.java @@ -0,0 +1,53 @@ +package domain; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class Cars { + + private static final String DUPLICATED_NAMES_MASSAGE= "자동차의 이름은 중복될 수 없습니다."; + private static final int DEFAULT_DISTANCE = 0; + private final List cars; + + public Cars(List carNames) { + final List cars= generateCars(carNames); + validateDuplication(carNames); + this.cars = cars; + } + + private List generateCars(List cars) { + return cars.stream() + .map(Car::new) + .collect(Collectors.toList()); + } + +// 이름 중복 확인 + private void validateDuplication(List carNames) { + Set duplicationCheck = new HashSet<>(carNames); + if (carNames.size() != duplicationCheck.size()) { + throw new IllegalArgumentException(DUPLICATED_NAMES_MASSAGE); + } + } + +// 최대 이동 거리 구하기 + private int findMaxDistance() { + return cars.stream() + .mapToInt(Car::getDistance) + .max() + .orElse(DEFAULT_DISTANCE); + } + +// 최대 이동 거리와 같은 위치에 있는 자동차들 찾기 + public List findWinner() { + int maxDistance = findMaxDistance(); + return cars.stream() + .filter(car -> car.getDistance() == maxDistance) + .collect(Collectors.toList()); + } + + public List getCars() { + return cars; + } +} diff --git a/src/main/java/domain/Distance.java b/src/main/java/domain/Distance.java new file mode 100644 index 0000000..abbed75 --- /dev/null +++ b/src/main/java/domain/Distance.java @@ -0,0 +1,19 @@ +package domain; + +public class Distance { + + private static final int INITIAL_VALUE = 0; + private int distance; + + public Distance() { + this.distance = INITIAL_VALUE; + } + + public void increaseDistance() { + distance++; + } + + public int getDistance() { + return distance; + } +} diff --git a/src/main/java/domain/TryCount.java b/src/main/java/domain/TryCount.java new file mode 100644 index 0000000..efadbae --- /dev/null +++ b/src/main/java/domain/TryCount.java @@ -0,0 +1,32 @@ +package domain; + +public class TryCount { + + private static final String NOT_POSITIVE_INTEGER_MESSAGE = "시도 횟수는 양의 정수여야 합니다"; + private static final int MINIMUM_COUNT = 1; + + private int tryCount; + + public TryCount(int tryCount) { + validate(tryCount); + this.tryCount = tryCount; + } + + private void validate(int tryCount) { + if (tryCount <= 0) { + throw new IllegalArgumentException(NOT_POSITIVE_INTEGER_MESSAGE); + } + } + + public void decrease() { + tryCount--; + } + + public boolean isRemain() { + return tryCount >= MINIMUM_COUNT; + } + + public int getTryCount() { + return tryCount; + } +} From 05d84f555fcaa42ac1c4a633677a7b67e9366e99 Mon Sep 17 00:00:00 2001 From: o0Orangee Date: Sun, 24 Mar 2024 03:10:41 +0900 Subject: [PATCH 2/6] =?UTF-8?q?utils,=20view=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 11 +++++- .../java/controller/RacingcarController.java | 4 ++ src/main/java/domain/Car.java | 4 +- src/main/java/utils/Parser.java | 23 +++++++++++ .../java/utils/RandomNumberGenerator.java | 7 ++++ src/main/java/view/InputView.java | 29 ++++++++++++++ src/main/java/view/OutputView.java | 39 +++++++++++++++++++ 7 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 src/main/java/controller/RacingcarController.java create mode 100644 src/main/java/utils/Parser.java create mode 100644 src/main/java/utils/RandomNumberGenerator.java create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/OutputView.java diff --git a/docs/README.md b/docs/README.md index 3b7b08d..b6cdbcc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,11 +16,18 @@ - ## TryConut(시도 횟수) ## - 음수 입력 X (횟수 상한은 없나??) -# dto +# ~~dto~~ # controller +- 이름 입력받아서 Cars로 저장 -# service +# utils +- ## Parser ## + - 이름: 쉼표 기준으로 분리 + - 시도 횟수 + +- ## RandomNumberGenerator ## + - 0~9 랜덤 숫자 생성기 # view - ## InputView ## diff --git a/src/main/java/controller/RacingcarController.java b/src/main/java/controller/RacingcarController.java new file mode 100644 index 0000000..e4473a5 --- /dev/null +++ b/src/main/java/controller/RacingcarController.java @@ -0,0 +1,4 @@ +package controller; + +public class RacingcarController { +} diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java index 14fbac5..549e875 100644 --- a/src/main/java/domain/Car.java +++ b/src/main/java/domain/Car.java @@ -18,8 +18,8 @@ public void move(int number) { } } - public CarName getCarName() { - return carName; + public String getCarName() { + return carName.getCarName(); } public int getDistance() { diff --git a/src/main/java/utils/Parser.java b/src/main/java/utils/Parser.java new file mode 100644 index 0000000..d65493b --- /dev/null +++ b/src/main/java/utils/Parser.java @@ -0,0 +1,23 @@ +package utils; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class Parser { + + private static final String NOT_POSITIVE_INTEGER = "시도 횟수는 정수여야 합니다"; + public static List parseNames(String input) { + return Arrays.stream(input.split(",")) + .map(String::trim) + .collect(Collectors.toList()); + } + + public static int parseCount(String input) { + try { + return Integer.parseInt(input); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(NOT_POSITIVE_INTEGER); + } + } +} diff --git a/src/main/java/utils/RandomNumberGenerator.java b/src/main/java/utils/RandomNumberGenerator.java new file mode 100644 index 0000000..ae2349b --- /dev/null +++ b/src/main/java/utils/RandomNumberGenerator.java @@ -0,0 +1,7 @@ +package utils; + +public class RandomNumberGenerator { + public int generate() { + return (int) (Math.random()*10); + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000..3fa3847 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,29 @@ +package view; + +import utils.Parser; + +import java.util.List; +import java.util.Scanner; + +public class InputView { + private static final String READ_CAR_NAMES_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; + private static final String READ_TRY_COUNT_MESSAGE = "시도할 횟수는 몇회인가요?"; + + private final Scanner scanner; + + public InputView(Scanner scanner) { + this.scanner = scanner; + } + + public List readCarNames() { + System.out.println(READ_CAR_NAMES_MESSAGE); + String input = scanner.nextLine(); + return Parser.parseNames(input); + } + + public int readTryCount() { + System.out.println(READ_TRY_COUNT_MESSAGE); + String input = scanner.nextLine(); + return Parser.parseCount(input); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000..bd6e48b --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,39 @@ +package view; + +import domain.Car; +import domain.Cars; + +import java.util.List; +import java.util.stream.Collectors; + +public class OutputView { + + private static final String RESULT_MESSAGE = "실행 결과"; + private static final String STATUS_FORMAT = "%s : %s\n"; + private static final String WINNER_FORMAT = "%s가 최종 우승했습니다."; + private static final String HYPHEN = "-"; + + public void printResult() { + System.out.println(RESULT_MESSAGE); + } + + public void printStatus(List cars) { + for (Car car : cars) { + String currentDistance = getCurrentDistance(car.getDistance()); + System.out.printf(STATUS_FORMAT, car.getCarName(), currentDistance); + } + System.out.println(); + } + + public void printWinners(List cars) { + List carNames = cars.stream() + .map(Car::getCarName) + .toList(); + String winners = String.join(",", carNames); + System.out.printf(WINNER_FORMAT, winners); + } + + private String getCurrentDistance(int distance) { + return HYPHEN.repeat(distance); + } +} From 6ffa0985646f261e3f5ae6442892717f7b8919e1 Mon Sep 17 00:00:00 2001 From: o0Orangee Date: Sun, 24 Mar 2024 20:19:52 +0900 Subject: [PATCH 3/6] =?UTF-8?q?controller=20=EA=B5=AC=ED=98=84,=20view=20?= =?UTF-8?q?=EC=88=98=EC=A0=95,=20cars=20=EC=88=98=EC=A0=95,=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 3 + src/main/java/RacingMain.java | 5 +- .../java/controller/RacingCarController.java | 66 +++++++++++++++++++ .../java/controller/RacingcarController.java | 4 -- src/main/java/domain/Cars.java | 9 +++ src/main/java/view/InputView.java | 8 +-- src/main/java/view/OutputView.java | 8 +-- 7 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 src/main/java/controller/RacingCarController.java delete mode 100644 src/main/java/controller/RacingcarController.java diff --git a/docs/README.md b/docs/README.md index b6cdbcc..7d7cbfc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,6 +20,9 @@ # controller - 이름 입력받아서 Cars로 저장 +- 시도 횟수 입력받아 TryCount로 저장 +- 레이스 진행 +- 결과 출력 # utils - ## Parser ## diff --git a/src/main/java/RacingMain.java b/src/main/java/RacingMain.java index 4394287..dcad986 100644 --- a/src/main/java/RacingMain.java +++ b/src/main/java/RacingMain.java @@ -1,7 +1,10 @@ +import controller.RacingCarController; + public class RacingMain { public static void main(String[] args) { // TODO: MVC 패턴을 기반으로 자동차 경주 미션 구현해보기 - System.out.println("Hello, World!"); + RacingCarController racingCarController = new RacingCarController(); + racingCarController.run(); } } diff --git a/src/main/java/controller/RacingCarController.java b/src/main/java/controller/RacingCarController.java new file mode 100644 index 0000000..58518de --- /dev/null +++ b/src/main/java/controller/RacingCarController.java @@ -0,0 +1,66 @@ +package controller; + +import domain.Car; +import domain.Cars; +import domain.TryCount; +import utils.RandomNumberGenerator; +import view.InputView; +import view.OutputView; + +import java.io.IOException; +import java.util.List; + +public class RacingCarController { + + private final RandomNumberGenerator randomNumberGenerator; + + public RacingCarController() { + this.randomNumberGenerator = new RandomNumberGenerator(); + } + + public void run() { + Cars cars = getCars(); + TryCount tryCount = getTryCount(); + race(cars, tryCount); + printWinner(cars); + } + + private Cars getCars() { + List carNames = InputView.readCarNames(); + try { + return new Cars(carNames); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return getCars(); //올바른 입력 넣을 때까지 반복 + } + } + + private TryCount getTryCount() { + try { + int number = InputView.readTryCount(); + return new TryCount(number); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return getTryCount(); //올바른 입력 넣을 때까지 반복 + } + } + + private void race(Cars cars, TryCount tryCount) { + OutputView.printResult(); + while (tryCount.isRemain()) { + cars.moveCars(randomNumberGenerator); + printStatus(cars); + tryCount.decrease(); + } + } + + private void printStatus(Cars cars) { + List carList = cars.getCars(); + OutputView.printStatus(carList); + } + + private void printWinner(Cars cars) { + List winnerList = cars.findWinner(); + OutputView.printWinners(winnerList); + } +} diff --git a/src/main/java/controller/RacingcarController.java b/src/main/java/controller/RacingcarController.java deleted file mode 100644 index e4473a5..0000000 --- a/src/main/java/controller/RacingcarController.java +++ /dev/null @@ -1,4 +0,0 @@ -package controller; - -public class RacingcarController { -} diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java index 4ac176c..b604372 100644 --- a/src/main/java/domain/Cars.java +++ b/src/main/java/domain/Cars.java @@ -1,5 +1,7 @@ package domain; +import utils.RandomNumberGenerator; + import java.util.HashSet; import java.util.List; import java.util.Set; @@ -23,6 +25,13 @@ private List generateCars(List cars) { .collect(Collectors.toList()); } + public void moveCars(RandomNumberGenerator randomNumberGenerator) { + for (Car car : cars) { + int randomNumber = randomNumberGenerator.generate(); + car.move(randomNumber); + } + } + // 이름 중복 확인 private void validateDuplication(List carNames) { Set duplicationCheck = new HashSet<>(carNames); diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 3fa3847..dc05ae6 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -9,19 +9,19 @@ public class InputView { private static final String READ_CAR_NAMES_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; private static final String READ_TRY_COUNT_MESSAGE = "시도할 횟수는 몇회인가요?"; - private final Scanner scanner; + private static Scanner scanner; public InputView(Scanner scanner) { - this.scanner = scanner; + InputView.scanner = scanner; } - public List readCarNames() { + public static List readCarNames() { System.out.println(READ_CAR_NAMES_MESSAGE); String input = scanner.nextLine(); return Parser.parseNames(input); } - public int readTryCount() { + public static int readTryCount() { System.out.println(READ_TRY_COUNT_MESSAGE); String input = scanner.nextLine(); return Parser.parseCount(input); diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index bd6e48b..1cdc040 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -13,11 +13,11 @@ public class OutputView { private static final String WINNER_FORMAT = "%s가 최종 우승했습니다."; private static final String HYPHEN = "-"; - public void printResult() { + public static void printResult() { System.out.println(RESULT_MESSAGE); } - public void printStatus(List cars) { + public static void printStatus(List cars) { for (Car car : cars) { String currentDistance = getCurrentDistance(car.getDistance()); System.out.printf(STATUS_FORMAT, car.getCarName(), currentDistance); @@ -25,7 +25,7 @@ public void printStatus(List cars) { System.out.println(); } - public void printWinners(List cars) { + public static void printWinners(List cars) { List carNames = cars.stream() .map(Car::getCarName) .toList(); @@ -33,7 +33,7 @@ public void printWinners(List cars) { System.out.printf(WINNER_FORMAT, winners); } - private String getCurrentDistance(int distance) { + private static String getCurrentDistance(int distance) { return HYPHEN.repeat(distance); } } From b49a7754534a5297196d035c6119a31914498fde Mon Sep 17 00:00:00 2001 From: o0Orangee Date: Sun, 24 Mar 2024 23:06:37 +0900 Subject: [PATCH 4/6] =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1(CarName,=20TryCount)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/CarNameTest.java | 40 ++++++++++++++++++++++ src/test/java/domain/TryCountTest.java | 46 ++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/test/java/domain/CarNameTest.java create mode 100644 src/test/java/domain/TryCountTest.java diff --git a/src/test/java/domain/CarNameTest.java b/src/test/java/domain/CarNameTest.java new file mode 100644 index 0000000..9e9debf --- /dev/null +++ b/src/test/java/domain/CarNameTest.java @@ -0,0 +1,40 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.assertThatCode; + +public class CarNameTest { + + @DisplayName("이름이 없거나, 5글자를 초과하면 예외") + @ParameterizedTest + @CsvSource(value = {"'', 이름이 반드시 존재해야 합니다.", + "asdfgh, 이름은 5글자 이하여야 합니다.", + "aassddff, 이름은 5글자 이하여야 합니다."}) + void 이름_예외_발생(String carName, String errorMessage) { + assertThatThrownBy(() -> new CarName(carName)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(errorMessage); + } + + @DisplayName("1~5글자 이름은 유효") + @ParameterizedTest + @CsvSource(value = {"asdf", "ff", "jklkj"}) + void 유효한_이름(String carName) { + assertThatCode(() -> new CarName(carName)) + .doesNotThrowAnyException(); + } + + +// @ParameterizedTest //하나의 테스트 메소드로 여러 개의 파라미터에 대해서 테스트할 수 있다고 함 +// @ValueSource //리터럴 값의 단일 배열을 지정할 수 있음 +// @CsvSource //입력값에 따라 결과값이 다른 경우를 테스트 하려면 //CSV(Comma Separated Values) + +// assertThatThrownBy: 예외가 발생하는 것을 검증할 때 사용 +// assertThatCode: 예외가 발생하지 않는 것을 검증할 때 사용 +} diff --git a/src/test/java/domain/TryCountTest.java b/src/test/java/domain/TryCountTest.java new file mode 100644 index 0000000..3a17eed --- /dev/null +++ b/src/test/java/domain/TryCountTest.java @@ -0,0 +1,46 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.*; + +class TryCountTest { + + @DisplayName("시도 횟수가 0이거나 음수이면 예외") + @ParameterizedTest + @CsvSource(value = {"-1", "-12", "0"}) + void 양의_정수가_아님(int tryCount) { + assertThatThrownBy(() -> new TryCount(tryCount)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("시도 횟수는 양의 정수여야 합니다"); + } + + @DisplayName("시도 횟수가 양수이면 유효") + @ParameterizedTest + @CsvSource(value = {"1", "5", "48"}) + void 유효한_시도_횟수(int tryCount) { + assertThatCode(() -> new TryCount(tryCount)) + .doesNotThrowAnyException(); + } + + @DisplayName("decrease는 시도 횟수를 1 감소시킴") + @ParameterizedTest + @CsvSource(value = {"1, 0", "5, 4", "48, 47"}) + void 시도_횟수_감소_확인(int beforeValue, int afterValue) { + TryCount tryCount = new TryCount(beforeValue); + tryCount.decrease(); + assertThat(tryCount.getTryCount()).isEqualTo(afterValue); + } + + @DisplayName("isRemain은 시도 횟수가 남았는지 확인함") + @ParameterizedTest + @CsvSource(value = {"1, false", "5, true"}) + void 시도_횟수_남았는지_확인(int beforeValue, boolean isRemain) { + TryCount tryCount = new TryCount(beforeValue); + tryCount.decrease(); + assertThat(tryCount.isRemain()).isEqualTo(isRemain); + } +} \ No newline at end of file From 1bb36c694e06650b8653bc6e3e37fffcd801311f Mon Sep 17 00:00:00 2001 From: o0Orangee Date: Sun, 24 Mar 2024 23:38:43 +0900 Subject: [PATCH 5/6] =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1(Car,=20Distance)=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95(TryCount)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/CarTest.java | 29 ++++++++++++++++++++++++++ src/test/java/domain/DistanceTest.java | 20 ++++++++++++++++++ src/test/java/domain/TryCountTest.java | 4 ++-- 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/test/java/domain/CarTest.java create mode 100644 src/test/java/domain/DistanceTest.java diff --git a/src/test/java/domain/CarTest.java b/src/test/java/domain/CarTest.java new file mode 100644 index 0000000..e6f0825 --- /dev/null +++ b/src/test/java/domain/CarTest.java @@ -0,0 +1,29 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.*; + +class CarTest { + + @DisplayName("0~3일 때는 움직이지 않음") + @ParameterizedTest + @CsvSource(value = {"0,0", "1,0", "2,0", "3,0"}) //생성했을 때의 distance의 INITIAL_VALUE = 0 + void 움직이지_않음(int number, int distance) { + Car car = new Car("test"); + car.move(number); + assertThat(car.getDistance()).isEqualTo(distance); + } + + @DisplayName("4~9일 때는 움직임") + @ParameterizedTest + @CsvSource(value = {"4,1", "5,1", "6,1", "7,1", "8,1", "9,1"}) //생성했을 때의 distance의 INITIAL_VALUE = 0 + void 움직임(int number, int distance) { + Car car = new Car("test"); + car.move(number); + assertThat(car.getDistance()).isEqualTo(distance); + } +} \ No newline at end of file diff --git a/src/test/java/domain/DistanceTest.java b/src/test/java/domain/DistanceTest.java new file mode 100644 index 0000000..46b0ed7 --- /dev/null +++ b/src/test/java/domain/DistanceTest.java @@ -0,0 +1,20 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.*; + +class DistanceTest { + + @DisplayName("increase는 distance를 1 증가시킴") + @ParameterizedTest + @CsvSource(value = {"1"}) + void 이동거리_증가(int afterValue) { + Distance distance = new Distance(); //애초에 기본 세팅이 0 + distance.increaseDistance(); + assertThat(distance.getDistance()).isEqualTo(afterValue); + } +} \ No newline at end of file diff --git a/src/test/java/domain/TryCountTest.java b/src/test/java/domain/TryCountTest.java index 3a17eed..542fa8e 100644 --- a/src/test/java/domain/TryCountTest.java +++ b/src/test/java/domain/TryCountTest.java @@ -26,10 +26,10 @@ class TryCountTest { .doesNotThrowAnyException(); } - @DisplayName("decrease는 시도 횟수를 1 감소시킴") + @DisplayName("decrease는 tryCount를 1 감소시킴") @ParameterizedTest @CsvSource(value = {"1, 0", "5, 4", "48, 47"}) - void 시도_횟수_감소_확인(int beforeValue, int afterValue) { + void 시도_횟수_감소(int beforeValue, int afterValue) { TryCount tryCount = new TryCount(beforeValue); tryCount.decrease(); assertThat(tryCount.getTryCount()).isEqualTo(afterValue); From 0b6af282da4dab5e10b70e60b40d8bcdd1bb81bb Mon Sep 17 00:00:00 2001 From: o0Orangee Date: Mon, 25 Mar 2024 00:13:38 +0900 Subject: [PATCH 6/6] =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1(Parser)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Cars.java | 2 +- src/test/java/domain/CarsTest.java | 13 ++++++++++++ src/test/java/utils/ParserTest.java | 33 +++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/test/java/domain/CarsTest.java create mode 100644 src/test/java/utils/ParserTest.java diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java index b604372..16a55ba 100644 --- a/src/main/java/domain/Cars.java +++ b/src/main/java/domain/Cars.java @@ -14,7 +14,7 @@ public class Cars { private final List cars; public Cars(List carNames) { - final List cars= generateCars(carNames); + final List cars = generateCars(carNames); validateDuplication(carNames); this.cars = cars; } diff --git a/src/test/java/domain/CarsTest.java b/src/test/java/domain/CarsTest.java new file mode 100644 index 0000000..9b31b46 --- /dev/null +++ b/src/test/java/domain/CarsTest.java @@ -0,0 +1,13 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.*; + +class CarsTest { + +} \ No newline at end of file diff --git a/src/test/java/utils/ParserTest.java b/src/test/java/utils/ParserTest.java new file mode 100644 index 0000000..52c0b9d --- /dev/null +++ b/src/test/java/utils/ParserTest.java @@ -0,0 +1,33 @@ +package utils; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; + +class ParserTest { + + @DisplayName("쉼표를 기준으로 이름 분리") +// @ParameterizedTest +// @CsvSource(value = {"aa,bb,cc", "aaa, bbb,ccc ", "a,,b,c"}) + @Test + void 이름_분리() { + String string = "aa,bb,cc"; + List names = Parser.parseNames(string); + assertThat(names).containsExactly("aa", "bb", "cc"); + } + + @DisplayName("쉼표가 연속으로 오면 빈 문자열로 처리") + @Test + void 쉼표_연속() { + String string = "a,,b,c"; + List names = Parser.parseNames(string); + assertThat(names).containsExactly("a", "", "b", "c"); + } +} \ No newline at end of file