diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..6a2a10a3 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,50 @@ +# πŸ’ͺ ν”„λ‘œμ νŠΈ κ°œμš” + +숫자 야ꡬ κ²Œμž„ + +# κ²Œμž„ μ„€λͺ… + +- 기본적으둜 1λΆ€ν„° 9κΉŒμ§€ μ„œλ‘œ λ‹€λ₯Έ 수둜 이루어진 3자리의 수λ₯Ό λ§žμΆ”λŠ” κ²Œμž„μ΄λ‹€. +- 같은 μˆ˜κ°€ 같은 μžλ¦¬μ— 있으면 슀트라이크, λ‹€λ₯Έ μžλ¦¬μ— 있으면 λ³Ό, 같은 μˆ˜κ°€ μ „ν˜€ μ—†μœΌλ©΄ 포볼 λ˜λŠ” λ‚«μ‹±μ΄λž€ 힌트λ₯Ό +μ–»κ³ , κ·Έ 힌트λ₯Ό μ΄μš©ν•΄μ„œ λ¨Όμ € μƒλŒ€λ°©(컴퓨터)의 수λ₯Ό λ§žμΆ”λ©΄ μŠΉλ¦¬ν•œλ‹€. +- [예] μƒλŒ€λ°©(컴퓨터)의 μˆ˜κ°€ 425일 λ•Œ, 123을 μ œμ‹œν•œ 경우 : 1슀트라이크, 456을 μ œμ‹œν•œ 경우 : 1슀트라이크 1λ³Ό, +789λ₯Ό μ œμ‹œν•œ 경우 : λ‚«μ‹± +- μœ„ 숫자 μ•Όκ΅¬κ²Œμž„μ—μ„œ μƒλŒ€λ°©μ˜ 역할을 컴퓨터가 ν•œλ‹€. μ»΄ν“¨ν„°λŠ” 1μ—μ„œ 9κΉŒμ§€ μ„œλ‘œ λ‹€λ₯Έ μž„μ˜μ˜ 수 3개λ₯Ό μ„ νƒν•œλ‹€. 게 +μž„ ν”Œλ ˆμ΄μ–΄λŠ” 컴퓨터가 μƒκ°ν•˜κ³  μžˆλŠ” 3개의 숫자λ₯Ό μž…λ ₯ν•˜κ³ , μ»΄ν“¨ν„°λŠ” μž…λ ₯ν•œ μˆ«μžμ— λŒ€ν•œ κ²°κ³Όλ₯Ό 좜λ ₯ν•œλ‹€. +- 이 같은 과정을 λ°˜λ³΅ν•΄ 컴퓨터가 μ„ νƒν•œ 3개의 숫자λ₯Ό λͺ¨λ‘ 맞히면 κ²Œμž„μ΄ μ’…λ£Œλœλ‹€. +- κ²Œμž„μ„ μ’…λ£Œν•œ ν›„ κ²Œμž„μ„ λ‹€μ‹œ μ‹œμž‘ν•˜κ±°λ‚˜ μ™„μ „νžˆ μ’…λ£Œν•  수 μžˆλ‹€. +- μ‚¬μš©μžκ°€ 잘λͺ»λœ 값을 μž…λ ₯ν•  경우 [ERROR]둜 μ‹œμž‘ν•˜λŠ” μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό 좜λ ₯ν•˜κ³  κ²Œμž„μ„ 계속 μ§„ν–‰ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€. + +# πŸ“ κ΅¬ν˜„ κΈ°λŠ₯ λͺ©λ‘ + +### κ²Œμž„ μ€€λΉ„ κΈ°λŠ₯ +- [x] μ»΄ν“¨ν„°λŠ” 1μ—μ„œ 9κΉŒμ§€ μ„œλ‘œ λ‹€λ₯Έ μž„μ˜μ˜ 수 3개λ₯Ό μ„ νƒν•˜κ³  μ €μž₯ν•œλ‹€. + +### μ‚¬μš©μž μž…λ ₯ κΈ°λŠ₯ +- [x] `숫자λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” :`λ₯Ό 좜λ ₯ν•œλ‹€. +- [x] μ‚¬μš©μžμ—κ²Œ μž…λ ₯을 λ°›λŠ”λ‹€. +- [x] μž…λ ₯값을 κ²€μ¦ν•œλ‹€. + - [x] 빈 λ¬Έμžμ—΄μ΄λ‚˜ 곡백이면 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œλ‹€. + - [x] μž…λ ₯된 λ¬Έμžμ—΄μ˜ 길이가 3이 μ•„λ‹ˆλ©΄ μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œλ‹€. + - [x] 3개 쀑에 ν•˜λ‚˜λΌλ„ μˆ«μžκ°€ μ•„λ‹ˆλ©΄ μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œλ‹€. + - [x] μˆ«μžμ— 0이 ν¬ν•¨λ˜μ–΄ 있으면 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œλ‹€. + - [x] μ„œλ‘œ λ‹€λ₯Έ μˆ«μžκ°€ μ•„λ‹ˆλ©΄ μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œλ‹€. + - [x] μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œ κ²½μš°μ—λŠ” μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό 좜λ ₯ν•œ 후에 μž…λ ₯을 λ‹€μ‹œ λ°›λŠ”λ‹€. + +### κ²Œμž„ κΈ°λŠ₯ +- [x] κ²°κ³Όλ₯Ό νŒλ‹¨ν•œλ‹€. + - [x] μŠ€νŠΈλΌμ΄ν¬μ™€ λ³Ό 갯수λ₯Ό μ„Όλ‹€. + - [x] 같은 μˆ˜κ°€ 같은 μžλ¦¬μ— 있으면 슀트라이크λ₯Ό μΆ”κ°€ν•œλ‹€. + - [x] 같은 μˆ˜κ°€ λ‹€λ₯Έ μžλ¦¬μ— 있으면 볼을 μΆ”κ°€ν•œλ‹€. + - [x] μŠ€νŠΈλΌμ΄ν¬μ™€ 볼이 μ—†μœΌλ©΄ λ‚«μ‹±μœΌλ‘œ νŒλ‹¨ν•œλ‹€. +- [x] κ²°κ³Όλ₯Ό 좜λ ₯ν•œλ‹€. +- [x] 정닡이 μ•„λ‹ˆλ©΄ `숫자λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” :`λ₯Ό 좜λ ₯ν•˜κ³  μ‚¬μš©μžμ—κ²Œ λ‹€μ‹œ μž…λ ₯을 λ°›λŠ”λ‹€. + +### κ²Œμž„ μ’…λ£Œ κΈ°λŠ₯ +- [x] `3개의 숫자λ₯Ό λͺ¨λ‘ λ§žνžˆμ…¨μŠ΅λ‹ˆλ‹€! κ²Œμž„ 끝`λ₯Ό 좜λ ₯ν•˜κ³  μ’…λ£Œν•œλ‹€. +- [x] `κ²Œμž„μ„ μƒˆλ‘œ μ‹œμž‘ν•˜λ €λ©΄ 1, μ’…λ£Œν•˜λ €λ©΄ 2λ₯Ό μž…λ ₯ν•˜μ„Έμš”.`λ₯Ό 좜λ ₯ν•œλ‹€. +- [x] μ‚¬μš©μžμ—κ²Œ 1 λ˜λŠ” 2λ₯Ό μž…λ ₯λ°›λŠ”λ‹€. +- [x] λ‹€λ₯Έ 값인 κ²½μš°μ—λŠ” μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œλ‹€. + - [x] μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œ κ²½μš°μ—λŠ” μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό 좜λ ₯ν•œ 후에 μž…λ ₯을 λ‹€μ‹œ λ°›λŠ”λ‹€. +- [x] 1을 μž…λ ₯받은 경우 κ²Œμž„ μ€€λΉ„ κΈ°λŠ₯λΆ€ν„° κ²Œμž„μ„ μƒˆλ‘œ μ‹œμž‘ν•œλ‹€. +- [x] 2λ₯Ό μž…λ ₯받은 경우 κ²Œμž„μ„ μ’…λ£Œν•œλ‹€. diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java new file mode 100644 index 00000000..5287d248 --- /dev/null +++ b/src/main/java/baseball/Application.java @@ -0,0 +1,15 @@ +package baseball; + +import baseball.controller.BaseballController; +import baseball.view.InputView; +import baseball.view.OutputView; + +public class Application { + public static void main(String[] args) { + BaseballController baseballController = new BaseballController( + new InputView(), + new OutputView() + ); + baseballController.run(); + } +} \ No newline at end of file diff --git a/src/main/java/baseball/controller/BaseballController.java b/src/main/java/baseball/controller/BaseballController.java new file mode 100644 index 00000000..e0312d6f --- /dev/null +++ b/src/main/java/baseball/controller/BaseballController.java @@ -0,0 +1,50 @@ +package baseball.controller; + +import baseball.domain.ComputerNumbers; +import baseball.domain.Numbers; +import baseball.domain.Result; +import baseball.domain.ResultType; +import baseball.global.exception.CustomException; +import baseball.global.message.InputMessage; +import baseball.view.InputView; +import baseball.view.OutputView; + +public class BaseballController { + private final InputView inputView; + private final OutputView outputView; + + public BaseballController(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void run() { + ComputerNumbers computerNumbers = new ComputerNumbers(); + process(computerNumbers); + } + + public void process(ComputerNumbers computerNumbers) { + Numbers inputNumbers = requestNumbers(); + Result result = new Result(computerNumbers, inputNumbers); + outputView.printlnStrikeAndBall(result); + if (result.getResultType() != ResultType.THREE_STRIKE) { + process(computerNumbers); + return; + } + outputView.printlnThreeStrike(); + if (inputView.enterFinishType() == 1) { + run(); + } + } + + private Numbers requestNumbers() { + outputView.printMessage(InputMessage.INPUT_NUMBERS.getMessage()); + try { + Numbers numbers = new Numbers(inputView.enterNumbers()); + return numbers; + } catch (CustomException e) { + outputView.printlnMessage(e.getMessage()); + return requestNumbers(); + } + } +} diff --git a/src/main/java/baseball/domain/ComputerNumbers.java b/src/main/java/baseball/domain/ComputerNumbers.java new file mode 100644 index 00000000..f9b37026 --- /dev/null +++ b/src/main/java/baseball/domain/ComputerNumbers.java @@ -0,0 +1,32 @@ +package baseball.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ComputerNumbers { + private final Numbers numbers; + + public ComputerNumbers() { + int[] randomNumbers = generateRandomNumbers(); + this.numbers = new Numbers(randomNumbers); + } + + private int[] generateRandomNumbers() { + List allNumbers = new ArrayList<>(); + for (int i = 1; i <= 9; i++) { + allNumbers.add(i); + } + Collections.shuffle(allNumbers); + int[] result = {allNumbers.get(0), allNumbers.get(1), allNumbers.get(2)}; + return result; + } + + public Number get(int idx) { + return numbers.get(idx); + } + + public boolean notContain(Number number) { + return numbers.notContain(number); + } +} diff --git a/src/main/java/baseball/domain/Number.java b/src/main/java/baseball/domain/Number.java new file mode 100644 index 00000000..3c90f774 --- /dev/null +++ b/src/main/java/baseball/domain/Number.java @@ -0,0 +1,13 @@ +package baseball.domain; + +public class Number { + private final int num; + + public Number(int num) { + this.num = num; + } + + public boolean isSameValue(Number number) { + return this.num == number.num; + } +} diff --git a/src/main/java/baseball/domain/Numbers.java b/src/main/java/baseball/domain/Numbers.java new file mode 100644 index 00000000..219a7078 --- /dev/null +++ b/src/main/java/baseball/domain/Numbers.java @@ -0,0 +1,32 @@ +package baseball.domain; + +import java.util.ArrayList; +import java.util.List; + +public class Numbers { + private final List numbers; + + public Numbers(int[] arr) { + numbers = new ArrayList<>(); + for (int num : arr) { + numbers.add(new Number(num)); + } + } + + public Number get(int idx) { + return numbers.get(idx); + } + + public boolean notContain(Number inputNumber) { + for (Number number: numbers) { + if (number.isSameValue(inputNumber)) { + return false; + } + } + return true; + } + + public int size() { + return numbers.size(); + } +} diff --git a/src/main/java/baseball/domain/Result.java b/src/main/java/baseball/domain/Result.java new file mode 100644 index 00000000..5c47a248 --- /dev/null +++ b/src/main/java/baseball/domain/Result.java @@ -0,0 +1,39 @@ +package baseball.domain; + +public class Result { + + private final ResultType resultType; + private final int strike; + private final int ball; + + public Result(ComputerNumbers computerNumbers, Numbers inputNumbers) { + int strike = 0; + int ball = 0; + for (int idx = 0; idx < inputNumbers.size(); idx++) { + Number number = inputNumbers.get(idx); + if (computerNumbers.notContain(number)) { + continue; + } + if (number.isSameValue(computerNumbers.get(idx))) { + strike++; + continue; + } + ball++; + } + this.strike = strike; + this.ball = ball; + this.resultType = ResultType.getResult(strike, ball); + } + + public ResultType getResultType() { + return resultType; + } + + public int getStrike() { + return strike; + } + + public int getBall() { + return ball; + } +} diff --git a/src/main/java/baseball/domain/ResultType.java b/src/main/java/baseball/domain/ResultType.java new file mode 100644 index 00000000..f58c2a45 --- /dev/null +++ b/src/main/java/baseball/domain/ResultType.java @@ -0,0 +1,18 @@ +package baseball.domain; + +public enum ResultType { + THREE_STRIKE, + STRIKE_AND_BALL, + NOTHING + ; + + public static ResultType getResult(int strike, int ball) { + if (strike == 3) { + return THREE_STRIKE; + } + if (strike != 0 || ball != 0) { + return STRIKE_AND_BALL; + } + return NOTHING; + } +} diff --git a/src/main/java/baseball/global/exception/CustomException.java b/src/main/java/baseball/global/exception/CustomException.java new file mode 100644 index 00000000..8fd4dfd1 --- /dev/null +++ b/src/main/java/baseball/global/exception/CustomException.java @@ -0,0 +1,13 @@ +package baseball.global.exception; + +import baseball.global.message.ErrorMessage; + +public class CustomException extends IllegalArgumentException { + private CustomException(ErrorMessage errorMessage) { + super(errorMessage.getMessage()); + } + + public static CustomException of(ErrorMessage errorMessage) { + return new CustomException(errorMessage); + } +} \ No newline at end of file diff --git a/src/main/java/baseball/global/message/ErrorMessage.java b/src/main/java/baseball/global/message/ErrorMessage.java new file mode 100644 index 00000000..43dcb3a2 --- /dev/null +++ b/src/main/java/baseball/global/message/ErrorMessage.java @@ -0,0 +1,22 @@ +package baseball.global.message; + +public enum ErrorMessage { + BLANK_INPUT("빈 λ¬Έμžμ—΄μ΄ μž…λ ₯λ˜μ—ˆμŠ΅λ‹ˆλ‹€."), + INVALID_INPUT_LENGTH("3개λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”"), + NON_DIGIT_CHARACTER_FOUND("λͺ¨λ‘ 숫자둜 μž…λ ₯ν•΄μ£Όμ„Έμš”"), + NON_POSITIVE_NUMBER_FOUND("λͺ¨λ‘ 0보닀 큰 μ–‘μˆ˜λ‘œ μž…λ ₯ν•΄μ£Όμ„Έμš”."), + DUPLICATE_NUMBER_FOUND("μ„œλ‘œ λ‹€λ₯Έ 숫자둜 μž…λ ₯ν•΄μ£Όμ„Έμš”."), + INVALID_FINISH_INPUT("κ²Œμž„μ„ μƒˆλ‘œ μ‹œμž‘ν•˜λ €λ©΄ 1, μ’…λ£Œν•˜λ €λ©΄ 2λ₯Ό μž…λ ₯ν•˜μ„Έμš”.") + ; + + private final static String PREFIX = "[ERROR]"; + private final String message; + + ErrorMessage(String message) { + this.message = message; + } + + public String getMessage() { + return PREFIX + " " + this.message; + } +} diff --git a/src/main/java/baseball/global/message/InputMessage.java b/src/main/java/baseball/global/message/InputMessage.java new file mode 100644 index 00000000..fd41ed23 --- /dev/null +++ b/src/main/java/baseball/global/message/InputMessage.java @@ -0,0 +1,17 @@ +package baseball.global.message; + +public enum InputMessage { + + INPUT_NUMBERS("숫자λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” : ") + ; + + private String message; + + InputMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/baseball/view/InputView.java b/src/main/java/baseball/view/InputView.java new file mode 100644 index 00000000..a76a6c69 --- /dev/null +++ b/src/main/java/baseball/view/InputView.java @@ -0,0 +1,85 @@ +package baseball.view; + +import baseball.global.exception.CustomException; +import baseball.global.message.ErrorMessage; + +import java.util.Scanner; + +public class InputView { + + public int[] enterNumbers() { + String input = readLine(); + validateStringFormat(input); + int[] nums = validateNumberFormat(input); + return nums; + } + + public int enterFinishType() { + String input = readLine(); + int num = parseFinishType(input); + return num; + } + + private int parseFinishType(String input) { + if (input.length() != 1 || !Character.isDigit(input.charAt(0))) { + throw CustomException.of(ErrorMessage.INVALID_FINISH_INPUT); + } + int num = input.charAt(0) - '0'; + if (num != 1 && num != 2) { + throw CustomException.of(ErrorMessage.INVALID_FINISH_INPUT); + } + return num; + } + + private void validateStringFormat(String str) { + if (isEmptyOrBlank(str)) { + throw CustomException.of(ErrorMessage.BLANK_INPUT); + } + if (str.length() != 3) { + throw CustomException.of(ErrorMessage.INVALID_INPUT_LENGTH); + } + } + + private int[] validateNumberFormat(String str) { + int[] nums = new int[3]; + for (int i = 0; i < 3; i++) { + validateDigit(str.charAt(i)); + int num = str.charAt(i) - '0'; + validatePositiveNumber(num); + nums[i] = num; + } + validateDuplicate(nums); + return nums; + } + + private void validateDigit(char c) { + if (!Character.isDigit(c)) { + throw CustomException.of(ErrorMessage.NON_DIGIT_CHARACTER_FOUND); + } + } + + private void validatePositiveNumber(int num) { + if (num <= 0) { + throw CustomException.of(ErrorMessage.NON_POSITIVE_NUMBER_FOUND); + } + } + + private void validateDuplicate(int[] arr) { + if (hasDuplicate(arr)) { + throw CustomException.of(ErrorMessage.DUPLICATE_NUMBER_FOUND); + } + } + + private boolean isEmptyOrBlank(String str) { + return str == null || str.isBlank(); + } + + private static boolean hasDuplicate(int[] arr) { + return arr[0] == arr[1] || arr[0] == arr[2] || arr[1] == arr[2]; + } + + private String readLine() { + Scanner scanner = new Scanner(System.in); + return scanner.nextLine(); + } +} diff --git a/src/main/java/baseball/view/OutputView.java b/src/main/java/baseball/view/OutputView.java new file mode 100644 index 00000000..54c46f4e --- /dev/null +++ b/src/main/java/baseball/view/OutputView.java @@ -0,0 +1,54 @@ +package baseball.view; + +import baseball.domain.Result; +import baseball.domain.ResultType; + +public class OutputView { + public void printlnMessage(String message) { + System.out.println(message); + } + + public void printMessage(String message) { + System.out.print(message); + } + + public void printEmptyLine() { + System.out.println(); + } + + public void printlnMessageWithEmptyLine(String message) { + printlnMessage(message); + printEmptyLine(); + } + + public void printlnStrikeAndBall(Result result) { + if (result.getResultType() == ResultType.NOTHING) { + printlnMessage("λ‚«μ‹±"); + return; + } + StringBuilder sb = new StringBuilder(); + appendStrike(result.getStrike(), sb); + appendBall(result.getBall(), sb); + printlnMessage(sb.toString()); + } + + public void printlnThreeStrike() { + printlnMessage("3개의 숫자λ₯Ό λͺ¨λ‘ λ§žνžˆμ…¨μŠ΅λ‹ˆλ‹€! κ²Œμž„ 끝"); + printlnMessage("κ²Œμž„μ„ μƒˆλ‘œ μ‹œμž‘ν•˜λ €λ©΄ 1, μ’…λ£Œν•˜λ €λ©΄ 2λ₯Ό μž…λ ₯ν•˜μ„Έμš”."); + } + + private void appendStrike(int strike, StringBuilder sb) { + if (strike != 0) { + sb.append(strike).append("슀트라이크"); + } + } + + private void appendBall(int ball, StringBuilder sb) { + if (ball != 0) { + if (!sb.isEmpty()) { + sb.append(" "); + } + sb.append(ball).append("λ³Ό"); + } + } +} diff --git a/src/test/java/baseball/domain/ComputerNumbersTest.java b/src/test/java/baseball/domain/ComputerNumbersTest.java new file mode 100644 index 00000000..e0c528c4 --- /dev/null +++ b/src/test/java/baseball/domain/ComputerNumbersTest.java @@ -0,0 +1,27 @@ +package baseball.domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class ComputerNumbersTest { + + @Test + void notContain_returnsFalse_forExistingNumberInstance() { + ComputerNumbers computerNumbers = new ComputerNumbers(); + + Number existingNumber = computerNumbers.get(0); + + assertThat(computerNumbers.notContain(existingNumber)).isFalse(); + } + + @Test + void get_throwsIndexOutOfBounds_whenIndexIsInvalid() { + ComputerNumbers computerNumbers = new ComputerNumbers(); + + assertThatThrownBy(() -> computerNumbers.get(3)) + .isInstanceOf(IndexOutOfBoundsException.class) + .hasMessageMatching("Index[: ]\\d+.*(Size|length)[: ]\\d+"); + } +} diff --git a/src/test/java/baseball/domain/NumberTest.java b/src/test/java/baseball/domain/NumberTest.java new file mode 100644 index 00000000..077a5bd7 --- /dev/null +++ b/src/test/java/baseball/domain/NumberTest.java @@ -0,0 +1,24 @@ +package baseball.domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class NumberTest { + + @Test + void isSameValue_returnsTrue_whenValuesMatch() { + Number number = new Number(5); + Number sameValue = new Number(5); + + assertThat(number.isSameValue(sameValue)).isTrue(); + } + + @Test + void isSameValue_returnsFalse_whenValuesDoNotMatch() { + Number number = new Number(5); + Number differentValue = new Number(7); + + assertThat(number.isSameValue(differentValue)).isFalse(); + } +} diff --git a/src/test/java/baseball/domain/NumbersTest.java b/src/test/java/baseball/domain/NumbersTest.java new file mode 100644 index 00000000..9c1d2bae --- /dev/null +++ b/src/test/java/baseball/domain/NumbersTest.java @@ -0,0 +1,48 @@ +package baseball.domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +class NumbersTest { + + @Test + void size_returnsLengthOfInputArray() { + Numbers numbers = new Numbers(new int[]{1, 2, 3}); + + assertThat(numbers.size()).isEqualTo(3); + } + + @Test + void get_returnsNumberAtIndex() { + Numbers numbers = new Numbers(new int[]{1, 2, 3}); + + Number number = numbers.get(0); + + assertThat(number.isSameValue(new Number(1))).isTrue(); + } + + @Test + void notContain_returnsFalse_whenNumberExists() { + Numbers numbers = new Numbers(new int[]{1, 2, 3}); + + assertThat(numbers.notContain(new Number(2))).isFalse(); + } + + @Test + void notContain_returnsTrue_whenNumberDoesNotExist() { + Numbers numbers = new Numbers(new int[]{1, 2, 3}); + + assertThat(numbers.notContain(new Number(9))).isTrue(); + } + + @Test + void get_throwsIndexOutOfBounds_whenIndexIsInvalid() { + Numbers numbers = new Numbers(new int[]{1, 2}); + + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> numbers.get(2)) + .withMessageMatching("Index[: ]\\d+.*(Size|length)[: ]\\d+"); + } +} diff --git a/src/test/java/baseball/domain/ResultTest.java b/src/test/java/baseball/domain/ResultTest.java new file mode 100644 index 00000000..e268cd33 --- /dev/null +++ b/src/test/java/baseball/domain/ResultTest.java @@ -0,0 +1,59 @@ +package baseball.domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ResultTest { + + private ComputerNumbers fixedComputerNumbers(int[] values) { + Numbers numbers = new Numbers(values); + return new ComputerNumbers() { + @Override + public Number get(int idx) { + return numbers.get(idx); + } + + @Override + public boolean notContain(Number number) { + return numbers.notContain(number); + } + }; + } + + @Test + void result_countsThreeStrike_whenAllMatchInPosition() { + ComputerNumbers computerNumbers = fixedComputerNumbers(new int[]{1, 2, 3}); + Numbers inputNumbers = new Numbers(new int[]{1, 2, 3}); + + Result result = new Result(computerNumbers, inputNumbers); + + assertThat(result.getStrike()).isEqualTo(3); + assertThat(result.getBall()).isEqualTo(0); + assertThat(result.getResultType()).isEqualTo(ResultType.THREE_STRIKE); + } + + @Test + void result_countsStrikeAndBall_whenValuesMatchDifferentPositions() { + ComputerNumbers computerNumbers = fixedComputerNumbers(new int[]{1, 2, 3}); + Numbers inputNumbers = new Numbers(new int[]{1, 3, 2}); + + Result result = new Result(computerNumbers, inputNumbers); + + assertThat(result.getStrike()).isEqualTo(1); + assertThat(result.getBall()).isEqualTo(2); + assertThat(result.getResultType()).isEqualTo(ResultType.STRIKE_AND_BALL); + } + + @Test + void result_countsNothing_whenNoValuesMatch() { + ComputerNumbers computerNumbers = fixedComputerNumbers(new int[]{1, 2, 3}); + Numbers inputNumbers = new Numbers(new int[]{4, 5, 6}); + + Result result = new Result(computerNumbers, inputNumbers); + + assertThat(result.getStrike()).isEqualTo(0); + assertThat(result.getBall()).isEqualTo(0); + assertThat(result.getResultType()).isEqualTo(ResultType.NOTHING); + } +} diff --git a/src/test/java/baseball/domain/ResultTypeTest.java b/src/test/java/baseball/domain/ResultTypeTest.java new file mode 100644 index 00000000..1128f8a9 --- /dev/null +++ b/src/test/java/baseball/domain/ResultTypeTest.java @@ -0,0 +1,30 @@ +package baseball.domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ResultTypeTest { + + @Test + void getResult_returnsThreeStrike_whenStrikeIsThree() { + ResultType result = ResultType.getResult(3, 0); + + assertEquals(ResultType.THREE_STRIKE, result); + assertThat(result).isEqualTo(ResultType.THREE_STRIKE); + } + + @Test + void getResult_returnsStrikeAndBall_whenAnyStrikeOrBall() { + assertThat(ResultType.getResult(1, 0)).isEqualTo(ResultType.STRIKE_AND_BALL); + assertThat(ResultType.getResult(0, 2)).isEqualTo(ResultType.STRIKE_AND_BALL); + } + + @Test + void getResult_returnsNothing_whenNoStrikeAndNoBall() { + ResultType result = ResultType.getResult(0, 0); + + assertEquals(ResultType.NOTHING, result); + } +}