diff --git a/README.md b/README.md new file mode 100644 index 0000000..5385ed1 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +### 프로그램 분석 + +--- + +**로또 기본 룰** + +- 로또의 기본적인 규칙은 45개의 숫자 중에서 6개를 선택하는 방식입니다. 1등에 당첨되기 위해서는 6자리의 숫자가 맞으면 1등에 당첨입니다. 당첨번호 5개 + 보너스 번호 1개에 맞으면 2등이며 보너스 번호는 2등에만 해당됩니다. +1. 입력한 금액 % 1000 만큼의 로또 개수 발급 + - 구입한 금액은 저장해야함. → Or 발급 개수를 저장. + - 나중에 수익률 계산할 때 사용. +2. 당첨번호를 입력 받아야함. + - 당첨 번호 + 보너스 번호 +3. 발급된 각 로또 번호와 당첨번호를 매칭해서 개수 일치 카운팅 + - 일치 카운트의 로또 개수 리턴 해아함. + + 상금 + + - 5등 + - 3개 일치 : 5000원 + - 4등 + - 4개 일치 : 50000원 + - 3등 + - 5개 일치 : 1500000원 + - 2등 + - 5개 일치, 보너스 볼 일치 : 30000000원 + - 1등 + - 6개 일치 : 20000000000원 +4. 3번 내용 바탕으로 총 수익률 계산. + +### 요구사항 분석 + +--- + +- 결과 값들에 대해서는 배열 보단 `ArrayList`로 일급 컬렉션으로 관리하기. +- `JAVA ENUM`을 활용하기 → 상금을 활용하면 좋을 듯?? +- 규칙 3 : 모든 원시값과 문자열을 포장한다. +- 규칙 5 : 줄여쓰지 않는다. +- 규칙 8 : 일급 컬렉션을 쓴다. + - 배열 대신 `ArrayList`로 결과 값을 일급 컬렉션으로 관리하는 것이 좋음 + +### 객체 설명 + +|클래스|역할과 책임| +|------|---| +|Money|로또 진행에 필요한 돈을 관리하는 불변 객체.
티켓을 구매, 티켓 구매 가능 여부 판단.| +|LottoShop|로또 티켓을 발급해주는 객체.
수동 티켓과 자동 로또 티켓 발급.| +|LottoNumberGenerator|로또 번호를 랜덤으로 발급해주는 객체.
로또 상점에서 발급되는 티켓을 생성해줌.
입력된 숫자를 로또 번호 객체로 변환.| +|LottoNumber|로또 번호를 관리하는 객체.
로또번호인 1~45 사이 값만 생성할 수 있도록 강제함.| +|LottoTicket|실제 추첨에 사용될 수 있는 로또 티켓을 관리하는 객체.
로또 게임에 유효한 티켓만 발급될 수 있도록 강제.
로또 티켓을 당첨 번호와 비교하며 당첨 결과를 알려줌.| +|WinningTicket|당첨 번호(보너스 번호 포함)를 관리하는 객체.| +|LottoTickets|실제 추첨에 사용될 수 있는 로또 티켓들을 관리하는 객체.
모든 티켓을 당첨 번호와 비교하며 당첨 결과를 알려줌.| +|LottoRank|당첨 순위에 대한 정보를 담고 있는 열거 객체.| +|LottoResult|최종 로또 추첨 결과를 가지고 있는 객체.| +|WinningStatistics| 추첨 결과에 따른 통계량을 구해주는 객체.| + + + +### 힌트 + +--- + +- 로또 자동 생성은 `Collections.shuffle()` 메소드 활용 +- `Collections.sort()` 메소드를 활용해 정렬 가능 +- `ArrayList`의 `Contains()` 메소드를 활용하면 어떤 값이 존재하는지 유무를 판단할 수 있음 + + +#### 로또 흐름 + - 시작! 돈을 넣어라. + - 게임에 참여하는 돈을 입력 받음 + - 돈을 주고, 티켓을 받음. + - 자동으로 1000당 한 개씩 반환해줌. + - 복권 번호는 1~45번까지 있고 총 6개의 번호를 반환. + - 중복번호 없어야 하고, 각 티켓은 Shuffle되서 반환되어야 함 + - 당첨 결과를 알려줘! + - 당첨번호와 보너스 번호가 입력을 받음 + - 당첨 번호와 보너스 번호는 중복되면 안됨. + - 발급받은 티켓에 대한 당첨 결과를 알려줘 + - 각 티켓별 결과 반환 + - 당첨결과에 따른 통계량을 계산해서 출력해줘! + - 당첨 결과를 계산해주고 출력 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 44e7c4d..1094d7d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Thu May 21 18:30:01 KST 2020 +distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/com/javabom/lotto/LottoApplication.java b/src/main/java/com/javabom/lotto/LottoApplication.java index 13f852e..8cbca84 100644 --- a/src/main/java/com/javabom/lotto/LottoApplication.java +++ b/src/main/java/com/javabom/lotto/LottoApplication.java @@ -1,7 +1,35 @@ package com.javabom.lotto; +import com.javabom.lotto.domain.result.LottoResult; +import com.javabom.lotto.domain.result.WinningStatistics; +import com.javabom.lotto.domain.shop.LottoNumbersGenerator; +import com.javabom.lotto.domain.shop.LottoShop; +import com.javabom.lotto.domain.ticket.LottoTickets; +import com.javabom.lotto.domain.ticket.WinningTicket; +import com.javabom.lotto.domain.vo.Money; +import com.javabom.lotto.dto.InputDto; +import com.javabom.lotto.dto.WinningNumbersDto; +import com.javabom.lotto.dto.WinningStatisticsDto; +import com.javabom.lotto.view.InputView; +import com.javabom.lotto.view.OutputView; + public class LottoApplication { public static void main(String[] args) { + InputDto inputDto = InputView.askInputMoneyAndManual(); + LottoShop lottoShop = new LottoShop(new LottoNumbersGenerator()); + + LottoTickets manualTickets = lottoShop.buyTicketsByManualInLottoShop(inputDto.getManualNumbers()); + Money remainMoney = lottoShop.getRemainMoney(manualTickets, inputDto.getMoney()); + LottoTickets automaticTickets = lottoShop.buyTicketsByAutomaticInLottoShop(remainMoney); + + OutputView.printLotteryTickets(automaticTickets, manualTickets); + WinningNumbersDto winningNumbersDto = InputView.askWinningNumbers(); + WinningTicket winningTicket = new WinningTicket(winningNumbersDto.getWinningNumbers(), + winningNumbersDto.getBonusNumber()); + + LottoTickets allTickets = manualTickets.joinTickets(automaticTickets); + LottoResult lottoResult = allTickets.getLottoResult(winningTicket); + OutputView.printWinningStatistics(new WinningStatisticsDto(new WinningStatistics(lottoResult))); } } diff --git a/src/main/java/com/javabom/lotto/domain/result/LottoRank.java b/src/main/java/com/javabom/lotto/domain/result/LottoRank.java new file mode 100644 index 0000000..e7edac3 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/result/LottoRank.java @@ -0,0 +1,40 @@ +package com.javabom.lotto.domain.result; + +import java.util.Arrays; + +public enum LottoRank { + FIFTH_PLACE(5000, 3), + FOURTH_PLACE(50000, 4), + THIRD_PLACE(1500000, 5), + SECOND_PLACE(30000000, 5), + FIRST_PLACE(2000000000, 6), + FAIL(0, 0); + + private int prizeMoney; + private int sameCount; + + LottoRank(int prizeMoney, int sameCount) { + this.prizeMoney = prizeMoney; + this.sameCount = sameCount; + } + + public static LottoRank findBySameCount(int sameCount) { + return Arrays.stream(LottoRank.values()) + .filter(rankInfo -> rankInfo.sameCount == sameCount) + .findAny() + .orElse(FAIL); + } + + public static LottoRank findLottoRank(int sameCount, boolean hasBonusNumber) { + if (sameCount == 5 && hasBonusNumber) { + return LottoRank.SECOND_PLACE; + } + + return findBySameCount(sameCount); + } + + public int getPrizeMoney() { + return prizeMoney; + } + +} diff --git a/src/main/java/com/javabom/lotto/domain/result/LottoResult.java b/src/main/java/com/javabom/lotto/domain/result/LottoResult.java new file mode 100644 index 0000000..c27389a --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/result/LottoResult.java @@ -0,0 +1,27 @@ +package com.javabom.lotto.domain.result; + +import java.util.Collections; +import java.util.List; + +public class LottoResult { + + private final List results; + + public LottoResult(List results) { + this.results = results; + } + + public int getRankCount(LottoRank rank) { + return (int) results.stream() + .filter(lottoRank -> lottoRank.equals(rank)) + .count(); + } + + public List getResults() { + return Collections.unmodifiableList(results); + } + + public int size() { + return results.size(); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/result/WinningStatistics.java b/src/main/java/com/javabom/lotto/domain/result/WinningStatistics.java new file mode 100644 index 0000000..28e0aba --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/result/WinningStatistics.java @@ -0,0 +1,33 @@ +package com.javabom.lotto.domain.result; + +import com.javabom.lotto.domain.shop.LottoShop; + +public class WinningStatistics { + + private final LottoResult results; + + public WinningStatistics(LottoResult results) { + this.results = results; + } + + private long calculateRevenue() { + long revenue = 0; + for (LottoRank result : results.getResults()) { + revenue += result.getPrizeMoney(); + } + return revenue; + } + + public int calculateProfitRatio() { + long revenue = calculateRevenue(); + return (int) ((revenue / (double) calculateCostMoney()) * 100); + } + + private long calculateCostMoney() { + return results.size() * LottoShop.TICKET_PRICE.getValue(); + } + + public LottoResult getResults() { + return results; + } +} diff --git a/src/main/java/com/javabom/lotto/domain/shop/LottoNumbersGenerator.java b/src/main/java/com/javabom/lotto/domain/shop/LottoNumbersGenerator.java new file mode 100644 index 0000000..4ac8efa --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/shop/LottoNumbersGenerator.java @@ -0,0 +1,31 @@ +package com.javabom.lotto.domain.shop; + +import com.javabom.lotto.domain.ticket.LottoNumber; +import com.javabom.lotto.domain.ticket.LottoTicket; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class LottoNumbersGenerator { + + private final List lottoNum; + + public LottoNumbersGenerator() { + lottoNum = IntStream.rangeClosed(LottoNumber.NUMBER_BEGIN, LottoNumber.NUMBER_END) + .mapToObj(LottoNumber::new) + .collect(Collectors.toList()); + } + + public List generate() { + Collections.shuffle(lottoNum); + return new ArrayList(lottoNum.subList(0, LottoTicket.LOTTO_NUMBER_COUNT)) { + }; + } + + public static List convertToLottoNumbers(List numbers) { + return numbers.stream() + .map(LottoNumber::new) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/shop/LottoShop.java b/src/main/java/com/javabom/lotto/domain/shop/LottoShop.java new file mode 100644 index 0000000..c994f73 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/shop/LottoShop.java @@ -0,0 +1,57 @@ +package com.javabom.lotto.domain.shop; + +import com.javabom.lotto.domain.ticket.LottoNumber; +import com.javabom.lotto.domain.ticket.LottoTicket; +import com.javabom.lotto.domain.ticket.LottoTickets; +import com.javabom.lotto.domain.vo.Money; + +import java.util.ArrayList; +import java.util.List; + + +public class LottoShop { + + public final static Money TICKET_PRICE = new Money(1000); + private final LottoNumbersGenerator numberGenerator; + + public LottoShop(LottoNumbersGenerator generator) { + this.numberGenerator = generator; + } + + + public LottoTickets buyTicketsByAutomaticInLottoShop(Money money) { + List lottoTickets = new ArrayList<>(); + Money currentMoney = money; + + while (currentMoney.canSpendMoney(TICKET_PRICE)) { + lottoTickets.add(generateTicket()); + currentMoney = currentMoney.spendMoney(TICKET_PRICE); + } + + return new LottoTickets(lottoTickets); + } + + private LottoTicket generateTicket() { + return new LottoTicket(numberGenerator.generate()); + } + + public LottoTickets buyTicketsByManualInLottoShop(List> manualLottoNumbers) { + List manualTickets = new ArrayList<>(); + + for (List lottoNumber : manualLottoNumbers) { + manualTickets.add(giveLottoTicket(lottoNumber)); + } + + return new LottoTickets(manualTickets); + } + + private LottoTicket giveLottoTicket(List lottoNumbers) { + return new LottoTicket(lottoNumbers); + } + + public Money getRemainMoney(LottoTickets lottoTickets, Money money) { + int price = lottoTickets.size() * TICKET_PRICE.getValue(); + + return money.spendMoney(new Money(price)); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/ticket/LottoNumber.java b/src/main/java/com/javabom/lotto/domain/ticket/LottoNumber.java new file mode 100644 index 0000000..a62bdff --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoNumber.java @@ -0,0 +1,40 @@ +package com.javabom.lotto.domain.ticket; + +import java.util.Objects; + +public class LottoNumber { + + private final int number; + public final static int NUMBER_BEGIN = 1; + public final static int NUMBER_END = 45; + + + public LottoNumber(int number) { + this.number = number; + validLottoNumber(); + } + + public int getNumber() { + return this.number; + } + + private void validLottoNumber() { + if (number < NUMBER_BEGIN || number > NUMBER_END) { + throw new IllegalArgumentException(String.format("로또 번호가 아닙니다. - %s", number)); + } + + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + LottoNumber that = (LottoNumber) o; + return number == that.number; + } + + @Override + public int hashCode() { + return Objects.hash(number); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java new file mode 100644 index 0000000..171e4b0 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java @@ -0,0 +1,75 @@ +package com.javabom.lotto.domain.ticket; + +import com.javabom.lotto.domain.result.LottoRank; + +import java.util.*; + +public class LottoTicket { + + public static final int LOTTO_NUMBER_COUNT = 6; + + private final List lottoNumbers; + + public LottoTicket(List lottoNumbers) { + this.lottoNumbers = lottoNumbers; + validNumbers(this.lottoNumbers); + } + + public static void validNumbers(List lottoNumbers) { + validLottoNumberCount(lottoNumbers); + validDuplicatedNumber(lottoNumbers); + } + + private static void validDuplicatedNumber(List lottoNumbers) { + HashSet setNumbers = new HashSet<>(lottoNumbers); + if (setNumbers.size() < LOTTO_NUMBER_COUNT) { + throw new IllegalArgumentException("로또번호 중 중복된 번호가 존재합니다."); + } + } + + private static void validLottoNumberCount(List lottoNumbers) { + if (lottoNumbers.size() != LOTTO_NUMBER_COUNT) { + throw new IllegalArgumentException("입력된 로또 번호 수가 6개가 아닙니다."); + } + } + + public LottoRank findLottoRank(WinningTicket winningTicket) { + int sameCount = getSameCount(winningTicket); + boolean hasBonusNumber = winningTicket.isSameBonusNumber(getLastNumber()); + + return LottoRank.findLottoRank(sameCount, hasBonusNumber); + } + + private LottoNumber getLastNumber() { + return getLottoNumbers().get(lottoNumbers.size() - 1); + } + + private int getSameCount(WinningTicket winningTicket) { + int sameCount = 0; + List winningNumbers = winningTicket.getWinningNumbers(); + + for (int i = 0; i < lottoNumbers.size(); i++) { + boolean isSame = lottoNumbers.get(i).equals(winningNumbers.get(i)); + sameCount += (isSame ? 1 : 0); + } + + return sameCount; + } + + public List getLottoNumbers() { + return Collections.unmodifiableList(lottoNumbers); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + LottoTicket that = (LottoTicket) o; + return Objects.equals(getLottoNumbers(), that.getLottoNumbers()); + } + + @Override + public int hashCode() { + return Objects.hash(getLottoNumbers()); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/ticket/LottoTickets.java b/src/main/java/com/javabom/lotto/domain/ticket/LottoTickets.java new file mode 100644 index 0000000..c095e6f --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoTickets.java @@ -0,0 +1,38 @@ +package com.javabom.lotto.domain.ticket; + +import com.javabom.lotto.domain.result.LottoResult; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class LottoTickets { + + private final List tickets; + + public LottoTickets(List lottoTickets) { + tickets = lottoTickets; + } + + public LottoResult getLottoResult(WinningTicket winningTicket) { + return new LottoResult(tickets.stream() + .map(lottoTicket -> lottoTicket.findLottoRank(winningTicket)) + .collect(Collectors.toList())); + } + + public LottoTickets joinTickets(LottoTickets lottoTickets) { + List joinTickets = new ArrayList<>(); + joinTickets.addAll(this.tickets); + joinTickets.addAll(lottoTickets.getTickets()); + return new LottoTickets(joinTickets); + } + + public List getTickets() { + return Collections.unmodifiableList(tickets); + } + + public int size() { + return tickets.size(); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/ticket/WinningTicket.java b/src/main/java/com/javabom/lotto/domain/ticket/WinningTicket.java new file mode 100644 index 0000000..c38d837 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/ticket/WinningTicket.java @@ -0,0 +1,34 @@ +package com.javabom.lotto.domain.ticket; + +import java.util.List; + +public class WinningTicket { + + private final List winningNumbers; + + private final LottoNumber bonusNumber; + + public WinningTicket(List winningNumbers, LottoNumber bonusNumber) { + this.winningNumbers = winningNumbers; + this.bonusNumber = bonusNumber; + validDuplicatedNumbers(); + } + + private void validDuplicatedNumbers() { + if (winningNumbers.contains(bonusNumber)) { + throw new IllegalArgumentException("당첨번호에 보너스 번호가 중복된 번호가 존재합니다."); + } + } + + public boolean contains(final LottoNumber lottoNumber) { + return winningNumbers.contains(lottoNumber); + } + + public boolean isSameBonusNumber(LottoNumber lottoNumber) { + return bonusNumber.equals(lottoNumber); + } + + public List getWinningNumbers() { + return winningNumbers; + } +} diff --git a/src/main/java/com/javabom/lotto/domain/vo/Money.java b/src/main/java/com/javabom/lotto/domain/vo/Money.java new file mode 100644 index 0000000..3ec41e8 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/vo/Money.java @@ -0,0 +1,29 @@ +package com.javabom.lotto.domain.vo; + +public class Money { + + private final int value; + + public Money(int value) { + this.value = value; + } + + private void checkSpendMoney(Money money) { + if (this.getValue() < money.getValue()) { + throw new IllegalArgumentException("잔액이 부족합니다."); + } + } + + public Money spendMoney(Money price) { + checkSpendMoney(price); + return new Money(value - price.getValue()); + } + + public boolean canSpendMoney(Money price) { + return this.getValue() >= price.getValue(); + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/com/javabom/lotto/dto/InputDto.java b/src/main/java/com/javabom/lotto/dto/InputDto.java new file mode 100644 index 0000000..6053d0c --- /dev/null +++ b/src/main/java/com/javabom/lotto/dto/InputDto.java @@ -0,0 +1,90 @@ +package com.javabom.lotto.dto; + +import com.javabom.lotto.domain.shop.LottoNumbersGenerator; +import com.javabom.lotto.domain.shop.LottoShop; +import com.javabom.lotto.domain.ticket.LottoNumber; +import com.javabom.lotto.domain.ticket.LottoTicket; +import com.javabom.lotto.domain.vo.Money; + +import java.util.List; +import java.util.stream.Collectors; + +public class InputDto { + + private Money money; + + private int manualCount; + + private List> manualNumbers; + + public InputDto(String money, String manualCount) { + validInputValue(money, manualCount); + this.money = new Money(Integer.parseInt(money)); + this.manualCount = Integer.parseInt(manualCount); + validMoney(); + } + + private void validMoney() { + int ticketPrice = manualCount * LottoShop.TICKET_PRICE.getValue(); + int inputMoney = money.getValue(); + if (ticketPrice > inputMoney || !money.canSpendMoney(LottoShop.TICKET_PRICE)) { + throw new IllegalArgumentException( + String.format("로또를 구매할 금액이 부족합니다. - Money : %d, Ticket Price : %d", inputMoney, ticketPrice)); + } + } + + private void validInputValue(String money, String manualCount) { + validNumberFormat(money); + validNegativeNumber(money); + validNumberFormat(manualCount); + validNegativeNumber(manualCount); + } + + private void validNegativeNumber(String number) { + if (Integer.parseInt(number) < 0) { + throw new IllegalArgumentException(String.format("양수 값을 입력 해주세요. - %s", number)); + } + } + + public void setManualNumbers(List> manualNumbers) { + this.manualNumbers = convertLottoNumbers(manualNumbers); + } + + private List> convertLottoNumbers(List> manualNumbers) { + return manualNumbers.stream() + .map(this::parseIntNumbers) + .map(LottoNumbersGenerator::convertToLottoNumbers) + .peek(LottoTicket::validNumbers) + .collect(Collectors.toList()); + } + + private List parseIntNumbers(List numbers) { + return numbers.stream() + .map(number -> { + validNumberFormat(number); + return Integer.parseInt(number); + }) + .collect(Collectors.toList()); + } + + private void validNumberFormat(String number) { + try { + Integer.parseInt(number); + } catch (NumberFormatException e) { + throw new NumberFormatException(String.format("숫자 값을 입력해주세요. - %s", number)); + } + } + + + public List> getManualNumbers() { + return manualNumbers; + } + + public int getManualCount() { + return manualCount; + } + + public Money getMoney() { + return money; + } +} diff --git a/src/main/java/com/javabom/lotto/dto/WinningNumbersDto.java b/src/main/java/com/javabom/lotto/dto/WinningNumbersDto.java new file mode 100644 index 0000000..7ff6238 --- /dev/null +++ b/src/main/java/com/javabom/lotto/dto/WinningNumbersDto.java @@ -0,0 +1,47 @@ +package com.javabom.lotto.dto; + +import com.javabom.lotto.domain.shop.LottoNumbersGenerator; +import com.javabom.lotto.domain.ticket.LottoNumber; +import com.javabom.lotto.domain.ticket.LottoTicket; + +import java.util.List; +import java.util.stream.Collectors; + +public class WinningNumbersDto { + + private final List winningNumbers; + + private final LottoNumber bonusNumber; + + public WinningNumbersDto(List numbers, String bonusNumber) { + validNumberFormat(bonusNumber); + this.bonusNumber = new LottoNumber(Integer.parseInt(bonusNumber)); + this.winningNumbers = LottoNumbersGenerator.convertToLottoNumbers(parseIntNumbers(numbers)); + LottoTicket.validNumbers(this.winningNumbers); + } + + private List parseIntNumbers(List numbers) { + return numbers.stream() + .map(number -> { + validNumberFormat(number); + return Integer.parseInt(number); + }) + .collect(Collectors.toList()); + } + + private void validNumberFormat(String number) { + try { + Integer.parseInt(number); + } catch (NumberFormatException e) { + throw new NumberFormatException(String.format("정수가 아닌 값이 입력 되었습니다. - %s", number)); + } + } + + public List getWinningNumbers() { + return winningNumbers; + } + + public LottoNumber getBonusNumber() { + return bonusNumber; + } +} diff --git a/src/main/java/com/javabom/lotto/dto/WinningStatisticsDto.java b/src/main/java/com/javabom/lotto/dto/WinningStatisticsDto.java new file mode 100644 index 0000000..2f76264 --- /dev/null +++ b/src/main/java/com/javabom/lotto/dto/WinningStatisticsDto.java @@ -0,0 +1,34 @@ +package com.javabom.lotto.dto; + +import com.javabom.lotto.domain.result.LottoRank; +import com.javabom.lotto.domain.result.LottoResult; +import com.javabom.lotto.domain.result.WinningStatistics; + +import java.util.LinkedHashMap; +import java.util.Map; + + +public class WinningStatisticsDto { + + private final LottoResult results; + + private final int profitRatio; + + public WinningStatisticsDto(WinningStatistics winningStatistics) { + this.results = winningStatistics.getResults(); + this.profitRatio = winningStatistics.calculateProfitRatio(); + } + + public Map getEachLottoRankCount() { + Map lottoRankMap = new LinkedHashMap<>(); + for (LottoRank lottoRank : LottoRank.values()) { + lottoRankMap.put(lottoRank, results.getRankCount(lottoRank)); + } + lottoRankMap.remove(LottoRank.FAIL); + return lottoRankMap; + } + + public int getProfitRatio() { + return profitRatio; + } +} diff --git a/src/main/java/com/javabom/lotto/view/InputView.java b/src/main/java/com/javabom/lotto/view/InputView.java new file mode 100644 index 0000000..96c6157 --- /dev/null +++ b/src/main/java/com/javabom/lotto/view/InputView.java @@ -0,0 +1,59 @@ +package com.javabom.lotto.view; + +import com.javabom.lotto.dto.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private static final Scanner SCANNER = new Scanner(System.in); + + public static final String DELIMITER = ","; + + public static InputDto askInputMoneyAndManual() { + InputDto inputDto = new InputDto(getMoney(), getManualCount()); + inputDto.setManualNumbers(getManualLottoNumbers(inputDto.getManualCount())); + + return inputDto; + } + + public static List> getManualLottoNumbers(int count) { + System.out.println(); + System.out.println("수동으로 구매할 번호를 입력해 주세요."); + List> lottoNumbers = new ArrayList<>(); + + for (int i = 0; i < count; i++) { + lottoNumbers.add(Arrays.asList(SCANNER.nextLine().split(DELIMITER))); + } + + return lottoNumbers; + } + + private static String getManualCount() { + System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); + return SCANNER.nextLine(); + } + + private static String getMoney() { + System.out.println("투입금액을 입력해 주세요."); + return SCANNER.nextLine(); + } + + public static WinningNumbersDto askWinningNumbers() { + System.out.println("\n지난 주 당첨 번호를 입력해 주세요."); + return new WinningNumbersDto(getWinningNumbers(), getBonusNumber()); + } + + private static List getWinningNumbers() { + return Arrays.asList(SCANNER.nextLine().split(DELIMITER)); + } + + private static String getBonusNumber() { + System.out.println("보너스 볼을 입력해 주세요."); + return SCANNER.nextLine(); + } + +} diff --git a/src/main/java/com/javabom/lotto/view/OutputView.java b/src/main/java/com/javabom/lotto/view/OutputView.java new file mode 100644 index 0000000..616388d --- /dev/null +++ b/src/main/java/com/javabom/lotto/view/OutputView.java @@ -0,0 +1,53 @@ +package com.javabom.lotto.view; + +import com.javabom.lotto.dto.WinningStatisticsDto; +import com.javabom.lotto.domain.result.LottoRank; +import com.javabom.lotto.domain.ticket.*; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class OutputView { + + public static void printLotteryTickets(LottoTickets automaticTickets, LottoTickets manualTickets) { + System.out.println(); + System.out.println(manualTickets.size() + "장, 자동으로 " + automaticTickets.size() + "개를 구매했습니다."); + + for (LottoTicket ticket : manualTickets.getTickets()) { + printLottoNumber(ticket); + } + + for (LottoTicket number : automaticTickets.getTickets()) { + printLottoNumber(number); + } + } + + public static void printLottoNumber(LottoTicket lottoTicket) { + List numbers = lottoTicket.getLottoNumbers().stream() + .map(LottoNumber::getNumber) + .map(Object::toString) + .collect(Collectors.toList()); + System.out.println("[" + String.join(", ", numbers) + "]"); + } + + public static void printWinningStatistics(WinningStatisticsDto winningStatisticsDto) { + System.out.println("\n당첨 통계"); + System.out.println("----------"); + printWinningNumberCount(winningStatisticsDto); + printProfitRatio(winningStatisticsDto.getProfitRatio()); + } + + private static void printProfitRatio(int profitRatio) { + System.out.printf("총 수익률은 %d%%입니다.\n", profitRatio); + } + + private static void printWinningNumberCount(WinningStatisticsDto winningStatisticsDto) { + Map eachLottoRankCount = winningStatisticsDto.getEachLottoRankCount(); + System.out.println("3개 일치(" + LottoRank.FIFTH_PLACE.getPrizeMoney() + "원) - " + eachLottoRankCount.get(LottoRank.FIFTH_PLACE) + "개"); + System.out.println("4개 일치(" + LottoRank.FOURTH_PLACE.getPrizeMoney() + "원) - " + eachLottoRankCount.get(LottoRank.FOURTH_PLACE) + "개"); + System.out.println("5개 일치(" + LottoRank.THIRD_PLACE.getPrizeMoney() + "원) - " + eachLottoRankCount.get(LottoRank.THIRD_PLACE) + "개"); + System.out.println("5개 일치, 보너스 볼 일치(" + LottoRank.SECOND_PLACE.getPrizeMoney() + "원) - " + eachLottoRankCount.get(LottoRank.SECOND_PLACE) + "개"); + System.out.println("6개 일치(" + LottoRank.FIRST_PLACE.getPrizeMoney() + "원) - " + eachLottoRankCount.get(LottoRank.FIRST_PLACE) + "개"); + } +} diff --git a/src/test/java/com/javabom/lotto/domain/result/LottoResultTest.java b/src/test/java/com/javabom/lotto/domain/result/LottoResultTest.java new file mode 100644 index 0000000..78e73da --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/result/LottoResultTest.java @@ -0,0 +1,31 @@ +package com.javabom.lotto.domain.result; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class LottoResultTest { + + @Test + void getRankCountTest() { + List ranks = new ArrayList<>(); + ranks.add(LottoRank.FIFTH_PLACE); + ranks.add(LottoRank.FIFTH_PLACE); + LottoResult result = new LottoResult(ranks); + + assertEquals(2, result.getRankCount(LottoRank.FIFTH_PLACE)); + } + + @Test + void getResultsTest() { + List ranks = new ArrayList<>(); + ranks.add(LottoRank.FIFTH_PLACE); + ranks.add(LottoRank.FIFTH_PLACE); + LottoResult result = new LottoResult(ranks); + + assertEquals(2, result.getResults().size()); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/shop/LottoNumberShufflerTest.java b/src/test/java/com/javabom/lotto/domain/shop/LottoNumberShufflerTest.java new file mode 100644 index 0000000..7428131 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/shop/LottoNumberShufflerTest.java @@ -0,0 +1,56 @@ +package com.javabom.lotto.domain.shop; + +import com.javabom.lotto.domain.ticket.LottoNumber; +import com.javabom.lotto.domain.ticket.LottoTicket; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class LottoNumberShufflerTest { + + @Test + @DisplayName("자동으로 로또 번호 6개를 생성하는지 확인.") + void generateNumberCountTest() { + LottoNumbersGenerator shuffler = new LottoNumbersGenerator(); + + assertEquals(LottoTicket.LOTTO_NUMBER_COUNT, shuffler.generate().size()); + } + + @Test + @DisplayName("설정된 로또 번호 범위에 맞게 생성하는지 확인.") + void generateTest() { + LottoNumbersGenerator shuffler = new LottoNumbersGenerator(); + List generate = shuffler.generate(); + int maxNumber = generate.stream() + .max(Comparator.comparing(LottoNumber::getNumber)) + .get() + .getNumber(); + + int minNumber = generate.stream() + .min(Comparator.comparing(LottoNumber::getNumber)) + .get() + .getNumber(); + + assertTrue(maxNumber <= LottoNumber.NUMBER_END); + assertTrue(minNumber >= LottoNumber.NUMBER_BEGIN); + } + + @Test + @DisplayName("입력된 숫자값을 로또번호로 변환하는지 확인.") + public void convertLottoNumberTest() { + List lottoNumbers = Stream.of(1, 2, 3, 4, 5, 6) + .map(LottoNumber::new) + .collect(Collectors.toList()); + + List convertToLottoNumbers = LottoNumbersGenerator.convertToLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 6)); + assertEquals(lottoNumbers, convertToLottoNumbers); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/shop/LottoShopTest.java b/src/test/java/com/javabom/lotto/domain/shop/LottoShopTest.java new file mode 100644 index 0000000..a024a9d --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/shop/LottoShopTest.java @@ -0,0 +1,75 @@ +package com.javabom.lotto.domain.shop; + +import com.javabom.lotto.domain.ticket.LottoNumber; +import com.javabom.lotto.domain.ticket.LottoTicket; +import com.javabom.lotto.domain.ticket.LottoTickets; +import com.javabom.lotto.domain.vo.Money; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +class LottoShopTest { + + @Test + @DisplayName("입력한 금액만큼 로또 티켓을 반환하는지 확인.") + void buyTicketsByAutomaticInLottoShop() { + Money money = new Money(5000); + LottoShop lottoShop = new LottoShop(new LottoNumbersGenerator()); + + LottoTickets lottoTickets = lottoShop.buyTicketsByAutomaticInLottoShop(money); + + assertEquals(5, lottoTickets.size()); + } + + @Test + @DisplayName("입력한 로또 수동번호 만큼 로또 티켓을 반환하는지 확인.") + void buyTicketsByManualInLottoShop() { + List> manualNumbers = createLottoNumbers(); + LottoShop lottoShop = new LottoShop(new LottoNumbersGenerator()); + + LottoTickets lottoTickets = lottoShop.buyTicketsByManualInLottoShop(manualNumbers); + + assertEquals(2, lottoTickets.size()); + } + + private List> createLottoNumbers() { + List> lottoNumbers = new ArrayList<>(); + List numbers1 = Stream.of(1, 2, 3, 4, 5, 6) + .map(LottoNumber::new) + .collect(Collectors.toList()); + List numbers2 = Stream.of(7, 8, 9, 10, 11, 12) + .map(LottoNumber::new) + .collect(Collectors.toList()); + + lottoNumbers.add(numbers1); + lottoNumbers.add(numbers2); + return lottoNumbers; + } + + @Test + @DisplayName("입력한 금액에서 구매한 티켓 금액만큼 차감 후 잔액을 반환하는지 확인.") + void getRemainMoney() { + LottoShop lottoShop = new LottoShop(new LottoNumbersGenerator()); + LottoTickets lottoTickets = getLottoTickets(); + Money money = new Money(5000); + Money remainMoney = lottoShop.getRemainMoney(lottoTickets, money); + assertEquals(3000, remainMoney.getValue()); + } + + private LottoTickets getLottoTickets() { + List> lottoNumbers = createLottoNumbers(); + List lottoTickets = new ArrayList<>(); + LottoTicket lottoTicket1 = new LottoTicket(lottoNumbers.get(0)); + LottoTicket lottoTicket2 = new LottoTicket(lottoNumbers.get(1)); + lottoTickets.add(lottoTicket1); + lottoTickets.add(lottoTicket2); + + return new LottoTickets(lottoTickets); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/ticket/LottoNumberTest.java b/src/test/java/com/javabom/lotto/domain/ticket/LottoNumberTest.java new file mode 100644 index 0000000..60c4574 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/ticket/LottoNumberTest.java @@ -0,0 +1,18 @@ +package com.javabom.lotto.domain.ticket; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class LottoNumberTest { + + @ParameterizedTest + @ValueSource(ints = {0, 46}) + public void 로또번호가_아닌값_입력시_예외처리(int number) { + // given + assertThatThrownBy(() -> new LottoNumber(number)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(String.format("로또 번호가 아닙니다. - %d", number)); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java new file mode 100644 index 0000000..85014c4 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java @@ -0,0 +1,73 @@ +package com.javabom.lotto.domain.ticket; + +import com.javabom.lotto.domain.result.LottoRank; +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.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class LottoTicketTest { + + @Test + @DisplayName("요구사항에 맞게 당첨 결과를 반환하는지 확인.(당첨로또의 번호 순서와 발급받은 티켓의 번호순서까지 완벽하게 일치할때 1개 일치)") + void findLottoRankTest() { + WinningTicket winningTicket = createWinningNumbers(); + + List lottoNumbers1 = Stream.of(1, 2, 3, 4, 5, 6) + .map(LottoNumber::new) + .collect(Collectors.toList()); + + List lottoNumbers2 = Stream.of(1, 2, 3, 4, 6, 5) + .map(LottoNumber::new) + .collect(Collectors.toList()); + + LottoTicket lottoTicket1 = new LottoTicket(lottoNumbers1); + LottoTicket lottoTicket2 = new LottoTicket(lottoNumbers2); + + assertEquals(LottoRank.FIRST_PLACE, lottoTicket1.findLottoRank(winningTicket)); + assertEquals(LottoRank.FOURTH_PLACE, lottoTicket2.findLottoRank(winningTicket)); + } + + @ParameterizedTest + @DisplayName("입력되는 로또번호가 6개가 아닐시 예외처리.") + @ValueSource(strings = {"1,2,3,4,5", "1,2,3,4,5,6,7"}) + void validLottoCountTest(String numbers) { + List lottoNumbers = Arrays.stream(numbers.split(",")) + .map(Integer::parseInt) + .map(LottoNumber::new) + .collect(Collectors.toList()); + + assertThatThrownBy(() -> new LottoTicket(lottoNumbers)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("입력된 로또 번호 수가 6개가 아닙니다."); + } + + @Test + @DisplayName("입력되는 로또번호가 6개가 아닐시 예외처리.") + void validDuplicatedTest() { + List lottoNumbers = Arrays.stream("1,2,3,4,5,5".split(",")) + .map(Integer::parseInt) + .map(LottoNumber::new) + .collect(Collectors.toList()); + + assertThatThrownBy(() -> new LottoTicket(lottoNumbers)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("로또번호 중 중복된 번호가 존재합니다."); + } + + private WinningTicket createWinningNumbers() { + List winningNumbers = Stream.of(1, 2, 3, 4, 5, 6) + .map(LottoNumber::new) + .collect(Collectors.toList()); + LottoNumber bonusNumber = new LottoNumber(7); + return new WinningTicket(winningNumbers, bonusNumber); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketsTest.java b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketsTest.java new file mode 100644 index 0000000..b82176f --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketsTest.java @@ -0,0 +1,71 @@ +package com.javabom.lotto.domain.ticket; + +import com.javabom.lotto.domain.result.LottoRank; +import com.javabom.lotto.domain.result.LottoResult; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class LottoTicketsTest { + + @Test + @DisplayName("로또 당첨 결과 반환 테스트.") + void getLottoResult() { + LottoTickets lottoTickets = createLottoTickets(); + List lottoNumbers = Stream.of(1, 2, 3, 4, 5, 6) + .map(LottoNumber::new) + .collect(Collectors.toList()); + LottoNumber bonusNumber = new LottoNumber(7); + + WinningTicket winningTicket = new WinningTicket(lottoNumbers, bonusNumber); + LottoResult lottoResult = lottoTickets.getLottoResult(winningTicket); + List lottoRanks = new ArrayList<>(); + lottoRanks.add(LottoRank.FIRST_PLACE); + lottoRanks.add(LottoRank.SECOND_PLACE); + + assertEquals(lottoRanks, lottoResult.getResults()); + } + + LottoTickets createLottoTickets() { + List lottoTickets = new ArrayList<>(); + List lottoNumbers1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6)) + .stream() + .map(LottoNumber::new) + .collect(Collectors.toList()); + LottoTicket lottoTicket1 = new LottoTicket(lottoNumbers1); + + List lottoNumbers2 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 7)) + .stream() + .map(LottoNumber::new) + .collect(Collectors.toList()); + + LottoTicket lottoTicket2 = new LottoTicket(lottoNumbers2); + lottoTickets.add(lottoTicket1); + lottoTickets.add(lottoTicket2); + return new LottoTickets(lottoTickets); + } + + @Test + void sizeTest() { + LottoTickets lottoTickets = createLottoTickets(); + assertEquals(2, lottoTickets.size()); + } + + @Test + @DisplayName("매개변수로 받은 티켓을 합쳐 반환하는지 확인.") + public void joinTicketsTest() { + LottoTickets lottoTickets1 = createLottoTickets(); + LottoTickets lottoTickets2 = createLottoTickets(); + LottoTickets joinTickets = lottoTickets1.joinTickets(lottoTickets2); + + assertEquals(4, joinTickets.size()); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/ticket/WinningTicketTest.java b/src/test/java/com/javabom/lotto/domain/ticket/WinningTicketTest.java new file mode 100644 index 0000000..0b0ef33 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/ticket/WinningTicketTest.java @@ -0,0 +1,49 @@ +package com.javabom.lotto.domain.ticket; + +import com.javabom.lotto.dto.WinningNumbersDto; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class WinningTicketTest { + + @Test + @DisplayName("당첨번호에 보너스 번호 중복된 번호가 존재시 예외처리.") + void validDuplicatedTest() { + List winningNumbers = Stream.of(1, 2, 3, 4, 5, 6) + .map(LottoNumber::new) + .collect(Collectors.toList()); + LottoNumber bonusNumber = new LottoNumber(5); + assertThatThrownBy(() -> new WinningTicket(winningNumbers, bonusNumber)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("당첨번호에 보너스 번호가 중복된 번호가 존재합니다."); + } + + @Test + void containsTest() { + List winningNumbers = Stream.of(1, 2, 3, 4, 5, 6) + .map(LottoNumber::new) + .collect(Collectors.toList()); + LottoNumber bonusNumber = new LottoNumber(7); + WinningTicket winningTicket = new WinningTicket(winningNumbers, bonusNumber); + LottoNumber lottoNumber = new LottoNumber(5); + assertTrue(winningTicket.contains(lottoNumber)); + } + + @Test + void isSameBonusNumber() { + List winningNumbers = Stream.of(1, 2, 3, 4, 5, 6) + .map(LottoNumber::new) + .collect(Collectors.toList()); + LottoNumber bonusNumber = new LottoNumber(7); + WinningTicket winningTicket = new WinningTicket(winningNumbers, bonusNumber); + LottoNumber lottoNumber = new LottoNumber(7); + assertTrue(winningTicket.isSameBonusNumber(lottoNumber)); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/vo/MoneyTest.java b/src/test/java/com/javabom/lotto/domain/vo/MoneyTest.java new file mode 100644 index 0000000..a4626c3 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/vo/MoneyTest.java @@ -0,0 +1,37 @@ +package com.javabom.lotto.domain.vo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.InstanceOfAssertFactories.atomicReferenceArray; +import static org.junit.jupiter.api.Assertions.*; + +class MoneyTest { + + @Test + @DisplayName("보유한 금액보다 많은 소비를 할 시 예외") + public void validRemainMoney() { + Money money = new Money(500); + assertThatThrownBy(() -> money.spendMoney(new Money(10000))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("잔액이 부족합니다."); + } + + @Test + @DisplayName("구입한 가격만큼 소비했는지 확인.") + void spendMoneyTest() { + Money money = new Money(5000); + Money remainMoney = money.spendMoney(new Money(3000)); + assertEquals(new Money(2000).getValue(), remainMoney.getValue()); + } + + @Test + @DisplayName("잔액에 맞게 구매 가능여부 확인.") + void canSpendMoney() { + Money money = new Money(5000); + + assertTrue(money.canSpendMoney(new Money(3000))); + assertFalse(money.canSpendMoney(new Money(10000))); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/dto/InputDtoTest.java b/src/test/java/com/javabom/lotto/dto/InputDtoTest.java new file mode 100644 index 0000000..4550d03 --- /dev/null +++ b/src/test/java/com/javabom/lotto/dto/InputDtoTest.java @@ -0,0 +1,92 @@ +package com.javabom.lotto.dto; + +import com.javabom.lotto.domain.ticket.LottoNumber; +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.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class InputDtoTest { + + @Test + @DisplayName("입력한 금액이 수동으로 구매할 금액보다 적으면 예외처리.") + public void validMoneyTest() { + assertThatThrownBy(() -> new InputDto("1000", "2")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("로또를 구매할 금액이 부족합니다. - Money : 1000, Ticket Price : 2000"); + + } + + @Test + @DisplayName("음수 값이 들어올 경우 예외처리.") + public void validNegativeValueTest() { + // given + assertThatThrownBy(() -> new InputDto("1000", "-1")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("양수 값을 입력 해주세요. - -1"); + } + + @Test + @DisplayName("정수 값이 아닌 값이 들어올 경우 예외처리.") + public void validNumberFormatTest() { + // given + assertThatThrownBy(() -> new InputDto("1000", "a")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("숫자 값을 입력해주세요. - a"); + } + + @Test + @DisplayName("입력받은 수동 로또 번호 중 중복된 번호가 있으면 예외처리.") + void validManualNumbers() { + InputDto inputDto = new InputDto("1000", "1"); + List> manualNumbers = new ArrayList<>(); + List manualNumber = Arrays.asList("1", "2", "3", "5", "5", "6"); + manualNumbers.add(manualNumber); + + assertThatThrownBy(() -> inputDto.setManualNumbers(manualNumbers)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("로또번호 중 중복된 번호가 존재합니다."); + } + + @DisplayName("입력받은 수동 로또 번호가 6개가 아니면 예외처리.") + @ParameterizedTest + @ValueSource(strings = {"1,2,3,4,5", "1,2,3,4,5,6,7"}) + void validManualNumbersCount(String inputManuals) { + InputDto inputDto = new InputDto("1000", "1"); + List> manualNumbers = new ArrayList<>(); + + List manualNumber = Arrays.asList(inputManuals.split(",")); + manualNumbers.add(manualNumber); + + assertThatThrownBy(() -> inputDto.setManualNumbers(manualNumbers)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("입력된 로또 번호 수가 6개가 아닙니다."); + } + + @DisplayName("입력받은 수동번호의 문자열 값을 로또번호 객체로 변환하는지 확인.") + @Test + public void convertLottoNumberTest() { + InputDto inputDto = new InputDto("1000", "1"); + List> manualNumbers = new ArrayList<>(); + List manualNumber = Arrays.asList("1", "2", "3", "4", "5", "6"); + manualNumbers.add(manualNumber); + + inputDto.setManualNumbers(manualNumbers); + List convertNumbers = manualNumber + .stream() + .map(Integer::parseInt) + .map(LottoNumber::new) + .collect(Collectors.toList()); + + assertEquals(convertNumbers, inputDto.getManualNumbers().get(0)); + } + +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/dto/WinningNumbersDtoTest.java b/src/test/java/com/javabom/lotto/dto/WinningNumbersDtoTest.java new file mode 100644 index 0000000..cb08ab7 --- /dev/null +++ b/src/test/java/com/javabom/lotto/dto/WinningNumbersDtoTest.java @@ -0,0 +1,48 @@ +package com.javabom.lotto.dto; + +import com.javabom.lotto.domain.ticket.LottoNumber; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class WinningNumbersDtoTest { + + @DisplayName("입력받은 당첨번호 문자열 값을 로또번호 객체로 변환하는지 확인.") + @Test + public void convertLottoNumberTest() { + List winningNumbers = Arrays.asList("1", "2", "3", "4", "5", "6"); + WinningNumbersDto winningNumbersDto = new WinningNumbersDto(winningNumbers, "3"); + + List lottoNumbers = winningNumbers.stream() + .map(Integer::parseInt) + .map(LottoNumber::new) + .collect(Collectors.toList()); + + assertEquals(lottoNumbers, winningNumbersDto.getWinningNumbers()); + } + + @DisplayName("입력받은 당첨번호 값에 정수가 아닌 값이 들어간 경우 예외 처리.") + @Test + public void validWinningNumberTest() { + List winningNumbers = Arrays.asList("1", "2", "a", "4", "5", "6"); + assertThatThrownBy(() -> new WinningNumbersDto(winningNumbers, "3")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("정수가 아닌 값이 입력 되었습니다. - a"); + } + + @DisplayName("입력받은 당첨번호 값에 로또 번호 범위가 아닌 값(1~45)이 들어간 경우 예외 처리.") + @Test + public void validWinningNumberRangeTest() { + List winningNumbers = Arrays.asList("1", "2", "3", "4", "5", "46"); + assertThatThrownBy(() -> new WinningNumbersDto(winningNumbers, "3")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("로또 번호가 아닙니다. - 46"); + } + +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/dto/WinningStatisticsDtoTest.java b/src/test/java/com/javabom/lotto/dto/WinningStatisticsDtoTest.java new file mode 100644 index 0000000..c4af5fd --- /dev/null +++ b/src/test/java/com/javabom/lotto/dto/WinningStatisticsDtoTest.java @@ -0,0 +1,39 @@ +package com.javabom.lotto.dto; + +import com.javabom.lotto.domain.result.LottoRank; +import com.javabom.lotto.domain.result.LottoResult; +import com.javabom.lotto.domain.result.WinningStatistics; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class WinningStatisticsDtoTest { + + @Test + void getEachLottoRankCountTest() { + List ranks = new ArrayList<>(); + ranks.add(LottoRank.FIFTH_PLACE); + WinningStatistics winningStatistics = new WinningStatistics(new LottoResult(ranks)); + WinningStatisticsDto winningStatisticsDto = new WinningStatisticsDto(winningStatistics); + + Map eachLottoRankCount = winningStatisticsDto.getEachLottoRankCount(); + assertEquals(1, eachLottoRankCount.get(LottoRank.FIFTH_PLACE)); + } + + @Test + void getProfitRatioTest() { + List ranks = new ArrayList<>(); + ranks.add(LottoRank.FIFTH_PLACE); + + WinningStatistics winningStatistics = new WinningStatistics(new LottoResult(ranks)); + WinningStatisticsDto winningStatisticsDto = new WinningStatisticsDto(winningStatistics); + int profitRatio = winningStatisticsDto.getProfitRatio(); + + assertEquals(500, profitRatio); + + } +} \ No newline at end of file