From a06a583d7b6e535f53959653864ffd5e2284f9c4 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Tue, 26 May 2020 19:37:10 +0900 Subject: [PATCH 01/13] =?UTF-8?q?=EB=A1=9C=EB=98=90(=EC=9E=90=EB=8F=99)=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/javabom/lotto/LottoApplication.java | 24 ++++++ .../javabom/lotto/domain/DrawingMachine.java | 53 ++++++++++++ .../javabom/lotto/domain/LottoMachine.java | 24 ++++++ .../com/javabom/lotto/domain/LottoResult.java | 49 +++++++++++ .../com/javabom/lotto/domain/LottoTicket.java | 44 ++++++++++ .../javabom/lotto/domain/WinningSheet.java | 38 +++++++++ .../lotto/domain/number/LottoNumber.java | 43 ++++++++++ .../domain/number/LottoNumberGenerator.java | 38 +++++++++ .../javabom/lotto/domain/vo/LottoMoney.java | 27 ++++++ .../com/javabom/lotto/view/InputView.java | 37 ++++++++ .../com/javabom/lotto/view/OutputView.java | 62 ++++++++++++++ .../lotto/domain/DrawingMachineTest.java | 85 +++++++++++++++++++ .../lotto/domain/LottoMachineTest.java | 23 +++++ .../javabom/lotto/domain/LottoResultTest.java | 43 ++++++++++ .../javabom/lotto/domain/LottoTicketTest.java | 65 ++++++++++++++ .../lotto/domain/WinningSheetTest.java | 28 ++++++ .../number/LottoNumberGeneratorTest.java | 41 +++++++++ .../lotto/domain/number/LottoNumberTest.java | 19 +++++ src/test/java/com/javabom/lotto/empty.txt | 0 19 files changed, 743 insertions(+) create mode 100644 src/main/java/com/javabom/lotto/domain/DrawingMachine.java create mode 100644 src/main/java/com/javabom/lotto/domain/LottoMachine.java create mode 100644 src/main/java/com/javabom/lotto/domain/LottoResult.java create mode 100644 src/main/java/com/javabom/lotto/domain/LottoTicket.java create mode 100644 src/main/java/com/javabom/lotto/domain/WinningSheet.java create mode 100644 src/main/java/com/javabom/lotto/domain/number/LottoNumber.java create mode 100644 src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java create mode 100644 src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java create mode 100644 src/main/java/com/javabom/lotto/view/InputView.java create mode 100644 src/main/java/com/javabom/lotto/view/OutputView.java create mode 100644 src/test/java/com/javabom/lotto/domain/DrawingMachineTest.java create mode 100644 src/test/java/com/javabom/lotto/domain/LottoMachineTest.java create mode 100644 src/test/java/com/javabom/lotto/domain/LottoResultTest.java create mode 100644 src/test/java/com/javabom/lotto/domain/LottoTicketTest.java create mode 100644 src/test/java/com/javabom/lotto/domain/WinningSheetTest.java create mode 100644 src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java create mode 100644 src/test/java/com/javabom/lotto/domain/number/LottoNumberTest.java delete mode 100644 src/test/java/com/javabom/lotto/empty.txt diff --git a/src/main/java/com/javabom/lotto/LottoApplication.java b/src/main/java/com/javabom/lotto/LottoApplication.java index 13f852e..38a9142 100644 --- a/src/main/java/com/javabom/lotto/LottoApplication.java +++ b/src/main/java/com/javabom/lotto/LottoApplication.java @@ -1,7 +1,31 @@ package com.javabom.lotto; +import com.javabom.lotto.domain.DrawingMachine; +import com.javabom.lotto.domain.LottoMachine; +import com.javabom.lotto.domain.LottoResult; +import com.javabom.lotto.domain.LottoTicket; +import com.javabom.lotto.domain.vo.LottoMoney; +import com.javabom.lotto.view.InputView; +import com.javabom.lotto.view.OutputView; + +import java.util.List; + public class LottoApplication { public static void main(String[] args) { + LottoMoney lottoMoney = InputView.inputPurchaseAmount(); + + OutputView.printNumberOfTicket(lottoMoney); + + List lottoTickets = LottoMachine.purchaseLottoTicket(lottoMoney); + + OutputView.printLottoTickets(lottoTickets); + + List winningNumbers = InputView.inputLastWinningNumbers(); + + DrawingMachine drawingMachine = new DrawingMachine(winningNumbers); + + LottoResult lottoResult = new LottoResult(lottoMoney, drawingMachine.drawAllLottoTicket(lottoTickets)); + OutputView.printWinningStatistics(lottoResult); } } diff --git a/src/main/java/com/javabom/lotto/domain/DrawingMachine.java b/src/main/java/com/javabom/lotto/domain/DrawingMachine.java new file mode 100644 index 0000000..d053f9d --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/DrawingMachine.java @@ -0,0 +1,53 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.number.LottoNumber; +import com.javabom.lotto.domain.number.LottoNumberGenerator; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class DrawingMachine { + private static final int WINNING_NUMBER_SIZE = 6; + + private final List winningNumbers; + + public DrawingMachine(List winningNumbers) { + validateWinningNumbersSize(winningNumbers); + validateDuplicateWinningNumbers(winningNumbers); + this.winningNumbers = mapLottoNumbersByNumbers(winningNumbers); + } + + private List mapLottoNumbersByNumbers(List winningNumbers) { + return winningNumbers.stream() + .map(LottoNumberGenerator::findByNumber) + .collect(Collectors.toList()); + } + + private void validateWinningNumbersSize(List winningNumbers) { + if (winningNumbers.size() != WINNING_NUMBER_SIZE) { + throw new IllegalArgumentException("당첨 번호의 개수가 6이 아닙니다."); + } + } + + private void validateDuplicateWinningNumbers(List winningNumbers) { + Set nonDuplicateNumbers = new HashSet<>(winningNumbers); + + if (nonDuplicateNumbers.size() != WINNING_NUMBER_SIZE) { + throw new IllegalArgumentException("당첨 번호는 중복될 수 없습니다."); + } + } + + public List drawAllLottoTicket(List lottoTickets) { + return lottoTickets.stream() + .map(this::drawLottoTicket) + .collect(Collectors.toList()); + } + + public int drawLottoTicket(LottoTicket lottoTicket) { + return (int) winningNumbers.stream() + .filter(lottoTicket::isContainingLottoNumbers) + .count(); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/LottoMachine.java b/src/main/java/com/javabom/lotto/domain/LottoMachine.java new file mode 100644 index 0000000..0081c04 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/LottoMachine.java @@ -0,0 +1,24 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.number.LottoNumber; +import com.javabom.lotto.domain.number.LottoNumberGenerator; +import com.javabom.lotto.domain.vo.LottoMoney; + +import java.util.ArrayList; +import java.util.List; + +public class LottoMachine { + private LottoMachine() { + } + + public static List purchaseLottoTicket(LottoMoney lottoMoney) { + List lottoTickets = new ArrayList<>(); + + for (int i = 0; i < lottoMoney.getNumberOfTicket(); i++) { + List lottoNumbers = LottoNumberGenerator.generateLottoNumbers(); + lottoTickets.add(new LottoTicket(lottoNumbers)); + } + + return lottoTickets; + } +} diff --git a/src/main/java/com/javabom/lotto/domain/LottoResult.java b/src/main/java/com/javabom/lotto/domain/LottoResult.java new file mode 100644 index 0000000..335abd4 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/LottoResult.java @@ -0,0 +1,49 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.vo.LottoMoney; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class LottoResult { + private final LottoMoney lottoMoney; + private final Map winningStatistics; + + public LottoResult(LottoMoney lottoMoney, List drawResults) { + this.lottoMoney = lottoMoney; + this.winningStatistics = makeWinningStatistics(drawResults); + } + + public Map getWinningStatistics() { + Map winningStatisticsWithoutFail = new LinkedHashMap<>(this.winningStatistics); + winningStatisticsWithoutFail.remove(WinningSheet.FAIL); + return winningStatisticsWithoutFail; + } + + private Map makeWinningStatistics(List drawResults) { + Map winningStatistics = new LinkedHashMap<>(); + + for (WinningSheet winningSheet : WinningSheet.values()) { + long count = drawResults.stream() + .filter(drawResult -> winningSheet.getMatchCount() == drawResult) + .count(); + + winningStatistics.put(winningSheet, count); + } + + return winningStatistics; + } + + public double calculateRateOfReturn() { + double profit = winningStatistics.entrySet().stream() + .filter(entry -> entry.getValue() > 0) + .map(entry -> entry.getKey().getPrice()) + .reduce(Integer::sum) + .orElse(0); + + double rateOfReturn = profit / lottoMoney.getPurchaseAmount(); + + return Double.parseDouble(String.format("%.2f", rateOfReturn)); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/LottoTicket.java b/src/main/java/com/javabom/lotto/domain/LottoTicket.java new file mode 100644 index 0000000..13329bd --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/LottoTicket.java @@ -0,0 +1,44 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.number.LottoNumber; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class LottoTicket { + private static final int LOTTO_NUMBERS_SIZE = 6; + private final List lottoNumbers; + + public LottoTicket(List lottoNumbers) { + validateSize(lottoNumbers); + validateDuplicateNumbers(lottoNumbers); + this.lottoNumbers = Collections.unmodifiableList(lottoNumbers); + } + + private void validateSize(List lottoNumbers) { + if (lottoNumbers.size() != LOTTO_NUMBERS_SIZE) { + throw new IllegalArgumentException("로또 번호는 6개만 가능합니다."); + } + } + + private void validateDuplicateNumbers(List lottoNumbers) { + Set nonDuplicateNumbers = new HashSet<>(lottoNumbers); + + if (nonDuplicateNumbers.size() < LOTTO_NUMBERS_SIZE) { + throw new IllegalArgumentException("로또 번호는 중복 될 수 없습니다."); + } + } + + public List getLottoNumbers() { + return lottoNumbers.stream() + .map(LottoNumber::getNumber) + .collect(Collectors.toList()); + } + + public boolean isContainingLottoNumbers(LottoNumber lottoNumber) { + return lottoNumbers.contains(lottoNumber); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/WinningSheet.java b/src/main/java/com/javabom/lotto/domain/WinningSheet.java new file mode 100644 index 0000000..d5dce2d --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/WinningSheet.java @@ -0,0 +1,38 @@ +package com.javabom.lotto.domain; + +import java.util.Arrays; + +public enum WinningSheet { + FAIL(0, 0), + FOURTH(3, 5000), + THIRD(4, 50000), + SECOND(5, 1500000), + FIRST(6, 2000000000); + + private final int matchCount; + private final int price; + + WinningSheet(int matchCount, int price) { + this.matchCount = matchCount; + this.price = price; + } + + public static WinningSheet findByMatchCount(int matchCount) { + return Arrays.stream(WinningSheet.values()) + .filter(winningSheet -> winningSheet.isSameMatchCount(matchCount)) + .findFirst() + .orElse(WinningSheet.FAIL); + } + + public int getMatchCount() { + return matchCount; + } + + public int getPrice() { + return price; + } + + private boolean isSameMatchCount(int matchCount) { + return this.matchCount == matchCount; + } +} diff --git a/src/main/java/com/javabom/lotto/domain/number/LottoNumber.java b/src/main/java/com/javabom/lotto/domain/number/LottoNumber.java new file mode 100644 index 0000000..6c95435 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/number/LottoNumber.java @@ -0,0 +1,43 @@ +package com.javabom.lotto.domain.number; + +import java.util.Objects; + +public class LottoNumber implements Comparable { + private static final int LOTTO_NUMBER_UNDER_BOUND = 1; + private static final int LOTTO_NUMBER_UPPER_BOUND = 45; + private final int number; + + public LottoNumber(int number) { + validateNumber(number); + this.number = number; + } + + public int getNumber() { + return number; + } + + private void validateNumber(int number) { + if (number < LOTTO_NUMBER_UNDER_BOUND || number > LOTTO_NUMBER_UPPER_BOUND) { + throw new IllegalArgumentException("로또 번호는 1 ~ 45 사이의 값이어야 합니다. - " + number); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LottoNumber)) return false; + LottoNumber that = (LottoNumber) o; + return this.number == that.number; + } + + @Override + public int hashCode() { + return Objects.hash(this.number); + } + + @Override + public int compareTo(LottoNumber o) { + return Integer.compare(this.number, o.number); + } +} + diff --git a/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java b/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java new file mode 100644 index 0000000..4c341e6 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java @@ -0,0 +1,38 @@ +package com.javabom.lotto.domain.number; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class LottoNumberGenerator { + private static final int LOTTO_NUMBER_UNDER_BOUND = 1; + private static final int LOTTO_NUMBER_UPPER_BOUND = 45; + private static final int LOTTO_NUMBERS_SIZE = 6; + private static final List lottoNumbers; + + static { + lottoNumbers = IntStream.rangeClosed(LOTTO_NUMBER_UNDER_BOUND, LOTTO_NUMBER_UPPER_BOUND) + .mapToObj(LottoNumber::new) + .collect(Collectors.toList()); + } + + private LottoNumberGenerator() { + } + + public static List generateLottoNumbers() { + Collections.shuffle(lottoNumbers); + + return lottoNumbers.stream() + .limit(LOTTO_NUMBERS_SIZE) + .sorted() + .collect(Collectors.toList()); + } + + public static LottoNumber findByNumber(int number) { + return lottoNumbers.stream() + .filter(lottoNumber -> lottoNumber.getNumber() == number) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("1 ~ 45 사이의 값이 아닙니다.")); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java new file mode 100644 index 0000000..00834bb --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java @@ -0,0 +1,27 @@ +package com.javabom.lotto.domain.vo; + +public class LottoMoney { + private static final int LOTTO_PRICE = 1000; + private final int purchaseAmount; + private final int numberOfTicket; + + public LottoMoney(int purchaseAmount) { + validatePurchaseAmount(purchaseAmount); + this.purchaseAmount = purchaseAmount; + this.numberOfTicket = purchaseAmount / LOTTO_PRICE; + } + + private void validatePurchaseAmount(int purchaseAmount) { + if (purchaseAmount < LOTTO_PRICE) { + throw new IllegalArgumentException("로또를 살 수 없습니다."); + } + } + + public int getPurchaseAmount() { + return purchaseAmount; + } + + public int getNumberOfTicket() { + return numberOfTicket; + } +} 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..7352fcf --- /dev/null +++ b/src/main/java/com/javabom/lotto/view/InputView.java @@ -0,0 +1,37 @@ +package com.javabom.lotto.view; + +import com.javabom.lotto.domain.vo.LottoMoney; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class InputView { + private static final Scanner SCANNER = new Scanner(System.in); + private static final String DELIMITER = ","; + + private InputView() { + } + + public static LottoMoney inputPurchaseAmount() { + System.out.println("구입금액을 입력해 주세요."); + + try { + int purchaseAmount = Integer.parseInt(SCANNER.nextLine()); + return new LottoMoney(purchaseAmount); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자를 입력해 주세요."); + } + } + + public static List inputLastWinningNumbers() { + System.out.println("지난 주 당첨 번호를 입력해 주세요."); + + String stringWinningNumbers = SCANNER.nextLine(); + return Arrays.stream(stringWinningNumbers.split(DELIMITER)) + .map(String::trim) + .map(Integer::new) + .collect(Collectors.toList()); + } +} 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..2dae713 --- /dev/null +++ b/src/main/java/com/javabom/lotto/view/OutputView.java @@ -0,0 +1,62 @@ +package com.javabom.lotto.view; + +import com.javabom.lotto.domain.LottoResult; +import com.javabom.lotto.domain.LottoTicket; +import com.javabom.lotto.domain.WinningSheet; +import com.javabom.lotto.domain.vo.LottoMoney; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class OutputView { + private static final int NOT_LOSE_RATE = 1; + + private OutputView() { + } + + public static void printNumberOfTicket(LottoMoney lottoMoney) { + System.out.println(String.format("%d개를 구매했습니다.", lottoMoney.getNumberOfTicket())); + } + + public static void printLottoTickets(List lottoTickets) { + lottoTickets.stream() + .forEach(OutputView::printOneLottoTicket); + } + + private static void printOneLottoTicket(LottoTicket lottoTicket) { + String lottoNumbers = lottoTicket.getLottoNumbers().stream() + .map(String::valueOf) + .collect(Collectors.joining(", ", "[", "]")); + + System.out.println(lottoNumbers); + } + + public static void printWinningStatistics(LottoResult lottoResult) { + System.out.println("당첨 통계"); + System.out.println("----------"); + + Map winningStatistics = lottoResult.getWinningStatistics(); + + for (Map.Entry statistics : winningStatistics.entrySet()) { + WinningSheet winningSheet = statistics.getKey(); + + System.out.println(String.format("%d개 일치 (%d원)- %d개", winningSheet.getMatchCount(), + winningSheet.getPrice(), + statistics.getValue())); + } + + printRateOfReturn(lottoResult.calculateRateOfReturn()); + } + + private static void printRateOfReturn(double rateOfReturn) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("총 수익률은 %.2f 입니다."); + + if (rateOfReturn < NOT_LOSE_RATE) { + stringBuilder.append("기준이 1이기 때문에 결과적으로 손해라는 의미임"); + } + + System.out.println(String.format(stringBuilder.toString(), rateOfReturn)); + } +} diff --git a/src/test/java/com/javabom/lotto/domain/DrawingMachineTest.java b/src/test/java/com/javabom/lotto/domain/DrawingMachineTest.java new file mode 100644 index 0000000..051c79a --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/DrawingMachineTest.java @@ -0,0 +1,85 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.number.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.CsvSource; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.*; + +class DrawingMachineTest { + @DisplayName("생성자로 입력받은 당첨 번호의 개수가 6이 아니면 IllegalArgumentException throw") + @Test + void notCorrectWinningNumberSizeThrowException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new DrawingMachine(Arrays.asList(1, 2, 3, 4, 5))) + .withMessage("당첨 번호의 개수가 6이 아닙니다."); + } + + @DisplayName("생성자로 입력받은 당첨 번호가 중복되는 값이 있으면 IllegalArgumentException throw") + @Test + void duplicateWinningNumberThrowException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new DrawingMachine(Arrays.asList(1, 2, 3, 3, 5, 6))) + .withMessage("당첨 번호는 중복될 수 없습니다."); + } + + @DisplayName("로또 티켓과 당첨 번호를 비교하여 맞은 개수를 반환한다.") + @ParameterizedTest + @CsvSource(value = {"1,2,3,4,5,6:6", "1,2,3,4,5,7:5", "10,11,12,22,33,44:0"}, delimiter = ':') + void drawLotto(String winningNumber, int matchCount) { + LottoTicket lottoTicket = createLottoTicket(Arrays.asList(1, 2, 3, 4, 5, 6)); + + List winningNumbers = Stream.of(winningNumber.split(",")) + .map(Integer::parseInt) + .collect(Collectors.toList()); + + DrawingMachine drawingMachine = new DrawingMachine(winningNumbers); + + int actualMatchCount = drawingMachine.drawLottoTicket(lottoTicket); + + assertThat(actualMatchCount).isEqualTo(matchCount); + } + + @DisplayName("모든 로또 티켓과 당첨 번홀르 비교하여 맞은 개수의 리스트를 반환한다.") + @Test + void drawAllLotto() { + DrawingMachine drawingMachine = new DrawingMachine(Arrays.asList(1, 2, 3, 4, 5, 6)); + + List actualMatchCounts = drawingMachine.drawAllLottoTicket(createLottoTickets(3)); + + assertThat(actualMatchCounts).contains(6, 5, 4); + } + + private List createLottoTickets(int numberOfTicket) { + List lottoTickets = new ArrayList<>(); + + for (int startNumber = 1; startNumber <= numberOfTicket; startNumber++) { + List numbers = IntStream.rangeClosed(startNumber, startNumber + 5) + .boxed() + .collect(Collectors.toList()); + LottoTicket lottoTicket = createLottoTicket(numbers); + lottoTickets.add(lottoTicket); + } + + return lottoTickets; + } + + private LottoTicket createLottoTicket(List numbers) { + List lottoNumbers = numbers.stream() + .map(LottoNumber::new) + .collect(Collectors.toList()); + + return new LottoTicket(lottoNumbers); + } +} diff --git a/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java b/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java new file mode 100644 index 0000000..3c23200 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java @@ -0,0 +1,23 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.vo.LottoMoney; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class LottoMachineTest { + @DisplayName("구입 금액에 맞는 로또 티켓을 생성한다.") + @ParameterizedTest + @CsvSource({"1000, 1", "3500, 3", "14000, 14"}) + void purchaseLottoTicket(int purchaseAmount, int ticketAmount) { + LottoMoney lottoMoney = new LottoMoney(purchaseAmount); + List lottoTickets = LottoMachine.purchaseLottoTicket(lottoMoney); + + assertThat(lottoTickets.size()).isEqualTo(ticketAmount); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/LottoResultTest.java b/src/test/java/com/javabom/lotto/domain/LottoResultTest.java new file mode 100644 index 0000000..e5a0e6b --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/LottoResultTest.java @@ -0,0 +1,43 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.vo.LottoMoney; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class LottoResultTest { + + @DisplayName("추첨 결과를 받아서 WinnigSheet 타입을 키로하는 맵을 만든다.") + @Test + void createWinningStatistics() { + LottoMoney lottoMoney = new LottoMoney(3000); + List drawResults = Arrays.asList(3, 4, 6); + LottoResult lottoResult = new LottoResult(lottoMoney, drawResults); + + Map winningStatistics = lottoResult.getWinningStatistics(); + + assertAll( + () -> assertThat(winningStatistics).containsEntry(WinningSheet.FOURTH, 1L), + () -> assertThat(winningStatistics).containsEntry(WinningSheet.THIRD, 1L), + () -> assertThat(winningStatistics).containsEntry(WinningSheet.FIRST, 1L), + () -> assertThat(winningStatistics).containsEntry(WinningSheet.SECOND, 0L) + ); + } + + @DisplayName("당첨 통계를 바탕으로 총 수익률을 반환한다.") + @Test + void calculateRateOfReturn() { + LottoMoney lottoMoney = new LottoMoney(3000); + List drawResults = Arrays.asList(3, 2, 2); + LottoResult lottoResult = new LottoResult(lottoMoney, drawResults); + + double rateOfReturn = lottoResult.calculateRateOfReturn(); + assertThat(rateOfReturn).isEqualTo(1.67); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/LottoTicketTest.java b/src/test/java/com/javabom/lotto/domain/LottoTicketTest.java new file mode 100644 index 0000000..def6938 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/LottoTicketTest.java @@ -0,0 +1,65 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.number.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.CsvSource; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.*; + +class LottoTicketTest { + + @DisplayName("LottoNumber 리스트의 크기가 6이 아니면 IllegalArgumentException Throw") + @Test + void lottoTicketThrowsExceptionWhenSizeOver() { + List lottoNumbers = createLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 6, 7)); + + assertThatIllegalArgumentException() + .isThrownBy(() -> new LottoTicket(lottoNumbers)) + .withMessage("로또 번호는 6개만 가능합니다."); + } + + @DisplayName("LottoNumber 리스트에 중복된 번호가 있으면 IllegalArgumentExceptionThrow") + @Test + void lottoTicketThrowsExceptionWhenDuplicateNumber() { + List lottoNumbers = createLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 5)); + + assertThatIllegalArgumentException() + .isThrownBy(() -> new LottoTicket(lottoNumbers)) + .withMessage("로또 번호는 중복 될 수 없습니다."); + } + + @DisplayName("LottoNumber 리스트에 매개값으로 받은 번호가 존재하는지 판단.") + @ParameterizedTest + @CsvSource({"3, true", "7, false"}) + void isContainingLottoNumber(int number, boolean expectResult) { + List lottoNumbers = createLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 6)); + + LottoTicket lottoTicket = new LottoTicket(lottoNumbers); + + assertThat(lottoTicket.isContainingLottoNumbers(new LottoNumber(number))).isEqualTo(expectResult); + } + + @DisplayName("가지고있는 LottoNumber 리스트를 Integer 리스트로 반환") + @Test + void getLottoNumbers() { + List lottoNumbers = createLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 6)); + + LottoTicket lottoTicket = new LottoTicket(lottoNumbers); + + assertThat(lottoTicket.getLottoNumbers()).containsExactly(1, 2, 3, 4, 5, 6); + } + + private List createLottoNumbers(List numbers) { + return numbers.stream() + .map(LottoNumber::new) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/WinningSheetTest.java b/src/test/java/com/javabom/lotto/domain/WinningSheetTest.java new file mode 100644 index 0000000..821cc6d --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/WinningSheetTest.java @@ -0,0 +1,28 @@ +package com.javabom.lotto.domain; + +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 static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class WinningSheetTest { + + @DisplayName("일치 횟수와 맞는 당첨을 찾는다.") + @Test + void findByMatchCount() { + int matchCount = 4; + WinningSheet findSheet = WinningSheet.findByMatchCount(matchCount); + assertThat(findSheet).isEqualTo(WinningSheet.THIRD); + } + + @DisplayName("일치 횟수가 0 이거나 당첨 횟수가 아니면 FAIL 반환") + @ParameterizedTest + @ValueSource(ints = {0, 1, 2}) + void findByMissMatchCount(int missMatchCount) { + WinningSheet failSheet = WinningSheet.findByMatchCount(missMatchCount); + assertThat(failSheet).isEqualTo(WinningSheet.FAIL); + } +} \ No newline at end of file diff --git a/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java b/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java new file mode 100644 index 0000000..c6d2e15 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java @@ -0,0 +1,41 @@ +package com.javabom.lotto.domain.number; + +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.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.*; + +class LottoNumberGeneratorTest { + + @DisplayName("임의의 로또 번호 6개를 가져온다.") + @Test + void generateLottoNumbers() { + List lottoNumbers = LottoNumberGenerator.generateLottoNumbers(); + + assertThat(lottoNumbers.size()).isEqualTo(6); + } + + @DisplayName("숫자로 로또 번호를 가져온다.") + @ParameterizedTest + @ValueSource(ints = {1, 3, 5, 45}) + void findByNumber(int number) { + LottoNumber lottoNumber = LottoNumberGenerator.findByNumber(number); + + assertThat(lottoNumber.getNumber()).isEqualTo(number); + } + + @DisplayName("1 ~ 45 사이의 번호가 아닐 경우 IllegalArgumentException throw") + @ParameterizedTest + @ValueSource(ints = {0, 46, 47}) + void findByWrongNumberThrowException(int number) { + assertThatIllegalArgumentException() + .isThrownBy(() -> LottoNumberGenerator.findByNumber(number)) + .withMessage("1 ~ 45 사이의 값이 아닙니다."); + } +} diff --git a/src/test/java/com/javabom/lotto/domain/number/LottoNumberTest.java b/src/test/java/com/javabom/lotto/domain/number/LottoNumberTest.java new file mode 100644 index 0000000..c28fb7c --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/number/LottoNumberTest.java @@ -0,0 +1,19 @@ +package com.javabom.lotto.domain.number; + +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.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.*; + +class LottoNumberTest { + @DisplayName("Lotto 번호가 1 ~ 45 사이의 값이 아니면 IllegalArgumentException Throw") + @ParameterizedTest + @ValueSource(ints = {-1, 0, 46, 47}) + void lottoNumberThrowException(int number) { + assertThatIllegalArgumentException() + .isThrownBy(() -> new LottoNumber(number)) + .withMessage("로또 번호는 1 ~ 45 사이의 값이어야 합니다. - " + number); + } +} diff --git a/src/test/java/com/javabom/lotto/empty.txt b/src/test/java/com/javabom/lotto/empty.txt deleted file mode 100644 index e69de29..0000000 From fc52a6587b9743003206fd588efef14e261d8397 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 4 Jun 2020 16:23:36 +0900 Subject: [PATCH 02/13] =?UTF-8?q?=EB=A1=9C=EB=98=90(2=EB=93=B1)=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/javabom/lotto/LottoApplication.java | 15 ++-- .../javabom/lotto/domain/DrawingMachine.java | 53 ------------ .../com/javabom/lotto/domain/LottoBill.java | 26 ++++++ .../javabom/lotto/domain/LottoMachine.java | 10 +-- .../com/javabom/lotto/domain/LottoResult.java | 49 ++++------- .../com/javabom/lotto/domain/LottoTicket.java | 44 ---------- .../javabom/lotto/domain/WinningSheet.java | 40 ++++++--- .../lotto/domain/number/LottoNumber.java | 38 +++++++-- .../domain/number/LottoNumberGenerator.java | 42 +++++---- .../lotto/domain/ticket/LottoTicket.java | 55 ++++++++++++ .../domain/ticket/LottoWinningTicket.java | 38 +++++++++ .../javabom/lotto/domain/vo/LottoMoney.java | 8 +- .../com/javabom/lotto/view/InputView.java | 8 ++ .../com/javabom/lotto/view/OutputView.java | 31 +++---- .../lotto/domain/DrawingMachineTest.java | 85 ------------------- .../javabom/lotto/domain/LottoBillTest.java | 32 +++++++ .../lotto/domain/LottoMachineTest.java | 9 +- .../javabom/lotto/domain/LottoResultTest.java | 31 ++----- .../lotto/domain/WinningSheetTest.java | 47 +++++++--- .../number/LottoNumberGeneratorTest.java | 33 +++---- .../lotto/domain/number/LottoNumberTest.java | 2 +- .../domain/{ => ticket}/LottoTicketTest.java | 36 +++----- .../domain/ticket/LottoWinningTicketTest.java | 45 ++++++++++ .../lotto/domain/vo/LottoMoneyTest.java | 43 ++++++++++ 24 files changed, 450 insertions(+), 370 deletions(-) delete mode 100644 src/main/java/com/javabom/lotto/domain/DrawingMachine.java create mode 100644 src/main/java/com/javabom/lotto/domain/LottoBill.java delete mode 100644 src/main/java/com/javabom/lotto/domain/LottoTicket.java create mode 100644 src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java create mode 100644 src/main/java/com/javabom/lotto/domain/ticket/LottoWinningTicket.java delete mode 100644 src/test/java/com/javabom/lotto/domain/DrawingMachineTest.java create mode 100644 src/test/java/com/javabom/lotto/domain/LottoBillTest.java rename src/test/java/com/javabom/lotto/domain/{ => ticket}/LottoTicketTest.java (56%) create mode 100644 src/test/java/com/javabom/lotto/domain/ticket/LottoWinningTicketTest.java create mode 100644 src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java diff --git a/src/main/java/com/javabom/lotto/LottoApplication.java b/src/main/java/com/javabom/lotto/LottoApplication.java index 38a9142..77bb245 100644 --- a/src/main/java/com/javabom/lotto/LottoApplication.java +++ b/src/main/java/com/javabom/lotto/LottoApplication.java @@ -1,9 +1,9 @@ package com.javabom.lotto; -import com.javabom.lotto.domain.DrawingMachine; +import com.javabom.lotto.domain.LottoBill; import com.javabom.lotto.domain.LottoMachine; import com.javabom.lotto.domain.LottoResult; -import com.javabom.lotto.domain.LottoTicket; +import com.javabom.lotto.domain.ticket.LottoWinningTicket; import com.javabom.lotto.domain.vo.LottoMoney; import com.javabom.lotto.view.InputView; import com.javabom.lotto.view.OutputView; @@ -16,16 +16,17 @@ public static void main(String[] args) { OutputView.printNumberOfTicket(lottoMoney); - List lottoTickets = LottoMachine.purchaseLottoTicket(lottoMoney); + LottoBill lottoBill = LottoMachine.purchaseLottoTicket(lottoMoney); - OutputView.printLottoTickets(lottoTickets); + OutputView.printLottoTickets(lottoBill.getAllTickets()); List winningNumbers = InputView.inputLastWinningNumbers(); + int bonusNumber = InputView.inputBonusNumber(); - DrawingMachine drawingMachine = new DrawingMachine(winningNumbers); + LottoWinningTicket lottoWinningTicket = new LottoWinningTicket(winningNumbers, bonusNumber); - LottoResult lottoResult = new LottoResult(lottoMoney, drawingMachine.drawAllLottoTicket(lottoTickets)); + LottoResult lottoResult = lottoBill.drawAllLotto(lottoWinningTicket); - OutputView.printWinningStatistics(lottoResult); + OutputView.printWinningStatistics(lottoResult, lottoMoney); } } diff --git a/src/main/java/com/javabom/lotto/domain/DrawingMachine.java b/src/main/java/com/javabom/lotto/domain/DrawingMachine.java deleted file mode 100644 index d053f9d..0000000 --- a/src/main/java/com/javabom/lotto/domain/DrawingMachine.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.javabom.lotto.domain; - -import com.javabom.lotto.domain.number.LottoNumber; -import com.javabom.lotto.domain.number.LottoNumberGenerator; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -public class DrawingMachine { - private static final int WINNING_NUMBER_SIZE = 6; - - private final List winningNumbers; - - public DrawingMachine(List winningNumbers) { - validateWinningNumbersSize(winningNumbers); - validateDuplicateWinningNumbers(winningNumbers); - this.winningNumbers = mapLottoNumbersByNumbers(winningNumbers); - } - - private List mapLottoNumbersByNumbers(List winningNumbers) { - return winningNumbers.stream() - .map(LottoNumberGenerator::findByNumber) - .collect(Collectors.toList()); - } - - private void validateWinningNumbersSize(List winningNumbers) { - if (winningNumbers.size() != WINNING_NUMBER_SIZE) { - throw new IllegalArgumentException("당첨 번호의 개수가 6이 아닙니다."); - } - } - - private void validateDuplicateWinningNumbers(List winningNumbers) { - Set nonDuplicateNumbers = new HashSet<>(winningNumbers); - - if (nonDuplicateNumbers.size() != WINNING_NUMBER_SIZE) { - throw new IllegalArgumentException("당첨 번호는 중복될 수 없습니다."); - } - } - - public List drawAllLottoTicket(List lottoTickets) { - return lottoTickets.stream() - .map(this::drawLottoTicket) - .collect(Collectors.toList()); - } - - public int drawLottoTicket(LottoTicket lottoTicket) { - return (int) winningNumbers.stream() - .filter(lottoTicket::isContainingLottoNumbers) - .count(); - } -} diff --git a/src/main/java/com/javabom/lotto/domain/LottoBill.java b/src/main/java/com/javabom/lotto/domain/LottoBill.java new file mode 100644 index 0000000..ec4fafa --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/LottoBill.java @@ -0,0 +1,26 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.ticket.LottoTicket; +import com.javabom.lotto.domain.ticket.LottoWinningTicket; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class LottoBill { + private final List lottoTickets; + + public LottoBill(List lottoTickets) { + this.lottoTickets = lottoTickets; + } + + public LottoResult drawAllLotto(LottoWinningTicket lottoWinningTicket) { + return lottoTickets.stream() + .map(lottoWinningTicket::findMatchingSheet) + .collect(Collectors.collectingAndThen(Collectors.toList(), LottoResult::new)); + } + + public List getAllTickets() { + return Collections.unmodifiableList(lottoTickets); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/LottoMachine.java b/src/main/java/com/javabom/lotto/domain/LottoMachine.java index 0081c04..5de77ad 100644 --- a/src/main/java/com/javabom/lotto/domain/LottoMachine.java +++ b/src/main/java/com/javabom/lotto/domain/LottoMachine.java @@ -1,7 +1,6 @@ package com.javabom.lotto.domain; -import com.javabom.lotto.domain.number.LottoNumber; -import com.javabom.lotto.domain.number.LottoNumberGenerator; +import com.javabom.lotto.domain.ticket.LottoTicket; import com.javabom.lotto.domain.vo.LottoMoney; import java.util.ArrayList; @@ -11,14 +10,13 @@ public class LottoMachine { private LottoMachine() { } - public static List purchaseLottoTicket(LottoMoney lottoMoney) { + public static LottoBill purchaseLottoTicket(LottoMoney lottoMoney) { List lottoTickets = new ArrayList<>(); for (int i = 0; i < lottoMoney.getNumberOfTicket(); i++) { - List lottoNumbers = LottoNumberGenerator.generateLottoNumbers(); - lottoTickets.add(new LottoTicket(lottoNumbers)); + lottoTickets.add(LottoTicket.ofAuto()); } - return lottoTickets; + return new LottoBill(lottoTickets); } } diff --git a/src/main/java/com/javabom/lotto/domain/LottoResult.java b/src/main/java/com/javabom/lotto/domain/LottoResult.java index 335abd4..db8eaa4 100644 --- a/src/main/java/com/javabom/lotto/domain/LottoResult.java +++ b/src/main/java/com/javabom/lotto/domain/LottoResult.java @@ -1,49 +1,36 @@ package com.javabom.lotto.domain; -import com.javabom.lotto.domain.vo.LottoMoney; - -import java.util.LinkedHashMap; +import java.util.Collections; +import java.util.EnumMap; import java.util.List; import java.util.Map; public class LottoResult { - private final LottoMoney lottoMoney; - private final Map winningStatistics; - - public LottoResult(LottoMoney lottoMoney, List drawResults) { - this.lottoMoney = lottoMoney; - this.winningStatistics = makeWinningStatistics(drawResults); - } + private final Map winningStatistics; - public Map getWinningStatistics() { - Map winningStatisticsWithoutFail = new LinkedHashMap<>(this.winningStatistics); - winningStatisticsWithoutFail.remove(WinningSheet.FAIL); - return winningStatisticsWithoutFail; + public LottoResult(List winningSheets) { + this.winningStatistics = makeStatistics(winningSheets); } - private Map makeWinningStatistics(List drawResults) { - Map winningStatistics = new LinkedHashMap<>(); + private Map makeStatistics(List winningSheets) { + Map statistics = new EnumMap<>(WinningSheet.class); for (WinningSheet winningSheet : WinningSheet.values()) { - long count = drawResults.stream() - .filter(drawResult -> winningSheet.getMatchCount() == drawResult) - .count(); - - winningStatistics.put(winningSheet, count); + statistics.put(winningSheet, winningSheet.countInList(winningSheets)); } - return winningStatistics; - } + statistics.remove(WinningSheet.FAIL); - public double calculateRateOfReturn() { - double profit = winningStatistics.entrySet().stream() - .filter(entry -> entry.getValue() > 0) - .map(entry -> entry.getKey().getPrice()) - .reduce(Integer::sum) - .orElse(0); + return Collections.unmodifiableMap(statistics); + } - double rateOfReturn = profit / lottoMoney.getPurchaseAmount(); + public Map getWinningStatistics() { + return winningStatistics; + } - return Double.parseDouble(String.format("%.2f", rateOfReturn)); + public int sumAllPrize() { + return winningStatistics.entrySet().stream() + .mapToInt(statistic -> statistic.getKey().getPrize() * statistic.getValue()) + .sum(); } } diff --git a/src/main/java/com/javabom/lotto/domain/LottoTicket.java b/src/main/java/com/javabom/lotto/domain/LottoTicket.java deleted file mode 100644 index 13329bd..0000000 --- a/src/main/java/com/javabom/lotto/domain/LottoTicket.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.javabom.lotto.domain; - -import com.javabom.lotto.domain.number.LottoNumber; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -public class LottoTicket { - private static final int LOTTO_NUMBERS_SIZE = 6; - private final List lottoNumbers; - - public LottoTicket(List lottoNumbers) { - validateSize(lottoNumbers); - validateDuplicateNumbers(lottoNumbers); - this.lottoNumbers = Collections.unmodifiableList(lottoNumbers); - } - - private void validateSize(List lottoNumbers) { - if (lottoNumbers.size() != LOTTO_NUMBERS_SIZE) { - throw new IllegalArgumentException("로또 번호는 6개만 가능합니다."); - } - } - - private void validateDuplicateNumbers(List lottoNumbers) { - Set nonDuplicateNumbers = new HashSet<>(lottoNumbers); - - if (nonDuplicateNumbers.size() < LOTTO_NUMBERS_SIZE) { - throw new IllegalArgumentException("로또 번호는 중복 될 수 없습니다."); - } - } - - public List getLottoNumbers() { - return lottoNumbers.stream() - .map(LottoNumber::getNumber) - .collect(Collectors.toList()); - } - - public boolean isContainingLottoNumbers(LottoNumber lottoNumber) { - return lottoNumbers.contains(lottoNumber); - } -} diff --git a/src/main/java/com/javabom/lotto/domain/WinningSheet.java b/src/main/java/com/javabom/lotto/domain/WinningSheet.java index d5dce2d..c3b68bb 100644 --- a/src/main/java/com/javabom/lotto/domain/WinningSheet.java +++ b/src/main/java/com/javabom/lotto/domain/WinningSheet.java @@ -1,35 +1,53 @@ package com.javabom.lotto.domain; import java.util.Arrays; +import java.util.List; public enum WinningSheet { FAIL(0, 0), - FOURTH(3, 5000), - THIRD(4, 50000), - SECOND(5, 1500000), - FIRST(6, 2000000000); + FIFTH(3, 5_000), + FOURTH(4, 50_000), + THIRD(5, 1_500_000), + SECOND(5, 30_000_000), + FIRST(6, 2_000_000_000); private final int matchCount; - private final int price; + private final int prize; - WinningSheet(int matchCount, int price) { + WinningSheet(int matchCount, int prize) { this.matchCount = matchCount; - this.price = price; + this.prize = prize; } - public static WinningSheet findByMatchCount(int matchCount) { - return Arrays.stream(WinningSheet.values()) + public static WinningSheet findByMatchCount(int matchCount, boolean matchBonus) { + WinningSheet findSheet = Arrays.stream(values()) .filter(winningSheet -> winningSheet.isSameMatchCount(matchCount)) .findFirst() .orElse(WinningSheet.FAIL); + + if (isThirdAndMatchBonus(findSheet, matchBonus)) { + return SECOND; + } + + return findSheet; + } + + private static boolean isThirdAndMatchBonus(WinningSheet winningSheet, boolean matchBonus) { + return (winningSheet.equals(THIRD) && matchBonus); } public int getMatchCount() { return matchCount; } - public int getPrice() { - return price; + public int getPrize() { + return prize; + } + + public int countInList(List winningSheets) { + return (int) winningSheets.stream() + .filter(this::equals) + .count(); } private boolean isSameMatchCount(int matchCount) { diff --git a/src/main/java/com/javabom/lotto/domain/number/LottoNumber.java b/src/main/java/com/javabom/lotto/domain/number/LottoNumber.java index 6c95435..ffb60eb 100644 --- a/src/main/java/com/javabom/lotto/domain/number/LottoNumber.java +++ b/src/main/java/com/javabom/lotto/domain/number/LottoNumber.java @@ -1,22 +1,28 @@ package com.javabom.lotto.domain.number; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; public class LottoNumber implements Comparable { - private static final int LOTTO_NUMBER_UNDER_BOUND = 1; - private static final int LOTTO_NUMBER_UPPER_BOUND = 45; + public static final int LOTTO_NUMBER_UNDER_BOUND = 1; + public static final int LOTTO_NUMBER_UPPER_BOUND = 45; private final int number; - public LottoNumber(int number) { - validateNumber(number); + private LottoNumber(int number) { this.number = number; } + public static LottoNumber valueOf(int number) { + validateNumber(number); + return LottoNumberCache.getLottoNumber(number); + } + public int getNumber() { return number; } - private void validateNumber(int number) { + private static void validateNumber(int number) { if (number < LOTTO_NUMBER_UNDER_BOUND || number > LOTTO_NUMBER_UPPER_BOUND) { throw new IllegalArgumentException("로또 번호는 1 ~ 45 사이의 값이어야 합니다. - " + number); } @@ -39,5 +45,25 @@ public int hashCode() { public int compareTo(LottoNumber o) { return Integer.compare(this.number, o.number); } -} + @Override + public String toString() { + return String.valueOf(number); + } + + private static class LottoNumberCache { + private static final Map cache; + + static { + cache = new HashMap<>(); + + for (int number = LOTTO_NUMBER_UNDER_BOUND; number <= LOTTO_NUMBER_UPPER_BOUND; number++) { + cache.put(number, new LottoNumber(number)); + } + } + + private static LottoNumber getLottoNumber(int number) { + return cache.get(number); + } + } +} diff --git a/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java b/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java index 4c341e6..7423f22 100644 --- a/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java +++ b/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java @@ -2,37 +2,35 @@ import java.util.Collections; import java.util.List; +import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.IntStream; +import static com.javabom.lotto.domain.number.LottoNumber.LOTTO_NUMBER_UNDER_BOUND; +import static com.javabom.lotto.domain.number.LottoNumber.LOTTO_NUMBER_UPPER_BOUND; + public class LottoNumberGenerator { - private static final int LOTTO_NUMBER_UNDER_BOUND = 1; - private static final int LOTTO_NUMBER_UPPER_BOUND = 45; - private static final int LOTTO_NUMBERS_SIZE = 6; - private static final List lottoNumbers; - - static { - lottoNumbers = IntStream.rangeClosed(LOTTO_NUMBER_UNDER_BOUND, LOTTO_NUMBER_UPPER_BOUND) - .mapToObj(LottoNumber::new) + private static final int FIRST_ELEMENT = 0; + + public static Set generateRandomNumber(int size) { + List numbers = IntStream.rangeClosed(LOTTO_NUMBER_UNDER_BOUND, LOTTO_NUMBER_UPPER_BOUND) + .boxed() .collect(Collectors.toList()); - } - private LottoNumberGenerator() { - } + Collections.shuffle(numbers); - public static List generateLottoNumbers() { - Collections.shuffle(lottoNumbers); + return convertIntegerToLottoNumber(numbers.subList(FIRST_ELEMENT, size)); + } - return lottoNumbers.stream() - .limit(LOTTO_NUMBERS_SIZE) - .sorted() - .collect(Collectors.toList()); + public static Set generateFixedNumber(List numbers) { + return convertIntegerToLottoNumber(numbers); } - public static LottoNumber findByNumber(int number) { - return lottoNumbers.stream() - .filter(lottoNumber -> lottoNumber.getNumber() == number) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("1 ~ 45 사이의 값이 아닙니다.")); + private static Set convertIntegerToLottoNumber(List numbers) { + return numbers.stream() + .sorted() + .map(LottoNumber::valueOf) + .collect(Collectors.toCollection(TreeSet::new)); } } 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..1a18fca --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java @@ -0,0 +1,55 @@ +package com.javabom.lotto.domain.ticket; + +import com.javabom.lotto.domain.number.LottoNumber; +import com.javabom.lotto.domain.number.LottoNumberGenerator; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class LottoTicket { + private static final int LOTTO_NUMBERS_SIZE = 6; + private final Set lottoNumbers; + + private LottoTicket(Set lottoNumbers) { + validateDuplicateNumbers(lottoNumbers); + this.lottoNumbers = lottoNumbers; + } + + public static LottoTicket ofFixed(List numbers) { + validateSize(numbers); + return new LottoTicket(LottoNumberGenerator.generateFixedNumber(numbers)); + } + + public static LottoTicket ofAuto() { + return new LottoTicket(LottoNumberGenerator.generateRandomNumber(LOTTO_NUMBERS_SIZE)); + } + + public List getLottoNumbers() { + return lottoNumbers.stream() + .map(LottoNumber::getNumber) + .collect(Collectors.toList()); + } + + private static void validateSize(List numbers) { + if (numbers.size() != LOTTO_NUMBERS_SIZE) { + throw new IllegalArgumentException("로또 번호는 6개만 가능합니다. - " + numbers); + } + } + + public boolean isContainingLottoNumbers(LottoNumber lottoNumber) { + return lottoNumbers.contains(lottoNumber); + } + + private static void validateDuplicateNumbers(Set lottoNumbers) { + if (lottoNumbers.size() < LOTTO_NUMBERS_SIZE) { + throw new IllegalArgumentException("로또 번호는 중복 될 수 없습니다. - " + lottoNumbers); + } + } + + public int findMatchCount(LottoTicket lottoTicket) { + return (int) lottoTicket.lottoNumbers.stream() + .filter(this::isContainingLottoNumbers) + .count(); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/ticket/LottoWinningTicket.java b/src/main/java/com/javabom/lotto/domain/ticket/LottoWinningTicket.java new file mode 100644 index 0000000..18d2928 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoWinningTicket.java @@ -0,0 +1,38 @@ +package com.javabom.lotto.domain.ticket; + + +import com.javabom.lotto.domain.WinningSheet; +import com.javabom.lotto.domain.number.LottoNumber; + +import java.util.List; + +public class LottoWinningTicket { + private final LottoTicket winningTicket; + private final LottoNumber bonusNumber; + + public LottoWinningTicket(List winningNumbers, int bonusNumber) { + validateDuplicateBonusNumber(winningNumbers, bonusNumber); + + this.winningTicket = LottoTicket.ofFixed(winningNumbers); + this.bonusNumber = LottoNumber.valueOf(bonusNumber); + } + + public LottoTicket getWinningTicket() { + return winningTicket; + } + + public LottoNumber getBonusNumber() { + return bonusNumber; + } + + private void validateDuplicateBonusNumber(List winningNumbers, int bonusNumber) { + if (winningNumbers.contains(bonusNumber)) { + throw new IllegalArgumentException("보너스 번호는 당첨 번호와 중복 될 수 없습니다. - " + bonusNumber); + } + } + + public WinningSheet findMatchingSheet(LottoTicket lottoTicket) { + return WinningSheet.findByMatchCount(lottoTicket.findMatchCount(winningTicket) + , lottoTicket.isContainingLottoNumbers(bonusNumber)); + } +} diff --git a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java index 00834bb..8b303a4 100644 --- a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java +++ b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java @@ -11,9 +11,15 @@ public LottoMoney(int purchaseAmount) { this.numberOfTicket = purchaseAmount / LOTTO_PRICE; } + public double calculateRateOfReturn(int profit) { + double rateOfReturn = profit / purchaseAmount; + + return rateOfReturn; + } + private void validatePurchaseAmount(int purchaseAmount) { if (purchaseAmount < LOTTO_PRICE) { - throw new IllegalArgumentException("로또를 살 수 없습니다."); + throw new IllegalArgumentException("로또를 살 수 없습니다. - " + purchaseAmount); } } diff --git a/src/main/java/com/javabom/lotto/view/InputView.java b/src/main/java/com/javabom/lotto/view/InputView.java index 7352fcf..69b1306 100644 --- a/src/main/java/com/javabom/lotto/view/InputView.java +++ b/src/main/java/com/javabom/lotto/view/InputView.java @@ -34,4 +34,12 @@ public static List inputLastWinningNumbers() { .map(Integer::new) .collect(Collectors.toList()); } + + public static int inputBonusNumber() { + System.out.println("보너스 볼을 입력해주세요."); + + String stringBonusNumber = SCANNER.nextLine(); + + return Integer.parseInt(stringBonusNumber); + } } diff --git a/src/main/java/com/javabom/lotto/view/OutputView.java b/src/main/java/com/javabom/lotto/view/OutputView.java index 2dae713..c704f97 100644 --- a/src/main/java/com/javabom/lotto/view/OutputView.java +++ b/src/main/java/com/javabom/lotto/view/OutputView.java @@ -1,13 +1,12 @@ package com.javabom.lotto.view; import com.javabom.lotto.domain.LottoResult; -import com.javabom.lotto.domain.LottoTicket; +import com.javabom.lotto.domain.ticket.LottoTicket; import com.javabom.lotto.domain.WinningSheet; import com.javabom.lotto.domain.vo.LottoMoney; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; public class OutputView { private static final int NOT_LOSE_RATE = 1; @@ -20,33 +19,25 @@ public static void printNumberOfTicket(LottoMoney lottoMoney) { } public static void printLottoTickets(List lottoTickets) { - lottoTickets.stream() - .forEach(OutputView::printOneLottoTicket); + lottoTickets.forEach(lottoTicket -> System.out.println(lottoTicket.getLottoNumbers())); } - private static void printOneLottoTicket(LottoTicket lottoTicket) { - String lottoNumbers = lottoTicket.getLottoNumbers().stream() - .map(String::valueOf) - .collect(Collectors.joining(", ", "[", "]")); - - System.out.println(lottoNumbers); - } - - public static void printWinningStatistics(LottoResult lottoResult) { + public static void printWinningStatistics(LottoResult lottoResult, LottoMoney lottoMoney) { System.out.println("당첨 통계"); - System.out.println("----------"); - Map winningStatistics = lottoResult.getWinningStatistics(); + System.out.println("----------"); - for (Map.Entry statistics : winningStatistics.entrySet()) { + for (Map.Entry statistics : lottoResult.getWinningStatistics().entrySet()) { WinningSheet winningSheet = statistics.getKey(); - System.out.println(String.format("%d개 일치 (%d원)- %d개", winningSheet.getMatchCount(), - winningSheet.getPrice(), - statistics.getValue())); + String format = winningSheet.equals(WinningSheet.SECOND) ? "%d개 일치 보너스 볼 일치(%d원)- %d개" : + "%d개 일치 (%d원)- %d개"; + + System.out.println(String.format(format, winningSheet.getMatchCount() + , winningSheet.getPrize(), statistics.getValue())); } - printRateOfReturn(lottoResult.calculateRateOfReturn()); + printRateOfReturn(lottoMoney.calculateRateOfReturn(lottoResult.sumAllPrize())); } private static void printRateOfReturn(double rateOfReturn) { diff --git a/src/test/java/com/javabom/lotto/domain/DrawingMachineTest.java b/src/test/java/com/javabom/lotto/domain/DrawingMachineTest.java deleted file mode 100644 index 051c79a..0000000 --- a/src/test/java/com/javabom/lotto/domain/DrawingMachineTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.javabom.lotto.domain; - -import com.javabom.lotto.domain.number.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.CsvSource; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.junit.jupiter.api.Assertions.*; - -class DrawingMachineTest { - @DisplayName("생성자로 입력받은 당첨 번호의 개수가 6이 아니면 IllegalArgumentException throw") - @Test - void notCorrectWinningNumberSizeThrowException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new DrawingMachine(Arrays.asList(1, 2, 3, 4, 5))) - .withMessage("당첨 번호의 개수가 6이 아닙니다."); - } - - @DisplayName("생성자로 입력받은 당첨 번호가 중복되는 값이 있으면 IllegalArgumentException throw") - @Test - void duplicateWinningNumberThrowException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new DrawingMachine(Arrays.asList(1, 2, 3, 3, 5, 6))) - .withMessage("당첨 번호는 중복될 수 없습니다."); - } - - @DisplayName("로또 티켓과 당첨 번호를 비교하여 맞은 개수를 반환한다.") - @ParameterizedTest - @CsvSource(value = {"1,2,3,4,5,6:6", "1,2,3,4,5,7:5", "10,11,12,22,33,44:0"}, delimiter = ':') - void drawLotto(String winningNumber, int matchCount) { - LottoTicket lottoTicket = createLottoTicket(Arrays.asList(1, 2, 3, 4, 5, 6)); - - List winningNumbers = Stream.of(winningNumber.split(",")) - .map(Integer::parseInt) - .collect(Collectors.toList()); - - DrawingMachine drawingMachine = new DrawingMachine(winningNumbers); - - int actualMatchCount = drawingMachine.drawLottoTicket(lottoTicket); - - assertThat(actualMatchCount).isEqualTo(matchCount); - } - - @DisplayName("모든 로또 티켓과 당첨 번홀르 비교하여 맞은 개수의 리스트를 반환한다.") - @Test - void drawAllLotto() { - DrawingMachine drawingMachine = new DrawingMachine(Arrays.asList(1, 2, 3, 4, 5, 6)); - - List actualMatchCounts = drawingMachine.drawAllLottoTicket(createLottoTickets(3)); - - assertThat(actualMatchCounts).contains(6, 5, 4); - } - - private List createLottoTickets(int numberOfTicket) { - List lottoTickets = new ArrayList<>(); - - for (int startNumber = 1; startNumber <= numberOfTicket; startNumber++) { - List numbers = IntStream.rangeClosed(startNumber, startNumber + 5) - .boxed() - .collect(Collectors.toList()); - LottoTicket lottoTicket = createLottoTicket(numbers); - lottoTickets.add(lottoTicket); - } - - return lottoTickets; - } - - private LottoTicket createLottoTicket(List numbers) { - List lottoNumbers = numbers.stream() - .map(LottoNumber::new) - .collect(Collectors.toList()); - - return new LottoTicket(lottoNumbers); - } -} diff --git a/src/test/java/com/javabom/lotto/domain/LottoBillTest.java b/src/test/java/com/javabom/lotto/domain/LottoBillTest.java new file mode 100644 index 0000000..31a2bf7 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/LottoBillTest.java @@ -0,0 +1,32 @@ +package com.javabom.lotto.domain; + +import com.javabom.lotto.domain.ticket.LottoTicket; +import com.javabom.lotto.domain.ticket.LottoWinningTicket; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class LottoBillTest { + @DisplayName("모든 로또 티켓과 당첨 번호를 비교하여 추첨 결과를 반환한다.") + @Test + void drawAllLotto() { + LottoTicket ticket1 = LottoTicket.ofFixed(Arrays.asList(1, 2, 3, 4, 5, 6)); + LottoTicket ticket2 = LottoTicket.ofFixed(Arrays.asList(1, 2, 3, 4, 5, 7)); + LottoTicket ticket3 = LottoTicket.ofFixed(Arrays.asList(1, 2, 3, 4, 5, 8)); + + LottoWinningTicket lottoWinningTicket = new LottoWinningTicket(Arrays.asList(1, 2, 3, 4, 5, 6), 7); + + LottoBill lottoBill = new LottoBill(Arrays.asList(ticket1, ticket2, ticket3)); + + LottoResult lottoResult = lottoBill.drawAllLotto(lottoWinningTicket); + + LottoResult expectedResult = new LottoResult(Arrays.asList(WinningSheet.FIRST, WinningSheet.SECOND + , WinningSheet.THIRD)); + + assertThat(lottoResult).isEqualToComparingFieldByField(expectedResult); + } +} diff --git a/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java b/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java index 3c23200..3f04927 100644 --- a/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java +++ b/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java @@ -1,5 +1,6 @@ package com.javabom.lotto.domain; +import com.javabom.lotto.domain.ticket.LottoTicket; import com.javabom.lotto.domain.vo.LottoMoney; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; @@ -8,16 +9,16 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; class LottoMachineTest { + @DisplayName("구입 금액에 맞는 로또 티켓을 생성한다.") @ParameterizedTest @CsvSource({"1000, 1", "3500, 3", "14000, 14"}) void purchaseLottoTicket(int purchaseAmount, int ticketAmount) { LottoMoney lottoMoney = new LottoMoney(purchaseAmount); - List lottoTickets = LottoMachine.purchaseLottoTicket(lottoMoney); + LottoBill lottoBill = LottoMachine.purchaseLottoTicket(lottoMoney); - assertThat(lottoTickets.size()).isEqualTo(ticketAmount); + assertThat(lottoBill.getAllTickets().size()).isEqualTo(ticketAmount); } -} \ No newline at end of file +} diff --git a/src/test/java/com/javabom/lotto/domain/LottoResultTest.java b/src/test/java/com/javabom/lotto/domain/LottoResultTest.java index e5a0e6b..4cd79df 100644 --- a/src/test/java/com/javabom/lotto/domain/LottoResultTest.java +++ b/src/test/java/com/javabom/lotto/domain/LottoResultTest.java @@ -13,31 +13,14 @@ class LottoResultTest { - @DisplayName("추첨 결과를 받아서 WinnigSheet 타입을 키로하는 맵을 만든다.") + @DisplayName("당첨 결과를 받아서 총 당첨액을 반환한다.") @Test - void createWinningStatistics() { - LottoMoney lottoMoney = new LottoMoney(3000); - List drawResults = Arrays.asList(3, 4, 6); - LottoResult lottoResult = new LottoResult(lottoMoney, drawResults); + void sumAllPrize() { + List winningSheets = Arrays.asList(WinningSheet.FIFTH, WinningSheet.SECOND); + LottoResult lottoResult = new LottoResult(winningSheets); - Map winningStatistics = lottoResult.getWinningStatistics(); + int totalPrize = lottoResult.sumAllPrize(); - assertAll( - () -> assertThat(winningStatistics).containsEntry(WinningSheet.FOURTH, 1L), - () -> assertThat(winningStatistics).containsEntry(WinningSheet.THIRD, 1L), - () -> assertThat(winningStatistics).containsEntry(WinningSheet.FIRST, 1L), - () -> assertThat(winningStatistics).containsEntry(WinningSheet.SECOND, 0L) - ); + assertThat(totalPrize).isEqualTo(30_005_000); } - - @DisplayName("당첨 통계를 바탕으로 총 수익률을 반환한다.") - @Test - void calculateRateOfReturn() { - LottoMoney lottoMoney = new LottoMoney(3000); - List drawResults = Arrays.asList(3, 2, 2); - LottoResult lottoResult = new LottoResult(lottoMoney, drawResults); - - double rateOfReturn = lottoResult.calculateRateOfReturn(); - assertThat(rateOfReturn).isEqualTo(1.67); - } -} \ No newline at end of file +} diff --git a/src/test/java/com/javabom/lotto/domain/WinningSheetTest.java b/src/test/java/com/javabom/lotto/domain/WinningSheetTest.java index 821cc6d..a0ccf29 100644 --- a/src/test/java/com/javabom/lotto/domain/WinningSheetTest.java +++ b/src/test/java/com/javabom/lotto/domain/WinningSheetTest.java @@ -3,26 +3,51 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class WinningSheetTest { - @DisplayName("일치 횟수와 맞는 당첨을 찾는다.") - @Test - void findByMatchCount() { - int matchCount = 4; - WinningSheet findSheet = WinningSheet.findByMatchCount(matchCount); - assertThat(findSheet).isEqualTo(WinningSheet.THIRD); + private static Stream provideMatchInformationAndResult() { + return Stream.of( + Arguments.of(6, true, WinningSheet.FIRST), + Arguments.of(5, true, WinningSheet.SECOND), + Arguments.of(5, false, WinningSheet.THIRD) + ); + } + + @DisplayName("일치 개수와 맞는 당첨을 찾는다.") + @ParameterizedTest + @MethodSource("provideMatchInformationAndResult") + void findByMatchCount(int matchCount, boolean matchBonus, WinningSheet findResult) { + WinningSheet findSheet = WinningSheet.findByMatchCount(matchCount, matchBonus); + assertThat(findSheet).isEqualTo(findResult); } - @DisplayName("일치 횟수가 0 이거나 당첨 횟수가 아니면 FAIL 반환") + @DisplayName("일치 개수가 0 이거나 당첨 개수가 아니면 FAIL 반환") @ParameterizedTest - @ValueSource(ints = {0, 1, 2}) - void findByMissMatchCount(int missMatchCount) { - WinningSheet failSheet = WinningSheet.findByMatchCount(missMatchCount); + @CsvSource({"2, true", "1, false", "0, true"}) + void findByMissMatchCount(int missMatchCount, boolean matchBonus) { + WinningSheet failSheet = WinningSheet.findByMatchCount(missMatchCount, matchBonus); assertThat(failSheet).isEqualTo(WinningSheet.FAIL); } -} \ No newline at end of file + + @DisplayName("Enum 리스트안에 자신이 몇개 있는지 반환한다.") + @ParameterizedTest + @CsvSource({"FAIL, 1", "THIRD, 2", "FIRST, 0"}) + void countInList(String name, int count) { + List winningSheets = Arrays.asList(WinningSheet.FAIL, WinningSheet.THIRD, WinningSheet.THIRD); + WinningSheet findSheet = WinningSheet.valueOf(name); + + assertThat(findSheet.countInList(winningSheets)).isEqualTo(count); + } +} diff --git a/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java b/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java index c6d2e15..beadeb7 100644 --- a/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java +++ b/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java @@ -5,7 +5,9 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import java.util.Arrays; import java.util.List; +import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -13,29 +15,20 @@ class LottoNumberGeneratorTest { - @DisplayName("임의의 로또 번호 6개를 가져온다.") - @Test - void generateLottoNumbers() { - List lottoNumbers = LottoNumberGenerator.generateLottoNumbers(); - - assertThat(lottoNumbers.size()).isEqualTo(6); - } - - @DisplayName("숫자로 로또 번호를 가져온다.") + @DisplayName("인자로 받은 개수 만큼 LottoNumber의 Set을 반환한다.") @ParameterizedTest - @ValueSource(ints = {1, 3, 5, 45}) - void findByNumber(int number) { - LottoNumber lottoNumber = LottoNumberGenerator.findByNumber(number); + @ValueSource(ints = {1, 2, 3, 4, 5}) + void generateRandomNumber(int size) { + Set lottoNumbers = LottoNumberGenerator.generateRandomNumber(size); - assertThat(lottoNumber.getNumber()).isEqualTo(number); + assertThat(lottoNumbers.size()).isEqualTo(size); } - @DisplayName("1 ~ 45 사이의 번호가 아닐 경우 IllegalArgumentException throw") - @ParameterizedTest - @ValueSource(ints = {0, 46, 47}) - void findByWrongNumberThrowException(int number) { - assertThatIllegalArgumentException() - .isThrownBy(() -> LottoNumberGenerator.findByNumber(number)) - .withMessage("1 ~ 45 사이의 값이 아닙니다."); + @DisplayName("인자로 받은 숫자 리스트를 LottoNumber로 변환하여 Set으로 반환한다.") + @Test + void generateFixedNumber() { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + + assertThat(LottoNumberGenerator.generateFixedNumber(numbers)).contains(LottoNumber.valueOf(3)); } } diff --git a/src/test/java/com/javabom/lotto/domain/number/LottoNumberTest.java b/src/test/java/com/javabom/lotto/domain/number/LottoNumberTest.java index c28fb7c..9ebed38 100644 --- a/src/test/java/com/javabom/lotto/domain/number/LottoNumberTest.java +++ b/src/test/java/com/javabom/lotto/domain/number/LottoNumberTest.java @@ -13,7 +13,7 @@ class LottoNumberTest { @ValueSource(ints = {-1, 0, 46, 47}) void lottoNumberThrowException(int number) { assertThatIllegalArgumentException() - .isThrownBy(() -> new LottoNumber(number)) + .isThrownBy(() -> LottoNumber.valueOf(number)) .withMessage("로또 번호는 1 ~ 45 사이의 값이어야 합니다. - " + number); } } diff --git a/src/test/java/com/javabom/lotto/domain/LottoTicketTest.java b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java similarity index 56% rename from src/test/java/com/javabom/lotto/domain/LottoTicketTest.java rename to src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java index def6938..836e71e 100644 --- a/src/test/java/com/javabom/lotto/domain/LottoTicketTest.java +++ b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java @@ -1,6 +1,7 @@ -package com.javabom.lotto.domain; +package com.javabom.lotto.domain.ticket; import com.javabom.lotto.domain.number.LottoNumber; +import com.javabom.lotto.domain.ticket.LottoTicket; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -12,54 +13,41 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.junit.jupiter.api.Assertions.*; class LottoTicketTest { @DisplayName("LottoNumber 리스트의 크기가 6이 아니면 IllegalArgumentException Throw") @Test void lottoTicketThrowsExceptionWhenSizeOver() { - List lottoNumbers = createLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 6, 7)); - + List lottoNumbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7); assertThatIllegalArgumentException() - .isThrownBy(() -> new LottoTicket(lottoNumbers)) - .withMessage("로또 번호는 6개만 가능합니다."); + .isThrownBy(() -> LottoTicket.ofFixed(lottoNumbers)) + .withMessage("로또 번호는 6개만 가능합니다. - " + lottoNumbers); } @DisplayName("LottoNumber 리스트에 중복된 번호가 있으면 IllegalArgumentExceptionThrow") @Test void lottoTicketThrowsExceptionWhenDuplicateNumber() { - List lottoNumbers = createLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 5)); - + List lottoNumbers = Arrays.asList(1, 2, 3, 4, 5, 5); assertThatIllegalArgumentException() - .isThrownBy(() -> new LottoTicket(lottoNumbers)) - .withMessage("로또 번호는 중복 될 수 없습니다."); + .isThrownBy(() -> LottoTicket.ofFixed(lottoNumbers)) + .withMessageContaining("로또 번호는 중복 될 수 없습니다."); } @DisplayName("LottoNumber 리스트에 매개값으로 받은 번호가 존재하는지 판단.") @ParameterizedTest @CsvSource({"3, true", "7, false"}) void isContainingLottoNumber(int number, boolean expectResult) { - List lottoNumbers = createLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 6)); - - LottoTicket lottoTicket = new LottoTicket(lottoNumbers); + LottoTicket lottoTicket = LottoTicket.ofFixed(Arrays.asList(1, 2, 3, 4, 5, 6)); - assertThat(lottoTicket.isContainingLottoNumbers(new LottoNumber(number))).isEqualTo(expectResult); + assertThat(lottoTicket.isContainingLottoNumbers(LottoNumber.valueOf(number))).isEqualTo(expectResult); } @DisplayName("가지고있는 LottoNumber 리스트를 Integer 리스트로 반환") @Test void getLottoNumbers() { - List lottoNumbers = createLottoNumbers(Arrays.asList(1, 2, 3, 4, 5, 6)); - - LottoTicket lottoTicket = new LottoTicket(lottoNumbers); + LottoTicket lottoTicket = LottoTicket.ofFixed(Arrays.asList(1, 2, 3, 4, 5, 6)); assertThat(lottoTicket.getLottoNumbers()).containsExactly(1, 2, 3, 4, 5, 6); } - - private List createLottoNumbers(List numbers) { - return numbers.stream() - .map(LottoNumber::new) - .collect(Collectors.toList()); - } -} \ No newline at end of file +} diff --git a/src/test/java/com/javabom/lotto/domain/ticket/LottoWinningTicketTest.java b/src/test/java/com/javabom/lotto/domain/ticket/LottoWinningTicketTest.java new file mode 100644 index 0000000..eb59ccd --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/ticket/LottoWinningTicketTest.java @@ -0,0 +1,45 @@ +package com.javabom.lotto.domain.ticket; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.*; + +class LottoWinningTicketTest { + @DisplayName("당첨 번호와 보너스 번호가 중복 되는 것이 있으면 IllegalArgumentException throw") + @Test + void winningNumberDuplicateBonusNumberThrowException() { + List winningNumbers = Arrays.asList(1, 2, 3, 4, 5, 6); + int bonusNumber = 5; + + assertThatIllegalArgumentException() + .isThrownBy(() -> new LottoWinningTicket(winningNumbers, bonusNumber)) + .withMessage("보너스 번호는 당첨 번호와 중복 될 수 없습니다. - " + bonusNumber); + } + + @DisplayName("당첨 번호의 갯수가 6개가 아니면 IllegalArgumentException throw") + @Test + void lessOrMoreNumberThrowException() { + List winningNumbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7); + int bonusNumber = 8; + + assertThatIllegalArgumentException() + .isThrownBy(() -> new LottoWinningTicket(winningNumbers, bonusNumber)) + .withMessage("로또 번호는 6개만 가능합니다. - " + winningNumbers); + } + + @DisplayName("당첨 번호가 중복되는 값이 있다면 IllegalArgumentException throw") + @Test + void duplicatedWinningNumberThrowException() { + List winningNumbers = Arrays.asList(1, 2, 3, 3, 4, 5); + int bonusNumber = 8; + + assertThatIllegalArgumentException() + .isThrownBy(() -> new LottoWinningTicket(winningNumbers, bonusNumber)) + .withMessageContaining("로또 번호는 중복 될 수 없습니다."); + } +} diff --git a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java new file mode 100644 index 0000000..9a611d9 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java @@ -0,0 +1,43 @@ +package com.javabom.lotto.domain.vo; + +import com.javabom.lotto.domain.WinningSheet; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.*; + +class LottoMoneyTest { + + @DisplayName("로또를 1장 이상 구매할 수 없으면 IllegalArgumentException throw") + @ParameterizedTest + @ValueSource(ints = {0, 100, 999}) + void cannotBuyLotto(int purchaseAmount) { + assertThatIllegalArgumentException() + .isThrownBy(() -> new LottoMoney(purchaseAmount)) + .withMessage("로또를 살 수 없습니다. - " + purchaseAmount); + } + + @DisplayName("입력받은 금액으로 구매 가능한 로또의 개수를 계산한다.") + @ParameterizedTest + @CsvSource({"1000, 1", "2499, 2", "14000, 14"}) + void calculateNumberOfTicket(int purchaseAmount, int expectNumberOfTicket) { + LottoMoney lottoMoney = new LottoMoney(purchaseAmount); + assertThat(lottoMoney.getNumberOfTicket()).isEqualTo(expectNumberOfTicket); + } + + @DisplayName("당첨 총액으로 수익률을 계산") + @Test + void calculateRateOfReturn() { + LottoMoney lottoMoney = new LottoMoney(2000); + int sumOfPrize = WinningSheet.FIFTH.getPrize() + WinningSheet.FOURTH.getPrize(); + + double rateOfReturn = lottoMoney.calculateRateOfReturn(sumOfPrize); + + assertThat(rateOfReturn).isEqualTo(sumOfPrize / 2000); + } +} From 8d34b91b5d3c64858567f4e57655402a1b930ba4 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 4 Jun 2020 16:51:50 +0900 Subject: [PATCH 03/13] =?UTF-8?q?feat(LottoMoney):=20=EC=88=98=EB=8F=99=20?= =?UTF-8?q?=EA=B0=9C=EC=88=98=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../javabom/lotto/domain/LottoMachine.java | 2 +- .../javabom/lotto/domain/vo/LottoMoney.java | 32 +++++++++++++------ .../com/javabom/lotto/view/OutputView.java | 2 +- .../lotto/domain/vo/LottoMoneyTest.java | 12 +++++-- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/javabom/lotto/domain/LottoMachine.java b/src/main/java/com/javabom/lotto/domain/LottoMachine.java index 5de77ad..919b6c2 100644 --- a/src/main/java/com/javabom/lotto/domain/LottoMachine.java +++ b/src/main/java/com/javabom/lotto/domain/LottoMachine.java @@ -13,7 +13,7 @@ private LottoMachine() { public static LottoBill purchaseLottoTicket(LottoMoney lottoMoney) { List lottoTickets = new ArrayList<>(); - for (int i = 0; i < lottoMoney.getNumberOfTicket(); i++) { + for (int i = 0; i < lottoMoney.getNumberOfAutoTicket(); i++) { lottoTickets.add(LottoTicket.ofAuto()); } diff --git a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java index 8b303a4..92a2bb8 100644 --- a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java +++ b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java @@ -2,19 +2,25 @@ public class LottoMoney { private static final int LOTTO_PRICE = 1000; - private final int purchaseAmount; - private final int numberOfTicket; + private int numberOfAutoTicket; + private int numberOfManualTicket; public LottoMoney(int purchaseAmount) { validatePurchaseAmount(purchaseAmount); - this.purchaseAmount = purchaseAmount; - this.numberOfTicket = purchaseAmount / LOTTO_PRICE; + this.numberOfAutoTicket = purchaseAmount / LOTTO_PRICE; + } + + public LottoMoney(int purchaseAmount, int numberOfManualTicket) { + validatePurchaseAmount(purchaseAmount); + validateNumberOfManualTicket(purchaseAmount, numberOfManualTicket); + this.numberOfManualTicket = numberOfManualTicket; + this.numberOfAutoTicket = purchaseAmount / LOTTO_PRICE - numberOfManualTicket; } public double calculateRateOfReturn(int profit) { - double rateOfReturn = profit / purchaseAmount; + int purchaseAmount = (numberOfAutoTicket + numberOfManualTicket) * LOTTO_PRICE; - return rateOfReturn; + return profit / purchaseAmount; } private void validatePurchaseAmount(int purchaseAmount) { @@ -23,11 +29,17 @@ private void validatePurchaseAmount(int purchaseAmount) { } } - public int getPurchaseAmount() { - return purchaseAmount; + private void validateNumberOfManualTicket(int purchaseAmount, int numberOfManualTicket) { + if (purchaseAmount < LOTTO_PRICE * numberOfManualTicket) { + throw new IllegalArgumentException("수동으로 구매할 수 있는 개수를 초과했습니다. - " + numberOfManualTicket); + } + } + + public int getNumberOfAutoTicket() { + return numberOfAutoTicket; } - public int getNumberOfTicket() { - return numberOfTicket; + public int getNumberOfManualTicket() { + return numberOfManualTicket; } } diff --git a/src/main/java/com/javabom/lotto/view/OutputView.java b/src/main/java/com/javabom/lotto/view/OutputView.java index c704f97..590a4c2 100644 --- a/src/main/java/com/javabom/lotto/view/OutputView.java +++ b/src/main/java/com/javabom/lotto/view/OutputView.java @@ -15,7 +15,7 @@ private OutputView() { } public static void printNumberOfTicket(LottoMoney lottoMoney) { - System.out.println(String.format("%d개를 구매했습니다.", lottoMoney.getNumberOfTicket())); + System.out.println(String.format("%d개를 구매했습니다.", lottoMoney.getNumberOfAutoTicket())); } public static void printLottoTickets(List lottoTickets) { diff --git a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java index 9a611d9..559446d 100644 --- a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java +++ b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java @@ -9,7 +9,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.junit.jupiter.api.Assertions.*; class LottoMoneyTest { @@ -27,7 +26,16 @@ void cannotBuyLotto(int purchaseAmount) { @CsvSource({"1000, 1", "2499, 2", "14000, 14"}) void calculateNumberOfTicket(int purchaseAmount, int expectNumberOfTicket) { LottoMoney lottoMoney = new LottoMoney(purchaseAmount); - assertThat(lottoMoney.getNumberOfTicket()).isEqualTo(expectNumberOfTicket); + assertThat(lottoMoney.getNumberOfAutoTicket()).isEqualTo(expectNumberOfTicket); + } + + @DisplayName("수동으로 할 티켓의 수가 입력한 금액으로 구매할 수 없으면 IllegalArgumentException throw") + @ParameterizedTest + @CsvSource({"1000, 2", "3000, 6"}) + void manualTicketOverPurchaseAmountThrowException(int purchaseAmount, int numberOfManualTicket) { + assertThatIllegalArgumentException() + .isThrownBy(() -> new LottoMoney(purchaseAmount, numberOfManualTicket)) + .withMessage("수동으로 구매할 수 있는 개수를 초과했습니다. - " + numberOfManualTicket); } @DisplayName("당첨 총액으로 수익률을 계산") From 3580cdbc3730c304d5010e6aef331c5071bbd3b5 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 4 Jun 2020 16:55:33 +0900 Subject: [PATCH 04/13] =?UTF-8?q?refactor(LottoMoneyTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/javabom/lotto/domain/vo/LottoMoneyTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java index 559446d..f4e8fd2 100644 --- a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java +++ b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java @@ -17,16 +17,16 @@ class LottoMoneyTest { @ValueSource(ints = {0, 100, 999}) void cannotBuyLotto(int purchaseAmount) { assertThatIllegalArgumentException() - .isThrownBy(() -> new LottoMoney(purchaseAmount)) + .isThrownBy(() -> new LottoMoney(purchaseAmount, 1)) .withMessage("로또를 살 수 없습니다. - " + purchaseAmount); } - @DisplayName("입력받은 금액으로 구매 가능한 로또의 개수를 계산한다.") + @DisplayName("입력받은 금액과 수동로또 개수로 자동 로또의 개수를 계산한다.") @ParameterizedTest - @CsvSource({"1000, 1", "2499, 2", "14000, 14"}) - void calculateNumberOfTicket(int purchaseAmount, int expectNumberOfTicket) { - LottoMoney lottoMoney = new LottoMoney(purchaseAmount); - assertThat(lottoMoney.getNumberOfAutoTicket()).isEqualTo(expectNumberOfTicket); + @CsvSource({"1000, 1, 0", "2499, 1, 1", "14000, 12, 2"}) + void calculateNumberOfTicket(int purchaseAmount, int numberOfManualTicket, int expectNumberOfAutoTicket) { + LottoMoney lottoMoney = new LottoMoney(purchaseAmount, numberOfManualTicket); + assertThat(lottoMoney.getNumberOfAutoTicket()).isEqualTo(expectNumberOfAutoTicket); } @DisplayName("수동으로 할 티켓의 수가 입력한 금액으로 구매할 수 없으면 IllegalArgumentException throw") From 30702ffd172104aed864322c79dc2e72abc88605 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 4 Jun 2020 17:05:00 +0900 Subject: [PATCH 05/13] =?UTF-8?q?refactor(InputView):=20=EC=88=98=EB=8F=99?= =?UTF-8?q?=20=EA=B0=9C=EC=88=98=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD,=20InputView=EC=97=90=20LottoMon?= =?UTF-8?q?ey=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/javabom/lotto/LottoApplication.java | 7 +++++-- .../java/com/javabom/lotto/view/InputView.java | 15 ++++++++++++--- .../java/com/javabom/lotto/view/OutputView.java | 3 ++- .../javabom/lotto/domain/vo/LottoMoneyTest.java | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/javabom/lotto/LottoApplication.java b/src/main/java/com/javabom/lotto/LottoApplication.java index 77bb245..3eb7822 100644 --- a/src/main/java/com/javabom/lotto/LottoApplication.java +++ b/src/main/java/com/javabom/lotto/LottoApplication.java @@ -12,12 +12,15 @@ public class LottoApplication { public static void main(String[] args) { - LottoMoney lottoMoney = InputView.inputPurchaseAmount(); + int purchaseAmount = InputView.inputPurchaseAmount(); + int numberOfManualTicket = InputView.inputNumberOfManualTicket(); + + LottoMoney lottoMoney = new LottoMoney(purchaseAmount, numberOfManualTicket); - OutputView.printNumberOfTicket(lottoMoney); LottoBill lottoBill = LottoMachine.purchaseLottoTicket(lottoMoney); + OutputView.printNumberOfTicket(lottoMoney); OutputView.printLottoTickets(lottoBill.getAllTickets()); List winningNumbers = InputView.inputLastWinningNumbers(); diff --git a/src/main/java/com/javabom/lotto/view/InputView.java b/src/main/java/com/javabom/lotto/view/InputView.java index 69b1306..a5d6f66 100644 --- a/src/main/java/com/javabom/lotto/view/InputView.java +++ b/src/main/java/com/javabom/lotto/view/InputView.java @@ -14,12 +14,21 @@ public class InputView { private InputView() { } - public static LottoMoney inputPurchaseAmount() { + public static int inputPurchaseAmount() { System.out.println("구입금액을 입력해 주세요."); try { - int purchaseAmount = Integer.parseInt(SCANNER.nextLine()); - return new LottoMoney(purchaseAmount); + return Integer.parseInt(SCANNER.nextLine()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자를 입력해 주세요."); + } + } + + public static int inputNumberOfManualTicket() { + System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); + + try { + return Integer.parseInt(SCANNER.nextLine()); } catch (NumberFormatException e) { throw new IllegalArgumentException("숫자를 입력해 주세요."); } diff --git a/src/main/java/com/javabom/lotto/view/OutputView.java b/src/main/java/com/javabom/lotto/view/OutputView.java index 590a4c2..f720dad 100644 --- a/src/main/java/com/javabom/lotto/view/OutputView.java +++ b/src/main/java/com/javabom/lotto/view/OutputView.java @@ -15,7 +15,8 @@ private OutputView() { } public static void printNumberOfTicket(LottoMoney lottoMoney) { - System.out.println(String.format("%d개를 구매했습니다.", lottoMoney.getNumberOfAutoTicket())); + System.out.println(String.format("수동으로 %d개, 자동으로 %d개를 구매했습니다.", lottoMoney.getNumberOfManualTicket() + , lottoMoney.getNumberOfAutoTicket())); } public static void printLottoTickets(List lottoTickets) { diff --git a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java index f4e8fd2..01b3b3b 100644 --- a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java +++ b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java @@ -41,7 +41,7 @@ void manualTicketOverPurchaseAmountThrowException(int purchaseAmount, int number @DisplayName("당첨 총액으로 수익률을 계산") @Test void calculateRateOfReturn() { - LottoMoney lottoMoney = new LottoMoney(2000); + LottoMoney lottoMoney = new LottoMoney(2000, 0); int sumOfPrize = WinningSheet.FIFTH.getPrize() + WinningSheet.FOURTH.getPrize(); double rateOfReturn = lottoMoney.calculateRateOfReturn(sumOfPrize); From 484b98e6c848d69c85c32b744b05972ba96958cd Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 4 Jun 2020 17:51:10 +0900 Subject: [PATCH 06/13] =?UTF-8?q?feat(ManualNumbersDto):=20=EC=88=98?= =?UTF-8?q?=EB=8F=99=EC=9C=BC=EB=A1=9C=20=EC=9E=85=EB=A0=A5=EB=B0=9B?= =?UTF-8?q?=EC=9D=80=20=EB=B2=88=ED=98=B8=EB=A5=BC=20Integer=EB=A1=9C=20pa?= =?UTF-8?q?rsing=ED=95=B4=EC=84=9C=20List=EB=A1=9C=20=EB=A7=8C=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EC=A3=BC=EB=8A=94=20Dto=20refactor(LottoMachine):=20?= =?UTF-8?q?=EC=88=98=EB=8F=99=20=EB=B2=88=ED=98=B8=EC=99=80=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=20=EA=B0=9C=EC=88=98=EB=A5=BC=20=EB=B0=9B=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/javabom/lotto/LottoApplication.java | 7 +++++- .../javabom/lotto/domain/LottoMachine.java | 10 +++++--- .../lotto/domain/dto/ManualNumbersDto.java | 25 +++++++++++++++++++ .../com/javabom/lotto/view/InputView.java | 16 +++++++++++- .../lotto/domain/LottoMachineTest.java | 25 ++++++++++++++----- .../domain/dto/ManualNumbersDtoTest.java | 25 +++++++++++++++++++ 6 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/javabom/lotto/domain/dto/ManualNumbersDto.java create mode 100644 src/test/java/com/javabom/lotto/domain/dto/ManualNumbersDtoTest.java diff --git a/src/main/java/com/javabom/lotto/LottoApplication.java b/src/main/java/com/javabom/lotto/LottoApplication.java index 3eb7822..aae36b9 100644 --- a/src/main/java/com/javabom/lotto/LottoApplication.java +++ b/src/main/java/com/javabom/lotto/LottoApplication.java @@ -3,6 +3,7 @@ import com.javabom.lotto.domain.LottoBill; import com.javabom.lotto.domain.LottoMachine; import com.javabom.lotto.domain.LottoResult; +import com.javabom.lotto.domain.dto.ManualNumbersDto; import com.javabom.lotto.domain.ticket.LottoWinningTicket; import com.javabom.lotto.domain.vo.LottoMoney; import com.javabom.lotto.view.InputView; @@ -13,17 +14,21 @@ public class LottoApplication { public static void main(String[] args) { int purchaseAmount = InputView.inputPurchaseAmount(); + int numberOfManualTicket = InputView.inputNumberOfManualTicket(); LottoMoney lottoMoney = new LottoMoney(purchaseAmount, numberOfManualTicket); + List manualNumbersDtos = InputView.inputManualNumber(lottoMoney.getNumberOfManualTicket()); - LottoBill lottoBill = LottoMachine.purchaseLottoTicket(lottoMoney); + LottoBill lottoBill = LottoMachine.purchaseLottoTicket(manualNumbersDtos, lottoMoney.getNumberOfAutoTicket()); OutputView.printNumberOfTicket(lottoMoney); + OutputView.printLottoTickets(lottoBill.getAllTickets()); List winningNumbers = InputView.inputLastWinningNumbers(); + int bonusNumber = InputView.inputBonusNumber(); LottoWinningTicket lottoWinningTicket = new LottoWinningTicket(winningNumbers, bonusNumber); diff --git a/src/main/java/com/javabom/lotto/domain/LottoMachine.java b/src/main/java/com/javabom/lotto/domain/LottoMachine.java index 919b6c2..7c7e2e7 100644 --- a/src/main/java/com/javabom/lotto/domain/LottoMachine.java +++ b/src/main/java/com/javabom/lotto/domain/LottoMachine.java @@ -1,19 +1,23 @@ package com.javabom.lotto.domain; +import com.javabom.lotto.domain.dto.ManualNumbersDto; import com.javabom.lotto.domain.ticket.LottoTicket; import com.javabom.lotto.domain.vo.LottoMoney; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class LottoMachine { private LottoMachine() { } - public static LottoBill purchaseLottoTicket(LottoMoney lottoMoney) { - List lottoTickets = new ArrayList<>(); + public static LottoBill purchaseLottoTicket(List manualNumbersDtos, int numberOfAutoTicket) { + List lottoTickets = manualNumbersDtos.stream() + .map(manualNumbersDto -> LottoTicket.ofFixed(manualNumbersDto.getManualNumbers())) + .collect(Collectors.toList()); - for (int i = 0; i < lottoMoney.getNumberOfAutoTicket(); i++) { + for (int i = 0; i < numberOfAutoTicket; i++) { lottoTickets.add(LottoTicket.ofAuto()); } diff --git a/src/main/java/com/javabom/lotto/domain/dto/ManualNumbersDto.java b/src/main/java/com/javabom/lotto/domain/dto/ManualNumbersDto.java new file mode 100644 index 0000000..da49772 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/dto/ManualNumbersDto.java @@ -0,0 +1,25 @@ +package com.javabom.lotto.domain.dto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ManualNumbersDto { + private final List manualNumbers; + + public ManualNumbersDto(String[] manualNumbers) { + try { + this.manualNumbers = Stream.of(manualNumbers) + .map(String::trim) + .map(Integer::parseInt) + .collect(Collectors.toList()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자를 입력해 주세요. - " + Arrays.toString(manualNumbers)); + } + } + + public List getManualNumbers() { + return manualNumbers; + } +} diff --git a/src/main/java/com/javabom/lotto/view/InputView.java b/src/main/java/com/javabom/lotto/view/InputView.java index a5d6f66..e7f75e4 100644 --- a/src/main/java/com/javabom/lotto/view/InputView.java +++ b/src/main/java/com/javabom/lotto/view/InputView.java @@ -1,7 +1,8 @@ package com.javabom.lotto.view; -import com.javabom.lotto.domain.vo.LottoMoney; +import com.javabom.lotto.domain.dto.ManualNumbersDto; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Scanner; @@ -34,6 +35,19 @@ public static int inputNumberOfManualTicket() { } } + public static List inputManualNumber(int numberOfManualTicket) { + System.out.println("수동으로 구매할 번호를 입력해 주세요."); + + List manualNumbersDtos = new ArrayList<>(); + + for (int i = 0; i < numberOfManualTicket; i++) { + String[] manualNumbers = SCANNER.nextLine().split(DELIMITER); + manualNumbersDtos.add(new ManualNumbersDto(manualNumbers)); + } + + return manualNumbersDtos; + } + public static List inputLastWinningNumbers() { System.out.println("지난 주 당첨 번호를 입력해 주세요."); diff --git a/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java b/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java index 3f04927..fbd8d9b 100644 --- a/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java +++ b/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java @@ -1,24 +1,37 @@ package com.javabom.lotto.domain; +import com.javabom.lotto.domain.dto.ManualNumbersDto; import com.javabom.lotto.domain.ticket.LottoTicket; import com.javabom.lotto.domain.vo.LottoMoney; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; class LottoMachineTest { - @DisplayName("구입 금액에 맞는 로또 티켓을 생성한다.") + private static Stream provideManualLottoNumbersAndNumberOfAutoTicket() { + return Stream.of( + Arguments.of(new ArrayList(), 2, 2), + Arguments.of(Arrays.asList(new ManualNumbersDto(new String[]{"1", "2", "3", "4", "5", "6"})), 1, 2) + ); + } + + @DisplayName("수동 로또 개수와 자동 로또 개수에 맞는 로또 티켓을 생성한다.") @ParameterizedTest - @CsvSource({"1000, 1", "3500, 3", "14000, 14"}) - void purchaseLottoTicket(int purchaseAmount, int ticketAmount) { - LottoMoney lottoMoney = new LottoMoney(purchaseAmount); - LottoBill lottoBill = LottoMachine.purchaseLottoTicket(lottoMoney); + @MethodSource("provideManualLottoNumbersAndNumberOfAutoTicket") + void purchaseLottoTicket(List manualNumbersDtos, int numberOfAutoTicket, int expectedResult) { + LottoBill lottoBill = LottoMachine.purchaseLottoTicket(manualNumbersDtos, numberOfAutoTicket); - assertThat(lottoBill.getAllTickets().size()).isEqualTo(ticketAmount); + assertThat(lottoBill.getAllTickets().size()).isEqualTo(expectedResult); } } diff --git a/src/test/java/com/javabom/lotto/domain/dto/ManualNumbersDtoTest.java b/src/test/java/com/javabom/lotto/domain/dto/ManualNumbersDtoTest.java new file mode 100644 index 0000000..bdeb306 --- /dev/null +++ b/src/test/java/com/javabom/lotto/domain/dto/ManualNumbersDtoTest.java @@ -0,0 +1,25 @@ +package com.javabom.lotto.domain.dto; + +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 static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.*; + +class ManualNumbersDtoTest { + + @DisplayName("숫자가 아닌값이 들어오면 IllegalArgumentException Throw") + @ParameterizedTest + @ValueSource(strings = {"1,2,3,a,5,6", "1,2,,, ,4"}) + void parseStringSplits(String stringNumbers) { + String[] splits = stringNumbers.split(","); + + assertThatIllegalArgumentException() + .isThrownBy(() -> new ManualNumbersDto(splits)) + .withMessage("숫자를 입력해 주세요. - " + Arrays.toString(splits)); + } +} \ No newline at end of file From c4e9ca039faec174a601e18862c0eb45e2d27cb4 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Fri, 5 Jun 2020 14:01:49 +0900 Subject: [PATCH 07/13] =?UTF-8?q?refactor():=20=EC=82=AC=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=83=9D=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=EB=B0=8F=20getter=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../javabom/lotto/domain/ticket/LottoWinningTicket.java | 8 -------- src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java | 5 ----- 2 files changed, 13 deletions(-) diff --git a/src/main/java/com/javabom/lotto/domain/ticket/LottoWinningTicket.java b/src/main/java/com/javabom/lotto/domain/ticket/LottoWinningTicket.java index 18d2928..364de5d 100644 --- a/src/main/java/com/javabom/lotto/domain/ticket/LottoWinningTicket.java +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoWinningTicket.java @@ -17,14 +17,6 @@ public LottoWinningTicket(List winningNumbers, int bonusNumber) { this.bonusNumber = LottoNumber.valueOf(bonusNumber); } - public LottoTicket getWinningTicket() { - return winningTicket; - } - - public LottoNumber getBonusNumber() { - return bonusNumber; - } - private void validateDuplicateBonusNumber(List winningNumbers, int bonusNumber) { if (winningNumbers.contains(bonusNumber)) { throw new IllegalArgumentException("보너스 번호는 당첨 번호와 중복 될 수 없습니다. - " + bonusNumber); diff --git a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java index 92a2bb8..049271f 100644 --- a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java +++ b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java @@ -5,11 +5,6 @@ public class LottoMoney { private int numberOfAutoTicket; private int numberOfManualTicket; - public LottoMoney(int purchaseAmount) { - validatePurchaseAmount(purchaseAmount); - this.numberOfAutoTicket = purchaseAmount / LOTTO_PRICE; - } - public LottoMoney(int purchaseAmount, int numberOfManualTicket) { validatePurchaseAmount(purchaseAmount); validateNumberOfManualTicket(purchaseAmount, numberOfManualTicket); From c8149df93da384f5a6fb2da3103bd8c33fee6ec2 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Fri, 5 Jun 2020 14:02:51 +0900 Subject: [PATCH 08/13] =?UTF-8?q?refactor(LottoMoney):=20return=20?= =?UTF-8?q?=EA=B0=92=20=EA=B3=84=EC=82=B0=20double=EB=A1=9C=20=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java index 049271f..53395a9 100644 --- a/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java +++ b/src/main/java/com/javabom/lotto/domain/vo/LottoMoney.java @@ -13,7 +13,7 @@ public LottoMoney(int purchaseAmount, int numberOfManualTicket) { } public double calculateRateOfReturn(int profit) { - int purchaseAmount = (numberOfAutoTicket + numberOfManualTicket) * LOTTO_PRICE; + double purchaseAmount = (numberOfAutoTicket + numberOfManualTicket) * LOTTO_PRICE; return profit / purchaseAmount; } From 492d40088797cc94ca6facc0e725b1b3f2a76ca4 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 11 Jun 2020 16:04:42 +0900 Subject: [PATCH 09/13] =?UTF-8?q?refactor(LottoBill):=20LottoBill=20->=20L?= =?UTF-8?q?ottoTickets=20=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD,=20drawAllLotto()=20->=20matchAllLotto()=20=EB=A1=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/javabom/lotto/LottoApplication.java | 8 ++++---- src/main/java/com/javabom/lotto/domain/LottoMachine.java | 6 ++---- .../lotto/domain/{LottoBill.java => LottoTickets.java} | 6 +++--- .../java/com/javabom/lotto/domain/LottoMachineTest.java | 8 ++------ .../domain/{LottoBillTest.java => LottoTicketsTest.java} | 7 +++---- 5 files changed, 14 insertions(+), 21 deletions(-) rename src/main/java/com/javabom/lotto/domain/{LottoBill.java => LottoTickets.java} (79%) rename src/test/java/com/javabom/lotto/domain/{LottoBillTest.java => LottoTicketsTest.java} (81%) diff --git a/src/main/java/com/javabom/lotto/LottoApplication.java b/src/main/java/com/javabom/lotto/LottoApplication.java index aae36b9..ac99e66 100644 --- a/src/main/java/com/javabom/lotto/LottoApplication.java +++ b/src/main/java/com/javabom/lotto/LottoApplication.java @@ -1,6 +1,6 @@ package com.javabom.lotto; -import com.javabom.lotto.domain.LottoBill; +import com.javabom.lotto.domain.LottoTickets; import com.javabom.lotto.domain.LottoMachine; import com.javabom.lotto.domain.LottoResult; import com.javabom.lotto.domain.dto.ManualNumbersDto; @@ -21,11 +21,11 @@ public static void main(String[] args) { List manualNumbersDtos = InputView.inputManualNumber(lottoMoney.getNumberOfManualTicket()); - LottoBill lottoBill = LottoMachine.purchaseLottoTicket(manualNumbersDtos, lottoMoney.getNumberOfAutoTicket()); + LottoTickets lottoTickets = LottoMachine.purchaseLottoTicket(manualNumbersDtos, lottoMoney.getNumberOfAutoTicket()); OutputView.printNumberOfTicket(lottoMoney); - OutputView.printLottoTickets(lottoBill.getAllTickets()); + OutputView.printLottoTickets(lottoTickets.getAllTickets()); List winningNumbers = InputView.inputLastWinningNumbers(); @@ -33,7 +33,7 @@ public static void main(String[] args) { LottoWinningTicket lottoWinningTicket = new LottoWinningTicket(winningNumbers, bonusNumber); - LottoResult lottoResult = lottoBill.drawAllLotto(lottoWinningTicket); + LottoResult lottoResult = lottoTickets.matchAllLotto(lottoWinningTicket); OutputView.printWinningStatistics(lottoResult, lottoMoney); } diff --git a/src/main/java/com/javabom/lotto/domain/LottoMachine.java b/src/main/java/com/javabom/lotto/domain/LottoMachine.java index 7c7e2e7..e29cc45 100644 --- a/src/main/java/com/javabom/lotto/domain/LottoMachine.java +++ b/src/main/java/com/javabom/lotto/domain/LottoMachine.java @@ -2,9 +2,7 @@ import com.javabom.lotto.domain.dto.ManualNumbersDto; import com.javabom.lotto.domain.ticket.LottoTicket; -import com.javabom.lotto.domain.vo.LottoMoney; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -12,7 +10,7 @@ public class LottoMachine { private LottoMachine() { } - public static LottoBill purchaseLottoTicket(List manualNumbersDtos, int numberOfAutoTicket) { + public static LottoTickets purchaseLottoTicket(List manualNumbersDtos, int numberOfAutoTicket) { List lottoTickets = manualNumbersDtos.stream() .map(manualNumbersDto -> LottoTicket.ofFixed(manualNumbersDto.getManualNumbers())) .collect(Collectors.toList()); @@ -21,6 +19,6 @@ public static LottoBill purchaseLottoTicket(List manualNumbers lottoTickets.add(LottoTicket.ofAuto()); } - return new LottoBill(lottoTickets); + return new LottoTickets(lottoTickets); } } diff --git a/src/main/java/com/javabom/lotto/domain/LottoBill.java b/src/main/java/com/javabom/lotto/domain/LottoTickets.java similarity index 79% rename from src/main/java/com/javabom/lotto/domain/LottoBill.java rename to src/main/java/com/javabom/lotto/domain/LottoTickets.java index ec4fafa..cbee1da 100644 --- a/src/main/java/com/javabom/lotto/domain/LottoBill.java +++ b/src/main/java/com/javabom/lotto/domain/LottoTickets.java @@ -7,14 +7,14 @@ import java.util.List; import java.util.stream.Collectors; -public class LottoBill { +public class LottoTickets { private final List lottoTickets; - public LottoBill(List lottoTickets) { + public LottoTickets(List lottoTickets) { this.lottoTickets = lottoTickets; } - public LottoResult drawAllLotto(LottoWinningTicket lottoWinningTicket) { + public LottoResult matchAllLotto(LottoWinningTicket lottoWinningTicket) { return lottoTickets.stream() .map(lottoWinningTicket::findMatchingSheet) .collect(Collectors.collectingAndThen(Collectors.toList(), LottoResult::new)); diff --git a/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java b/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java index fbd8d9b..fc21119 100644 --- a/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java +++ b/src/test/java/com/javabom/lotto/domain/LottoMachineTest.java @@ -1,17 +1,13 @@ package com.javabom.lotto.domain; import com.javabom.lotto.domain.dto.ManualNumbersDto; -import com.javabom.lotto.domain.ticket.LottoTicket; -import com.javabom.lotto.domain.vo.LottoMoney; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.MethodSource; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.stream.Stream; @@ -30,8 +26,8 @@ private static Stream provideManualLottoNumbersAndNumberOfAutoTicket( @ParameterizedTest @MethodSource("provideManualLottoNumbersAndNumberOfAutoTicket") void purchaseLottoTicket(List manualNumbersDtos, int numberOfAutoTicket, int expectedResult) { - LottoBill lottoBill = LottoMachine.purchaseLottoTicket(manualNumbersDtos, numberOfAutoTicket); + LottoTickets lottoTickets = LottoMachine.purchaseLottoTicket(manualNumbersDtos, numberOfAutoTicket); - assertThat(lottoBill.getAllTickets().size()).isEqualTo(expectedResult); + assertThat(lottoTickets.getAllTickets().size()).isEqualTo(expectedResult); } } diff --git a/src/test/java/com/javabom/lotto/domain/LottoBillTest.java b/src/test/java/com/javabom/lotto/domain/LottoTicketsTest.java similarity index 81% rename from src/test/java/com/javabom/lotto/domain/LottoBillTest.java rename to src/test/java/com/javabom/lotto/domain/LottoTicketsTest.java index 31a2bf7..7d24aa4 100644 --- a/src/test/java/com/javabom/lotto/domain/LottoBillTest.java +++ b/src/test/java/com/javabom/lotto/domain/LottoTicketsTest.java @@ -8,9 +8,8 @@ import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; -class LottoBillTest { +class LottoTicketsTest { @DisplayName("모든 로또 티켓과 당첨 번호를 비교하여 추첨 결과를 반환한다.") @Test void drawAllLotto() { @@ -20,9 +19,9 @@ void drawAllLotto() { LottoWinningTicket lottoWinningTicket = new LottoWinningTicket(Arrays.asList(1, 2, 3, 4, 5, 6), 7); - LottoBill lottoBill = new LottoBill(Arrays.asList(ticket1, ticket2, ticket3)); + LottoTickets lottoTickets = new LottoTickets(Arrays.asList(ticket1, ticket2, ticket3)); - LottoResult lottoResult = lottoBill.drawAllLotto(lottoWinningTicket); + LottoResult lottoResult = lottoTickets.matchAllLotto(lottoWinningTicket); LottoResult expectedResult = new LottoResult(Arrays.asList(WinningSheet.FIRST, WinningSheet.SECOND , WinningSheet.THIRD)); From 7dd512b767fc8ee064bfba4a328d712e3d0db69c Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 11 Jun 2020 16:32:22 +0900 Subject: [PATCH 10/13] =?UTF-8?q?feat(NumberGenerator):=20=EC=9D=B8?= =?UTF-8?q?=EC=9E=90=EB=A1=9C=20=EB=B0=9B=EC=9D=80=20=EC=B5=9C=EC=86=9F?= =?UTF-8?q?=EA=B0=92=EA=B3=BC=20=EC=B5=9C=EB=8C=93=EA=B0=92=20=EC=82=AC?= =?UTF-8?q?=EC=9D=B4=EC=9D=98=20=EC=A0=95=EC=88=98=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20refactor(LottoNumberGenerator):=20generateRandomNum?= =?UTF-8?q?ber=EA=B0=80=20=EC=9D=B8=EC=9E=90=EB=A1=9C=20NumberGenerator=20?= =?UTF-8?q?=EB=A5=BC=20=EB=B0=9B=EC=95=84=EC=84=9C=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD=20refactor(Lot?= =?UTF-8?q?toTicket):=20ofAuto()=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=9D=B8?= =?UTF-8?q?=EC=9E=90=EB=A1=9C=20NumberGenerator=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EC=B2=B4=EB=A5=BC=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../javabom/lotto/domain/LottoMachine.java | 3 ++- .../domain/number/LottoNumberGenerator.java | 8 ++------ .../lotto/domain/number/NumberGenerator.java | 7 +++++++ .../number/ShuffledNumberGenerator.java | 19 +++++++++++++++++++ .../lotto/domain/ticket/LottoTicket.java | 6 ++++-- .../number/LottoNumberGeneratorTest.java | 6 +++++- .../lotto/domain/ticket/LottoTicketTest.java | 11 +++++++++++ .../lotto/domain/vo/LottoMoneyTest.java | 2 +- 8 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/javabom/lotto/domain/number/NumberGenerator.java create mode 100644 src/main/java/com/javabom/lotto/domain/number/ShuffledNumberGenerator.java diff --git a/src/main/java/com/javabom/lotto/domain/LottoMachine.java b/src/main/java/com/javabom/lotto/domain/LottoMachine.java index e29cc45..d88650d 100644 --- a/src/main/java/com/javabom/lotto/domain/LottoMachine.java +++ b/src/main/java/com/javabom/lotto/domain/LottoMachine.java @@ -1,6 +1,7 @@ package com.javabom.lotto.domain; import com.javabom.lotto.domain.dto.ManualNumbersDto; +import com.javabom.lotto.domain.number.ShuffledNumberGenerator; import com.javabom.lotto.domain.ticket.LottoTicket; import java.util.List; @@ -16,7 +17,7 @@ public static LottoTickets purchaseLottoTicket(List manualNumb .collect(Collectors.toList()); for (int i = 0; i < numberOfAutoTicket; i++) { - lottoTickets.add(LottoTicket.ofAuto()); + lottoTickets.add(LottoTicket.ofAuto(new ShuffledNumberGenerator())); } return new LottoTickets(lottoTickets); diff --git a/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java b/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java index 7423f22..7728a3e 100644 --- a/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java +++ b/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java @@ -13,12 +13,8 @@ public class LottoNumberGenerator { private static final int FIRST_ELEMENT = 0; - public static Set generateRandomNumber(int size) { - List numbers = IntStream.rangeClosed(LOTTO_NUMBER_UNDER_BOUND, LOTTO_NUMBER_UPPER_BOUND) - .boxed() - .collect(Collectors.toList()); - - Collections.shuffle(numbers); + public static Set generateRandomNumber(int size, NumberGenerator numberGenerator) { + List numbers = numberGenerator.generate(LOTTO_NUMBER_UNDER_BOUND, LOTTO_NUMBER_UPPER_BOUND); return convertIntegerToLottoNumber(numbers.subList(FIRST_ELEMENT, size)); } diff --git a/src/main/java/com/javabom/lotto/domain/number/NumberGenerator.java b/src/main/java/com/javabom/lotto/domain/number/NumberGenerator.java new file mode 100644 index 0000000..69476e8 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/number/NumberGenerator.java @@ -0,0 +1,7 @@ +package com.javabom.lotto.domain.number; + +import java.util.List; + +public interface NumberGenerator { + List generate(int min, int max); +} diff --git a/src/main/java/com/javabom/lotto/domain/number/ShuffledNumberGenerator.java b/src/main/java/com/javabom/lotto/domain/number/ShuffledNumberGenerator.java new file mode 100644 index 0000000..e4c1336 --- /dev/null +++ b/src/main/java/com/javabom/lotto/domain/number/ShuffledNumberGenerator.java @@ -0,0 +1,19 @@ +package com.javabom.lotto.domain.number; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class ShuffledNumberGenerator implements NumberGenerator { + @Override + public List generate(int min, int max) { + List numbers = IntStream.rangeClosed(min, max) + .boxed() + .collect(Collectors.toList()); + + Collections.shuffle(numbers); + + return numbers; + } +} diff --git a/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java index 1a18fca..425e39f 100644 --- a/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java @@ -2,6 +2,8 @@ import com.javabom.lotto.domain.number.LottoNumber; import com.javabom.lotto.domain.number.LottoNumberGenerator; +import com.javabom.lotto.domain.number.NumberGenerator; +import com.javabom.lotto.domain.number.ShuffledNumberGenerator; import java.util.List; import java.util.Set; @@ -21,8 +23,8 @@ public static LottoTicket ofFixed(List numbers) { return new LottoTicket(LottoNumberGenerator.generateFixedNumber(numbers)); } - public static LottoTicket ofAuto() { - return new LottoTicket(LottoNumberGenerator.generateRandomNumber(LOTTO_NUMBERS_SIZE)); + public static LottoTicket ofAuto(NumberGenerator numberGenerator) { + return new LottoTicket(LottoNumberGenerator.generateRandomNumber(LOTTO_NUMBERS_SIZE, numberGenerator)); } public List getLottoNumbers() { diff --git a/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java b/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java index beadeb7..0d48933 100644 --- a/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java +++ b/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java @@ -8,6 +8,8 @@ import java.util.Arrays; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -19,7 +21,9 @@ class LottoNumberGeneratorTest { @ParameterizedTest @ValueSource(ints = {1, 2, 3, 4, 5}) void generateRandomNumber(int size) { - Set lottoNumbers = LottoNumberGenerator.generateRandomNumber(size); + Set lottoNumbers = LottoNumberGenerator.generateRandomNumber(size, (min, max) -> IntStream.rangeClosed(1, size) + .boxed() + .collect(Collectors.toList())); assertThat(lottoNumbers.size()).isEqualTo(size); } diff --git a/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java index 836e71e..363f1d4 100644 --- a/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java +++ b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java @@ -1,6 +1,7 @@ package com.javabom.lotto.domain.ticket; import com.javabom.lotto.domain.number.LottoNumber; +import com.javabom.lotto.domain.number.NumberGenerator; import com.javabom.lotto.domain.ticket.LottoTicket; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -16,6 +17,16 @@ class LottoTicketTest { + @DisplayName("1 ~ 45 사이의 자동 티켓 생성") + @Test + void lottoTicketOfAuto() { + NumberGenerator testNumberGenerator = (min, max) -> Arrays.asList(1, 2, 3, 4, 5, 6); + + LottoTicket lottoTicket = LottoTicket.ofAuto(testNumberGenerator); + + assertThat(lottoTicket.getLottoNumbers()).containsExactly(1, 2, 3, 4, 5, 6); + } + @DisplayName("LottoNumber 리스트의 크기가 6이 아니면 IllegalArgumentException Throw") @Test void lottoTicketThrowsExceptionWhenSizeOver() { diff --git a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java index 01b3b3b..cbc395f 100644 --- a/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java +++ b/src/test/java/com/javabom/lotto/domain/vo/LottoMoneyTest.java @@ -46,6 +46,6 @@ void calculateRateOfReturn() { double rateOfReturn = lottoMoney.calculateRateOfReturn(sumOfPrize); - assertThat(rateOfReturn).isEqualTo(sumOfPrize / 2000); + assertThat(rateOfReturn).isEqualTo(sumOfPrize / 2000D); } } From 5e3a58fe484953096270672b7f2021db30754b4d Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 11 Jun 2020 16:41:52 +0900 Subject: [PATCH 11/13] =?UTF-8?q?refactor(LottoNumberGenerator,=20LottoTic?= =?UTF-8?q?ket):=20=EC=9E=90=EB=A3=8C=EA=B5=AC=EC=A1=B0=20Set=20=EC=97=90?= =?UTF-8?q?=EC=84=9C=20List=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lotto/domain/number/LottoNumberGenerator.java | 9 ++++----- .../com/javabom/lotto/domain/ticket/LottoTicket.java | 12 ++++++++---- .../domain/number/LottoNumberGeneratorTest.java | 6 +++--- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java b/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java index 7728a3e..f1eace6 100644 --- a/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java +++ b/src/main/java/com/javabom/lotto/domain/number/LottoNumberGenerator.java @@ -13,20 +13,19 @@ public class LottoNumberGenerator { private static final int FIRST_ELEMENT = 0; - public static Set generateRandomNumber(int size, NumberGenerator numberGenerator) { + public static List generateRandomNumber(int size, NumberGenerator numberGenerator) { List numbers = numberGenerator.generate(LOTTO_NUMBER_UNDER_BOUND, LOTTO_NUMBER_UPPER_BOUND); return convertIntegerToLottoNumber(numbers.subList(FIRST_ELEMENT, size)); } - public static Set generateFixedNumber(List numbers) { + public static List generateFixedNumber(List numbers) { return convertIntegerToLottoNumber(numbers); } - private static Set convertIntegerToLottoNumber(List numbers) { + private static List convertIntegerToLottoNumber(List numbers) { return numbers.stream() - .sorted() .map(LottoNumber::valueOf) - .collect(Collectors.toCollection(TreeSet::new)); + .collect(Collectors.toList()); } } diff --git a/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java index 425e39f..727ddd1 100644 --- a/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java @@ -5,15 +5,16 @@ import com.javabom.lotto.domain.number.NumberGenerator; import com.javabom.lotto.domain.number.ShuffledNumberGenerator; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class LottoTicket { private static final int LOTTO_NUMBERS_SIZE = 6; - private final Set lottoNumbers; + private final List lottoNumbers; - private LottoTicket(Set lottoNumbers) { + private LottoTicket(List lottoNumbers) { validateDuplicateNumbers(lottoNumbers); this.lottoNumbers = lottoNumbers; } @@ -43,8 +44,11 @@ public boolean isContainingLottoNumbers(LottoNumber lottoNumber) { return lottoNumbers.contains(lottoNumber); } - private static void validateDuplicateNumbers(Set lottoNumbers) { - if (lottoNumbers.size() < LOTTO_NUMBERS_SIZE) { + private static void validateDuplicateNumbers(List lottoNumbers) { + Set duplicateNumbers = lottoNumbers.stream() + .map(LottoNumber::getNumber) + .collect(Collectors.toSet()); + if (duplicateNumbers.size() < LOTTO_NUMBERS_SIZE) { throw new IllegalArgumentException("로또 번호는 중복 될 수 없습니다. - " + lottoNumbers); } } diff --git a/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java b/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java index 0d48933..4f023c3 100644 --- a/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java +++ b/src/test/java/com/javabom/lotto/domain/number/LottoNumberGeneratorTest.java @@ -17,18 +17,18 @@ class LottoNumberGeneratorTest { - @DisplayName("인자로 받은 개수 만큼 LottoNumber의 Set을 반환한다.") + @DisplayName("인자로 받은 개수 만큼 LottoNumber의 List를 반환한다.") @ParameterizedTest @ValueSource(ints = {1, 2, 3, 4, 5}) void generateRandomNumber(int size) { - Set lottoNumbers = LottoNumberGenerator.generateRandomNumber(size, (min, max) -> IntStream.rangeClosed(1, size) + List lottoNumbers = LottoNumberGenerator.generateRandomNumber(size, (min, max) -> IntStream.rangeClosed(1, 45) .boxed() .collect(Collectors.toList())); assertThat(lottoNumbers.size()).isEqualTo(size); } - @DisplayName("인자로 받은 숫자 리스트를 LottoNumber로 변환하여 Set으로 반환한다.") + @DisplayName("인자로 받은 숫자 리스트를 LottoNumber로 변환하여 List으로 반환한다.") @Test void generateFixedNumber() { List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); From 173b3a77848bb95363904e2f086fc7bea47fa981 Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 11 Jun 2020 16:50:58 +0900 Subject: [PATCH 12/13] =?UTF-8?q?refactor(LottoTicketTest):=20ofAuto=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lotto/domain/ticket/LottoTicketTest.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java index 363f1d4..c4bb58a 100644 --- a/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java +++ b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java @@ -11,38 +11,50 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; class LottoTicketTest { - @DisplayName("1 ~ 45 사이의 자동 티켓 생성") + @DisplayName("1 ~ 45 사이의 6개의 로또 번호를 가지는 자동 티켓 생성") @Test void lottoTicketOfAuto() { - NumberGenerator testNumberGenerator = (min, max) -> Arrays.asList(1, 2, 3, 4, 5, 6); + NumberGenerator testNumberGenerator = (min, max) -> IntStream.rangeClosed(min, max) + .boxed() + .collect(Collectors.toList()); LottoTicket lottoTicket = LottoTicket.ofAuto(testNumberGenerator); assertThat(lottoTicket.getLottoNumbers()).containsExactly(1, 2, 3, 4, 5, 6); } - @DisplayName("LottoNumber 리스트의 크기가 6이 아니면 IllegalArgumentException Throw") + @DisplayName("자동 LottoNumber 리스트에 중복된 번호가 있으면 IllegalArgumentExceptionThrow") @Test - void lottoTicketThrowsExceptionWhenSizeOver() { + void autoLottoTicketThrowsExceptionWhenDuplicateNumber() { + NumberGenerator testNumberGenerator = (min, max) -> Arrays.asList(1, 2, 3, 4, 5, 5); + assertThatIllegalArgumentException() + .isThrownBy(() -> LottoTicket.ofAuto(testNumberGenerator)) + .withMessage("로또 번호는 중복 될 수 없습니다. - " + Arrays.asList(1, 2, 3, 4, 5, 5)); + } + + @DisplayName("수동 LottoNumber 리스트의 크기가 6이 아니면 IllegalArgumentException Throw") + @Test + void fixedLottoTicketThrowsExceptionWhenSizeOver() { List lottoNumbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7); assertThatIllegalArgumentException() .isThrownBy(() -> LottoTicket.ofFixed(lottoNumbers)) .withMessage("로또 번호는 6개만 가능합니다. - " + lottoNumbers); } - @DisplayName("LottoNumber 리스트에 중복된 번호가 있으면 IllegalArgumentExceptionThrow") + @DisplayName("수동 LottoNumber 리스트에 중복된 번호가 있으면 IllegalArgumentExceptionThrow") @Test - void lottoTicketThrowsExceptionWhenDuplicateNumber() { + void fixedLottoTicketThrowsExceptionWhenDuplicateNumber() { List lottoNumbers = Arrays.asList(1, 2, 3, 4, 5, 5); assertThatIllegalArgumentException() .isThrownBy(() -> LottoTicket.ofFixed(lottoNumbers)) - .withMessageContaining("로또 번호는 중복 될 수 없습니다."); + .withMessage("로또 번호는 중복 될 수 없습니다. - " + Arrays.asList(1, 2, 3, 4, 5, 5)); } @DisplayName("LottoNumber 리스트에 매개값으로 받은 번호가 존재하는지 판단.") From 41093fcb240b98936a4b3a63e006ff541f53b53d Mon Sep 17 00:00:00 2001 From: Gobukgol Date: Thu, 11 Jun 2020 17:07:17 +0900 Subject: [PATCH 13/13] =?UTF-8?q?refactor(LottoTicket):=20=EC=88=9C?= =?UTF-8?q?=EC=84=9C=EA=B9=8C=EC=A7=80=20=EB=A7=9E=EC=95=84=EC=95=BC=20cou?= =?UTF-8?q?nt=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../javabom/lotto/domain/ticket/LottoTicket.java | 11 ++++++++--- .../com/javabom/lotto/domain/LottoTicketsTest.java | 13 +++++++------ .../lotto/domain/ticket/LottoTicketTest.java | 11 +++++++++++ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java index 727ddd1..307ab10 100644 --- a/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java +++ b/src/main/java/com/javabom/lotto/domain/ticket/LottoTicket.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.IntStream; public class LottoTicket { private static final int LOTTO_NUMBERS_SIZE = 6; @@ -44,6 +45,10 @@ public boolean isContainingLottoNumbers(LottoNumber lottoNumber) { return lottoNumbers.contains(lottoNumber); } + private LottoNumber findByIndex(int index) { + return lottoNumbers.get(index); + } + private static void validateDuplicateNumbers(List lottoNumbers) { Set duplicateNumbers = lottoNumbers.stream() .map(LottoNumber::getNumber) @@ -53,9 +58,9 @@ private static void validateDuplicateNumbers(List lottoNumbers) { } } - public int findMatchCount(LottoTicket lottoTicket) { - return (int) lottoTicket.lottoNumbers.stream() - .filter(this::isContainingLottoNumbers) + public int findMatchCount(LottoTicket winningTicket) { + return (int) IntStream.range(0, LOTTO_NUMBERS_SIZE) + .filter(index -> winningTicket.findByIndex(index).equals(this.findByIndex(index))) .count(); } } diff --git a/src/test/java/com/javabom/lotto/domain/LottoTicketsTest.java b/src/test/java/com/javabom/lotto/domain/LottoTicketsTest.java index 7d24aa4..5ae54d3 100644 --- a/src/test/java/com/javabom/lotto/domain/LottoTicketsTest.java +++ b/src/test/java/com/javabom/lotto/domain/LottoTicketsTest.java @@ -13,18 +13,19 @@ class LottoTicketsTest { @DisplayName("모든 로또 티켓과 당첨 번호를 비교하여 추첨 결과를 반환한다.") @Test void drawAllLotto() { - LottoTicket ticket1 = LottoTicket.ofFixed(Arrays.asList(1, 2, 3, 4, 5, 6)); - LottoTicket ticket2 = LottoTicket.ofFixed(Arrays.asList(1, 2, 3, 4, 5, 7)); - LottoTicket ticket3 = LottoTicket.ofFixed(Arrays.asList(1, 2, 3, 4, 5, 8)); + LottoTicket ticket1 = LottoTicket.ofFixed(Arrays.asList(1, 2, 4, 3, 5, 6)); + LottoTicket ticket2 = LottoTicket.ofFixed(Arrays.asList(1, 2, 7, 3, 5, 6)); + LottoTicket ticket3 = LottoTicket.ofFixed(Arrays.asList(1, 2, 8, 3, 5, 6)); + LottoTicket ticket4 = LottoTicket.ofFixed(Arrays.asList(1, 2, 4, 3, 6, 7)); - LottoWinningTicket lottoWinningTicket = new LottoWinningTicket(Arrays.asList(1, 2, 3, 4, 5, 6), 7); + LottoWinningTicket lottoWinningTicket = new LottoWinningTicket(Arrays.asList(1, 2, 4, 3, 5, 6), 7); - LottoTickets lottoTickets = new LottoTickets(Arrays.asList(ticket1, ticket2, ticket3)); + LottoTickets lottoTickets = new LottoTickets(Arrays.asList(ticket1, ticket2, ticket3, ticket4)); LottoResult lottoResult = lottoTickets.matchAllLotto(lottoWinningTicket); LottoResult expectedResult = new LottoResult(Arrays.asList(WinningSheet.FIRST, WinningSheet.SECOND - , WinningSheet.THIRD)); + , WinningSheet.THIRD, WinningSheet.FOURTH)); assertThat(lottoResult).isEqualToComparingFieldByField(expectedResult); } diff --git a/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java index c4bb58a..4d99b51 100644 --- a/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java +++ b/src/test/java/com/javabom/lotto/domain/ticket/LottoTicketTest.java @@ -73,4 +73,15 @@ void getLottoNumbers() { assertThat(lottoTicket.getLottoNumbers()).containsExactly(1, 2, 3, 4, 5, 6); } + + @DisplayName("두 티켓이 번호와 순서까지 일치하는 개수 반환") + @Test + void findMatchCount() { + LottoTicket lottoTicket = LottoTicket.ofFixed(Arrays.asList(1, 3, 2, 5, 6, 4)); + LottoTicket winningTicket = LottoTicket.ofFixed(Arrays.asList(1, 3, 5, 2, 6, 4)); + + int actualCount = lottoTicket.findMatchCount(winningTicket); + + assertThat(actualCount).isEqualTo(4); + } }