diff --git a/README.md b/README.md index 91744e0bd0..63c40aa9d9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,69 @@ # java-racingcar 자동차 경주 게임 미션 저장소 -## 우아한테크코스 코드리뷰 -* [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) \ No newline at end of file +## 문자열 덧셈 계산기 +요구사항 +- 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환 (예: “” => 0, "1,2" => 3, "1,2,3" => 6, “1,2:3” => 6) +- 앞의 기본 구분자(쉼표, 콜론)외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 “//”와 “\n” 사이에 위치하는 문자를 커스텀 구분자로 사용한다. 예를 들어 “//;\n1;2;3”과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다. +- 문자열 계산기에 숫자 이외의 값 또는 음수를 전달하는 경우 RuntimeException 예외를 throw한다. +- 문자열을 입력 받는다 + - 예외사항 + - 숫자 또는 슬래쉬로 시작하지 않는 문자열은 RuntimeException 예외를 throw 한다. + - 숫자로 시작하는 문자열의 구분자는 , 또는 : 만 허용된다. + - 커스텀 구분자를 // 와 \n 로 감싸지 않으면 RuntimException 예외를 throw 한다. + +프로그래밍 요구사항 +- indent(들여쓰기) depth를 2단계에서 1단계로 줄여라. +- depth의 경우 if문을 사용하는 경우 1단계의 depth가 증가한다. if문 안에 while문을 사용한다면 depth가 2단계가 된다. +- 메소드의 크기가 최대 10라인을 넘지 않도록 구현한다. +- method가 한 가지 일만 하도록 최대한 작게 만들어라. +- else를 사용하지 마라. + +## 자동차 경주 +### 기능 요구사항 +- 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. +- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. + - 횟수는 음수이면 안된다. + - 횟수는 양의 정수이어야 한다. +- 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. + - 이름에는 쉼표를 제외한 모든 문자가 포함 가능하다. + - 길이가 5 이하인 문자열이면 자동차 이름으로 할 수 있다. + - 공백 또는 쉼표로 시작하는 문자열을 입력하면 안된다.(ex: ,lavine) +- 전진하는 조건은 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다. +- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. + +### 프로그래밍 요구사항 +- 모든 로직에 단위 테스트를 구현한다. 단, UI(System.out, System.in) 로직은 제외 +- 자바 코드 컨벤션을 지키면서 프로그래밍한다. + - 참고문서: https://google.github.io/styleguide/javaguide.html 또는 https://myeonguni.tistory.com/1596 +- indent(인덴트, 들여쓰기) depth를 3을 넘지 않도록 구현한다. 2까지만 허용한다. + - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. + - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다. +- else 예약어를 쓰지 않는다. + - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다. + - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. +- 함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다. +- 함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다. + +### 기능 목록 및 commit 로그 요구사항 +- 기능을 구현하기 전에 README.md 파일에 구현할 기능 목록을 정리해 추가한다. +- git의 commit 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위로 추가한다. + +### 기능 목록 +- CarName + - 자동차 이름을 검증하고 저장하는 클래스 +- RacingLab + - 시도 횟수를 검증하고 저장하는 클래스 +- Output + - 실행 결과를 출력하는 메소드 + - 우승자를 출력하는 메소드 +- Car + - 이름과 위치를 필드로 갖는다. + - 랜덤 숫자에 따라서 진행을 판단하는 메소드 +- Racing + - 입력받은 시도 횟수만큼 반복하는 메소드 + - 랜덤 숫자를 생성하는 메소드 + - 우승자를 판단하는 메소드 +- Application + - 자동차 경주 실행 diff --git a/src/main/java/application/calculator/CalculatorApplication.java b/src/main/java/application/calculator/CalculatorApplication.java new file mode 100644 index 0000000000..0a5f83127a --- /dev/null +++ b/src/main/java/application/calculator/CalculatorApplication.java @@ -0,0 +1,35 @@ +package application.calculator; + +import java.util.Scanner; + +public class CalculatorApplication { + private static Scanner scanner = new Scanner(System.in); + + private static void runCalculator() { + try { + String userInputText = getUserInputText(); + int calculateResult = StringCalculator.splitAndSum(userInputText); + String result = makeResultString(userInputText, calculateResult); + System.out.println(result); + } catch (Exception e) { + System.out.println(e.getMessage()); + runCalculator(); + } + } + + private static String makeResultString(String userInputText, int calculateResult) { + StringBuilder sb = new StringBuilder(); + sb.append(userInputText); + sb.append(ConstantForCalculator.ARROW); + sb.append(calculateResult); + return sb.toString(); + } + + private static String getUserInputText() { + return scanner.nextLine(); + } + + public static void main(String[] args) { + runCalculator(); + } +} diff --git a/src/main/java/application/calculator/ConstantForCalculator.java b/src/main/java/application/calculator/ConstantForCalculator.java new file mode 100644 index 0000000000..4aae3f53d3 --- /dev/null +++ b/src/main/java/application/calculator/ConstantForCalculator.java @@ -0,0 +1,8 @@ +package application.calculator; + +public class ConstantForCalculator { + public final static String ARROW = " => "; + public final static String BIT_OR_OPERATOR = "|"; + public final static String DEFAULT_DELIMITER = ",|:"; + public final static String REGULAR_EXPRESSION = "//(.)\\\\n(.*)"; +} diff --git a/src/main/java/application/calculator/StringCalculator.java b/src/main/java/application/calculator/StringCalculator.java new file mode 100644 index 0000000000..c9f4965d91 --- /dev/null +++ b/src/main/java/application/calculator/StringCalculator.java @@ -0,0 +1,72 @@ +package application.calculator; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StringCalculator { + public static int splitAndSum(String text) { + if (isNullOrEmptyText(text)) { + return 0; + } + String delimiter = ConstantForCalculator.DEFAULT_DELIMITER; + String[] splitedText = splitText(text, delimiter); + List numbers = new ArrayList<>(); + splitText(text, delimiter); + addNumbers(splitedText, numbers); + return calculateNumberSum(numbers); + } + + private static String[] splitText(String text, String delimiter) { + Matcher matcher = Pattern.compile(ConstantForCalculator.REGULAR_EXPRESSION).matcher(text); + if (matcher.find()) { + String customDelimiter = matcher.group(1); + delimiter = addCustomDelimiter(delimiter, customDelimiter); + return matcher.group(2).split(delimiter); + } + return text.split(delimiter); + } + + private static String addCustomDelimiter(String delimiter, String customDelimiter) { + StringBuilder sb = new StringBuilder(); + sb.append(delimiter); + sb.append(ConstantForCalculator.BIT_OR_OPERATOR); + sb.append(customDelimiter); + return sb.toString(); + } + + private static int calculateNumberSum(List numbers) { + int sum = 0; + for (int integer : numbers) { + sum = sum + integer; + } + return sum; + } + + private static void addNumbers(String[] splitString, List numbers) { + for (String string : splitString) { + int convertNumber = getConvertNumber(string); + throwRuntimeExceptionWhenNegativeNumber(convertNumber); + numbers.add(convertNumber); + } + } + + private static void throwRuntimeExceptionWhenNegativeNumber(int number) { + if (number < 0) { + throw new RuntimeException("음수를 입력하였습니다."); + } + } + + private static int getConvertNumber(String string) { + try { + return Integer.parseInt(string); + } catch (Exception e) { + throw new RuntimeException("잘못된 수를 입력하였습니다."); + } + } + + private static boolean isNullOrEmptyText(String text) { + return text == null || text.isEmpty(); + } +} diff --git a/src/main/java/application/racing/RacingApplication.java b/src/main/java/application/racing/RacingApplication.java new file mode 100644 index 0000000000..c7c431a3c6 --- /dev/null +++ b/src/main/java/application/racing/RacingApplication.java @@ -0,0 +1,9 @@ +package application.racing; + +import application.racing.controller.RacingGameController; + +public class RacingApplication { + public static void main(String[] args) { + RacingGameController.run(); + } +} diff --git a/src/main/java/application/racing/controller/RacingGameController.java b/src/main/java/application/racing/controller/RacingGameController.java new file mode 100644 index 0000000000..f0ebd381bd --- /dev/null +++ b/src/main/java/application/racing/controller/RacingGameController.java @@ -0,0 +1,53 @@ +package application.racing.controller; + +import application.racing.domain.Cars; +import application.racing.domain.RacingGame; +import application.racing.domain.RacingLab; +import application.racing.view.InputViewer; +import application.racing.view.OutputViewer; + +public class RacingGameController { + private static Cars cars; + private static RacingLab racingLab; + private static RacingGame racingGame; + + public static void run() { + initializeCars(); + initializeRacingLab(); + race(); + OutputViewer.printWinner(cars.findWinner()); + } + + private static void initializeCars() { + boolean flag = false; + while (!flag) { + try { + cars = new Cars(InputViewer.getCarsName()); + flag = true; + } catch (IllegalArgumentException e) { + OutputViewer.printErrorMessage(e.getMessage()); + } + } + } + + private static void initializeRacingLab() { + boolean flag = false; + while (!flag) { + try { + racingLab = new RacingLab(InputViewer.getRacingLab()); + flag = true; + } catch (IllegalArgumentException e) { + OutputViewer.printErrorMessage(e.getMessage()); + } + } + } + + private static void race() { + racingGame = new RacingGame(); + OutputViewer.printRacingResultMessage(); + while (!racingGame.isEnd(racingLab)) { + racingGame.raceOneLab(cars); + OutputViewer.printPositionDuringRace(cars); + } + } +} diff --git a/src/main/java/application/racing/domain/Car.java b/src/main/java/application/racing/domain/Car.java new file mode 100644 index 0000000000..e63f96e11c --- /dev/null +++ b/src/main/java/application/racing/domain/Car.java @@ -0,0 +1,46 @@ +package application.racing.domain; + +public class Car { + private CarName carName; + private Position position; + + public Car(CarName carName) { + this.carName = carName; + this.position = new Position(); + } + + public void move(int number) { + this.position.move(number); + } + + public boolean isMaxPosition(int maxPosition) { + return this.getPosition() == maxPosition; + } + + public int getPosition() { + return this.position.getPosition(); + } + + @Override + public String toString() { + return this.carName.toString(); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || !(o instanceof Car)) { + return false; + } + Car compareCar = (Car) o; + return compareCar.carName.equals(this.carName) + && compareCar.position.equals(this.position); + } + + @Override + public int hashCode() { + return 31 * (this.carName.hashCode() + this.position.hashCode()); + } +} diff --git a/src/main/java/application/racing/domain/CarName.java b/src/main/java/application/racing/domain/CarName.java new file mode 100644 index 0000000000..80dbfd4a3b --- /dev/null +++ b/src/main/java/application/racing/domain/CarName.java @@ -0,0 +1,55 @@ +package application.racing.domain; + +public class CarName { + private final static String BLANK = " "; + private final static int MAX_NAME_LENGTH = 5; + + private String carName; + + public CarName(String carName) { + validateCarNameFormat(carName); + validateCarNameContainBlank(carName); + validateCarNameLength(carName); + this.carName = carName; + } + + private void validateCarNameFormat(String carName) { + if (carName == null || carName.isEmpty()) { + throw new IllegalArgumentException("이름을 잘못 입력하였습니다."); + } + } + + private void validateCarNameContainBlank(String carName) { + if (carName.contains(BLANK)) { + throw new IllegalArgumentException("공백을 포함한 이름을 입력하였습니다."); + } + } + + private void validateCarNameLength(String carName) { + if (carName.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException("5글자 초과의 자동차 이름을 입력하였습니다."); + } + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || !(o instanceof CarName)) { + return false; + } + CarName compareCarName = (CarName) o; + return compareCarName.carName.equals(this.carName); + } + + @Override + public int hashCode() { + return this.carName.hashCode() * 31; + } + + @Override + public String toString() { + return this.carName; + } +} diff --git a/src/main/java/application/racing/domain/Cars.java b/src/main/java/application/racing/domain/Cars.java new file mode 100644 index 0000000000..a90753ff61 --- /dev/null +++ b/src/main/java/application/racing/domain/Cars.java @@ -0,0 +1,57 @@ +package application.racing.domain; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class Cars { + private final static String NAME_DELIMITER = ","; + + List cars; + + public Cars(String name) { + initializeCar(name); + validateDuplicateCar(); + } + + private void initializeCar(String name) { + String[] names = name.split(NAME_DELIMITER); + cars = new ArrayList<>(); + for (int i = 0; i < names.length; i++) { + cars.add(new Car(new CarName(names[i]))); + } + } + + private void validateDuplicateCar() { + Set duplicateCar = new HashSet<>(cars); + if (duplicateCar.size() != cars.size()) { + throw new IllegalArgumentException("중복된 자동차 이름을 입력하였습니다."); + } + } + + public void moveEachCar() { + this.cars.stream() + .forEach(car -> car.move(new RandomNumber().getRandomNumber())); + } + + public List findWinner() { + int maxPosition = findMaxPosition(); + return this.cars.stream() + .filter(car -> car.isMaxPosition(maxPosition)) + .map(Car::toString) + .collect(Collectors.toList()); + } + + private int findMaxPosition() { + return this.cars.stream() + .map(Car::getPosition) + .max(Integer::compare) + .orElseThrow(IllegalArgumentException::new); + } + + public List getCars() { + return this.cars; + } +} diff --git a/src/main/java/application/racing/domain/Position.java b/src/main/java/application/racing/domain/Position.java new file mode 100644 index 0000000000..d57d7fe2a9 --- /dev/null +++ b/src/main/java/application/racing/domain/Position.java @@ -0,0 +1,38 @@ +package application.racing.domain; + +public class Position { + private final static int MOVING_STANDARD = 4; + + private int position; + + public Position() { + this.position = 0; + } + + public void move(int randomNumber) { + if (randomNumber >= MOVING_STANDARD) { + this.position = this.position + 1; + } + } + + public int getPosition() { + return this.position; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || !(o instanceof Position)) { + return false; + } + Position comparePosition = (Position) o; + return comparePosition.position == this.position; + } + + @Override + public int hashCode() { + return 31 + this.position; + } +} diff --git a/src/main/java/application/racing/domain/RacingGame.java b/src/main/java/application/racing/domain/RacingGame.java new file mode 100644 index 0000000000..38d7c3f079 --- /dev/null +++ b/src/main/java/application/racing/domain/RacingGame.java @@ -0,0 +1,18 @@ +package application.racing.domain; + +public class RacingGame { + private int round; + + public RacingGame() { + this.round = 0; + } + + public void raceOneLab(Cars cars) { + cars.moveEachCar(); + this.round = this.round + 1; + } + + public boolean isEnd(RacingLab racingLab) { + return this.round == racingLab.getRacingLab(); + } +} diff --git a/src/main/java/application/racing/domain/RacingLab.java b/src/main/java/application/racing/domain/RacingLab.java new file mode 100644 index 0000000000..52faa1ef2b --- /dev/null +++ b/src/main/java/application/racing/domain/RacingLab.java @@ -0,0 +1,30 @@ +package application.racing.domain; + +public class RacingLab { + private final static int RACING_LAB_STANDARD = 0; + + private int racingLab; + + public RacingLab(String input) { + validateRightNumber(input); + validateRacingLabUnderZero(); + } + + private void validateRightNumber(String input) { + try { + this.racingLab = Integer.parseInt(input); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자를 입력하십시오."); + } + } + + private void validateRacingLabUnderZero() { + if (this.racingLab < RACING_LAB_STANDARD) { + throw new IllegalArgumentException("0 이상의 수를 입력하십시오."); + } + } + + public int getRacingLab() { + return this.racingLab; + } +} diff --git a/src/main/java/application/racing/domain/RandomNumber.java b/src/main/java/application/racing/domain/RandomNumber.java new file mode 100644 index 0000000000..1a5043991c --- /dev/null +++ b/src/main/java/application/racing/domain/RandomNumber.java @@ -0,0 +1,24 @@ +package application.racing.domain; + +public class RandomNumber { + private static final int MINIMUM_RANDOM_NUMBER = 0; + private static final int MAXIMUM_RANDOM_NUMBER = 9; + + private int randomNumber; + + public RandomNumber() { + int randomValue = (int) (Math.random() * 10); + validateRandomNumber(randomValue); + this.randomNumber = randomValue; + } + + private void validateRandomNumber(int randomNumber) { + if (randomNumber < MINIMUM_RANDOM_NUMBER || randomNumber > MAXIMUM_RANDOM_NUMBER) { + throw new IllegalArgumentException("범위를 벗어나는 값입니다."); + } + } + + public int getRandomNumber() { + return this.randomNumber; + } +} diff --git a/src/main/java/application/racing/view/InputViewer.java b/src/main/java/application/racing/view/InputViewer.java new file mode 100644 index 0000000000..cf2635f754 --- /dev/null +++ b/src/main/java/application/racing/view/InputViewer.java @@ -0,0 +1,20 @@ +package application.racing.view; + +import java.util.Scanner; + +public class InputViewer { + private final static String GET_CARS_NAME_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; + private final static String GET_RACING_LAB_MESSAGE = "시도할 회수는 몇회인가요?"; + + private static Scanner scanner = new Scanner(System.in); + + public static String getCarsName() { + System.out.println(GET_CARS_NAME_MESSAGE); + return scanner.nextLine(); + } + + public static String getRacingLab() { + System.out.println(GET_RACING_LAB_MESSAGE); + return scanner.nextLine(); + } +} diff --git a/src/main/java/application/racing/view/OutputViewer.java b/src/main/java/application/racing/view/OutputViewer.java new file mode 100644 index 0000000000..123732438e --- /dev/null +++ b/src/main/java/application/racing/view/OutputViewer.java @@ -0,0 +1,58 @@ +package application.racing.view; + +import application.racing.domain.Car; +import application.racing.domain.Cars; + +import java.util.List; + +public class OutputViewer { + private final static String RUN_RESULT = "\n실행 결과"; + private final static String COLON = " : "; + private final static String BAR = "-"; + private final static String WINNER_MENTION = "가 최종 우승했습니다."; + private final static String NAME_DELIMITER = ", "; + + public static void printErrorMessage(String message) { + System.out.println(message); + } + + public static void printRacingResultMessage() { + System.out.println(RUN_RESULT); + } + + public static void printPositionDuringRace(Cars cars) { + for (Car car : cars.getCars()) { + StringBuilder sb = new StringBuilder(); + sb.append(car.toString()); + sb.append(COLON); + System.out.print(sb.toString()); + printCarPositionUsingBar(car); + System.out.println(); + } + System.out.println(); + } + + private static void printCarPositionUsingBar(Car car) { + for (int i = 0; i < car.getPosition(); i++) { + System.out.print(BAR); + } + } + + public static void printWinner(List winners) { + StringBuilder sb = new StringBuilder(); + String winnerNameString = makeWinnerNameString(winners); + sb.append(winnerNameString); + sb.append(WINNER_MENTION); + System.out.println(sb.toString()); + } + + private static String makeWinnerNameString(List winners) { + return String.join(addCommaWithBlank(), winners); + } + + private static String addCommaWithBlank() { + StringBuilder sb = new StringBuilder(); + sb.append(NAME_DELIMITER); + return sb.toString(); + } +} diff --git a/src/test/java/application/calculator/StringCalculatorTest.java b/src/test/java/application/calculator/StringCalculatorTest.java new file mode 100644 index 0000000000..a611e644fc --- /dev/null +++ b/src/test/java/application/calculator/StringCalculatorTest.java @@ -0,0 +1,70 @@ +package application.calculator; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StringCalculatorTest { + @DisplayName("null 또는 빈 문자열 계산 시 0을 결과로 반환 테스트") + @Test + public void splitAndSumNullOrEmptyStringTest() { + int result = StringCalculator.splitAndSum(null); + Assertions.assertThat(result).isEqualTo(0); + + result = StringCalculator.splitAndSum(""); + Assertions.assertThat(result).isEqualTo(0); + } + + @DisplayName("숫자 하나를 입력 시 그 숫자 그대로 반환 테스트") + @Test + public void splitAndSumOneNumberTest() throws Exception { + int result = StringCalculator.splitAndSum("1"); + Assertions.assertThat(result).isEqualTo(1); + } + + @DisplayName("쉼표구분자로 문자열을 나눠서 숫자들의 합을 반환 테스트") + @Test + public void splitAndSumUsingCommaDelimiterTest() throws Exception { + int result = StringCalculator.splitAndSum("1,2"); + Assertions.assertThat(result).isEqualTo(3); + } + + @DisplayName("쉼표 또는 콜론 구분자를 이용해 문자열을 나눠서 숫자들의 합을 반환 테스트") + @Test + public void splitAndSumUsingCommaOrColonDelimiterTest() throws Exception { + int result = StringCalculator.splitAndSum("1,2:3"); + Assertions.assertThat(result).isEqualTo(6); + } + + @DisplayName("Matcher 와 Pattern 클래스를 사용해 정규표현식을 사용한 문자열 나누는 API 테스트") + @Test + public void matcherAndPatternApiTest() { + String text = "//;\n1;2;3"; + String expectedCustomDelimiter = ";"; + String[] expectedTokens = {"1", "2", "3"}; + Matcher matcher = Pattern.compile("//(.)\n(.*)").matcher(text); + if (matcher.find()) { + String customDelimiter = matcher.group(1); + String[] tokens = matcher.group(2).split(customDelimiter); + Assertions.assertThat(customDelimiter).isEqualTo(expectedCustomDelimiter); + Assertions.assertThat(tokens).isEqualTo(expectedTokens); + } + } + + @DisplayName("커스텀 구분자로 문자열을 나눠서 숫자들의 합을 반환 테스트") + @Test + public void splitAndSumUsingCustomDelimiterTest() throws Exception { + int result = StringCalculator.splitAndSum("//;\\n1;2;3"); + Assertions.assertThat(result).isEqualTo(6); + } + + @DisplayName("음수를 전달할 경우 RuntimeException 예외가 발생하는지 테스트") + @Test + public void splitAndSumThrowRuntimeExceptionWhenNegativeTest() throws Exception { + Assertions.assertThatThrownBy(() -> StringCalculator.splitAndSum("-1,2,3")) + .isInstanceOf(RuntimeException.class); + } +} diff --git a/src/test/java/application/racing/CarNameTest.java b/src/test/java/application/racing/CarNameTest.java new file mode 100644 index 0000000000..59557779b4 --- /dev/null +++ b/src/test/java/application/racing/CarNameTest.java @@ -0,0 +1,29 @@ +package application.racing; + +import application.racing.domain.CarName; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class CarNameTest { + @DisplayName("비정상적인 입력에 대해 예외를 던지는지 CarName 클래스 생성자 테스트") + @ParameterizedTest + @ValueSource(strings = {"", " ", " ", "ab cd", "abcdefg"}) + public void carNameConstructorTest(String input) { + Assertions.assertThatThrownBy(() -> { + new CarName(input); + }).isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("equals 메소드 오버라이드 테스트") + @Test + public void CarNameEqualsTest() { + CarName input = new CarName("lavin"); + + CarName expected = new CarName("lavin"); + + Assertions.assertThat(input).isEqualTo(expected); + } +} diff --git a/src/test/java/application/racing/CarTest.java b/src/test/java/application/racing/CarTest.java new file mode 100644 index 0000000000..7ee0620cbb --- /dev/null +++ b/src/test/java/application/racing/CarTest.java @@ -0,0 +1,31 @@ +package application.racing; + +import application.racing.domain.Car; +import application.racing.domain.CarName; +import org.assertj.core.api.Assertions; +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; + +public class CarTest { + @DisplayName("입력값에 따라서 위치가 변하는지 테스트") + @ParameterizedTest + @CsvSource(value = {"0,0", "3,0", "4,1", "9,1"}, delimiter = ',') + public void positionMoveValidNumberTest(String input, String expected) { + Car car = new Car(new CarName("test")); + + car.move(Integer.parseInt(input)); + Assertions.assertThat(car.getPosition()).isEqualTo(Integer.parseInt(expected)); + } + + @DisplayName("Car equals 메소드 오버라이드 테스트") + @Test + public void carConstructorTest() { + Car input = new Car(new CarName("lavin")); + + Car expected = new Car(new CarName("lavin")); + + Assertions.assertThat(input).isEqualTo(expected); + } +} diff --git a/src/test/java/application/racing/CarsTest.java b/src/test/java/application/racing/CarsTest.java new file mode 100644 index 0000000000..ed1cf8730f --- /dev/null +++ b/src/test/java/application/racing/CarsTest.java @@ -0,0 +1,19 @@ +package application.racing; + +import application.racing.domain.Cars; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + + +public class CarsTest { + @DisplayName("Cars 클래스 생성자 테스트") + @ParameterizedTest + @ValueSource(strings = {"", ",asd", "asdfrq,pobi", "pobi,pobi", "pobi,,crong", "pobi, ,crong", " ,pobi"}) + public void carsConstructorTest(String input) { + Assertions.assertThatThrownBy(() -> { + new Cars(input); + }).isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/application/racing/PositionTest.java b/src/test/java/application/racing/PositionTest.java new file mode 100644 index 0000000000..24107fbd18 --- /dev/null +++ b/src/test/java/application/racing/PositionTest.java @@ -0,0 +1,30 @@ +package application.racing; + +import application.racing.domain.Position; +import org.assertj.core.api.Assertions; +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; + +public class PositionTest { + @DisplayName("입력값에 따라서 위치가 변하는지 테스트") + @ParameterizedTest + @CsvSource(value = {"0,0", "3,0", "4,1", "9,1"}, delimiter = ',') + public void positionMoveValidNumberTest(String input, String expected) { + Position position = new Position(); + + position.move(Integer.parseInt(input)); + Assertions.assertThat(position.getPosition()).isEqualTo(Integer.parseInt(expected)); + } + + @DisplayName("equals 메소드 오버라이드 테스트") + @Test + public void positionEqualsTest() { + Position input = new Position(); + + Position expected = new Position(); + + Assertions.assertThat(input).isEqualTo(expected); + } +} diff --git a/src/test/java/application/racing/RacingGameTest.java b/src/test/java/application/racing/RacingGameTest.java new file mode 100644 index 0000000000..02d75deb07 --- /dev/null +++ b/src/test/java/application/racing/RacingGameTest.java @@ -0,0 +1,23 @@ +package application.racing; + +import application.racing.domain.Cars; +import application.racing.domain.RacingGame; +import application.racing.domain.RacingLab; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class RacingGameTest { + @DisplayName("RacingLab 만큼 게임이 실행되었는지 확인하는 메소드 테스트") + @Test + public void gameTest() { + Cars cars = new Cars("lavin,pobi"); + RacingLab racingLab = new RacingLab("5"); + RacingGame racingGame = new RacingGame(); + + for (int i = 0; i < 5; i++) { + racingGame.raceOneLab(cars); + } + Assertions.assertThat(racingGame.isEnd(racingLab)).isTrue(); + } +} diff --git a/src/test/java/application/racing/RacingLabTest.java b/src/test/java/application/racing/RacingLabTest.java new file mode 100644 index 0000000000..e0b8c5b566 --- /dev/null +++ b/src/test/java/application/racing/RacingLabTest.java @@ -0,0 +1,18 @@ +package application.racing; + +import application.racing.domain.RacingLab; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class RacingLabTest { + @DisplayName("RacingLab 클래스 생성자 테스트") + @ParameterizedTest + @ValueSource(strings = {"-1", "ajsd;lfk", "8946846534164684684165841684687687684168468468546846541687465"}) + public void racingLabConstructorTest(String input) { + Assertions.assertThatThrownBy(() -> { + new RacingLab(input); + }).isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/application/racing/RandomNumberTest.java b/src/test/java/application/racing/RandomNumberTest.java new file mode 100644 index 0000000000..f4af809fd9 --- /dev/null +++ b/src/test/java/application/racing/RandomNumberTest.java @@ -0,0 +1,15 @@ +package application.racing; + +import application.racing.domain.RandomNumber; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class RandomNumberTest { + @DisplayName("RandomNumber 생성자 테스트") + @Test + public void randomNumberConstructorTest() { + RandomNumber randomNumber = new RandomNumber(); + Assertions.assertThat(randomNumber.getRandomNumber()).isBetween(0, 9); + } +}