From c211692aa5d3aeb8493280e2c366260242dcf4c7 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 1 Jun 2024 01:01:00 +0900 Subject: [PATCH 01/79] =?UTF-8?q?feat:=20InputMessage=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/game/view/constant/InputMessage.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/game/view/constant/InputMessage.java diff --git a/src/main/java/game/view/constant/InputMessage.java b/src/main/java/game/view/constant/InputMessage.java new file mode 100644 index 00000000..943124b8 --- /dev/null +++ b/src/main/java/game/view/constant/InputMessage.java @@ -0,0 +1,16 @@ +package game.view.constant; + +public enum InputMessage { + RACING_CAR_NAME("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분"), + ATTEMPT_COUNT("시도할 회수는 몇회인가요?"); + + private final String description; + + InputMessage(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} From df75c0ceb25d7e069b79612b590aec14c98c8689 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 1 Jun 2024 01:01:10 +0900 Subject: [PATCH 02/79] =?UTF-8?q?feat:=20OutputMessage=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/game/view/constant/OutputMessage.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/game/view/constant/OutputMessage.java diff --git a/src/main/java/game/view/constant/OutputMessage.java b/src/main/java/game/view/constant/OutputMessage.java new file mode 100644 index 00000000..3764e444 --- /dev/null +++ b/src/main/java/game/view/constant/OutputMessage.java @@ -0,0 +1,18 @@ +package game.view.constant; + +public enum OutputMessage { + + RESULT("실행 결과"), + WINNER("최종 우승자 : "); + + private final String description; + + OutputMessage(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } + +} From 988e13eec0546b25046ab20b5a827faf2273e930 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Wed, 5 Jun 2024 00:24:28 +0900 Subject: [PATCH 03/79] =?UTF-8?q?feat:=20InputMessage=20toString()=20?= =?UTF-8?q?=EC=98=A4=EB=B2=84=EB=9D=BC=EC=9D=B4=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/constant/InputMessage.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/game/view/constant/InputMessage.java b/src/main/java/game/view/constant/InputMessage.java index 943124b8..6a4bbc9b 100644 --- a/src/main/java/game/view/constant/InputMessage.java +++ b/src/main/java/game/view/constant/InputMessage.java @@ -1,7 +1,7 @@ package game.view.constant; public enum InputMessage { - RACING_CAR_NAME("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분"), + RACING_CAR_NAME("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), ATTEMPT_COUNT("시도할 회수는 몇회인가요?"); private final String description; @@ -10,7 +10,8 @@ public enum InputMessage { this.description = description; } - public String getDescription() { + @Override + public String toString() { return description; } } From 9fb7c9ae53a3ef8345cf87a8f5e97984bc7395f7 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Wed, 5 Jun 2024 00:24:38 +0900 Subject: [PATCH 04/79] =?UTF-8?q?feat:=20OutputMessage=20toString()=20?= =?UTF-8?q?=EC=98=A4=EB=B2=84=EB=9D=BC=EC=9D=B4=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/constant/OutputMessage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/game/view/constant/OutputMessage.java b/src/main/java/game/view/constant/OutputMessage.java index 3764e444..331c6ea9 100644 --- a/src/main/java/game/view/constant/OutputMessage.java +++ b/src/main/java/game/view/constant/OutputMessage.java @@ -11,7 +11,8 @@ public enum OutputMessage { this.description = description; } - public String getDescription() { + @Override + public String toString() { return description; } From 2e08c62a165a3fa138268abb616a5ce26f282915 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Wed, 5 Jun 2024 00:25:22 +0900 Subject: [PATCH 05/79] =?UTF-8?q?feat:=20InputView=20=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/InputView.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/game/view/InputView.java diff --git a/src/main/java/game/view/InputView.java b/src/main/java/game/view/InputView.java new file mode 100644 index 00000000..cd3e97dd --- /dev/null +++ b/src/main/java/game/view/InputView.java @@ -0,0 +1,12 @@ +package game.view; + +import java.util.Scanner; + +public class InputView { + + private Scanner scanner = new Scanner(System.in); + + private InputView() { + } + +} From eb3118cf24c645c9f33da8e4ac2bf778234fb630 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Wed, 5 Jun 2024 00:32:43 +0900 Subject: [PATCH 06/79] =?UTF-8?q?style:=20InputView=20RACING=5FCAR=5FNAME?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RACING_CAR_NAME -> CAR_NAME --- src/main/java/game/view/constant/InputMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/game/view/constant/InputMessage.java b/src/main/java/game/view/constant/InputMessage.java index 6a4bbc9b..ef89fc63 100644 --- a/src/main/java/game/view/constant/InputMessage.java +++ b/src/main/java/game/view/constant/InputMessage.java @@ -1,7 +1,7 @@ package game.view.constant; public enum InputMessage { - RACING_CAR_NAME("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), + CAR_NAME("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), ATTEMPT_COUNT("시도할 회수는 몇회인가요?"); private final String description; From d16b7e85cf01322857d3bab986e065ea96c1b967 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Wed, 5 Jun 2024 14:22:11 +0900 Subject: [PATCH 07/79] =?UTF-8?q?feat:=20CarNameValidator=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/game/validator/CarNameValidator.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/game/validator/CarNameValidator.java diff --git a/src/main/java/game/validator/CarNameValidator.java b/src/main/java/game/validator/CarNameValidator.java new file mode 100644 index 00000000..1888cfef --- /dev/null +++ b/src/main/java/game/validator/CarNameValidator.java @@ -0,0 +1,28 @@ +package game.validator; + +import java.util.StringTokenizer; + +public class CarNameValidator { + + private CarNameValidator() { + } + + public void validate(String input) { + validateDelimiter(input); + validateNameLength(input); + validateDuplication(input); + } + + private void validateDelimiter(String input) { + + } + + private void validateNameLength(String input) { + + } + + private void validateDuplication(String input) { + + } + +} From 105a6ae5e580c18d8d2b90ef9177362bd3c5966f Mon Sep 17 00:00:00 2001 From: nove1080 Date: Wed, 5 Jun 2024 22:18:33 +0900 Subject: [PATCH 08/79] =?UTF-8?q?refactor:=20CarNameValidator=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit validateDelimiter() 삭제 --- src/main/java/game/validator/CarNameValidator.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/game/validator/CarNameValidator.java b/src/main/java/game/validator/CarNameValidator.java index 1888cfef..95ff9786 100644 --- a/src/main/java/game/validator/CarNameValidator.java +++ b/src/main/java/game/validator/CarNameValidator.java @@ -8,15 +8,10 @@ private CarNameValidator() { } public void validate(String input) { - validateDelimiter(input); validateNameLength(input); validateDuplication(input); } - private void validateDelimiter(String input) { - - } - private void validateNameLength(String input) { } From 81b6205e1f08d096250bff0448be73e8de58ebb8 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Wed, 5 Jun 2024 22:49:56 +0900 Subject: [PATCH 09/79] =?UTF-8?q?feat:=20ErrorMessage=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game/exception/constant/ErrorMessage.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/game/exception/constant/ErrorMessage.java diff --git a/src/main/java/game/exception/constant/ErrorMessage.java b/src/main/java/game/exception/constant/ErrorMessage.java new file mode 100644 index 00000000..91ba13f6 --- /dev/null +++ b/src/main/java/game/exception/constant/ErrorMessage.java @@ -0,0 +1,19 @@ +package game.exception.constant; + +import static game.config.constant.Rule.*; + +public enum ErrorMessage { + + EXCEED_NAME_LENGTH("길이 %d를 초과하여 이름을 생성할 수 없습니다!".formatted(MAX_NAME_LENGTH)); + + private final String message; + + ErrorMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + +} From c2ad090bd9d2ef3a29157bb7bbee95fd6e945d6f Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 01:27:09 +0900 Subject: [PATCH 10/79] =?UTF-8?q?feat:=20CarNameValidator=20=EC=8B=B1?= =?UTF-8?q?=EA=B8=80=ED=84=B4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/validator/CarNameValidator.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/game/validator/CarNameValidator.java b/src/main/java/game/validator/CarNameValidator.java index 95ff9786..67739902 100644 --- a/src/main/java/game/validator/CarNameValidator.java +++ b/src/main/java/game/validator/CarNameValidator.java @@ -1,12 +1,16 @@ package game.validator; -import java.util.StringTokenizer; - public class CarNameValidator { + private static final CarNameValidator instance = new CarNameValidator(); + private CarNameValidator() { } + public static CarNameValidator getInstance() { + return instance; + } + public void validate(String input) { validateNameLength(input); validateDuplication(input); From b5e3af648ae76875cf6e96458dbc9d308e0b965a Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 01:27:49 +0900 Subject: [PATCH 11/79] =?UTF-8?q?feat:=20CarNameValidator=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EA=B8=B8=EC=9D=B4=20=EA=B2=80=EC=A6=9D=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/validator/CarNameValidator.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/game/validator/CarNameValidator.java b/src/main/java/game/validator/CarNameValidator.java index 67739902..036ca940 100644 --- a/src/main/java/game/validator/CarNameValidator.java +++ b/src/main/java/game/validator/CarNameValidator.java @@ -1,5 +1,10 @@ package game.validator; +import static game.config.constant.Rule.*; + +import game.exception.constant.ErrorMessage; +import java.util.Arrays; + public class CarNameValidator { private static final CarNameValidator instance = new CarNameValidator(); @@ -17,7 +22,13 @@ public void validate(String input) { } private void validateNameLength(String input) { - + String[] names = input.split(NAME_DELIMITER); + Arrays.stream(names) + .filter(name -> name.length() > MAX_NAME_LENGTH) + .findAny() + .ifPresent(name -> { + throw new IllegalArgumentException(ErrorMessage.EXCEED_NAME_LENGTH.getMessage()); + }); } private void validateDuplication(String input) { From 837a7441e0e3287eedaf13d81540c252f52dd125 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 01:47:33 +0900 Subject: [PATCH 12/79] =?UTF-8?q?feat:=20ErrorMessage=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=EC=97=90=20=EB=8C=80=ED=95=9C=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/exception/constant/ErrorMessage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/game/exception/constant/ErrorMessage.java b/src/main/java/game/exception/constant/ErrorMessage.java index 91ba13f6..ded4a552 100644 --- a/src/main/java/game/exception/constant/ErrorMessage.java +++ b/src/main/java/game/exception/constant/ErrorMessage.java @@ -4,8 +4,8 @@ public enum ErrorMessage { - EXCEED_NAME_LENGTH("길이 %d를 초과하여 이름을 생성할 수 없습니다!".formatted(MAX_NAME_LENGTH)); - + EXCEED_NAME_LENGTH("길이 %d를 초과하여 이름을 생성할 수 없습니다!".formatted(MAX_NAME_LENGTH)), + DUPLICATE_NAME_FOUND("중복된 이름이 존재합니다!"); private final String message; ErrorMessage(String message) { From a63f15cc84db673eba19fc55b987ef5c95bace76 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 01:48:51 +0900 Subject: [PATCH 13/79] =?UTF-8?q?feat:=20CarNameValidator=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=9D=B4=EB=A6=84=20=EA=B2=80=EC=A6=9D=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/validator/CarNameValidator.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/game/validator/CarNameValidator.java b/src/main/java/game/validator/CarNameValidator.java index 036ca940..8dc100f2 100644 --- a/src/main/java/game/validator/CarNameValidator.java +++ b/src/main/java/game/validator/CarNameValidator.java @@ -32,7 +32,13 @@ private void validateNameLength(String input) { } private void validateDuplication(String input) { + String[] names = input.split(NAME_DELIMITER); + long originalCount = names.length; + long uniqueCount = Arrays.stream(names).distinct().count(); + if (originalCount != uniqueCount) { + throw new IllegalArgumentException(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); + } } } From 1c85f3098b33c4d3c2baff645c3200a38cf42b07 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 01:49:51 +0900 Subject: [PATCH 14/79] =?UTF-8?q?feat:=20Rule=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/config/constant/Rule.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/game/config/constant/Rule.java diff --git a/src/main/java/game/config/constant/Rule.java b/src/main/java/game/config/constant/Rule.java new file mode 100644 index 00000000..9555cfca --- /dev/null +++ b/src/main/java/game/config/constant/Rule.java @@ -0,0 +1,11 @@ +package game.config.constant; + +public class Rule { + + private Rule() { + } + + public static String NAME_DELIMITER = ","; + public static int MAX_NAME_LENGTH = 5; + +} From 39e0ec5afcd3c602b3a5eab3b70359d08cf54ffb Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 12:33:19 +0900 Subject: [PATCH 15/79] =?UTF-8?q?test:=20CarNameValidatorTest=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game/validator/CarNameValidatorTest.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/test/java/game/validator/CarNameValidatorTest.java diff --git a/src/test/java/game/validator/CarNameValidatorTest.java b/src/test/java/game/validator/CarNameValidatorTest.java new file mode 100644 index 00000000..9914fb1e --- /dev/null +++ b/src/test/java/game/validator/CarNameValidatorTest.java @@ -0,0 +1,38 @@ +package game.validator; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import game.exception.constant.ErrorMessage; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class CarNameValidatorTest { + + CarNameValidator carNameValidator = CarNameValidator.getInstance(); + + @ParameterizedTest(name = "{0}은 적절한 이름 입력입니다.") + @ValueSource(strings = {"en.zo,silva,james","silva","_enzo,en zo,enzo "}) + void 적절한_이름_입력에_대해_예외를_던지지_않습니다(String input) { + assertDoesNotThrow(() -> carNameValidator.validate(input)); + } + + @ParameterizedTest(name = "{0}은 길이를 초과한 이름 입력입니다.") + @ValueSource(strings = {"thiago,sil ","en ,zo"}) + void 부적절한_이름_길이는_예외를_발생시킵니다(String input) { + IllegalArgumentException error = assertThrows( + IllegalArgumentException.class, () -> carNameValidator.validate(input)); + + assertThat(error.getMessage()).isEqualTo(ErrorMessage.EXCEED_NAME_LENGTH.getMessage()); + } + + @ParameterizedTest(name = "{0}은 중복이 존재하는 이름 입력입니다.") + @ValueSource(strings = {"enzo,bruno,enzo","james,james,james"}) + void 중복이_존재하는_이름은_예외를_발생시킵니다(String input) { + IllegalArgumentException error = assertThrows( + IllegalArgumentException.class, () -> carNameValidator.validate(input)); + + assertThat(error.getMessage()).isEqualTo(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); + } + +} \ No newline at end of file From 434e028ea7ae099e8f234f49462ee0c088f335cb Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 12:34:32 +0900 Subject: [PATCH 16/79] =?UTF-8?q?feat:=20InputView=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/InputView.java | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/game/view/InputView.java b/src/main/java/game/view/InputView.java index cd3e97dd..612ec3fb 100644 --- a/src/main/java/game/view/InputView.java +++ b/src/main/java/game/view/InputView.java @@ -1,12 +1,29 @@ package game.view; +import game.config.constant.Rule; +import game.validator.CarNameValidator; +import game.view.constant.InputMessage; +import java.util.Arrays; +import java.util.List; import java.util.Scanner; public class InputView { - private Scanner scanner = new Scanner(System.in); + private final Scanner scanner; + private final CarNameValidator carNameValidator; - private InputView() { + public InputView() { + scanner = new Scanner(System.in); + carNameValidator = CarNameValidator.getInstance(); + } + + public List enterCarNames() { + System.out.println(InputMessage.CAR_NAME); + + String input = scanner.next(); + carNameValidator.validate(input); + + return Arrays.asList(input.split(Rule.NAME_DELIMITER)); } } From 8ecaee9755190cb6eaa628b1c674c53192411fda Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 12:41:29 +0900 Subject: [PATCH 17/79] =?UTF-8?q?feat:=20ErrorMessage=20[ERROR]=20?= =?UTF-8?q?=EB=9D=BC=EB=B2=A8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/exception/constant/ErrorMessage.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/game/exception/constant/ErrorMessage.java b/src/main/java/game/exception/constant/ErrorMessage.java index ded4a552..545bd1b7 100644 --- a/src/main/java/game/exception/constant/ErrorMessage.java +++ b/src/main/java/game/exception/constant/ErrorMessage.java @@ -3,9 +3,9 @@ import static game.config.constant.Rule.*; public enum ErrorMessage { - - EXCEED_NAME_LENGTH("길이 %d를 초과하여 이름을 생성할 수 없습니다!".formatted(MAX_NAME_LENGTH)), - DUPLICATE_NAME_FOUND("중복된 이름이 존재합니다!"); + + EXCEED_NAME_LENGTH("[ERROR] 길이 %d를 초과하여 이름을 생성할 수 없습니다!".formatted(MAX_NAME_LENGTH)), + DUPLICATE_NAME_FOUND("[ERROR] 중복된 이름이 존재합니다!"); private final String message; ErrorMessage(String message) { From a56fee684cea666cb7248d6af5ce8d26c16f26ef Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 15:40:24 +0900 Subject: [PATCH 18/79] =?UTF-8?q?feat:=20ErrorMessage=20=EC=8B=9C=EB=8F=84?= =?UTF-8?q?=20=ED=9A=9F=EC=88=98=EC=99=80=20=EA=B4=80=EB=A0=A8=EB=90=9C=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit INVALID_NUMBER_INPUT INVALID_ATTEMPT_COUNT_INPUT --- src/main/java/game/exception/constant/ErrorMessage.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/game/exception/constant/ErrorMessage.java b/src/main/java/game/exception/constant/ErrorMessage.java index 545bd1b7..da4d0517 100644 --- a/src/main/java/game/exception/constant/ErrorMessage.java +++ b/src/main/java/game/exception/constant/ErrorMessage.java @@ -3,9 +3,11 @@ import static game.config.constant.Rule.*; public enum ErrorMessage { - + EXCEED_NAME_LENGTH("[ERROR] 길이 %d를 초과하여 이름을 생성할 수 없습니다!".formatted(MAX_NAME_LENGTH)), - DUPLICATE_NAME_FOUND("[ERROR] 중복된 이름이 존재합니다!"); + DUPLICATE_NAME_FOUND("[ERROR] 중복된 이름이 존재합니다!"), + INVALID_NUMBER_INPUT("[ERROR] 숫자를 입력해주세요!"), + INVALID_ATTEMPT_COUNT_INPUT("[ERROR] 1 이상의 숫자를 입력해주세요!"); private final String message; ErrorMessage(String message) { From 4ffb742ad4a408ca337a771628a6a3c02a73a69f Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 15:43:38 +0900 Subject: [PATCH 19/79] =?UTF-8?q?feat:=20AttemptCountValidator=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 시도 횟수 입력에 관한 검증기 --- .../game/validator/AttemptCountValidator.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/java/game/validator/AttemptCountValidator.java diff --git a/src/main/java/game/validator/AttemptCountValidator.java b/src/main/java/game/validator/AttemptCountValidator.java new file mode 100644 index 00000000..d29c920c --- /dev/null +++ b/src/main/java/game/validator/AttemptCountValidator.java @@ -0,0 +1,37 @@ +package game.validator; + +import game.exception.constant.ErrorMessage; + +/** + * 시도 횟수 입력에 대한 검증기 + */ +public class AttemptCountValidator { + + private static final AttemptCountValidator instance = new AttemptCountValidator(); + + private AttemptCountValidator() { + } + + public static AttemptCountValidator getInstance() { + return instance; + } + + public void validate(String attemptCountInput) { + validateNumberFormat(attemptCountInput); + validatePositiveValue(attemptCountInput); + } + + private void validateNumberFormat(String attemptCountInput) { + try { + Integer.parseInt(attemptCountInput); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(ErrorMessage.INVALID_NUMBER_INPUT.getMessage()); + } + } + + private void validatePositiveValue(String attemptCountInput) { + if (Integer.parseInt(attemptCountInput) <= 0) { + throw new IllegalArgumentException(ErrorMessage.INVALID_ATTEMPT_COUNT_INPUT.getMessage()); + } + } +} From e724efb3fea44860a46e1a936f76265485baf8a6 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 15:44:30 +0900 Subject: [PATCH 20/79] =?UTF-8?q?feat:=20InputView=20=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98=20=EC=9E=85=EB=A0=A5=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/InputView.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/game/view/InputView.java b/src/main/java/game/view/InputView.java index 612ec3fb..8a62199f 100644 --- a/src/main/java/game/view/InputView.java +++ b/src/main/java/game/view/InputView.java @@ -1,6 +1,7 @@ package game.view; import game.config.constant.Rule; +import game.validator.AttemptCountValidator; import game.validator.CarNameValidator; import game.view.constant.InputMessage; import java.util.Arrays; @@ -11,10 +12,12 @@ public class InputView { private final Scanner scanner; private final CarNameValidator carNameValidator; + private final AttemptCountValidator attemptCountValidator; public InputView() { scanner = new Scanner(System.in); carNameValidator = CarNameValidator.getInstance(); + attemptCountValidator = AttemptCountValidator.getInstance(); } public List enterCarNames() { @@ -26,4 +29,17 @@ public List enterCarNames() { return Arrays.asList(input.split(Rule.NAME_DELIMITER)); } + /** + * 시도 횟수를 입력 받습니다. + * + * @return 시도 횟수 + */ + public int enterAttemptCount() { + System.out.println(InputMessage.ATTEMPT_COUNT); + + String input = scanner.next(); + attemptCountValidator.validate(input); + + return Integer.parseInt(input); + } } From e77fd91ec8e0dd4a6fd682fba7e0c6166b574296 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 15:45:05 +0900 Subject: [PATCH 21/79] =?UTF-8?q?style:=20CarNameValidatorTest=20DisplayNa?= =?UTF-8?q?me=20=EB=A7=88=EC=B9=A8=ED=91=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/game/validator/CarNameValidatorTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/game/validator/CarNameValidatorTest.java b/src/test/java/game/validator/CarNameValidatorTest.java index 9914fb1e..f4d04658 100644 --- a/src/test/java/game/validator/CarNameValidatorTest.java +++ b/src/test/java/game/validator/CarNameValidatorTest.java @@ -11,13 +11,13 @@ class CarNameValidatorTest { CarNameValidator carNameValidator = CarNameValidator.getInstance(); - @ParameterizedTest(name = "{0}은 적절한 이름 입력입니다.") + @ParameterizedTest(name = "{0}은 적절한 이름 입력입니다") @ValueSource(strings = {"en.zo,silva,james","silva","_enzo,en zo,enzo "}) void 적절한_이름_입력에_대해_예외를_던지지_않습니다(String input) { assertDoesNotThrow(() -> carNameValidator.validate(input)); } - @ParameterizedTest(name = "{0}은 길이를 초과한 이름 입력입니다.") + @ParameterizedTest(name = "{0}은 길이를 초과한 이름 입력입니다") @ValueSource(strings = {"thiago,sil ","en ,zo"}) void 부적절한_이름_길이는_예외를_발생시킵니다(String input) { IllegalArgumentException error = assertThrows( @@ -26,7 +26,7 @@ class CarNameValidatorTest { assertThat(error.getMessage()).isEqualTo(ErrorMessage.EXCEED_NAME_LENGTH.getMessage()); } - @ParameterizedTest(name = "{0}은 중복이 존재하는 이름 입력입니다.") + @ParameterizedTest(name = "{0}은 중복이 존재하는 이름 입력입니다") @ValueSource(strings = {"enzo,bruno,enzo","james,james,james"}) void 중복이_존재하는_이름은_예외를_발생시킵니다(String input) { IllegalArgumentException error = assertThrows( From 86a698159574d29a542a3eb338b65252eb5f6082 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 15:45:42 +0900 Subject: [PATCH 22/79] =?UTF-8?q?test:=20AttemptCountValidatorTest=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validator/AttemptCountValidatorTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/test/java/game/validator/AttemptCountValidatorTest.java diff --git a/src/test/java/game/validator/AttemptCountValidatorTest.java b/src/test/java/game/validator/AttemptCountValidatorTest.java new file mode 100644 index 00000000..ca639f7b --- /dev/null +++ b/src/test/java/game/validator/AttemptCountValidatorTest.java @@ -0,0 +1,40 @@ +package game.validator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import game.exception.constant.ErrorMessage; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class AttemptCountValidatorTest { + + AttemptCountValidator attemptCountValidator = AttemptCountValidator.getInstance(); + + @ParameterizedTest(name = "{0}은 적절한 시도 횟수 입력입니다") + @ValueSource(strings = {"5", "10", "100"}) + void 적절한_시도_횟수_입력에_대해_예외를_던지지_않습니다(String input) { + assertDoesNotThrow(() -> attemptCountValidator.validate(input)); + } + + @ParameterizedTest(name = "{0}은 숫자가 아닌 입력") + @ValueSource(strings = {"thiago,sil", "enzo", "a", "", " "}) + void 숫자가_아닌_입력값에_대하여_예외를_발생시킵니다(String input) { + IllegalArgumentException error = assertThrows( + IllegalArgumentException.class, () -> attemptCountValidator.validate(input)); + + assertThat(error.getMessage()).isEqualTo(ErrorMessage.INVALID_NUMBER_INPUT.getMessage()); + } + + @ParameterizedTest(name = "{0}은 1보다 작은 입력") + @ValueSource(strings = {"-1", "-100", "-99999", "0"}) + void 입력이_1보다_작은_입력값에_대하여_예외를_발생시킵니다(String input) { + IllegalArgumentException error = assertThrows( + IllegalArgumentException.class, () -> attemptCountValidator.validate(input)); + + assertThat(error.getMessage()).isEqualTo( + ErrorMessage.INVALID_ATTEMPT_COUNT_INPUT.getMessage()); + } + +} \ No newline at end of file From 0654871b3b6c87e274535abf89e39fe83ff89bd4 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 17:09:49 +0900 Subject: [PATCH 23/79] =?UTF-8?q?feat:=20Rule=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=9E=90=20=EC=A0=84=EC=A7=84=20=EC=A1=B0=EA=B1=B4=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/config/constant/Rule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/game/config/constant/Rule.java b/src/main/java/game/config/constant/Rule.java index 9555cfca..721cea04 100644 --- a/src/main/java/game/config/constant/Rule.java +++ b/src/main/java/game/config/constant/Rule.java @@ -7,5 +7,5 @@ private Rule() { public static String NAME_DELIMITER = ","; public static int MAX_NAME_LENGTH = 5; - + public static int MOVEMENT_THRESHOLD = 4; } From 0b835d64ed347423e0e21d9d0216d52fe4003fe6 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Thu, 6 Jun 2024 17:11:49 +0900 Subject: [PATCH 24/79] =?UTF-8?q?feat:=20Rule=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EC=9C=84=EC=B9=98=20=EC=B6=9C=EB=A0=A5=20=EB=A7=88?= =?UTF-8?q?=EC=BB=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/config/constant/Rule.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/game/config/constant/Rule.java b/src/main/java/game/config/constant/Rule.java index 721cea04..c10efd44 100644 --- a/src/main/java/game/config/constant/Rule.java +++ b/src/main/java/game/config/constant/Rule.java @@ -8,4 +8,5 @@ private Rule() { public static String NAME_DELIMITER = ","; public static int MAX_NAME_LENGTH = 5; public static int MOVEMENT_THRESHOLD = 4; + public static String CAR_POSITION_MAKER = "-"; } From 27efd28392c8bced4512125305e608f1fb6761f4 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 01:04:28 +0900 Subject: [PATCH 25/79] =?UTF-8?q?feat:=20Car=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Car.java | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/java/game/domain/Car.java diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java new file mode 100644 index 00000000..ccebd7c4 --- /dev/null +++ b/src/main/java/game/domain/Car.java @@ -0,0 +1,37 @@ +package game.domain; + +import game.config.constant.Rule; +import game.validator.CarNameValidator; +import java.util.Random; + +public class Car { + + private String name; + private int position; + + public Car(String name) { + CarNameValidator.getInstance().validateNameLength(name); + this.name = name; + } + + public String getName() { + return name; + } + + public int getPosition() { + return position; + } + + public int move() { + if(canMove()) { + this.position++; + } + return this.position; + } + + private boolean canMove() { + Random random = new Random(); + return random.nextInt(Rule.MAX_RANDOM_VALUE + 1) >= Rule.MOVEMENT_THRESHOLD; + } + +} From ef1c18239275bbb23a3623ecd5ff86618844c462 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 01:06:26 +0900 Subject: [PATCH 26/79] =?UTF-8?q?feat:=20Rule=20=EB=82=9C=EC=88=98=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9D=98=20=EC=B5=9C=EB=8C=80=20=EB=B2=94?= =?UTF-8?q?=EC=9C=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/config/constant/Rule.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/game/config/constant/Rule.java b/src/main/java/game/config/constant/Rule.java index c10efd44..b0a9f6c8 100644 --- a/src/main/java/game/config/constant/Rule.java +++ b/src/main/java/game/config/constant/Rule.java @@ -7,6 +7,7 @@ private Rule() { public static String NAME_DELIMITER = ","; public static int MAX_NAME_LENGTH = 5; + public static int MAX_RANDOM_VALUE = 9; public static int MOVEMENT_THRESHOLD = 4; public static String CAR_POSITION_MAKER = "-"; } From f6ed02c2ea3c399ab8bc43bf8dbd60cb89661705 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 14:01:39 +0900 Subject: [PATCH 27/79] =?UTF-8?q?feat:=20Car=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Car(String, int) --- src/main/java/game/domain/Car.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java index ccebd7c4..783c7afe 100644 --- a/src/main/java/game/domain/Car.java +++ b/src/main/java/game/domain/Car.java @@ -6,12 +6,17 @@ public class Car { - private String name; + private final String name; private int position; public Car(String name) { + this(name, 0); + } + + public Car(String name, int position) { CarNameValidator.getInstance().validateNameLength(name); this.name = name; + this.position = position; } public String getName() { From bfd7acec46b74b89e58e6b209d412ae3ce98858b Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 14:03:12 +0900 Subject: [PATCH 28/79] =?UTF-8?q?feat:=20Cars=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/game/domain/Cars.java diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java new file mode 100644 index 00000000..fee00fa3 --- /dev/null +++ b/src/main/java/game/domain/Cars.java @@ -0,0 +1,13 @@ +package game.domain; + +import java.util.List; + +public class Cars { + + private List carList; + + public Cars(List carList) { + this.carList = carList; + } + +} From 1e1c9f0c88e8e79f9ab1503100322ebe49f98fda Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 14:03:52 +0900 Subject: [PATCH 29/79] =?UTF-8?q?feat:=20Cars=20move()=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index fee00fa3..53365d73 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -10,4 +10,8 @@ public Cars(List carList) { this.carList = carList; } + public void move() { + carList.forEach(Car::move); + } + } From 316b1daf50020047258c5249966664bfe467360e Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 14:04:20 +0900 Subject: [PATCH 30/79] =?UTF-8?q?feat:=20Cars=20=EC=9A=B0=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=EB=A5=BC=20=EC=B0=BE=EB=8A=94=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 53365d73..6ca5e162 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -1,6 +1,10 @@ package game.domain; +import game.exception.constant.ErrorMessage; +import java.util.Comparator; import java.util.List; +import java.util.NoSuchElementException; +import java.util.stream.Collectors; public class Cars { @@ -14,4 +18,17 @@ public void move() { carList.forEach(Car::move); } + public List findWinners() { + int maxPosition = getMaxPosition(); + return carList.stream() + .filter(car -> car.getPosition() == maxPosition) + .collect(Collectors.toList()); + } + + public int getMaxPosition() { + return carList.stream() + .map(Car::getPosition) + .max(Comparator.naturalOrder()) + .orElseThrow(() -> new NoSuchElementException(ErrorMessage.EMPTY_LIST.getMessage())); + } } From 44f3bb574fa03d1c1dd3478222f87151f8cba0cf Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 18:51:27 +0900 Subject: [PATCH 31/79] =?UTF-8?q?test:=20CarTest=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EC=9B=80=EC=A7=81=EC=9E=84=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/game/domain/CarTest.java | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/java/game/domain/CarTest.java diff --git a/src/test/java/game/domain/CarTest.java b/src/test/java/game/domain/CarTest.java new file mode 100644 index 00000000..4d03c1d9 --- /dev/null +++ b/src/test/java/game/domain/CarTest.java @@ -0,0 +1,49 @@ +package game.domain; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class CarTest { + + @ParameterizedTest(name = "{0}은 난수 {1} 일 때 전진합니다") + @MethodSource("getMovableCar") + void movableCar(Car car, int movementValue) { + assertThat(car.getPosition()).isEqualTo(0); + assertThat(car.move(movementValue)).isEqualTo(1); + } + + @ParameterizedTest(name = "{0}은 난수 {1} 일 때 전진하지 않습니다") + @MethodSource("getUnmovableCar") + void unmovableCar(Car car, int movementValue) { + assertThat(car.getPosition()).isEqualTo(0); + assertThat(car.move(movementValue)).isEqualTo(0); + } + + static Stream getMovableCar() { + return Stream.of( + Arguments.arguments(new Car("enzo"), 4), + Arguments.arguments(new Car("enzo"), 5), + Arguments.arguments(new Car("enzo"), 6), + Arguments.arguments(new Car("enzo"), 7), + Arguments.arguments(new Car("enzo"), 8), + Arguments.arguments(new Car("enzo"), 9) + ); + } + + static Stream getUnmovableCar() { + return Stream.of( + Arguments.arguments(new Car("enzo"), 0), + Arguments.arguments(new Car("enzo"), 1), + Arguments.arguments(new Car("enzo"), 2), + Arguments.arguments(new Car("enzo"), 3) + ); + } + + + +} \ No newline at end of file From 86a29a7edcf97eb073bf674c16cc722ae461b7f1 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 18:52:36 +0900 Subject: [PATCH 32/79] =?UTF-8?q?feat:=20Car=20move=EC=99=80=20canMove=20?= =?UTF-8?q?=EC=98=A4=EB=B2=84=EB=A1=9C=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit move(int), canMove(int) --- src/main/java/game/domain/Car.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java index 783c7afe..016e3d19 100644 --- a/src/main/java/game/domain/Car.java +++ b/src/main/java/game/domain/Car.java @@ -2,6 +2,7 @@ import game.config.constant.Rule; import game.validator.CarNameValidator; +import java.util.Objects; import java.util.Random; public class Car { @@ -34,9 +35,20 @@ public int move() { return this.position; } + public int move(int randomValue) { + if(canMove(randomValue)) { + this.position++; + } + return this.position; + } + private boolean canMove() { Random random = new Random(); return random.nextInt(Rule.MAX_RANDOM_VALUE + 1) >= Rule.MOVEMENT_THRESHOLD; } + private boolean canMove(int randomValue) { + return randomValue >= Rule.MOVEMENT_THRESHOLD; + } + } From 9a7e9f343d690ba569416c6b99d070b3feebd638 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 18:53:04 +0900 Subject: [PATCH 33/79] =?UTF-8?q?feat:=20Car=20equalsAndHashcode,=20toStri?= =?UTF-8?q?ng=20=EC=98=A4=EB=B2=84=EB=9D=BC=EC=9D=B4=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Car.java | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java index 016e3d19..18fa1dd6 100644 --- a/src/main/java/game/domain/Car.java +++ b/src/main/java/game/domain/Car.java @@ -51,4 +51,28 @@ private boolean canMove(int randomValue) { return randomValue >= Rule.MOVEMENT_THRESHOLD; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Car car = (Car) o; + return position == car.position && Objects.equals(name, car.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, position); + } + + @Override + public String toString() { + return "Car{" + + "name='" + name + '\'' + + ", position=" + position + + '}'; + } } From d72d493ad56dda57f48b3b350a7b11aee7cfea2c Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 18:56:22 +0900 Subject: [PATCH 34/79] =?UTF-8?q?refactor:=20Car=EC=9D=98=20=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=AF=B8=ED=84=B0=EA=B0=80=20=EC=97=86=EB=8A=94=20mov?= =?UTF-8?q?e=EC=99=80=20canMove=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 테스트가 어려우므로 Random 클래스와의 의존성 제거를 위함 --- src/main/java/game/domain/Car.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java index 18fa1dd6..e664e69f 100644 --- a/src/main/java/game/domain/Car.java +++ b/src/main/java/game/domain/Car.java @@ -3,7 +3,6 @@ import game.config.constant.Rule; import game.validator.CarNameValidator; import java.util.Objects; -import java.util.Random; public class Car { @@ -28,13 +27,6 @@ public int getPosition() { return position; } - public int move() { - if(canMove()) { - this.position++; - } - return this.position; - } - public int move(int randomValue) { if(canMove(randomValue)) { this.position++; @@ -42,11 +34,6 @@ public int move(int randomValue) { return this.position; } - private boolean canMove() { - Random random = new Random(); - return random.nextInt(Rule.MAX_RANDOM_VALUE + 1) >= Rule.MOVEMENT_THRESHOLD; - } - private boolean canMove(int randomValue) { return randomValue >= Rule.MOVEMENT_THRESHOLD; } From 16f3337f1c76ace892f359292379491da8739996 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 19:08:54 +0900 Subject: [PATCH 35/79] =?UTF-8?q?test:=20CarsTest=20findWinner()=EC=97=90?= =?UTF-8?q?=20=EB=8C=80=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/game/domain/CarsTest.java | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/java/game/domain/CarsTest.java diff --git a/src/test/java/game/domain/CarsTest.java b/src/test/java/game/domain/CarsTest.java new file mode 100644 index 00000000..002100d4 --- /dev/null +++ b/src/test/java/game/domain/CarsTest.java @@ -0,0 +1,35 @@ +package game.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class CarsTest { + + @ParameterizedTest(name = "{0}의 경주 결과 승자는 {1}입니다") + @MethodSource("getCarList") + void findWinner(Cars cars, Cars winners) { + assertThat(cars.findWinners()).isEqualTo(winners); + } + + private static Stream getCarList() { + List carList = new ArrayList<>(); + carList.add(new Car("enzo", 5)); + carList.add(new Car("gusto", 5)); + carList.add(new Car("james", 1)); + + List winners = new ArrayList<>(); + winners.add(new Car("enzo", 5)); + winners.add(new Car("gusto", 5)); + + return Stream.of( + Arguments.arguments(new Cars(carList), new Cars(winners)) + ); + } + +} \ No newline at end of file From 16a4bbb0f01b7935de78741debb25f3c653a35d3 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 19:11:20 +0900 Subject: [PATCH 36/79] =?UTF-8?q?refactor:=20Cars=EC=9D=98=20findWinner()?= =?UTF-8?q?=20=EB=A6=AC=ED=84=B4=20=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - List -> Cars --- src/main/java/game/domain/Cars.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 6ca5e162..240b1109 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -18,11 +18,12 @@ public void move() { carList.forEach(Car::move); } - public List findWinners() { + public Cars findWinners() { int maxPosition = getMaxPosition(); - return carList.stream() + List winners = carList.stream() .filter(car -> car.getPosition() == maxPosition) .collect(Collectors.toList()); + return new Cars(winners); } public int getMaxPosition() { From 2af05dc877b493150257c75b0d13a2731f36faed Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 19:12:25 +0900 Subject: [PATCH 37/79] =?UTF-8?q?refactor:=20Cars=EC=9D=98=20move()=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 수정된 로직: 내부에서 Random 값을 생성 --- src/main/java/game/domain/Cars.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 240b1109..7997247f 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -1,9 +1,11 @@ package game.domain; +import game.config.constant.Rule; import game.exception.constant.ErrorMessage; import java.util.Comparator; import java.util.List; import java.util.NoSuchElementException; +import java.util.Random; import java.util.stream.Collectors; public class Cars { @@ -15,7 +17,9 @@ public Cars(List carList) { } public void move() { - carList.forEach(Car::move); + Random random = new Random(); + int movementValue = random.nextInt(Rule.MAX_RANDOM_VALUE + 1); + carList.forEach(car -> car.move(movementValue)); } public Cars findWinners() { From a4685ed5c615b1b9d8d1db47183e78c2d3a1e9d9 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 19:12:59 +0900 Subject: [PATCH 38/79] =?UTF-8?q?feat:=20Cars=EC=97=90=20getCarList()=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 7997247f..851bb2d3 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -2,6 +2,7 @@ import game.config.constant.Rule; import game.exception.constant.ErrorMessage; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.NoSuchElementException; @@ -36,4 +37,8 @@ public int getMaxPosition() { .max(Comparator.naturalOrder()) .orElseThrow(() -> new NoSuchElementException(ErrorMessage.EMPTY_LIST.getMessage())); } + + public List getCarList() { + return Collections.unmodifiableList(carList); + } } From da384d2aac6347fdcbd83ae1a5e2426db1952b24 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 19:14:26 +0900 Subject: [PATCH 39/79] =?UTF-8?q?feat:=20Cars=EC=97=90=20equalsAndHashcode?= =?UTF-8?q?=20=EC=98=A4=EB=B2=84=EB=9D=BC=EC=9D=B4=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 851bb2d3..27ee18a9 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -4,8 +4,10 @@ import game.exception.constant.ErrorMessage; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Random; import java.util.stream.Collectors; @@ -41,4 +43,27 @@ public int getMaxPosition() { public List getCarList() { return Collections.unmodifiableList(carList); } + + /** + * 리스트의 순서와 상관없이 내부 원소만 비교하여 동등성을 판단합니다 + * + * @param o 비교할 Cars 인스턴스 + * @return 동등여부 + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Cars cars = (Cars) o; + return new HashSet<>(carList).equals(new HashSet<>(cars.getCarList())); + } + + @Override + public int hashCode() { + return Objects.hash(carList); + } } From e252a77b00d18826936355bb1439033e1aa3bac7 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 19:15:22 +0900 Subject: [PATCH 40/79] =?UTF-8?q?feat:=20Cars=EC=97=90=20toString=20?= =?UTF-8?q?=EC=98=A4=EB=B2=84=EB=9D=BC=EC=9D=B4=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 27ee18a9..4114dc10 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -66,4 +66,17 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(carList); } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("Cars = "); + carList.forEach(car -> + stringBuilder.append("(") + .append(car.getName()) + .append(", position: ") + .append(car.getPosition()) + .append(")")); + return stringBuilder.toString(); + } } From 9e41f045d98769d3e72ccaf52fe47ad8144973b0 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 19:16:28 +0900 Subject: [PATCH 41/79] =?UTF-8?q?refactor:=20Cars=EC=9D=98=20findWinners?= =?UTF-8?q?=20=EC=8A=B9=EC=9E=90=20=EB=B0=98=ED=99=98=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 4114dc10..1a6cc0f3 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -29,7 +29,7 @@ public Cars findWinners() { int maxPosition = getMaxPosition(); List winners = carList.stream() .filter(car -> car.getPosition() == maxPosition) - .collect(Collectors.toList()); + .toList(); return new Cars(winners); } From 53173ef6289672d192f6ce2f774477980510ce99 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 22:58:25 +0900 Subject: [PATCH 42/79] =?UTF-8?q?test:=20CarsTest=20getCarList=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getCarList -> getCarListAndWinner --- src/test/java/game/domain/CarsTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/game/domain/CarsTest.java b/src/test/java/game/domain/CarsTest.java index 002100d4..a9183f48 100644 --- a/src/test/java/game/domain/CarsTest.java +++ b/src/test/java/game/domain/CarsTest.java @@ -12,12 +12,12 @@ class CarsTest { @ParameterizedTest(name = "{0}의 경주 결과 승자는 {1}입니다") - @MethodSource("getCarList") + @MethodSource("getCarListAndWinner") void findWinner(Cars cars, Cars winners) { assertThat(cars.findWinners()).isEqualTo(winners); } - private static Stream getCarList() { + private static Stream getCarListAndWinner() { List carList = new ArrayList<>(); carList.add(new Car("enzo", 5)); carList.add(new Car("gusto", 5)); From 7014f3bc67f39d39520dd1202e9dfc4b4891740f Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 23:02:44 +0900 Subject: [PATCH 43/79] =?UTF-8?q?test:=20CarsTest=20Cars.getMaxPosition()?= =?UTF-8?q?=20=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/game/domain/CarsTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/game/domain/CarsTest.java b/src/test/java/game/domain/CarsTest.java index a9183f48..dedc88d8 100644 --- a/src/test/java/game/domain/CarsTest.java +++ b/src/test/java/game/domain/CarsTest.java @@ -11,6 +11,25 @@ class CarsTest { + @ParameterizedTest(name = "{0}의 최대 위치는 {1} 입니다") + @MethodSource("getCarAndMaxPosition") + void getMaxPosition(Cars cars, int maxPosition) { + assertThat(cars.getMaxPosition()).isEqualTo(maxPosition); + } + + private static Stream getCarAndMaxPosition() { + int maxPosition = 5; + + List carList = new ArrayList<>(); + carList.add(new Car("enzo", maxPosition)); + carList.add(new Car("gusto", 3)); + carList.add(new Car("james", 1)); + + return Stream.of( + Arguments.arguments(new Cars(carList), maxPosition) + ); + } + @ParameterizedTest(name = "{0}의 경주 결과 승자는 {1}입니다") @MethodSource("getCarListAndWinner") void findWinner(Cars cars, Cars winners) { From 520d711da4a7a6c16542c1e233b32614eb3e675d Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 23:06:52 +0900 Subject: [PATCH 44/79] =?UTF-8?q?feat:=20Car=20isWinner(int)=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 승자임을 판단하는 메서드 --- src/main/java/game/domain/Car.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java index e664e69f..0890ad15 100644 --- a/src/main/java/game/domain/Car.java +++ b/src/main/java/game/domain/Car.java @@ -38,6 +38,10 @@ private boolean canMove(int randomValue) { return randomValue >= Rule.MOVEMENT_THRESHOLD; } + public boolean isWinner(int maxPosition) { + return position == maxPosition; + } + @Override public boolean equals(Object o) { if (this == o) { From 6d6f754e40a05f78d4912b7a2cd2d0b608d9bd40 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 23:08:18 +0900 Subject: [PATCH 45/79] =?UTF-8?q?feat:=20Cars=20=EC=8A=B9=EC=9E=90=20?= =?UTF-8?q?=ED=8C=90=EB=B3=84=20=EB=A1=9C=EC=A7=81=20=EC=A4=91=20filter=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Car 클래스에서 승자 판별 메서드(isWinner)를 추가함에 따른 변경 --- src/main/java/game/domain/Cars.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 1a6cc0f3..50c94e59 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -9,7 +9,6 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.Random; -import java.util.stream.Collectors; public class Cars { @@ -28,7 +27,7 @@ public void move() { public Cars findWinners() { int maxPosition = getMaxPosition(); List winners = carList.stream() - .filter(car -> car.getPosition() == maxPosition) + .filter(car -> car.isWinner(maxPosition)) .toList(); return new Cars(winners); } @@ -72,11 +71,11 @@ public String toString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("Cars = "); carList.forEach(car -> - stringBuilder.append("(") - .append(car.getName()) - .append(", position: ") - .append(car.getPosition()) - .append(")")); + stringBuilder.append("(") + .append(car.getName()) + .append(", position: ") + .append(car.getPosition()) + .append(")")); return stringBuilder.toString(); } } From ee9a35a89ce6d5c6c6595cf3ba97bf2ebddcaf6f Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 23:09:02 +0900 Subject: [PATCH 46/79] =?UTF-8?q?test:=20CarTest=20movableCar=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 초기 위치 검증을 isEqualTo() -> isZero() 로 변경 --- src/test/java/game/domain/CarTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/game/domain/CarTest.java b/src/test/java/game/domain/CarTest.java index 4d03c1d9..a95ae2a4 100644 --- a/src/test/java/game/domain/CarTest.java +++ b/src/test/java/game/domain/CarTest.java @@ -13,7 +13,7 @@ class CarTest { @ParameterizedTest(name = "{0}은 난수 {1} 일 때 전진합니다") @MethodSource("getMovableCar") void movableCar(Car car, int movementValue) { - assertThat(car.getPosition()).isEqualTo(0); + assertThat(car.getPosition()).isZero(); assertThat(car.move(movementValue)).isEqualTo(1); } From 0ab2067e0357faa1501c192eac38d2c30a05544e Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sat, 8 Jun 2024 23:13:28 +0900 Subject: [PATCH 47/79] =?UTF-8?q?test:=20CarTest=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=EA=B0=80=20=EC=A0=9C=EC=9E=90=EB=A6=AC=EC=9D=B8=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EA=B2=80=EC=A6=9D=20=EC=8B=9C=20isZero()=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/game/domain/CarTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/game/domain/CarTest.java b/src/test/java/game/domain/CarTest.java index a95ae2a4..48b1ae8e 100644 --- a/src/test/java/game/domain/CarTest.java +++ b/src/test/java/game/domain/CarTest.java @@ -20,8 +20,8 @@ void movableCar(Car car, int movementValue) { @ParameterizedTest(name = "{0}은 난수 {1} 일 때 전진하지 않습니다") @MethodSource("getUnmovableCar") void unmovableCar(Car car, int movementValue) { - assertThat(car.getPosition()).isEqualTo(0); - assertThat(car.move(movementValue)).isEqualTo(0); + assertThat(car.getPosition()).isZero(); + assertThat(car.move(movementValue)).isZero(); } static Stream getMovableCar() { From 7546811bee35ad69fed42b545c1aa4889ba23410 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 02:02:08 +0900 Subject: [PATCH 48/79] =?UTF-8?q?feat:=20Cars=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20fro?= =?UTF-8?q?m()=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 50c94e59..c185260e 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -14,10 +14,15 @@ public class Cars { private List carList; + //todo public -> private public Cars(List carList) { this.carList = carList; } + public static Cars from(List carNames) { + return new Cars(carNames.stream().map(Car::new).toList()); + } + public void move() { Random random = new Random(); int movementValue = random.nextInt(Rule.MAX_RANDOM_VALUE + 1); From 6f8adf57865dfad6010995ee9de069cfb2f8d1ff Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 02:04:03 +0900 Subject: [PATCH 49/79] =?UTF-8?q?refactor:=20InputView=20enterCarNames()?= =?UTF-8?q?=20=EC=A0=95=EC=83=81=20=EC=9E=85=EB=A0=A5=EA=B9=8C=EC=A7=80=20?= =?UTF-8?q?=EC=88=98=ED=96=89=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/InputView.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/game/view/InputView.java b/src/main/java/game/view/InputView.java index 8a62199f..3a9c2772 100644 --- a/src/main/java/game/view/InputView.java +++ b/src/main/java/game/view/InputView.java @@ -14,6 +14,7 @@ public class InputView { private final CarNameValidator carNameValidator; private final AttemptCountValidator attemptCountValidator; + //todo validator를 주입받도록(validator 인터페이스 선언 + 파라미터로 Validator... validator) public InputView() { scanner = new Scanner(System.in); carNameValidator = CarNameValidator.getInstance(); @@ -21,11 +22,17 @@ public InputView() { } public List enterCarNames() { - System.out.println(InputMessage.CAR_NAME); - - String input = scanner.next(); - carNameValidator.validate(input); - + String input = ""; + while(input.isBlank()) { + System.out.println(InputMessage.CAR_NAME); + input = scanner.next(); + try { + carNameValidator.validate(input); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + input = ""; + } + } return Arrays.asList(input.split(Rule.NAME_DELIMITER)); } From 9782fa5e46c47f4e5a409eccd8c5ef00533590fd Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 12:53:14 +0900 Subject: [PATCH 50/79] =?UTF-8?q?refactor:=20InputView=20enterAttempCount(?= =?UTF-8?q?)=20=EC=A0=95=EC=83=81=20=EC=9E=85=EB=A0=A5=EA=B9=8C=EC=A7=80?= =?UTF-8?q?=20=EC=88=98=ED=96=89=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/InputView.java | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/java/game/view/InputView.java b/src/main/java/game/view/InputView.java index 3a9c2772..2b55a61a 100644 --- a/src/main/java/game/view/InputView.java +++ b/src/main/java/game/view/InputView.java @@ -23,9 +23,9 @@ public InputView() { public List enterCarNames() { String input = ""; - while(input.isBlank()) { + while (input.isBlank()) { System.out.println(InputMessage.CAR_NAME); - input = scanner.next(); + input = scanner.nextLine(); try { carNameValidator.validate(input); } catch (IllegalArgumentException e) { @@ -42,11 +42,17 @@ public List enterCarNames() { * @return 시도 횟수 */ public int enterAttemptCount() { - System.out.println(InputMessage.ATTEMPT_COUNT); - - String input = scanner.next(); - attemptCountValidator.validate(input); - + String input = ""; + while (input.isBlank()) { + System.out.println(InputMessage.ATTEMPT_COUNT); + input = scanner.nextLine(); + try { + attemptCountValidator.validate(input); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + input = ""; + } + } return Integer.parseInt(input); } } From bde7ff7d6cf43967f223b3c5fc6158e4af6c7a0c Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 13:05:32 +0900 Subject: [PATCH 51/79] =?UTF-8?q?feat:=20RandomNumberGenerator=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 난수 발생기 --- .../java/game/util/RandomNumberGenerator.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/game/util/RandomNumberGenerator.java diff --git a/src/main/java/game/util/RandomNumberGenerator.java b/src/main/java/game/util/RandomNumberGenerator.java new file mode 100644 index 00000000..91c1f7d2 --- /dev/null +++ b/src/main/java/game/util/RandomNumberGenerator.java @@ -0,0 +1,20 @@ +package game.util; + +import java.util.Random; + +public class RandomNumberGenerator { + + private RandomNumberGenerator() { + } + + /** + * 파라미터로 전달받은 범위 안에서 무작위 양의 정수를 반환합니다. + * @param maxRange 최대값 + * @return 양의 정수 + */ + public static int getNumber(int maxRange) { + Random random = new Random(); + return random.nextInt(maxRange + 1); + } + +} From 8befc756b00c1dd2e6c9fdf6a29555b77ee9dfb8 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 13:06:20 +0900 Subject: [PATCH 52/79] =?UTF-8?q?refactor:=20Cars=20Random=20=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Random 대신 RandomNumberGenerator 사용 --- src/main/java/game/domain/Cars.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index c185260e..9af088f0 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -2,13 +2,13 @@ import game.config.constant.Rule; import game.exception.constant.ErrorMessage; +import game.util.RandomNumberGenerator; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.NoSuchElementException; import java.util.Objects; -import java.util.Random; public class Cars { @@ -24,9 +24,7 @@ public static Cars from(List carNames) { } public void move() { - Random random = new Random(); - int movementValue = random.nextInt(Rule.MAX_RANDOM_VALUE + 1); - carList.forEach(car -> car.move(movementValue)); + carList.forEach(car -> car.move(RandomNumberGenerator.getNumber(Rule.MAX_RANDOM_VALUE))); } public Cars findWinners() { From 9bad14060d76a331bf66ef5252505440a4ab1752 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 13:06:49 +0900 Subject: [PATCH 53/79] =?UTF-8?q?feat:=20ErrorMessage=20EMPTY=5FLIST=20?= =?UTF-8?q?=EB=AC=B8=EA=B5=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/exception/constant/ErrorMessage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/game/exception/constant/ErrorMessage.java b/src/main/java/game/exception/constant/ErrorMessage.java index da4d0517..12a61d9a 100644 --- a/src/main/java/game/exception/constant/ErrorMessage.java +++ b/src/main/java/game/exception/constant/ErrorMessage.java @@ -7,7 +7,8 @@ public enum ErrorMessage { EXCEED_NAME_LENGTH("[ERROR] 길이 %d를 초과하여 이름을 생성할 수 없습니다!".formatted(MAX_NAME_LENGTH)), DUPLICATE_NAME_FOUND("[ERROR] 중복된 이름이 존재합니다!"), INVALID_NUMBER_INPUT("[ERROR] 숫자를 입력해주세요!"), - INVALID_ATTEMPT_COUNT_INPUT("[ERROR] 1 이상의 숫자를 입력해주세요!"); + INVALID_ATTEMPT_COUNT_INPUT("[ERROR] 1 이상의 숫자를 입력해주세요!"), + EMPTY_LIST("[ERROR] 리스트가 비어 있습니다!"); private final String message; ErrorMessage(String message) { From d9f0dc1251ea9dc657f364c3f2a3b77356846771 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 15:04:56 +0900 Subject: [PATCH 54/79] =?UTF-8?q?refactor:=20Cars=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9E=90=20=EB=8C=80=EC=8B=A0=20=EC=A0=95=EC=A0=81=20=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=A0=9C=EA=B3=B5=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 생성자를 private 로 변경 - from -> fromCarNames, fromCarList 두 메서드로 분리 --- src/main/java/game/domain/Cars.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index 9af088f0..fac383f4 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -14,15 +14,18 @@ public class Cars { private List carList; - //todo public -> private - public Cars(List carList) { + private Cars(List carList) { this.carList = carList; } - public static Cars from(List carNames) { + public static Cars fromCarNames(List carNames) { return new Cars(carNames.stream().map(Car::new).toList()); } + public static Cars fromCarList(List carList) { + return new Cars(carList); + } + public void move() { carList.forEach(car -> car.move(RandomNumberGenerator.getNumber(Rule.MAX_RANDOM_VALUE))); } From 40e321bf1d9d24315fb89a03251785aa014e4c3c Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 15:05:21 +0900 Subject: [PATCH 55/79] =?UTF-8?q?test:=20Cars=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9D=84=20=EC=A0=95=EC=A0=81=20=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/game/domain/CarsTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/game/domain/CarsTest.java b/src/test/java/game/domain/CarsTest.java index dedc88d8..5f3b6570 100644 --- a/src/test/java/game/domain/CarsTest.java +++ b/src/test/java/game/domain/CarsTest.java @@ -26,7 +26,7 @@ private static Stream getCarAndMaxPosition() { carList.add(new Car("james", 1)); return Stream.of( - Arguments.arguments(new Cars(carList), maxPosition) + Arguments.arguments(Cars.fromCarList(carList), maxPosition) ); } @@ -47,7 +47,7 @@ private static Stream getCarListAndWinner() { winners.add(new Car("gusto", 5)); return Stream.of( - Arguments.arguments(new Cars(carList), new Cars(winners)) + Arguments.arguments(Cars.fromCarList(carList), Cars.fromCarList(winners)) ); } From 740dc9a19f86b5b5d1e5fae450a42bdac2f80da8 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 15:21:40 +0900 Subject: [PATCH 56/79] =?UTF-8?q?docs:=20RandomNumberGenerator=20getNumber?= =?UTF-8?q?=20=EC=A3=BC=EC=84=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/util/RandomNumberGenerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/game/util/RandomNumberGenerator.java b/src/main/java/game/util/RandomNumberGenerator.java index 91c1f7d2..2d1e9e9e 100644 --- a/src/main/java/game/util/RandomNumberGenerator.java +++ b/src/main/java/game/util/RandomNumberGenerator.java @@ -8,9 +8,9 @@ private RandomNumberGenerator() { } /** - * 파라미터로 전달받은 범위 안에서 무작위 양의 정수를 반환합니다. - * @param maxRange 최대값 - * @return 양의 정수 + * 파라미터로 전달받은 범위 안에서 무작위 음이 아닌 정수를 반환합니다. + * @param maxRange 난수의 최댓값 + * @return 음이 아닌 정수 */ public static int getNumber(int maxRange) { Random random = new Random(); From 5e9a16cf03944b6a377cb9e192e2d33d072dab55 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 15:23:08 +0900 Subject: [PATCH 57/79] =?UTF-8?q?refactor:=20RandomNumberGenerator=20Rando?= =?UTF-8?q?m=20=EA=B0=9D=EC=B2=B4=20=ED=95=84=EB=93=9C=EB=A1=9C=20?= =?UTF-8?q?=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/util/RandomNumberGenerator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/game/util/RandomNumberGenerator.java b/src/main/java/game/util/RandomNumberGenerator.java index 2d1e9e9e..929e24ac 100644 --- a/src/main/java/game/util/RandomNumberGenerator.java +++ b/src/main/java/game/util/RandomNumberGenerator.java @@ -4,6 +4,8 @@ public class RandomNumberGenerator { + private static Random random = new Random(); + private RandomNumberGenerator() { } @@ -13,7 +15,6 @@ private RandomNumberGenerator() { * @return 음이 아닌 정수 */ public static int getNumber(int maxRange) { - Random random = new Random(); return random.nextInt(maxRange + 1); } From f4e2fa2896468098dcc56e3ed29d221d8ba5c092 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 16:56:50 +0900 Subject: [PATCH 58/79] =?UTF-8?q?refactor:=20CarNameValidator=20=EC=A0=95?= =?UTF-8?q?=EC=A0=81=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/validator/CarNameValidator.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/game/validator/CarNameValidator.java b/src/main/java/game/validator/CarNameValidator.java index 8dc100f2..652ddbc2 100644 --- a/src/main/java/game/validator/CarNameValidator.java +++ b/src/main/java/game/validator/CarNameValidator.java @@ -7,21 +7,15 @@ public class CarNameValidator { - private static final CarNameValidator instance = new CarNameValidator(); - private CarNameValidator() { } - public static CarNameValidator getInstance() { - return instance; - } - - public void validate(String input) { + public static void validate(String input) { validateNameLength(input); validateDuplication(input); } - private void validateNameLength(String input) { + public static void validateNameLength(String input) { String[] names = input.split(NAME_DELIMITER); Arrays.stream(names) .filter(name -> name.length() > MAX_NAME_LENGTH) @@ -31,7 +25,7 @@ private void validateNameLength(String input) { }); } - private void validateDuplication(String input) { + private static void validateDuplication(String input) { String[] names = input.split(NAME_DELIMITER); long originalCount = names.length; long uniqueCount = Arrays.stream(names).distinct().count(); From dac08255b01e542fc1cbff9ef6e3313b0a8a4f2d Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 16:57:25 +0900 Subject: [PATCH 59/79] =?UTF-8?q?refactor:=20AttemptCountValidator=20?= =?UTF-8?q?=EC=A0=95=EC=A0=81=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/game/validator/AttemptCountValidator.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/game/validator/AttemptCountValidator.java b/src/main/java/game/validator/AttemptCountValidator.java index d29c920c..0ad9b99c 100644 --- a/src/main/java/game/validator/AttemptCountValidator.java +++ b/src/main/java/game/validator/AttemptCountValidator.java @@ -7,21 +7,15 @@ */ public class AttemptCountValidator { - private static final AttemptCountValidator instance = new AttemptCountValidator(); - private AttemptCountValidator() { } - public static AttemptCountValidator getInstance() { - return instance; - } - - public void validate(String attemptCountInput) { + public static void validate(String attemptCountInput) { validateNumberFormat(attemptCountInput); - validatePositiveValue(attemptCountInput); + validatePositiveNumber(attemptCountInput); } - private void validateNumberFormat(String attemptCountInput) { + private static void validateNumberFormat(String attemptCountInput) { try { Integer.parseInt(attemptCountInput); } catch (NumberFormatException e) { @@ -29,7 +23,7 @@ private void validateNumberFormat(String attemptCountInput) { } } - private void validatePositiveValue(String attemptCountInput) { + private static void validatePositiveNumber(String attemptCountInput) { if (Integer.parseInt(attemptCountInput) <= 0) { throw new IllegalArgumentException(ErrorMessage.INVALID_ATTEMPT_COUNT_INPUT.getMessage()); } From a94977190d2b3ead6631f14328b16ee1d591bfea Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 16:58:15 +0900 Subject: [PATCH 60/79] =?UTF-8?q?test:=20CarNameValidatorTest=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=EA=B8=B0=EA=B0=80=20=EC=A0=95=EC=A0=81=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B3=80=EA=B2=BD=EB=90=A8?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game/validator/CarNameValidatorTest.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/test/java/game/validator/CarNameValidatorTest.java b/src/test/java/game/validator/CarNameValidatorTest.java index f4d04658..fc38c1db 100644 --- a/src/test/java/game/validator/CarNameValidatorTest.java +++ b/src/test/java/game/validator/CarNameValidatorTest.java @@ -1,7 +1,8 @@ package game.validator; -import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; import game.exception.constant.ErrorMessage; import org.junit.jupiter.params.ParameterizedTest; @@ -9,30 +10,36 @@ class CarNameValidatorTest { - CarNameValidator carNameValidator = CarNameValidator.getInstance(); - @ParameterizedTest(name = "{0}은 적절한 이름 입력입니다") - @ValueSource(strings = {"en.zo,silva,james","silva","_enzo,en zo,enzo "}) + @ValueSource(strings = {"en.zo,silva,james", "silva", "_enzo,en zo,enzo "}) void 적절한_이름_입력에_대해_예외를_던지지_않습니다(String input) { - assertDoesNotThrow(() -> carNameValidator.validate(input)); + assertDoesNotThrow(() -> CarNameValidator.validate(input)); } @ParameterizedTest(name = "{0}은 길이를 초과한 이름 입력입니다") - @ValueSource(strings = {"thiago,sil ","en ,zo"}) + @ValueSource(strings = {"thiago,sil ", "en ,zo"}) void 부적절한_이름_길이는_예외를_발생시킵니다(String input) { IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> carNameValidator.validate(input)); + IllegalArgumentException.class, () -> CarNameValidator.validate(input)); assertThat(error.getMessage()).isEqualTo(ErrorMessage.EXCEED_NAME_LENGTH.getMessage()); } @ParameterizedTest(name = "{0}은 중복이 존재하는 이름 입력입니다") - @ValueSource(strings = {"enzo,bruno,enzo","james,james,james"}) + @ValueSource(strings = {"enzo,bruno,enzo", "james,james,james"}) void 중복이_존재하는_이름은_예외를_발생시킵니다(String input) { IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> carNameValidator.validate(input)); + IllegalArgumentException.class, () -> CarNameValidator.validate(input)); assertThat(error.getMessage()).isEqualTo(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); } + @ParameterizedTest(name = "{0}은 길이가 0인 이름 입력입니다") + @ValueSource(strings = {",,,,"}) + void 길이가_0인_이름은_예외를_발생시킵니다(String input) { + IllegalArgumentException error = assertThrows( + IllegalArgumentException.class, () -> CarNameValidator.validate(input)); + + assertThat(error.getMessage()).isEqualTo(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); + } } \ No newline at end of file From a4dadbe164dd3e3c194b8deb64034bf064053298 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 16:58:22 +0900 Subject: [PATCH 61/79] =?UTF-8?q?test:=20AttemptCountValidatorTest=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=EA=B8=B0=EA=B0=80=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EB=90=A8=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/game/validator/AttemptCountValidatorTest.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/test/java/game/validator/AttemptCountValidatorTest.java b/src/test/java/game/validator/AttemptCountValidatorTest.java index ca639f7b..ed173e8b 100644 --- a/src/test/java/game/validator/AttemptCountValidatorTest.java +++ b/src/test/java/game/validator/AttemptCountValidatorTest.java @@ -10,19 +10,17 @@ class AttemptCountValidatorTest { - AttemptCountValidator attemptCountValidator = AttemptCountValidator.getInstance(); - @ParameterizedTest(name = "{0}은 적절한 시도 횟수 입력입니다") @ValueSource(strings = {"5", "10", "100"}) void 적절한_시도_횟수_입력에_대해_예외를_던지지_않습니다(String input) { - assertDoesNotThrow(() -> attemptCountValidator.validate(input)); + assertDoesNotThrow(() -> AttemptCountValidator.validate(input)); } @ParameterizedTest(name = "{0}은 숫자가 아닌 입력") @ValueSource(strings = {"thiago,sil", "enzo", "a", "", " "}) void 숫자가_아닌_입력값에_대하여_예외를_발생시킵니다(String input) { IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> attemptCountValidator.validate(input)); + IllegalArgumentException.class, () -> AttemptCountValidator.validate(input)); assertThat(error.getMessage()).isEqualTo(ErrorMessage.INVALID_NUMBER_INPUT.getMessage()); } @@ -31,7 +29,7 @@ class AttemptCountValidatorTest { @ValueSource(strings = {"-1", "-100", "-99999", "0"}) void 입력이_1보다_작은_입력값에_대하여_예외를_발생시킵니다(String input) { IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> attemptCountValidator.validate(input)); + IllegalArgumentException.class, () -> AttemptCountValidator.validate(input)); assertThat(error.getMessage()).isEqualTo( ErrorMessage.INVALID_ATTEMPT_COUNT_INPUT.getMessage()); From d0d26580296a5df431dfad6ed2ce9eef7332c205 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 16:58:42 +0900 Subject: [PATCH 62/79] =?UTF-8?q?refactor:=20Car=EC=9D=98=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=EA=B8=B0=EA=B0=80=20=EC=A0=95=EC=A0=81=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B3=80=EA=B2=BD=EB=90=A8?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Car.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java index 0890ad15..1242f635 100644 --- a/src/main/java/game/domain/Car.java +++ b/src/main/java/game/domain/Car.java @@ -14,7 +14,7 @@ public Car(String name) { } public Car(String name, int position) { - CarNameValidator.getInstance().validateNameLength(name); + CarNameValidator.validateNameLength(name); this.name = name; this.position = position; } From 8395c5f69a6cf7b033a76af15b5981322909e774 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 16:59:08 +0900 Subject: [PATCH 63/79] =?UTF-8?q?refactor:=20InputView=EC=9D=98=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=EA=B8=B0=EA=B0=80=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EB=90=A8=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/InputView.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/java/game/view/InputView.java b/src/main/java/game/view/InputView.java index 2b55a61a..2e7ea63a 100644 --- a/src/main/java/game/view/InputView.java +++ b/src/main/java/game/view/InputView.java @@ -11,14 +11,9 @@ public class InputView { private final Scanner scanner; - private final CarNameValidator carNameValidator; - private final AttemptCountValidator attemptCountValidator; - //todo validator를 주입받도록(validator 인터페이스 선언 + 파라미터로 Validator... validator) - public InputView() { - scanner = new Scanner(System.in); - carNameValidator = CarNameValidator.getInstance(); - attemptCountValidator = AttemptCountValidator.getInstance(); + public InputView(Scanner scanner) { + this.scanner = scanner; } public List enterCarNames() { @@ -27,7 +22,7 @@ public List enterCarNames() { System.out.println(InputMessage.CAR_NAME); input = scanner.nextLine(); try { - carNameValidator.validate(input); + CarNameValidator.validate(input); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); input = ""; @@ -47,7 +42,7 @@ public int enterAttemptCount() { System.out.println(InputMessage.ATTEMPT_COUNT); input = scanner.nextLine(); try { - attemptCountValidator.validate(input); + AttemptCountValidator.validate(input); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); input = ""; From 1c0a3a0e65a995d83124c19ace10e69234d4d097 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 16:59:46 +0900 Subject: [PATCH 64/79] =?UTF-8?q?feat:=20OutputView=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 경주 결과 출력 메서드 구현 --- src/main/java/game/view/OutputView.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/game/view/OutputView.java diff --git a/src/main/java/game/view/OutputView.java b/src/main/java/game/view/OutputView.java new file mode 100644 index 00000000..4a2bfb46 --- /dev/null +++ b/src/main/java/game/view/OutputView.java @@ -0,0 +1,16 @@ +package game.view; + +import game.config.constant.Rule; +import game.domain.Car; +import game.domain.Cars; +import java.util.List; + +public class OutputView { + + public void printResult(Cars cars) { + List carList = cars.getCarList(); + carList.forEach(car -> System.out.println(car.getName() + " : " + Rule.CAR_POSITION_MAKER.repeat(car.getPosition()))); + System.out.println(); + } + +} From 41f4a6e51b1c1442580845d01eeb3ff37e6d9f23 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 17:00:11 +0900 Subject: [PATCH 65/79] =?UTF-8?q?feat:=20OutputView=20printWinner=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/view/OutputView.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/game/view/OutputView.java b/src/main/java/game/view/OutputView.java index 4a2bfb46..1619e825 100644 --- a/src/main/java/game/view/OutputView.java +++ b/src/main/java/game/view/OutputView.java @@ -3,6 +3,7 @@ import game.config.constant.Rule; import game.domain.Car; import game.domain.Cars; +import game.view.constant.OutputMessage; import java.util.List; public class OutputView { @@ -13,4 +14,19 @@ public void printResult(Cars cars) { System.out.println(); } + public void printWinner(Cars cars) { + System.out.print(OutputMessage.WINNER); + + StringBuilder result = new StringBuilder(); + List winnerList = cars.findWinners().getCarList(); + for (Car car : winnerList) { + result.append(car.getName()); + if (winnerList.indexOf(car) < winnerList.size() - 1) { + result.append(", "); + } + } + + System.out.println(result); + } + } From 2ba2cf6871e2005ee5b1df5b3a4c185c7d251264 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 17:00:32 +0900 Subject: [PATCH 66/79] =?UTF-8?q?feat:=20RacingGameController=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game/controller/RacingGameController.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/java/game/controller/RacingGameController.java diff --git a/src/main/java/game/controller/RacingGameController.java b/src/main/java/game/controller/RacingGameController.java new file mode 100644 index 00000000..5088493c --- /dev/null +++ b/src/main/java/game/controller/RacingGameController.java @@ -0,0 +1,33 @@ +package game.controller; + +import game.domain.Cars; +import game.view.InputView; +import game.view.OutputView; +import game.view.constant.OutputMessage; +import java.util.List; + +public class RacingGameController { + + private InputView inputView; + private OutputView outputView; + + public RacingGameController(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void startGame() { + List carNames = inputView.enterCarNames(); + Cars cars = Cars.fromCarNames(carNames); + + int attemptCount = inputView.enterAttemptCount(); + System.out.println(OutputMessage.RESULT); + for (int i = 0; i < attemptCount; i++) { + cars.move(); + outputView.printResult(cars); + } + + outputView.printWinner(cars); + } + +} From 029353c71e58fc150dd551b20c52ab4ec463af3c Mon Sep 17 00:00:00 2001 From: nove1080 Date: Sun, 9 Jun 2024 17:02:58 +0900 Subject: [PATCH 67/79] =?UTF-8?q?feat:=20RacingGameApplication=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/RacingGameApplication.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/game/RacingGameApplication.java diff --git a/src/main/java/game/RacingGameApplication.java b/src/main/java/game/RacingGameApplication.java new file mode 100644 index 00000000..e92c4ddd --- /dev/null +++ b/src/main/java/game/RacingGameApplication.java @@ -0,0 +1,18 @@ +package game; + +import game.controller.RacingGameController; +import game.view.InputView; +import game.view.OutputView; +import java.util.Scanner; + +public class RacingGameApplication { + + public static void main(String[] args) { + InputView inputView = new InputView(new Scanner(System.in)); + OutputView outputView = new OutputView(); + RacingGameController racingGameController = new RacingGameController(inputView, outputView); + + racingGameController.startGame(); + } + +} From 998a1a7af6622077c2ecc95c53dca28023755eb1 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 00:22:39 +0900 Subject: [PATCH 68/79] =?UTF-8?q?test:=20AttemptCountValidatorTest=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EA=B2=80=EC=A6=9D=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - assertThrows -> assertThatThrownBy --- .../validator/AttemptCountValidatorTest.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/test/java/game/validator/AttemptCountValidatorTest.java b/src/test/java/game/validator/AttemptCountValidatorTest.java index ed173e8b..1ee4fb76 100644 --- a/src/test/java/game/validator/AttemptCountValidatorTest.java +++ b/src/test/java/game/validator/AttemptCountValidatorTest.java @@ -1,6 +1,7 @@ package game.validator; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -19,20 +20,17 @@ class AttemptCountValidatorTest { @ParameterizedTest(name = "{0}은 숫자가 아닌 입력") @ValueSource(strings = {"thiago,sil", "enzo", "a", "", " "}) void 숫자가_아닌_입력값에_대하여_예외를_발생시킵니다(String input) { - IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> AttemptCountValidator.validate(input)); - - assertThat(error.getMessage()).isEqualTo(ErrorMessage.INVALID_NUMBER_INPUT.getMessage()); + assertThatThrownBy(() -> AttemptCountValidator.validate(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_NUMBER_INPUT.getMessage()); } @ParameterizedTest(name = "{0}은 1보다 작은 입력") @ValueSource(strings = {"-1", "-100", "-99999", "0"}) void 입력이_1보다_작은_입력값에_대하여_예외를_발생시킵니다(String input) { - IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> AttemptCountValidator.validate(input)); - - assertThat(error.getMessage()).isEqualTo( - ErrorMessage.INVALID_ATTEMPT_COUNT_INPUT.getMessage()); + assertThatThrownBy(() -> AttemptCountValidator.validate(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_ATTEMPT_COUNT_INPUT.getMessage()); } } \ No newline at end of file From 22414bab0f067227fa74d4f56b1fa8f66fec5a25 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 00:34:51 +0900 Subject: [PATCH 69/79] =?UTF-8?q?feat:=20Rule=20MIN=5FNAME=5FLENGTH=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/config/constant/Rule.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/game/config/constant/Rule.java b/src/main/java/game/config/constant/Rule.java index b0a9f6c8..850ae103 100644 --- a/src/main/java/game/config/constant/Rule.java +++ b/src/main/java/game/config/constant/Rule.java @@ -7,6 +7,7 @@ private Rule() { public static String NAME_DELIMITER = ","; public static int MAX_NAME_LENGTH = 5; + public static int MIN_NAME_LENGTH = 1; public static int MAX_RANDOM_VALUE = 9; public static int MOVEMENT_THRESHOLD = 4; public static String CAR_POSITION_MAKER = "-"; From 23c6bd18a032cf2aedac68a3f41227b70d30bd3d Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 00:35:19 +0900 Subject: [PATCH 70/79] =?UTF-8?q?feat:=20Rule=20final=20=ED=82=A4=EC=9B=8C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/config/constant/Rule.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/game/config/constant/Rule.java b/src/main/java/game/config/constant/Rule.java index 850ae103..d42d16b1 100644 --- a/src/main/java/game/config/constant/Rule.java +++ b/src/main/java/game/config/constant/Rule.java @@ -5,10 +5,10 @@ public class Rule { private Rule() { } - public static String NAME_DELIMITER = ","; - public static int MAX_NAME_LENGTH = 5; - public static int MIN_NAME_LENGTH = 1; - public static int MAX_RANDOM_VALUE = 9; - public static int MOVEMENT_THRESHOLD = 4; - public static String CAR_POSITION_MAKER = "-"; + public static final String NAME_DELIMITER = ","; + public static final int MAX_NAME_LENGTH = 5; + public static final int MIN_NAME_LENGTH = 1; + public static final int MAX_RANDOM_VALUE = 9; + public static final int MOVEMENT_THRESHOLD = 4; + public static final String CAR_POSITION_MAKER = "-"; } From 9a4d967b8027aed009559886405a424ddb3a01fa Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:08:57 +0900 Subject: [PATCH 71/79] =?UTF-8?q?refactor:=20ErrorMessage=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EA=B8=B8=EC=9D=B4=20=EC=98=88=EC=99=B8=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - EXCEED_NAME_LENGTH -> INVALID_NAME_LENGTH --- src/main/java/game/exception/constant/ErrorMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/game/exception/constant/ErrorMessage.java b/src/main/java/game/exception/constant/ErrorMessage.java index 12a61d9a..5c7bd50b 100644 --- a/src/main/java/game/exception/constant/ErrorMessage.java +++ b/src/main/java/game/exception/constant/ErrorMessage.java @@ -4,7 +4,7 @@ public enum ErrorMessage { - EXCEED_NAME_LENGTH("[ERROR] 길이 %d를 초과하여 이름을 생성할 수 없습니다!".formatted(MAX_NAME_LENGTH)), + INVALID_NAME_LENGTH("[ERROR] %d ~ %d 글자를 벗어난 이름이 존재합니다!".formatted(MIN_NAME_LENGTH, MAX_NAME_LENGTH)), DUPLICATE_NAME_FOUND("[ERROR] 중복된 이름이 존재합니다!"), INVALID_NUMBER_INPUT("[ERROR] 숫자를 입력해주세요!"), INVALID_ATTEMPT_COUNT_INPUT("[ERROR] 1 이상의 숫자를 입력해주세요!"), From b7890655a7dcbb5dc385e98c0473cf04795cdb0a Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:10:09 +0900 Subject: [PATCH 72/79] =?UTF-8?q?test:=20CarNameValidatorTest=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 길이가 0인 이름 테스트케이스를 부적절한 이름 길이에 대한 테스트로 병합 --- .../java/game/validator/CarNameValidatorTest.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/test/java/game/validator/CarNameValidatorTest.java b/src/test/java/game/validator/CarNameValidatorTest.java index fc38c1db..169b02c0 100644 --- a/src/test/java/game/validator/CarNameValidatorTest.java +++ b/src/test/java/game/validator/CarNameValidatorTest.java @@ -16,13 +16,13 @@ class CarNameValidatorTest { assertDoesNotThrow(() -> CarNameValidator.validate(input)); } - @ParameterizedTest(name = "{0}은 길이를 초과한 이름 입력입니다") - @ValueSource(strings = {"thiago,sil ", "en ,zo"}) + @ParameterizedTest(name = "{0}은 부적절한 길이의 이름이 존재합니다") + @ValueSource(strings = {"thiago,sil ", "en ,zo", ",,,,", " "}) void 부적절한_이름_길이는_예외를_발생시킵니다(String input) { IllegalArgumentException error = assertThrows( IllegalArgumentException.class, () -> CarNameValidator.validate(input)); - assertThat(error.getMessage()).isEqualTo(ErrorMessage.EXCEED_NAME_LENGTH.getMessage()); + assertThat(error.getMessage()).isEqualTo(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); } @ParameterizedTest(name = "{0}은 중복이 존재하는 이름 입력입니다") @@ -33,13 +33,4 @@ class CarNameValidatorTest { assertThat(error.getMessage()).isEqualTo(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); } - - @ParameterizedTest(name = "{0}은 길이가 0인 이름 입력입니다") - @ValueSource(strings = {",,,,"}) - void 길이가_0인_이름은_예외를_발생시킵니다(String input) { - IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> CarNameValidator.validate(input)); - - assertThat(error.getMessage()).isEqualTo(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); - } } \ No newline at end of file From a8a779369e039c78a183f9f71d11013bbd58a2de Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:12:12 +0900 Subject: [PATCH 73/79] =?UTF-8?q?test:=20CarNameValidatorTest=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EA=B2=80=EC=A6=9D=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - assertThrows -> assertThatThrownBy --- .../game/validator/CarNameValidatorTest.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/test/java/game/validator/CarNameValidatorTest.java b/src/test/java/game/validator/CarNameValidatorTest.java index 169b02c0..8c6bc258 100644 --- a/src/test/java/game/validator/CarNameValidatorTest.java +++ b/src/test/java/game/validator/CarNameValidatorTest.java @@ -1,8 +1,7 @@ package game.validator; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; import game.exception.constant.ErrorMessage; import org.junit.jupiter.params.ParameterizedTest; @@ -19,18 +18,16 @@ class CarNameValidatorTest { @ParameterizedTest(name = "{0}은 부적절한 길이의 이름이 존재합니다") @ValueSource(strings = {"thiago,sil ", "en ,zo", ",,,,", " "}) void 부적절한_이름_길이는_예외를_발생시킵니다(String input) { - IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> CarNameValidator.validate(input)); - - assertThat(error.getMessage()).isEqualTo(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); + assertThatThrownBy(() -> CarNameValidator.validate(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); } @ParameterizedTest(name = "{0}은 중복이 존재하는 이름 입력입니다") @ValueSource(strings = {"enzo,bruno,enzo", "james,james,james"}) void 중복이_존재하는_이름은_예외를_발생시킵니다(String input) { - IllegalArgumentException error = assertThrows( - IllegalArgumentException.class, () -> CarNameValidator.validate(input)); - - assertThat(error.getMessage()).isEqualTo(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); + assertThatThrownBy(() -> CarNameValidator.validate(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); } } \ No newline at end of file From d2800cf70a06ba2d5c3ff9ee248dad70ffd3a50e Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:12:36 +0900 Subject: [PATCH 74/79] =?UTF-8?q?feat:=20CarNameValidator=20validateNameEx?= =?UTF-8?q?ists=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/validator/CarNameValidator.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/game/validator/CarNameValidator.java b/src/main/java/game/validator/CarNameValidator.java index 652ddbc2..824952de 100644 --- a/src/main/java/game/validator/CarNameValidator.java +++ b/src/main/java/game/validator/CarNameValidator.java @@ -11,17 +11,25 @@ private CarNameValidator() { } public static void validate(String input) { + validateNameExists(input); validateNameLength(input); validateDuplication(input); } + private static void validateNameExists(String input) { + String[] names = input.split(NAME_DELIMITER); + if (names.length == 0) { + throw new IllegalArgumentException(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); + } + } + public static void validateNameLength(String input) { String[] names = input.split(NAME_DELIMITER); Arrays.stream(names) - .filter(name -> name.length() > MAX_NAME_LENGTH) + .filter(name -> name.length() > MAX_NAME_LENGTH || name.isBlank()) .findAny() .ifPresent(name -> { - throw new IllegalArgumentException(ErrorMessage.EXCEED_NAME_LENGTH.getMessage()); + throw new IllegalArgumentException(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); }); } @@ -36,3 +44,4 @@ private static void validateDuplication(String input) { } } + From 02bab4008a3d0e30a06f722ca3524f56bd915602 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:13:05 +0900 Subject: [PATCH 75/79] =?UTF-8?q?refactor:=20AttemptCountValidatorTest=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20imp?= =?UTF-8?q?ort=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/game/validator/AttemptCountValidatorTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/game/validator/AttemptCountValidatorTest.java b/src/test/java/game/validator/AttemptCountValidatorTest.java index 1ee4fb76..19ebc991 100644 --- a/src/test/java/game/validator/AttemptCountValidatorTest.java +++ b/src/test/java/game/validator/AttemptCountValidatorTest.java @@ -1,9 +1,7 @@ package game.validator; -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; import game.exception.constant.ErrorMessage; import org.junit.jupiter.params.ParameterizedTest; From 5f31536d4aa9b1e9e7a9515d1920f4e9c58db0e9 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:13:15 +0900 Subject: [PATCH 76/79] =?UTF-8?q?refactor:=20CarTest=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/game/domain/CarTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/game/domain/CarTest.java b/src/test/java/game/domain/CarTest.java index 48b1ae8e..faec0e79 100644 --- a/src/test/java/game/domain/CarTest.java +++ b/src/test/java/game/domain/CarTest.java @@ -1,7 +1,6 @@ package game.domain; -import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; @@ -45,5 +44,4 @@ static Stream getUnmovableCar() { } - } \ No newline at end of file From fb66105d8bb7eb815a1b71ef6b1e6864972daa7f Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:47:25 +0900 Subject: [PATCH 77/79] =?UTF-8?q?feat:=20Cars=20getCarNames=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/domain/Cars.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java index fac383f4..9dea55c0 100644 --- a/src/main/java/game/domain/Cars.java +++ b/src/main/java/game/domain/Cars.java @@ -45,6 +45,10 @@ public int getMaxPosition() { .orElseThrow(() -> new NoSuchElementException(ErrorMessage.EMPTY_LIST.getMessage())); } + public List getCarNames() { + return carList.stream().map(Car::getName).toList(); + } + public List getCarList() { return Collections.unmodifiableList(carList); } From 3a1235901c37a8988b6f80938d52695ef40ce1c0 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:48:11 +0900 Subject: [PATCH 78/79] =?UTF-8?q?refactor:=20OutputView=20printWinner=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - forEach -> String.join 사용 --- src/main/java/game/view/OutputView.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/main/java/game/view/OutputView.java b/src/main/java/game/view/OutputView.java index 1619e825..5574f880 100644 --- a/src/main/java/game/view/OutputView.java +++ b/src/main/java/game/view/OutputView.java @@ -16,15 +16,8 @@ public void printResult(Cars cars) { public void printWinner(Cars cars) { System.out.print(OutputMessage.WINNER); - - StringBuilder result = new StringBuilder(); - List winnerList = cars.findWinners().getCarList(); - for (Car car : winnerList) { - result.append(car.getName()); - if (winnerList.indexOf(car) < winnerList.size() - 1) { - result.append(", "); - } - } + Cars winners = cars.findWinners(); + String result = String.join(", ", winners.getCarNames()); System.out.println(result); } From cd287d8bbd498af66c249a4c47c1317f3b0a3257 Mon Sep 17 00:00:00 2001 From: nove1080 Date: Mon, 10 Jun 2024 01:49:04 +0900 Subject: [PATCH 79/79] =?UTF-8?q?docs:=20README.md=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 491aece1..4a3568b5 100644 --- a/README.md +++ b/README.md @@ -1 +1,92 @@ -# java-racingcar-precourse \ No newline at end of file +# java-racingcar-precourse +*** +## 패키지 구조 +*** +``` +├── RacingGameApplication.java +├── config +│   └── constant +│   └── Rule.java +├── controller +│   └── RacingGameController.java +├── domain +│   ├── Car.java +│   └── Cars.java +├── exception +│   └── constant +│   └── ErrorMessage.java +├── util +│   └── RandomNumberGenerator.java +├── validator +│   ├── AttemptCountValidator.java +│   └── CarNameValidator.java +└── view + ├── InputView.java + ├── OutputView.java + └── constant + ├── InputMessage.java + └── OutputMessage.java +``` + +### config 패키지 +> 게임 설정과 관련된 파일이 위치합니다. +* `Rule.java` + * 레이싱 게임을 진행함에 있어 지켜야 할 규칙에 대해 상수로 정의합니다. + +### controller 패키지 +> Model과 View를 이어주는 Controller가 위치합니다. +* `RacingGameController.java` + * 레이싱 게임을 진행하기 위한 컨트롤러 + +### domain 패키지 +> 레이싱 게임을 구성하기 위한 도메인이 위치합니다. +* `Car.java` + * 레이싱 게임에 참여하는 한 대의 자동차를 의미합니다. + + +* `Cars.java` + * 레이싱 게임에 참여하는 자동차들의 집합을 의미합니다. + * 자동차의 집합 중 승자를 판단할 수 있습니다. + +### exception 패키지 +> 레이싱 게임 진행 중 발생하는 예외에 대한 정보가 위치합니다. +* `ErrorMessage.java` + * 게임 중 발생하는 예외 메시지에 대해 정의합니다. + +### util 패키지 +> 게임 진행에 필요한 유틸리티 클래스들이 위치합니다. +* `RandomNumberGenerator.java` + * 자동차를 움직이기 위한 난수를 발생시킵니다. + +### validator 패키지 +> 게임에 사용되는 검증기가 위치합니다. +* `AttemptCountValidator.java` + * 레이싱 실행 횟수에 대하여 검증합니다. + * 입력값이 숫자가 맞는지 검증합니다. + * 입력값이 양의 정수가 맞는지 검증합니다. + + +* `CarNameValidator.java` + * 자동차 이름에 대한 검증을 실시합니다. + * 이름이 존재하는지 검증합니다. + * 이름의 길이가 적절한지 검증합니다. + * 이름에 빈 문자열이 있는지 검증합니다. + * 이름 입력에 대해 중복이 존재하는지 검증합니다. + +### view 패키지 +> view 계층이 위치합니다. +* `InputView.java` + * 입력에 필요한 내용을 출력합니다. + * 적절한 입력이 발생할 때까지 사용자로부터 입력을 받습니다. + + +* `OutputView.java` + * 게임의 결과에 대해 출력합니다. + + +* `InputMessage.java` + * 입력에 필요한 메시지를 정의합니다. + + +* `OutputMessage.java` + * 출력에 필요한 메시지를 정의합니다. \ No newline at end of file