diff --git a/build.gradle b/build.gradle index 239f9e78..4d9ca3fc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java' + id 'org.jetbrains.kotlin.jvm' } group = 'cholog' @@ -14,8 +15,12 @@ dependencies { testImplementation platform('org.assertj:assertj-bom:3.25.1') testImplementation('org.junit.jupiter:junit-jupiter') testImplementation('org.assertj:assertj-core') + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" } test { useJUnitPlatform() } +kotlin { + jvmToolchain(17) +} diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..a6b722e5 --- /dev/null +++ b/src/README.md @@ -0,0 +1,18 @@ +# 로또 미션 + +## 기능 요구사항 + +- 로또 당첨 번호를 받아 일치한 번호 수에 따라 당첨 결과를 보여준다. + +## 프로그래밍 요구사항 + +- 모든 원시 값과 문자열을 포장한다. +- 일급 컬렉션을 쓴다. + +## 추가 기능 요구사항 + +- 2등을 위한 보너스볼을 추첨한다. +- 당첨 통계에 2등을 추가한다. +- 2등 당첨 조건은 당첨 번호 5개 + 보너스 볼이다 +- 사용자가 수동으로 추첨 번호를 입력할 수 있도록 해야 한다. +- 입력한 금액, 자동 생성 숫자, 수동 생성 번호를 입력하도록 해야 한다. diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 00000000..bdd3694f --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,30 @@ +import controller.LottoController; +import model.PurchaseAmount; +import model.LottoNumber; +import model.LottoTicket; +import model.LottoTicketBundle; + +public class Main { + public static void main(String[] args) { + LottoController controller = new LottoController(); + + // 1. 구입 금액 입력 + PurchaseAmount purchaseAmount = controller.askPurchaseAmount(); + + // 2. 수동 및 자동 로또 번호 생성 + LottoTicketBundle allTickets = controller.buyTickets(purchaseAmount.calculateLottoCount()); + + // 3. 당첨 번호 입력 + LottoTicket winningNumbers = controller.askWinningNumbers(); + + // 4. 보너스 볼 입력 + LottoNumber bonusBall = controller.askBonusBall(); + + // 5. 통계 출력 + controller.showStatistics(allTickets.readLottoNumbersRepository(), + winningNumbers.getNumbers(), + purchaseAmount.getValue(), + bonusBall + ); + } +} diff --git a/src/main/java/controller/LottoController.java b/src/main/java/controller/LottoController.java new file mode 100644 index 00000000..72f0bdeb --- /dev/null +++ b/src/main/java/controller/LottoController.java @@ -0,0 +1,100 @@ +package controller; + +import view.InputView; +import view.OutputView; +import model.PurchaseAmount; +import model.LottoNumber; +import model.LottoTicket; +import model.LottoService; +import model.LottoTicketBundle; +import model.MatchResult; + + +import java.util.List; +import java.util.Map; + +public class LottoController { + private final LottoService lottoService = new LottoService(); + private final OutputView outView = new OutputView(); + private final InputView inputView = new InputView(); + + private PurchaseAmount readPrice() { + outView.printInputPrice(); + while (true) { + PurchaseAmount purchaseAmount = readPriceException(); + if (purchaseAmount != null) return purchaseAmount; + } + } + + private PurchaseAmount readPriceException() { + try { + return new PurchaseAmount(Integer.parseInt(inputView.inputPrice())); + } catch (NumberFormatException input) { + outView.printInvalidNumber(); + } catch (IllegalArgumentException input) { + outView.printInvalidPrice(); + } + return null; + } + + public PurchaseAmount askPurchaseAmount() { + PurchaseAmount purchaseAmount = readPrice(); + outView.printPriceValue(purchaseAmount.getValue()); + outView.printBlankLine(); + return purchaseAmount; + } + + public LottoTicketBundle buyTickets(int ticketCount) { + int manualCount = requestManualTicketCount(); + int autoCount = calculateAutoCount(ticketCount, manualCount); + + LottoTicketBundle tickets = generateTickets(manualCount, autoCount); + displayTickets(manualCount, autoCount, tickets); + + return tickets; + } + + private int requestManualTicketCount() { + outView.printManualTicketCount(); + return Integer.parseInt(inputView.inputManualCount()); + } + + private int calculateAutoCount(int totalTickets, int manualCount) { + return totalTickets - manualCount; + } + + private LottoTicketBundle generateTickets(int manualCount, int autoCount) { + outView.printManualLottoNumbersPrompt(); + List manualInputs = inputView.inputManualLottos(manualCount); + + LottoTicketBundle manualTickets = lottoService.createManualLottos(manualInputs); + LottoTicketBundle autoTickets = lottoService.createLottos(autoCount); + + return lottoService.mergeAutoAndManualLottos(manualTickets, autoTickets); + } + + private void displayTickets(int manualCount, int autoCount, LottoTicketBundle tickets) { + outView.printBuyCount(manualCount, autoCount); + outView.printLottos(tickets.readLottoNumbersRepository()); + } + + public LottoTicket askWinningNumbers() { + outView.printInputWinningNumbers(); + LottoTicket winningLotto = lottoService.createInputLotto(inputView.inputWinningNumbers()); + outView.printBlankLine(); + return winningLotto; + } + + public LottoNumber askBonusBall() { + outView.printBonusBall(); + LottoNumber bonusNumber = new LottoNumber(Integer.parseInt(inputView.inputBonusBall())); + outView.printBlankLine(); + return bonusNumber; + } + + public void showStatistics(List allTickets, List winningNumbers, int purchaseAmount, LottoNumber bonusBall) { + Map matchCounts = lottoService.countMatchResults(allTickets, winningNumbers, bonusBall); + String profitRate = lottoService.calculateProfitRate(matchCounts, purchaseAmount); + outView.printLotteryStatistics(matchCounts, profitRate); + } +} diff --git a/src/main/java/model/FixedLottoNumberGenerator.java b/src/main/java/model/FixedLottoNumberGenerator.java new file mode 100644 index 00000000..6c9c79d2 --- /dev/null +++ b/src/main/java/model/FixedLottoNumberGenerator.java @@ -0,0 +1,21 @@ +package model; + +import java.util.List; + +public class FixedLottoNumberGenerator implements LottoNumberGenerator { + private final List fixedNumbers; + + public FixedLottoNumberGenerator(List numbers) { + if (numbers.size() != 6) { + throw new IllegalArgumentException("로또 번호는 6개여야 합니다."); + } + this.fixedNumbers = numbers.stream() + .map(LottoNumber::new) + .toList(); + } + + @Override + public LottoTicket generate() { + return new LottoTicket(fixedNumbers); + } +} diff --git a/src/main/java/model/LottoNumber.java b/src/main/java/model/LottoNumber.java new file mode 100644 index 00000000..b08b294f --- /dev/null +++ b/src/main/java/model/LottoNumber.java @@ -0,0 +1,41 @@ +package model; + +import java.util.Objects; + +public class LottoNumber { + private final int number; + + public LottoNumber(int number) { + validateRange(number); + this.number = number; + } + + private void validateRange(int number) { + if (number < 1 || number > 45) { + throw new IllegalArgumentException("로또 번호는 1~45 사이여야 합니다"); + } + } + + public int getNumber() { + return number; + } + + @Override + public String toString() { + return String.valueOf(number); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LottoNumber)) return false; + LottoNumber lottoNumber = (LottoNumber) o; + return number == lottoNumber.number; + } + + @Override + public int hashCode() { + return Objects.hash(number); + } +} + diff --git a/src/main/java/model/LottoNumberGenerator.java b/src/main/java/model/LottoNumberGenerator.java new file mode 100644 index 00000000..e16ac363 --- /dev/null +++ b/src/main/java/model/LottoNumberGenerator.java @@ -0,0 +1,5 @@ +package model; + +public interface LottoNumberGenerator { + LottoTicket generate(); +} diff --git a/src/main/java/model/LottoService.java b/src/main/java/model/LottoService.java new file mode 100644 index 00000000..a8b721e9 --- /dev/null +++ b/src/main/java/model/LottoService.java @@ -0,0 +1,108 @@ +package model; + + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +public class LottoService { + private final LottoNumberGenerator generator; + + public LottoService() { + this(new RandomLottoNumberGenerator()); + } + + public LottoService(LottoNumberGenerator generator) { + this.generator = generator; + } + + public LottoTicket createOneLotto() { + return generator.generate(); + } + + public LottoTicketBundle createLottos(int count) { + LottoTicketBundle repository = new LottoTicketBundle(); + for (int i = 0; i < count; i++) { + repository.addLottoNumbers(createOneLotto().sortNumbers()); + } + return repository; + } + + public LottoTicket createInputLotto(String inputNumber) { + List numbers = parseInputToNumbers(inputNumber); + return new LottoTicket(numbers); + } + + private List parseInputToNumbers(String inputNumber) { + String[] rawNumbers = inputNumber.split(","); + List numbers = new ArrayList<>(); + for (String raw : rawNumbers) { + numbers.add(new LottoNumber(Integer.parseInt(raw.trim()))); + } + return numbers; + } + + public LottoTicketBundle createManualLottos(List inputs) { + LottoTicketBundle repository = new LottoTicketBundle(); + for (String input : inputs) { + repository.addLottoNumbers(createInputLotto(input)); + } + return repository; + } + + public LottoTicketBundle mergeAutoAndManualLottos(LottoTicketBundle manual, LottoTicketBundle auto) { + LottoTicketBundle repository = new LottoTicketBundle(); + for (LottoTicket lotto : manual.readLottoNumbersRepository()) { + repository.addLottoNumbers(lotto); + } + + for (LottoTicket lotto : auto.readLottoNumbersRepository()) { + repository.addLottoNumbers(lotto); + } + return repository; + } + + public Map countMatchResults(List allLotteries, + List winningLotto, + LottoNumber bonusBall) { + Map matchCounts = initializeMatchCounts(); + for (LottoTicket lotto : allLotteries) { + int count = matchLottoNumber(lotto.getNumbers(), winningLotto); + boolean bonusMatch = matchBonus(lotto.getNumbers(), bonusBall, count); + MatchResult result = MatchResult.fromCount(count, bonusMatch); + matchCounts.put(result, matchCounts.get(result) + 1); + } + return matchCounts; + } + + private Map initializeMatchCounts() { + Map counts = new EnumMap<>(MatchResult.class); + for (MatchResult result : MatchResult.values()) { + counts.put(result, 0); + } + return counts; + } + + private int matchLottoNumber(List lotto, List winningLotto) { + return (int) lotto.stream() + .filter(winningLotto::contains) + .count(); + } + + private boolean matchBonus(List lotto, LottoNumber bonusBall, int count) { + if (count == 5) { + return lotto.contains(bonusBall); + } + return false; + } + + public String calculateProfitRate(Map matchCounts, int money) { + double profitRate = 0; + for (MatchResult result : matchCounts.keySet()) { + profitRate += matchCounts.get(result) * result.getReward(); + } + profitRate = profitRate / (double) money; + return String.format("%.2f", profitRate); + } +} diff --git a/src/main/java/model/LottoTicket.java b/src/main/java/model/LottoTicket.java new file mode 100644 index 00000000..0c740255 --- /dev/null +++ b/src/main/java/model/LottoTicket.java @@ -0,0 +1,29 @@ +package model; + +import java.util.*; + +public class LottoTicket { + private final List numbers; + + public LottoTicket(List numbers) { + validateSize(numbers); + this.numbers = List.copyOf(numbers); + } + + private void validateSize(List numbers) { + if (numbers.size() != 6) { + throw new IllegalArgumentException("로또 번호가 6개가 아닙니다"); + } + } + + public LottoTicket sortNumbers() { + List sortNumber = new ArrayList<>(numbers); + Collections.sort(sortNumber, Comparator.comparingInt(LottoNumber::getNumber)); + return new LottoTicket(sortNumber); + } + + public List getNumbers() { + return numbers; + } + +} diff --git a/src/main/java/model/LottoTicketBundle.java b/src/main/java/model/LottoTicketBundle.java new file mode 100644 index 00000000..c7dba79b --- /dev/null +++ b/src/main/java/model/LottoTicketBundle.java @@ -0,0 +1,19 @@ +package model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class LottoTicketBundle { + private final List repository = new ArrayList<>(); + + public void addLottoNumbers(LottoTicket lottoTicket) { + repository.add(lottoTicket); + } + + public List readLottoNumbersRepository() { + return Collections.unmodifiableList(repository); + } + +} diff --git a/src/main/java/model/MatchResult.java b/src/main/java/model/MatchResult.java new file mode 100644 index 00000000..898b7392 --- /dev/null +++ b/src/main/java/model/MatchResult.java @@ -0,0 +1,42 @@ +package model; + +import java.util.Arrays; + +public enum MatchResult { + ZERO(0, 0), + ONE(1, 0), + TWO(2, 0), + THREE(3, 5000), + FOUR(4, 50000), + FIVE(5, 1500000), + FIVE_BONUS(5, 30000000), + SIX(6, 2000000000); + + private final int count; + private final int reward; + + MatchResult(int count, int reward) { + this.count = count; + this.reward = reward; + } + + public int getCount() { + return count; + } + + public int getReward() { + return reward; + } + + public static MatchResult fromCount(int count, boolean bonusMatch) { + if (count == 5 && bonusMatch) { + return FIVE_BONUS; + } + + MatchResult[] results = values(); + return Arrays.stream(values()) + .filter(result -> result.count == count && result != FIVE_BONUS) + .findFirst() + .orElse(ZERO); + } +} diff --git a/src/main/java/model/PurchaseAmount.java b/src/main/java/model/PurchaseAmount.java new file mode 100644 index 00000000..33cd24ca --- /dev/null +++ b/src/main/java/model/PurchaseAmount.java @@ -0,0 +1,39 @@ +package model; + +import java.util.Objects; + +public class PurchaseAmount { + private final int value; + + public PurchaseAmount(int value) { + validateNegative(value); + this.value = value; + } + + private static void validateNegative(int value) { + if (value < 0) { + throw new IllegalArgumentException("구입 금액은 0원 이상입니다."); + } + } + + public int getValue() { + return value; + } + + public int calculateLottoCount() { + return value / 1000; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PurchaseAmount)) return false; + PurchaseAmount money = (PurchaseAmount) o; + return value == money.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/main/java/model/RandomLottoNumberGenerator.java b/src/main/java/model/RandomLottoNumberGenerator.java new file mode 100644 index 00000000..4e11ece6 --- /dev/null +++ b/src/main/java/model/RandomLottoNumberGenerator.java @@ -0,0 +1,23 @@ +package model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class RandomLottoNumberGenerator implements LottoNumberGenerator { + + @Override + public LottoTicket generate() { + List numbers = createLottoNumbers(); + Collections.shuffle(numbers); + return new LottoTicket(numbers.subList(0, 6)); + } + + public List createLottoNumbers() { + List numbers = new ArrayList<>(); + for (int i = 1; i < 46; i++) { + numbers.add(new LottoNumber(i)); + } + return numbers; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000..5919c61c --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,33 @@ +package view; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class InputView { + private static final Scanner scanner = new Scanner(System.in); + + public String inputPrice() { + return scanner.nextLine(); + } + + public String inputManualCount() { + return scanner.nextLine(); + } + + public List inputManualLottos(int count) { + List inputs = new ArrayList<>(); + for (int i = 0; i < count; i++) { + inputs.add(scanner.nextLine()); + } + return inputs; + } + + public String inputBonusBall() { + return scanner.nextLine(); + } + + public String inputWinningNumbers() { + return scanner.nextLine(); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 00000000..ed7174e1 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,66 @@ +package view; + +import model.LottoTicket; +import model.MatchResult; + +import java.util.List; +import java.util.Map; + +public class OutputView { + public void printInputPrice() { + System.out.print("구입 금액을 입력해 주세요: "); + } + + public void printInvalidNumber() { + System.out.println("숫자만 입력해 주세요"); + } + + public void printInvalidPrice() { + System.out.println("0원 이상을 입력해 주세요"); + } + + public void printPriceValue(int price) { + System.out.println(price); + } + + public void printBuyCount(int manualCount, int autoCount) { + System.out.println("수동으로 " + manualCount + "장, 자동으로 " + autoCount + "개를 구매했습니다."); + } + + public void printInputWinningNumbers() { + System.out.println("지난 주 당첨 번호를 입력해 주세요."); + } + + public void printLottos(List Lottos) { + for (LottoTicket lotto : Lottos) { + System.out.println(lotto.getNumbers()); + } + } + + public void printManualTicketCount() { + System.out.println("수동으로 구매할 로또 수를 입력해 주세요."); + } + + public void printManualLottoNumbersPrompt() { + System.out.println("수동으로 구매할 번호를 입력해 주세요."); + } + + public void printBonusBall() { + System.out.println("보너스 볼을 입력해 주세요."); + } + + public void printBlankLine(){ + System.out.println(); + } + + public void printLotteryStatistics(Map matchCounts, String profitRate) { + System.out.println("당첨 통계"); + System.out.println("---------"); + System.out.println("3개 일치 (5000원)- " + matchCounts.get(MatchResult.THREE) + "개"); + System.out.println("4개 일치 (50000원)- " + matchCounts.get(MatchResult.FOUR) + "개"); + System.out.println("5개 일치 (150000원)- " + matchCounts.get(MatchResult.FIVE) + "개"); + System.out.println("5개 일치, 보너스 볼 일치(30000000원)- " + matchCounts.get(MatchResult.FIVE_BONUS) + "개"); + System.out.println("6개 일치 (2000000000원)- " + matchCounts.get(MatchResult.SIX) + "개"); + System.out.println("총 수익률은 " + profitRate + "입니다."); + } +} diff --git a/src/test/java/model/FixedLottoNumberGeneratorTest.java b/src/test/java/model/FixedLottoNumberGeneratorTest.java new file mode 100644 index 00000000..107a3c5a --- /dev/null +++ b/src/test/java/model/FixedLottoNumberGeneratorTest.java @@ -0,0 +1,44 @@ +package model; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class FixedLottoNumberGeneratorTest { + + @Test + void 고정된숫자를_반환() { + // Given + List input = List.of(1, 2, 3, 4, 5, 6); + FixedLottoNumberGenerator generator = new FixedLottoNumberGenerator(input); + + // When + LottoTicket lotto = generator.generate(); + + // Then + assertEquals(input.toString(), lotto.getNumbers().toString()); + } + + @Test + void 숫자가_6개가_아니면_예외가_발생한다() { + // Given + List input = List.of(1, 2, 3, 4, 5); + + // When & Then + assertThrows(IllegalArgumentException.class, + () -> new FixedLottoNumberGenerator(input)); + } + + @Test + void 숫자가_1에서_45범위를_벗어나면_예외가_발생한다() { + // Given + List input = List.of(1, 2, 3, 4, 5, 46); + + // When & Then + assertThrows(IllegalArgumentException.class, + () -> new FixedLottoNumberGenerator(input)); + } + +} diff --git a/src/test/java/model/LottoFixture.java b/src/test/java/model/LottoFixture.java new file mode 100644 index 00000000..5efb9b24 --- /dev/null +++ b/src/test/java/model/LottoFixture.java @@ -0,0 +1,32 @@ +package model; + +import java.util.List; + +public class LottoFixture { + + // 기본 1~6 로또 + public static LottoTicket 기본로또() { + return new LottoTicket(List.of( + new LottoNumber(1), new LottoNumber(2), new LottoNumber(3), + new LottoNumber(4), new LottoNumber(5), new LottoNumber(6) + )); + } + + // 보너스볼(7) 포함된 로또 + public static LottoTicket 보너스7포함로또() { + return new LottoTicket(List.of( + new LottoNumber(1), new LottoNumber(2), new LottoNumber(3), + new LottoNumber(4), new LottoNumber(5), new LottoNumber(7) + )); + } + + // 4개 일치 로또 (1~4 일치) + public static LottoTicket 네개일치로또() { + return new LottoTicket(List.of( + new LottoNumber(1), new LottoNumber(2), new LottoNumber(3), + new LottoNumber(4), new LottoNumber(7), new LottoNumber(8) + )); + } +} + + diff --git a/src/test/java/model/LottoNumberTest.java b/src/test/java/model/LottoNumberTest.java new file mode 100644 index 00000000..039f16a4 --- /dev/null +++ b/src/test/java/model/LottoNumberTest.java @@ -0,0 +1,43 @@ +package model; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class LottoNumberTest { + + @Test + void 유효한_번호면_LottoNumber_객체가_생성된다() { + // given + int validNumber = 20; + + // when + LottoNumber lottoNumber = new LottoNumber(validNumber); + + // then + assertThat(lottoNumber.getNumber()).isEqualTo(20); + assertThat(lottoNumber.toString()).isEqualTo("20"); + } + + @Test + void _1보다_작거나_45보다_크면_예외가_발생한다() { + // given + int invalidMin = 0; + int invalidMax = 46; + + // when & then + assertThrows(IllegalArgumentException.class, () -> new LottoNumber(invalidMin)); + assertThrows(IllegalArgumentException.class, () -> new LottoNumber(invalidMax)); + } + + @Test + void 같은숫자는_equal비교() { + //given + LottoNumber n1 = new LottoNumber(3); + LottoNumber n2 = new LottoNumber(3); + + //when & then + assertEquals(n1, n2); + } +} diff --git a/src/test/java/model/LottoServiceTest.java b/src/test/java/model/LottoServiceTest.java new file mode 100644 index 00000000..06c3c3b0 --- /dev/null +++ b/src/test/java/model/LottoServiceTest.java @@ -0,0 +1,108 @@ +package model; + +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; + +import static model.LottoFixture.기본로또; +import static model.LottoFixture.네개일치로또; +import static model.LottoFixture.보너스7포함로또; +import static org.junit.jupiter.api.Assertions.*; + +class LottoServiceTest { + private final LottoService business = new LottoService(); + + @Test + void 고정된로또가_생성된다() { + // Given + LottoService business = + new LottoService(new FixedLottoNumberGenerator(List.of(1, 2, 3, 4, 5, 6))); + + // When + LottoTicket lotto = business.createOneLotto(); + + // Then + assertEquals(기본로또(), lotto); + } + + @Test + void 요청한_개수만큼_로또가_생성된다() { + // Given + int count = 3; + + // When + LottoTicketBundle re = business.createLottos(count); + + // Then + assertEquals(count, re.readLottoNumbersRepository().size()); + assertTrue(re.readLottoNumbersRepository() + .stream().allMatch(n -> n.getNumbers().size() == 6)); + } + + @Test + void 지난주_로또가_생성된다() { + // Given + String input = "1, 2,3, 4 ,5,6"; + + // When + LottoTicket last = business.createInputLotto(input); + + // Then + assertEquals(6, last.getNumbers().size()); + assertEquals(기본로또(), last); + } + + @Test + void countMatchResults_4개일치면_FOUR가_1로_집계된다() { + // Given + LottoTicket mine = 기본로또(); + LottoTicket last = 네개일치로또(); + LottoNumber bonus = new LottoNumber(9); + + // When + Map result = + business.countMatchResults(List.of(mine), last.getNumbers(), bonus); + + // Then + assertEquals(1, result.get(MatchResult.FOUR)); + } + + @Test + void calculateProfitRrate_3개일치_한장_구입1000원은_5배다() { + // Given + Map matchCounts = Map.of( + MatchResult.THREE, 1, + MatchResult.ZERO, 0, + MatchResult.ONE, 0, + MatchResult.TWO, 0, + MatchResult.FOUR, 0, + MatchResult.FIVE, 0, + MatchResult.FIVE_BONUS, 0, + MatchResult.SIX, 0 + ); + LottoNumber bonus = new LottoNumber(7); + int money = 1000; + + // When + String rate = business.calculateProfitRate(matchCounts, money); + + // Then + assertEquals("5.00", rate); + } + + @Test + void 보너스볼까지_맞추면_FIVE_BONUS로_집계된다() { + // Given + LottoTicket mine = 보너스7포함로또(); + LottoTicket winning = 기본로또(); + LottoNumber bonus = new LottoNumber(7); + + // When + Map result = + business.countMatchResults(List.of(mine), winning.getNumbers(), bonus); + + // Then + assertEquals(1, result.get(MatchResult.FIVE_BONUS)); + } +} diff --git a/src/test/java/model/LottoTicketBundleTest.java b/src/test/java/model/LottoTicketBundleTest.java new file mode 100644 index 00000000..bc989b10 --- /dev/null +++ b/src/test/java/model/LottoTicketBundleTest.java @@ -0,0 +1,22 @@ +package model; + +import org.junit.jupiter.api.Test; + +import static model.LottoFixture.기본로또; +import static org.junit.jupiter.api.Assertions.*; + +class LottoTicketBundleTest { + + @Test + void 저장소에_로또번호를_추가하면_읽을때_사이즈가_증가한다() { + // given + LottoTicketBundle repository = new LottoTicketBundle(); + LottoTicket lottoTicket = 기본로또(); + + // when + repository.addLottoNumbers(lottoTicket); + + // then + assertEquals(1, repository.readLottoNumbersRepository().size()); + } +} diff --git a/src/test/java/model/LottoTicketTest.java b/src/test/java/model/LottoTicketTest.java new file mode 100644 index 00000000..de41e73f --- /dev/null +++ b/src/test/java/model/LottoTicketTest.java @@ -0,0 +1,46 @@ +package model; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + + +import static model.LottoFixture.기본로또; +import static org.junit.jupiter.api.Assertions.*; + +class LottoTicketTest { + + @Test + void 로또번호가_6개면_정상적으로_생성된다() { + List numbers = Arrays.asList( + new LottoNumber(1), new LottoNumber(2), new LottoNumber(3), + new LottoNumber(4), new LottoNumber(5), new LottoNumber(6)); + + LottoTicket lottoTicket = new LottoTicket(numbers); + + assertEquals(6, lottoTicket.getNumbers().size()); + } + + @Test + void 로또번호가_6개가_아니면_예외가_발생한다() { + List numbers = Arrays.asList( + new LottoNumber(1), new LottoNumber(2), new LottoNumber(3), + new LottoNumber(4)); + + assertThrows(IllegalArgumentException.class, + () -> new LottoTicket(numbers)); + } + + @Test + void sortNumbers는_번호를_오름차순으로_정렬한다() { + List numbers = Arrays.asList( + new LottoNumber(6), new LottoNumber(3), new LottoNumber(5), + new LottoNumber(1), new LottoNumber(4), new LottoNumber(2) + ); + + LottoTicket sorted = new LottoTicket(numbers).sortNumbers(); + + assertEquals(기본로또(), sorted); + } +} diff --git a/src/test/java/model/PurchaseAmountTest.java b/src/test/java/model/PurchaseAmountTest.java new file mode 100644 index 00000000..46e0b3da --- /dev/null +++ b/src/test/java/model/PurchaseAmountTest.java @@ -0,0 +1,41 @@ +package model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class PurchaseAmountTest { + + @Test + void 올바른_금액이면_로또개수계산() { + // given + PurchaseAmount purchaseAmount = new PurchaseAmount(2000); + + // when + int count = purchaseAmount.calculateLottoCount(); + + // then + assertEquals(2, count); + } + + @Test + void _0원_미만이면_예외가_발생한다() { + // given + int invalidMoney = -2000; + + // when & then + assertThrows(IllegalArgumentException.class, () -> new PurchaseAmount(invalidMoney)); + } + + @Test + void 같은금액이면_동일객체() { + // given + PurchaseAmount purchaseAmount1 = new PurchaseAmount(6000); + PurchaseAmount purchaseAmount2 = new PurchaseAmount(6000); + + // when & then + assertEquals(purchaseAmount1, purchaseAmount2); + assertEquals(purchaseAmount1.hashCode(), purchaseAmount2.hashCode()); + } +}