diff --git a/README.md b/README.md index edd124ad18..b73177b6c2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,31 @@ +# README + # java-lotto -로또 미션 진행을 위한 저장소 + +> 기능 요구사항 + +- [x] 구입금액을 입력받는다. + - [x] (예외) 1000원 이하 단위일 경우 + - [x] (예외) 숫자가 아닐 경우 + - [x] (예외) 음수 또는 50000원 이상 입력될 경우 +- [x] 구매한 로또 장 수와 번호를 출력한다. +- [x] 지난 주 당첨 번호를 입력받는다. + - [x] (예외) 1~45 이외의 숫자가 입력되는 경우 + - [x] (예외) 올바른 입력 형식이 아닌 경우 + - [x] (예외) 6개가 아닌 경우 + - [x] (예외) 공백이 입력되는 경우 +- [x] 보너스 볼을 입력받는다. + - [x] (예외) 위와 동일 +- [x] 당첨 번호를 대조해서 결과를 얻는다. +- [x] 당첨 통계와 수익률을 출력한다. + +> 프로그래밍 요구사항 + +- indent(인덴트, 들여쓰기) depth를 2단계에서 1단계로 줄여라. +- else를 사용하지 마라. +- 메소드의 크기가 최대 10라인을 넘지 않도록 구현한다. +- 배열 대신 ArrayList를 사용한다. +- enum을 적용해 프로그래밍을 구현한다. +- 규칙 3: 모든 원시값과 문자열을 포장한다. +- 규칙 5: 줄여쓰지 않는다(축약 금지). +- 규칙 8: 일급 콜렉션을 쓴다. \ No newline at end of file diff --git a/src/main/java/LottoApplication.java b/src/main/java/LottoApplication.java new file mode 100644 index 0000000000..63e063e7a9 --- /dev/null +++ b/src/main/java/LottoApplication.java @@ -0,0 +1,44 @@ +import domain.*; +import domain.numberscontainer.BonusNumberDTO; +import domain.numberscontainer.SixLottoNumbersDTO; +import domain.numberscontainer.Ticket; +import domain.numberscontainer.WinningNumbers; +import view.InputView; +import view.OutputView; + +import java.util.List; +import java.util.Map; + +public class LottoApplication { + public static void main(String[] args) { + Money money = new Money(enterMoney()); + List tickets = LottoStore.generateTickets(money.getNumberOfTickets()); + OutputView.printNumberOfTickets(tickets.size()); + OutputView.printTickets(tickets); + + WinningNumbers winningNumbers = enterWinningNumbers(); + Map result = LottoResultMachine.confirmResult(tickets, winningNumbers); + OutputView.printLottoResults(result); + OutputView.printProfit(LottoProfit.ofProfit(result, money)); + } + + private static String enterMoney() { + try { + return InputView.enterMoney(); + } catch (Exception e) { + System.out.println(e.getMessage()); + return enterMoney(); + } + } + + private static WinningNumbers enterWinningNumbers() { + try { + SixLottoNumbersDTO sixLottoNumbersDTO = new SixLottoNumbersDTO(InputView.enterLastWeekWinningNumbers()); + BonusNumberDTO bonusNumberDTO = new BonusNumberDTO(InputView.enterBonusNumber()); + return new WinningNumbers(sixLottoNumbersDTO, bonusNumberDTO); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return enterWinningNumbers(); + } + } +} \ No newline at end of file diff --git a/src/main/java/domain/LottoProfit.java b/src/main/java/domain/LottoProfit.java new file mode 100644 index 0000000000..0bbf01b766 --- /dev/null +++ b/src/main/java/domain/LottoProfit.java @@ -0,0 +1,27 @@ +package domain; + +import java.util.Map; + +public class LottoProfit { + private static final int TO_PERCENTAGE = 100; + + private long profit; + + private LottoProfit(long profit) { + this.profit = profit; + } + + public static LottoProfit ofProfit(Map lottoResults, Money money) { + long totalPrize = 0; + for (LottoResult result : lottoResults.keySet()) { + long prize = result.getPrize(); + long matchCount = lottoResults.get(result); + totalPrize += prize * matchCount; + } + return new LottoProfit(totalPrize / money.getMoney() * TO_PERCENTAGE); + } + + public long getValue() { + return profit; + } +} \ No newline at end of file diff --git a/src/main/java/domain/LottoResult.java b/src/main/java/domain/LottoResult.java new file mode 100644 index 0000000000..fbfc610d87 --- /dev/null +++ b/src/main/java/domain/LottoResult.java @@ -0,0 +1,42 @@ +package domain; + +import java.util.Arrays; +import java.util.List; + +public enum LottoResult { + FIRST(2_000_000_000, 6), + SECOND(30_000_000, 5), + THIRD(1_500_000, 5), + FOURTH(50_000, 4), + FIFTH(5_000, 3), + FAILED(0, 0); + + private final int prize; + private final int matchCount; + + LottoResult(int prize, int matchCount) { + this.prize = prize; + this.matchCount = matchCount; + } + + public static LottoResult findLottoResult(int matchCount, boolean isBonus) { + List lottoResults = Arrays.asList(LottoResult.values()); + LottoResult lottoResult = lottoResults.stream() + .filter(result -> result.matchCount == matchCount) + .findFirst() + .orElse(FAILED); + + if (lottoResult == SECOND && !isBonus) { + return THIRD; + } + return lottoResult; + } + + public int getPrize() { + return prize; + } + + public int getMatchCount() { + return matchCount; + } +} \ No newline at end of file diff --git a/src/main/java/domain/LottoResultMachine.java b/src/main/java/domain/LottoResultMachine.java new file mode 100644 index 0000000000..ca913f4678 --- /dev/null +++ b/src/main/java/domain/LottoResultMachine.java @@ -0,0 +1,16 @@ +package domain; + +import domain.numberscontainer.Ticket; +import domain.numberscontainer.WinningNumbers; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class LottoResultMachine { + + public static Map confirmResult(List tickets, WinningNumbers winningNumbers) { + return tickets.stream() + .collect(Collectors.groupingBy(winningNumbers::getLottoResult, Collectors.summingInt(x -> 1))); + } +} \ No newline at end of file diff --git a/src/main/java/domain/LottoStore.java b/src/main/java/domain/LottoStore.java new file mode 100644 index 0000000000..16ad76c9bf --- /dev/null +++ b/src/main/java/domain/LottoStore.java @@ -0,0 +1,38 @@ +package domain; + +import domain.numberscontainer.SixLottoNumbersDTO; +import domain.numberscontainer.Ticket; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/* + * Ticket 리스트 생성 + */ +public class LottoStore { + + public static List generateTickets(int ticketSize) { + List tickets = new ArrayList<>(); + + for (int i = 0; i < ticketSize; i++) { + tickets.add(RandomTicketFactory.createTicket()); + } + return tickets; + } + + public static List generateTickets(int ticketSize, List givenNumbers) { + List tickets = givenNumbers.stream() + .map(Ticket::new) + .collect(Collectors.toList()); + + int randomTicketsSize = getRandomTicketSize(ticketSize, givenNumbers.size()); + tickets.addAll(generateTickets(randomTicketsSize)); + + return tickets; + } + + private static int getRandomTicketSize(int totalTicketSize, int manualTicketSize) { + return totalTicketSize - manualTicketSize; + } +} \ No newline at end of file diff --git a/src/main/java/domain/Money.java b/src/main/java/domain/Money.java new file mode 100644 index 0000000000..49546391c8 --- /dev/null +++ b/src/main/java/domain/Money.java @@ -0,0 +1,38 @@ +package domain; + +public class Money { + private static final String NUMBER_REGEX = "^[+-]?[0-9]+$"; + + private final int money; + + public Money(String moneyInput) { + int money = parseInt(moneyInput); + validateMoneyUnit(money); + this.money = money; + } + + private static int parseInt(String input) { + validateNumber(input); + return Integer.parseInt(input); + } + + private static void validateNumber(String input) { + if (!input.matches(NUMBER_REGEX)) { + throw new NumberFormatException("0원 이상 숫자를 입력해주세요."); + } + } + + public int getNumberOfTickets() { + return this.money / 1000; + } + + private void validateMoneyUnit(int money) { + if (money % 1000 != 0) { + throw new IllegalArgumentException("천 원 단위로만 구매 가능합니다."); + } + } + + public int getMoney() { + return this.money; + } +} \ No newline at end of file diff --git a/src/main/java/domain/RandomTicketFactory.java b/src/main/java/domain/RandomTicketFactory.java new file mode 100644 index 0000000000..3c680e4513 --- /dev/null +++ b/src/main/java/domain/RandomTicketFactory.java @@ -0,0 +1,23 @@ +package domain; + +import domain.numberscontainer.LottoNumber; +import domain.numberscontainer.SixLottoNumbersDTO; +import domain.numberscontainer.Ticket; + +import java.util.*; + +public class RandomTicketFactory { + private static final int FIRST_INDEX = 0; + private static final int SIXTH_INDEX = 6; + + public static Ticket createTicket() { + return new Ticket(new SixLottoNumbersDTO(getShuffledList())); + } + + private static Set getShuffledList() { + List lottoNumbers = Arrays.asList(LottoNumber.values()); + Collections.shuffle(lottoNumbers); + + return new HashSet<>(lottoNumbers.subList(FIRST_INDEX, SIXTH_INDEX)); + } +} \ No newline at end of file diff --git a/src/main/java/domain/numberscontainer/BonusNumberDTO.java b/src/main/java/domain/numberscontainer/BonusNumberDTO.java new file mode 100644 index 0000000000..7b1fd66006 --- /dev/null +++ b/src/main/java/domain/numberscontainer/BonusNumberDTO.java @@ -0,0 +1,26 @@ +package domain.numberscontainer; + +public class BonusNumberDTO { + private static final String NUMBER_REGEX = "^[+-]?[0-9]+$"; + + private final LottoNumber bonusNumber; + + public BonusNumberDTO(String bonusNumberInput) { + this.bonusNumber = LottoNumber.getLottoNumber(parseInt(bonusNumberInput)); + } + + private static int parseInt(String input) { + validateNumber(input); + return Integer.parseInt(input); + } + + private static void validateNumber(String input) { + if (!input.matches(NUMBER_REGEX)) { + throw new NumberFormatException("숫자를 입력해주세요."); + } + } + + public LottoNumber getBonusNumber() { + return bonusNumber; + } +} \ No newline at end of file diff --git a/src/main/java/domain/numberscontainer/LottoNumber.java b/src/main/java/domain/numberscontainer/LottoNumber.java new file mode 100644 index 0000000000..05b86644d8 --- /dev/null +++ b/src/main/java/domain/numberscontainer/LottoNumber.java @@ -0,0 +1,71 @@ +package domain.numberscontainer; + +import java.util.Arrays; +import java.util.List; + +public enum LottoNumber { + ONE(1), + TWO(2), + THREE(3), + FOUR(4), + FIVE(5), + SIX(6), + SEVEN(7), + EIGHT(8), + NINE(9), + TEN(10), + ELEVEN(11), + TWELVE(12), + THIRTEEN(13), + FOURTEEN(14), + FIFTEEN(15), + SIXTEEN(16), + SEVENTEEN(17), + EIGHTEEN(18), + NINETEEN(19), + TWENTY(20), + TWENTY_ONE(21), + TWENTY_TWO(22), + TWENTY_THREE(23), + TWENTY_FOUR(24), + TWENTY_FIVE(25), + TWENTY_SIX(26), + TWENTY_SEVEN(27), + TWENTY_EIGHT(28), + TWENTY_NINE(29), + THIRTY(30), + THIRTY_ONE(31), + THIRTY_TWO(32), + THIRTY_THREE(33), + THIRTY_FOUR(34), + THIRTY_FIVE(35), + THIRTY_SIX(36), + THIRTY_SEVEN(37), + THIRTY_EIGHT(38), + THIRTY_NINE(39), + FORTY(40), + FORTY_ONE(41), + FORTY_TWO(42), + FORTY_THREE(43), + FORTY_FOUR(44), + FORTY_FIVE(45); + + private final int number; + + LottoNumber(int number) { + this.number = number; + } + + public static LottoNumber getLottoNumber(int number) { + List lottoNumbers = Arrays.asList(LottoNumber.values()); + + return lottoNumbers.stream() + .filter(lottoNumber -> lottoNumber.number == number) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format("%d이(가) 입력되었습니다. 1부터 45까지의 숫자를 입력해주세요.", number))); + } + + public int getValue() { + return this.number; + } +} diff --git a/src/main/java/domain/numberscontainer/SixLottoNumbers.java b/src/main/java/domain/numberscontainer/SixLottoNumbers.java new file mode 100644 index 0000000000..0cc1650120 --- /dev/null +++ b/src/main/java/domain/numberscontainer/SixLottoNumbers.java @@ -0,0 +1,20 @@ +package domain.numberscontainer; + +import java.util.Set; + +public class SixLottoNumbers { + private static final int LOTTO_NUMBERS_SIZE = 6; + + protected final Set sixLottoNumbers; + + public SixLottoNumbers(SixLottoNumbersDTO sixLottoNumbersDTO) { + validateSize(sixLottoNumbersDTO.getSixNumbers()); + this.sixLottoNumbers = sixLottoNumbersDTO.getSixNumbers(); + } + + protected void validateSize(Set lottoNumbers) { + if (lottoNumbers.size() != LOTTO_NUMBERS_SIZE) { + throw new IllegalArgumentException(String.format("%d개의 숫자를 입력해주세요.", LOTTO_NUMBERS_SIZE)); + } + } +} \ No newline at end of file diff --git a/src/main/java/domain/numberscontainer/SixLottoNumbersDTO.java b/src/main/java/domain/numberscontainer/SixLottoNumbersDTO.java new file mode 100644 index 0000000000..cd1411829e --- /dev/null +++ b/src/main/java/domain/numberscontainer/SixLottoNumbersDTO.java @@ -0,0 +1,30 @@ +package domain.numberscontainer; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +public class SixLottoNumbersDTO { + private final Set sixNumbers; + + public SixLottoNumbersDTO(String sixNumbersInput) { + Set sixNumbers = parseSixNumbers(sixNumbersInput); + this.sixNumbers = sixNumbers; + } + + public SixLottoNumbersDTO(Set sixNumbers) { + this.sixNumbers = sixNumbers; + } + + private Set parseSixNumbers(String sixNumbersInput) { + return Arrays.asList(sixNumbersInput.split(",")).stream() + .map(String::trim) + .map(Integer::new) + .map(LottoNumber::getLottoNumber) + .collect(Collectors.toSet()); + } + + public Set getSixNumbers() { + return sixNumbers; + } +} \ No newline at end of file diff --git a/src/main/java/domain/numberscontainer/Ticket.java b/src/main/java/domain/numberscontainer/Ticket.java new file mode 100644 index 0000000000..098d2a0261 --- /dev/null +++ b/src/main/java/domain/numberscontainer/Ticket.java @@ -0,0 +1,21 @@ +package domain.numberscontainer; + +import java.util.stream.Collectors; + +public class Ticket extends SixLottoNumbers { + + public Ticket(SixLottoNumbersDTO sixLottoNumbersDTO) { + super(sixLottoNumbersDTO); + } + + public boolean contains(LottoNumber number) { + return this.sixLottoNumbers.contains(number); + } + + @Override + public String toString() { + return this.sixLottoNumbers.stream() + .map(lottoNumber -> Integer.toString(lottoNumber.getValue())) + .collect(Collectors.joining(", ", "[", "]")); + } +} \ No newline at end of file diff --git a/src/main/java/domain/numberscontainer/WinningNumbers.java b/src/main/java/domain/numberscontainer/WinningNumbers.java new file mode 100644 index 0000000000..4a0bcee6b9 --- /dev/null +++ b/src/main/java/domain/numberscontainer/WinningNumbers.java @@ -0,0 +1,32 @@ +package domain.numberscontainer; + +import domain.LottoResult; + +public class WinningNumbers extends SixLottoNumbers { + + private final LottoNumber bonusNumber; + + public WinningNumbers(SixLottoNumbersDTO sixLottoNumbersDTO, BonusNumberDTO bonusNumberDTO) { + super(sixLottoNumbersDTO); + validateBonusNumber(bonusNumberDTO.getBonusNumber()); + this.bonusNumber = bonusNumberDTO.getBonusNumber(); + } + + private void validateBonusNumber(LottoNumber bonusNumber) { + if (this.sixLottoNumbers.contains(bonusNumber)) { + throw new IllegalArgumentException("당첨 번호와 중복되지 않는 보너스 번호를 입력해주세요."); + } + } + + public LottoResult getLottoResult(Ticket ticket) { + int matchCount = findDuplicatedNumbers(ticket); + boolean isBonus = ticket.contains(bonusNumber); + return LottoResult.findLottoResult(matchCount, isBonus); + } + + public int findDuplicatedNumbers(Ticket ticket) { + return (int) this.sixLottoNumbers.stream() + .filter(ticket::contains) + .count(); + } +} \ No newline at end of file diff --git a/src/main/java/lotto/WebUILottoApplication.java b/src/main/java/lotto/WebUILottoApplication.java deleted file mode 100644 index 1926550119..0000000000 --- a/src/main/java/lotto/WebUILottoApplication.java +++ /dev/null @@ -1,22 +0,0 @@ -package lotto; - -import spark.ModelAndView; -import spark.template.handlebars.HandlebarsTemplateEngine; - -import java.util.HashMap; -import java.util.Map; - -import static spark.Spark.get; - -public class WebUILottoApplication { - public static void main(String[] args) { - get("/", (req, res) -> { - Map model = new HashMap<>(); - return render(model, "index.html"); - }); - } - - private static String render(Map model, String templatePath) { - return new HandlebarsTemplateEngine().render(new ModelAndView(model, templatePath)); - } -} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000000..02c3ff35e4 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,22 @@ +package view; + +import java.util.*; + +public class InputView { + private static Scanner scanner = new Scanner(System.in); + + public static String enterMoney() { + System.out.println("구입 금액을 입력해주세요."); + return scanner.nextLine(); + } + + public static String enterLastWeekWinningNumbers() { + System.out.println("지난 주 당첨 번호를 입력해 주세요."); + return scanner.nextLine(); + } + + public static String enterBonusNumber() { + System.out.println("보너스 볼을 입력해 주세요."); + return scanner.nextLine(); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000000..53ca169be7 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,59 @@ +package view; + +import domain.LottoProfit; +import domain.LottoResult; +import domain.numberscontainer.Ticket; + +import java.util.List; +import java.util.Map; + +public class OutputView { + public static final String LOTTO_RESULT_MESSAGE = "%d개 일치 (%d원)- %d개"; + public static final String LOTTO_RESULT_MESSAGE_FOR_BONUS = "%d개 일치, 보너스 볼 일치 (%d원)- %d개"; + public static final String LOTTO_RESULT_TITLE = "당첨 통계"; + public static final String LOTTO_RESULT_SEPARATOR = "---------------"; + public static final String LOTTO_PROFIT_MESSAGE = "총 수익률은 %d%%입니다."; + + public static void printNumberOfTickets(int size) { + System.out.println(size + "개를 구매했습니다."); + } + + public static void printTickets(List tickets) { + StringBuilder stringBuilder = new StringBuilder(); + for (Ticket ticket : tickets) { + System.out.println(ticket.toString()); + System.lineSeparator(); + } + System.out.println(stringBuilder.toString()); + } + + public static void printLottoResults(Map lottoResults) { + System.out.println(LOTTO_RESULT_TITLE); + System.lineSeparator(); + System.out.println(LOTTO_RESULT_SEPARATOR); + System.lineSeparator(); + + for (LottoResult result : LottoResult.values()) { + System.out.println(String.format(findProperFormat(result), result.getMatchCount(), result.getPrize(), convertNullToZero(lottoResults.get(result)))); + } + System.lineSeparator(); + } + + private static String findProperFormat(LottoResult result) { + if (result == LottoResult.SECOND) { + return LOTTO_RESULT_MESSAGE_FOR_BONUS; + } + return LOTTO_RESULT_MESSAGE; + } + + private static int convertNullToZero(Integer number) { + if (number == null) { + return 0; + } + return number; + } + + public static void printProfit(LottoProfit profit) { + System.out.println(String.format(LOTTO_PROFIT_MESSAGE, profit.getValue())); + } +} \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html deleted file mode 100644 index 3a7dbfecdf..0000000000 --- a/src/main/resources/templates/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - 로또 - - -Hello World!! - - \ No newline at end of file diff --git a/src/test/java/domain/LottoNumberTest.java b/src/test/java/domain/LottoNumberTest.java new file mode 100644 index 0000000000..bd46c52d7c --- /dev/null +++ b/src/test/java/domain/LottoNumberTest.java @@ -0,0 +1,18 @@ +package domain; + +import domain.numberscontainer.LottoNumber; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayName("로또 숫자 테스트") +public class LottoNumberTest { + @Test + @DisplayName("로또 숫자 생성 예외처리") + void lottoNumberConstructorTest() { + assertThatThrownBy(() -> LottoNumber.getLottoNumber(46)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("46이(가) 입력되었습니다. 1부터 45까지의 숫자를 입력해주세요."); + } +} \ No newline at end of file diff --git a/src/test/java/domain/LottoResultMachineTest.java b/src/test/java/domain/LottoResultMachineTest.java new file mode 100644 index 0000000000..b0219235f9 --- /dev/null +++ b/src/test/java/domain/LottoResultMachineTest.java @@ -0,0 +1,59 @@ +package domain; + +import domain.numberscontainer.*; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LottoResultMachineTest { + @Test + @DisplayName("당첨 결과 계산") + void test1() { + Money money = new Money("10000"); + List tickets = LottoStore.generateTickets(money.getNumberOfTickets(), createFixedNumbersList()); + + SixLottoNumbersDTO sixNumbers = createFixedNumbers(3, 4, 5, 6, 7, 8); + WinningNumbers winningNumbers = new WinningNumbers(sixNumbers, new BonusNumberDTO("9")); + Map lottoResults = LottoResultMachine.confirmResult(tickets, winningNumbers); + + assertThat(lottoResults.get(LottoResult.FIRST)).isEqualTo(1); + assertThat(lottoResults.get(LottoResult.SECOND)).isEqualTo(2); + assertThat(lottoResults.get(LottoResult.THIRD)).isEqualTo(2); + assertThat(lottoResults.get(LottoResult.FOURTH)).isEqualTo(2); + assertThat(lottoResults.get(LottoResult.FIFTH)).isEqualTo(1); + assertThat(lottoResults.get(LottoResult.FAILED)).isEqualTo(2); + } + + @Test + @DisplayName("수익률 계산") + void test2() { + Money money = new Money("10000"); + List tickets = LottoStore.generateTickets(money.getNumberOfTickets(), createFixedNumbersList()); + + SixLottoNumbersDTO sixNumbers = createFixedNumbers(3, 4, 5, 6, 7, 8); + WinningNumbers winningNumbers = new WinningNumbers(sixNumbers, new BonusNumberDTO("9")); + Map lottoResults = LottoResultMachine.confirmResult(tickets, winningNumbers); + LottoProfit profit = LottoProfit.ofProfit(lottoResults, money); + assertThat(profit.getValue()).isEqualTo(20631000); + } + + private List createFixedNumbersList() { + return Arrays.asList(createFixedNumbers(3, 4, 5, 6, 7, 8), //1등 + createFixedNumbers(3, 4, 5, 6, 7, 9), //2등 + createFixedNumbers(3, 4, 5, 6, 7, 10), //3등 + createFixedNumbers(3, 4, 5, 6, 10, 11), //4등 + createFixedNumbers(3, 4, 5, 10, 11, 12), //5등 + createFixedNumbers(4, 5, 6, 7, 8, 9), //2등 + createFixedNumbers(4, 5, 6, 7, 8, 10), //3등 + createFixedNumbers(4, 5, 6, 7, 10, 11), //4등 + createFixedNumbers(10, 11, 12, 13, 14, 15), //당첨 x + createFixedNumbers(16, 17, 18, 19, 20, 21)); //당첨 x + } + + private SixLottoNumbersDTO createFixedNumbers(int number1, int number2, int number3, int number4, int number5, int number6) { + return new SixLottoNumbersDTO(String.format("%d, %d, %d, %d, %d, %d", number1, number2, number3, number4, number5, number6)); + } +} diff --git a/src/test/java/domain/LottoStoreTest.java b/src/test/java/domain/LottoStoreTest.java new file mode 100644 index 0000000000..00222be498 --- /dev/null +++ b/src/test/java/domain/LottoStoreTest.java @@ -0,0 +1,15 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LottoStoreTest { + + @Test + @DisplayName("티켓들 생성") + void generateRandomTicket() { + assertThat(LottoStore.generateTickets(10).size()).isEqualTo(10); + } +} diff --git a/src/test/java/domain/MoneyTest.java b/src/test/java/domain/MoneyTest.java new file mode 100644 index 0000000000..6753a49a86 --- /dev/null +++ b/src/test/java/domain/MoneyTest.java @@ -0,0 +1,28 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayName("돈 객체 테스트") +class MoneyTest { + @ParameterizedTest + @ValueSource(strings = {" ", "만 원"}) + @DisplayName("돈 객체 생성자") + void moneyTest1(String money) { + assertThatThrownBy(() -> new Money(money)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("0원 이상 숫자를 입력해주세요."); + } + + @ParameterizedTest + @ValueSource(strings = {"1700", "-1", "50001"}) + @DisplayName("돈 객체 생성자") + void moneyTest2(String money) { + assertThatThrownBy(() -> new Money(money)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("천 원 단위로만 구매 가능합니다."); + } +} \ No newline at end of file diff --git a/src/test/java/domain/numberscontainer/TicketTest.java b/src/test/java/domain/numberscontainer/TicketTest.java new file mode 100644 index 0000000000..1c60d7ea65 --- /dev/null +++ b/src/test/java/domain/numberscontainer/TicketTest.java @@ -0,0 +1,34 @@ +package domain.numberscontainer; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.HashSet; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayName("티켓 객체 테스트") +public class TicketTest { + @Test + @DisplayName("티켓 생성") + void ticketConstructor() { + SixLottoNumbersDTO sixLottoNumbersDTO = createLottoNumberDto(1, 2, 3, 4, 5, 5); + assertThatThrownBy(() -> new Ticket(sixLottoNumbersDTO)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("6개의 숫자를 입력해주세요."); + } + + @Test + @DisplayName("두 티켓의 같은 숫자 비교") + void compareTwoTickets() { + SixLottoNumbersDTO sixLottoNumbersDTO = createLottoNumberDto(1, 2, 3, 4, 5, 6); + Ticket ticket = new Ticket(sixLottoNumbersDTO); + assertThat(ticket.contains(LottoNumber.THREE)).isTrue(); + } + + private SixLottoNumbersDTO createLottoNumberDto(int number1, int number2, int number3, int number4, int number5, int number6) { + return new SixLottoNumbersDTO(String.format("%d, %d, %d, %d, %d, %d", number1, number2, number3, number4, number5, number6)); + } +} diff --git a/src/test/java/domain/numberscontainer/WinningNumbersTest.java b/src/test/java/domain/numberscontainer/WinningNumbersTest.java new file mode 100644 index 0000000000..a36f34444b --- /dev/null +++ b/src/test/java/domain/numberscontainer/WinningNumbersTest.java @@ -0,0 +1,75 @@ +package domain.numberscontainer; + +import domain.LottoResult; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayName("당첨 번호 객체 테스트") +public class WinningNumbersTest { + @Test + @DisplayName("당첨 번호 객체 생성") + void winningNumberConstructor() { + SixLottoNumbersDTO sixLottoNumbersDTO = createSixNumbersDto(1, 2, 3, 4, 5, 5); + BonusNumberDTO bonusNumberDTO = new BonusNumberDTO("7"); + assertThatThrownBy(() -> new WinningNumbers(sixLottoNumbersDTO, bonusNumberDTO)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("6개의 숫자를 입력해주세요."); + } + + @ParameterizedTest + @ValueSource(strings = {"1", "5"}) + @DisplayName("중복 없는 보너스 번호인지 검증") + void validateBonusNumber(String input) { + SixLottoNumbersDTO sixLottoNumbersDTO = createSixNumbersDto(1, 2, 3, 4, 5, 6); + BonusNumberDTO bonusNumberDTO = new BonusNumberDTO(input); + assertThatThrownBy(() -> new WinningNumbers(sixLottoNumbersDTO, bonusNumberDTO)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageEndingWith("보너스 번호를 입력해주세요."); + } + + @ParameterizedTest + @ValueSource(strings = {"-1", "46"}) + @DisplayName("1부터 45까지의 보너스 번호인지 검증") + void validateBonusNumber2(String input) { + assertThatThrownBy(() -> new BonusNumberDTO(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageEndingWith("숫자를 입력해주세요."); + } + + @Test + @DisplayName("Ticket과 당첨 번호 비교") + void findDuplicatedNumbers() { + SixLottoNumbersDTO sixLottoNumbersDTO1 = createSixNumbersDto(1, 2, 3, 4, 5, 6); + BonusNumberDTO bonusNumberDTO = new BonusNumberDTO("7"); + SixLottoNumbersDTO sixLottoNumbersDTO2 = createSixNumbersDto(4, 5, 6, 7, 8, 9); + WinningNumbers winningNumbers = new WinningNumbers(sixLottoNumbersDTO1, bonusNumberDTO); + Ticket ticket = new Ticket(sixLottoNumbersDTO2); + assertThat((winningNumbers.findDuplicatedNumbers(ticket))).isEqualTo(3); + } + + @Test + @DisplayName("당첨 결과 확인") + void getLottoResultTest() { + WinningNumbers winningNumbers = new WinningNumbers(createSixNumbersDto(3, 4, 5, 6, 7, 8), new BonusNumberDTO("9")); + + assertThat(winningNumbers.getLottoResult(new Ticket(createSixNumbersDto(3, 4, 5, 6, 7, 8)))).isEqualTo(LottoResult.FIRST); + assertThat(winningNumbers.getLottoResult(new Ticket(createSixNumbersDto(3, 4, 5, 6, 7, 9)))).isEqualTo(LottoResult.SECOND); + assertThat(winningNumbers.getLottoResult(new Ticket(createSixNumbersDto(3, 4, 5, 6, 7, 10)))).isEqualTo(LottoResult.THIRD); + assertThat(winningNumbers.getLottoResult(new Ticket(createSixNumbersDto(3, 4, 5, 6, 10, 11)))).isEqualTo(LottoResult.FOURTH); + assertThat(winningNumbers.getLottoResult(new Ticket(createSixNumbersDto(3, 4, 5, 10, 11, 12)))).isEqualTo(LottoResult.FIFTH); + assertThat(winningNumbers.getLottoResult(new Ticket(createSixNumbersDto(10, 11, 12, 13, 14, 15)))).isEqualTo(LottoResult.FAILED); + } + + private SixLottoNumbersDTO createSixNumbersDto(int number1, int number2, int number3, int number4, int number5, int number6) { + return new SixLottoNumbersDTO(String.format("%d, %d, %d, %d, %d, %d", number1, number2, number3, number4, number5, number6)); + } +} \ No newline at end of file diff --git a/src/test/java/empty.txt b/src/test/java/empty.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/java/strategy/RandomTicketFactoryTest.java b/src/test/java/strategy/RandomTicketFactoryTest.java new file mode 100644 index 0000000000..3ab362a30f --- /dev/null +++ b/src/test/java/strategy/RandomTicketFactoryTest.java @@ -0,0 +1,18 @@ +package strategy; + +import domain.RandomTicketFactory; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatCode; + +@DisplayName("티켓 생성 테스트") +class RandomTicketFactoryTest { + + @Test + @DisplayName("랜덤 티켓 생성") + void generateRandomTicket() { + assertThatCode(() -> RandomTicketFactory.createTicket()) + .doesNotThrowAnyException(); + } +} \ No newline at end of file