diff --git a/.gitignore b/.gitignore index b6c378809..e3dd29f7d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,23 @@ build/ !**/src/main/** !**/src/test/** +### Local configuration file ### +local.properties + +### Kotlin ### +*.class + +### Log ### +*.log + +### Android Studio ### +captures/ +.externalNativeBuild/ +.cxx/ +*.apk +output.json +*.hprof + ### macOS ### .DS_Store diff --git a/docs/README.md b/docs/README.md index e69de29bb..0f2369354 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,91 @@ +# 미션 - 로또 + +## 기능 목록 + +### UI +- [x] 로또 구입 문구 출력 +- [x] 로또 구입 금액 입력 (1,000원 단위) +- [x] 구매한 로또 개수 출력 +- [x] 구매한 로또 번호 위 개수 만큼 출력 +- [x] 당첨 번호 입력 (중복 없이 6개 숫자, 1~45 범위, 쉼표로 구분) +- [x] 보너스 번호 입력 (1개 숫자, 1~45 범위) +- [x] 당첨 내역 출력 + - [x] 당첨 통계 문구 출력 + - [x] 로또 번호 수 일치 기준으로 개수 출력 (오름차순 정렬) + - [x] 수익률 출력 (소수점 둘째 자리 반올림) +- [x] 예외 상황시 에러 문구 출력 ("[ERROR]"로 시작) + +### Domain +- [x] 구매한 로또 금액으로 개수 계산 -> LottoCount +- [x] 개수 만큼 로또 발행 (각각 6개의 랜덤 값) - LottoMake +- [x] 사용자 구매 로또 번호와 당첨 번호 비교 - LottoCompare, LottoWinning +- [x] 수익률 계산 - LottoProfit +- [x] 에러 문구 출력 후 재입력 진행 - Exception +- 예외 처리 + - [x] 로또 구입 금액이 1,000원으로 나누어 떨어지지 않는 경우 + - [x] 로또 구입 금액이 숫자가 아닐 경우 + - [x] 로또 구입 금액이 음수일 경우 + - [x] 로또 번호 숫자 범위가 1~45가 아닐 경우 + - [x] 로또 번호가 중복된 경우 + - [x] 로또 번호 개수가 6개가 아닐 경우 + - [x] 로또 번호 쉼표 구분이 아닐 경우 + - [x] 보너스 번호 개수가 1개가 아닐 경우 + - [x] 보너스 번호가 로또 번호와 중복일 경우 + +## 테스트 목록 + +- [x] 당첨 번호와 랜덤 번호 비교 +- [x] 보너스 번호와 랜덤 번호 비교 +- [x] 로또 발행 +- [ ] 로또 구입 금액 +- [x] 로또 숫자 개수 +- [x] 로또 수익률 + +## 프로그래밍 요구 사항 + +- [x] Kotlin 1.9.0 +- [x] Kotlin 코드로만 구현 +- [x] `Application`의 `main()`에서 시작 +- [x] `build.gradle(.kts)`을 변경 불가능, 외부 라이브러리를 사용하지 않는다. +- [x] Kotlin 코드 컨벤션 가이드 준수 +- [x] `System.exit()` 호출하지 않음 +- [ ] ApplicationTest의 모든 테스트 성공 +- [x] 파일, 패키지 이름 수정하거나 이동하지 않음 +- [x] indent depth 3이 넘지 않도록 함 +- [x] 함수(또는 메서드)가 한 가지 일만 하도록 함 +- [x] JUnit 5와 AssertJ 이용해 기능 목록이 정상 동작함을 테스트 코드로 확인 +- [x] `camp.nextstep.edu.missionutils`에서 제공하는 `Randoms` 및 `Console` API를 사용. +- [x] 함수의 길이가 15라인을 넘어가지 않도록 함 +- [x] else 지양 +- [ ] Enum 클래스 적용 +- [x] 도메인 로직에 단위 테스트 구현(UI 로직 제외) +- [x] 핵심 로직 구현 코드와 UI 담당 로직 분리 +- [x] 제공된 `Lotto` 클래스 활용해 구현 +- [x] `numbers` 접근 제어자인 private 변경 불가능 +- [x] `Lotto` 필드 추가 불가능 +- [x] `Lotto`패키지 변경 가능 + +## 과제 진행 요구 사항 + +- [X] `docs/README.md`에 기능 목록 작성 +- [x] 기능 목록 단위로 커밋 +- [x] 커밋 메시지 컨벤션 참고해 작성 +- [x] 요구 사항에 명시된 출력값 형식 지키기 + +## 피드백 반영 + +- git 통해 관리할 자원 고려 +- 기능 목록 재검토 및 업데이트 +- 커밋 메시지 의미 있게 작성 +- 이름을 통해 의도 드러내기 +- 축약 X (클래스와 메서드 한두단어 유지 노력) +- 변수 이름에 자료형 X +- 공백 의미 있게 사용 +- space와 tab 혼용 X +- 의미 없는 주석 X +- kotlin 제공 API 활용 +- 배열 대신 kotlin collection 사용 +- 하드 코딩 X +- 구현 순서 신경쓰기 +- 한 함수 한가지 기능(길이 15라인 넘지 않게) +- 작은 단위 테스트 \ No newline at end of file diff --git a/src/main/kotlin/lotto/Application.kt b/src/main/kotlin/lotto/Application.kt index d7168761c..94d6a4bb6 100644 --- a/src/main/kotlin/lotto/Application.kt +++ b/src/main/kotlin/lotto/Application.kt @@ -1,5 +1,37 @@ package lotto +import lotto.domain.LottoCompare +import lotto.domain.LottoMake +import lotto.domain.LottoWinning +import lotto.domain.Validation +import lotto.presentation.LottoDecisionView.inputBonusNumber +import lotto.presentation.LottoDecisionView.inputWinningNumber +import lotto.presentation.LottoDecisionView.printBonusNumber +import lotto.presentation.LottoDecisionView.printWinningNumber +import lotto.presentation.LottoPurchaseView.inputLottoPurchase +import lotto.presentation.LottoPurchaseView.outputPurchaseCount +import lotto.presentation.LottoPurchaseView.printLottoPurchase +import lotto.presentation.LottoWinningView.outputProfitRate +import lotto.presentation.LottoWinningView.printWinningStatic + fun main() { - TODO("프로그램 구현") + printLottoPurchase() + val amount = Validation().validationAmount(inputLottoPurchase()) + val count = outputPurchaseCount(amount) + val lotto = LottoMake().resultLottoNumber(count) + println() + printWinningNumber() + val winningNumber = + Validation().validationLotto(inputWinningNumber().sorted()) + val winningCount = LottoCompare(lotto).compare(winningNumber) + println() + printBonusNumber() + val bonusNumber = + Validation().validationBonusDuplication(inputBonusNumber(), winningNumber) + val bonusCount = LottoCompare(lotto).compareBonus(bonusNumber) + println() + printWinningStatic() + LottoWinning(winningCount, bonusCount).calculate() + val profit = LottoWinning(winningCount, bonusCount).profit(amount) + outputProfitRate(profit) } diff --git a/src/main/kotlin/lotto/Lotto.kt b/src/main/kotlin/lotto/Lotto.kt deleted file mode 100644 index 5ca00b4e4..000000000 --- a/src/main/kotlin/lotto/Lotto.kt +++ /dev/null @@ -1,9 +0,0 @@ -package lotto - -class Lotto(private val numbers: List) { - init { - require(numbers.size == 6) - } - - // TODO: 추가 기능 구현 -} diff --git a/src/main/kotlin/lotto/domain/Lotto.kt b/src/main/kotlin/lotto/domain/Lotto.kt new file mode 100644 index 000000000..65c347a2d --- /dev/null +++ b/src/main/kotlin/lotto/domain/Lotto.kt @@ -0,0 +1,21 @@ +package lotto.domain + +import lotto.util.WRONG_COUNT_EXCEPTION + +class Lotto(private val numbers: List) { + init { + require(numbers.size == 6) { WRONG_COUNT_EXCEPTION } + } + + override fun toString(): String = numbers.joinToString(", ", "[", "]") + fun intersect(winning: List): Set { + return numbers.intersect(winning.toSet()) + } + + fun contains(bonus: Int): Boolean { + if (numbers.contains(bonus)) return true + return false + } + +// fun sortNumber(): List = numbers.sorted() +} diff --git a/src/main/kotlin/lotto/domain/LottoCompare.kt b/src/main/kotlin/lotto/domain/LottoCompare.kt new file mode 100644 index 000000000..b6365c9b9 --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoCompare.kt @@ -0,0 +1,33 @@ +package lotto.domain + + +class LottoCompare(private val numbers: MutableList) { + fun compare(winning: List): MutableList { + val winningCount: MutableList = mutableListOf() + for (index in numbers.indices) { + winningCount.add(winningResult(winning, numbers[index])) + } + return winningCount + } + + fun compareBonus(bonus: Int): Int { + var count = 0 + for (index in numbers.indices) { + count = bonusResult(bonus, numbers[index]) + } + return count + } + + private fun winningResult(winning: List, i: Lotto): Int { + val intersectNumber: Set = i.intersect(winning) + return intersectNumber.size + } + + private fun bonusResult(bonus: Int, i: Lotto): Int { + var bonusCount = 0 + if (i.contains(bonus)) { + bonusCount++ + } + return bonusCount + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/domain/LottoCount.kt b/src/main/kotlin/lotto/domain/LottoCount.kt new file mode 100644 index 000000000..4be4d7db5 --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoCount.kt @@ -0,0 +1,5 @@ +package lotto.domain + +class LottoCount(private val amount: Int) { + fun calculate() = amount.div(1000) +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/domain/LottoMake.kt b/src/main/kotlin/lotto/domain/LottoMake.kt new file mode 100644 index 000000000..d404c5037 --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoMake.kt @@ -0,0 +1,25 @@ +package lotto.domain + +import camp.nextstep.edu.missionutils.Randoms +import lotto.util.LOTTO_NUMBER_COUNT +import lotto.util.LOTTO_NUMBER_MAX +import lotto.util.LOTTO_NUMBER_MIN + +class LottoMake() { + fun resultLottoNumber(purchaseCount: Int): MutableList { + val lotto: MutableList = mutableListOf() + for (count in 0 until purchaseCount) { + val numbers = makeLottoNumber() + println(numbers) + lotto.add(numbers) + } + return lotto + } + + private fun makeLottoNumber(): Lotto { + val number = + Randoms.pickUniqueNumbersInRange(LOTTO_NUMBER_MIN, LOTTO_NUMBER_MAX, LOTTO_NUMBER_COUNT) + .sorted() + return Lotto(number) + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/domain/LottoWinning.kt b/src/main/kotlin/lotto/domain/LottoWinning.kt new file mode 100644 index 000000000..848e28a38 --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoWinning.kt @@ -0,0 +1,33 @@ +package lotto.domain + +import lotto.presentation.LottoWinningView.outputFiveBonusWinningResult +import lotto.presentation.LottoWinningView.outputFiveWinningResult +import lotto.presentation.LottoWinningView.outputFourWinningResult +import lotto.presentation.LottoWinningView.outputSixWinningResult +import lotto.presentation.LottoWinningView.outputThreeWinningResult + +class LottoWinning(private val winningCount: MutableList, private val bonusCount: Int) { + private val threeCount = winningCount.count { it == 3 } + private val fourCount = winningCount.count { it == 4 } + private val fiveCount = winningCount.count { it == 5 } + private val sixCount = winningCount.count { it == 6 } + private val count = fiveCount.minus(bonusCount) + + fun calculate() { + outputThreeWinningResult(threeCount) + outputFourWinningResult(fourCount) + outputFiveWinningResult(count) + outputFiveBonusWinningResult(bonusCount) + outputSixWinningResult(sixCount) + } + + fun profit(amount: Int): String { + val first = 2000000000 * sixCount + val second = 30000000 * bonusCount + val third = 1500000 * count + val fourth = 50000 * fourCount + val fifth = 5000 * threeCount + val total = first + second + third + fourth + fifth + return String.format("%.1f", total.toDouble() / amount * 100) + "%" + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/domain/Validation.kt b/src/main/kotlin/lotto/domain/Validation.kt new file mode 100644 index 000000000..d5f84db13 --- /dev/null +++ b/src/main/kotlin/lotto/domain/Validation.kt @@ -0,0 +1,115 @@ +package lotto.domain + +import lotto.presentation.LottoDecisionView.inputBonusNumber +import lotto.presentation.LottoDecisionView.inputWinningNumber +import lotto.presentation.LottoPurchaseView +import lotto.presentation.LottoPurchaseView.inputLottoPurchase +import lotto.util.DUPLICATE_NUMBER_EXCEPTION +import lotto.util.DUPLYCATE_BONUS_EXCEPTION +import lotto.util.EXCEPTION_MESSAGE +import lotto.util.Exception.validationBonusCountException +import lotto.util.Exception.validationBonusDuplicationException +import lotto.util.Exception.validationDuplicationException +import lotto.util.Exception.validationRangeException +import lotto.util.Exception.validationSeparatorException +import lotto.util.WRONG_BONUS_COUNT_EXCEPTION +import lotto.util.WRONG_NUMBER_EXCEPTION +import lotto.util.WRONG_RANGE_EXCEPTION +import lotto.util.WRONG_RANGE_NEGATIVE_EXCEPTION +import lotto.util.WRONG_SEPARATOR +import lotto.util.WRONG_UNIT_EXCEPTION + +class Validation { + fun validationAmount(amount: String): Int { + validationType(amount) + validationNegative(amount) + validationUnit(amount) + return amount.toInt() + } + + fun validationLotto(lotto: List): List { + validationRange(lotto) + validationDuplication(lotto) + return lotto + } + + fun validationType(amount: String): Int { + try { + lotto.util.Exception.validateTypeException(amount) + } catch (e: IllegalArgumentException) { + println(EXCEPTION_MESSAGE + WRONG_NUMBER_EXCEPTION) + inputLottoPurchase() + } + return amount.toInt() + } + + fun validationNegative(amount: String): Int { + try { + lotto.util.Exception.validateNegativeException(amount.toInt()) + } catch (e: IllegalArgumentException) { + println(EXCEPTION_MESSAGE + WRONG_RANGE_NEGATIVE_EXCEPTION) + inputLottoPurchase() + } + return amount.toInt() + } + + fun validationUnit(amount: String): Int { + try { + lotto.util.Exception.validateUnitException(amount.toInt()) + } catch (e: IllegalArgumentException) { + println(EXCEPTION_MESSAGE + WRONG_UNIT_EXCEPTION) + inputLottoPurchase() + } + return amount.toInt() + } + + private fun validationRange(lotto: List): List { + try { + lotto.forEach { number -> validationRangeException(number) } + } catch (e: IllegalArgumentException) { + println(EXCEPTION_MESSAGE + WRONG_RANGE_EXCEPTION) + inputWinningNumber().sorted() + } + return lotto + } + + private fun validationDuplication(lotto: List): List { + try { + lotto.forEach { number -> validationDuplicationException(lotto, number) } + } catch (e: IllegalArgumentException) { + println(EXCEPTION_MESSAGE + DUPLICATE_NUMBER_EXCEPTION) + inputWinningNumber().sorted() + } + return lotto + } + + fun validationBonusCount(bonus: String): String { + try { + validationBonusCountException(bonus) + } catch (e: IllegalArgumentException) { + println(EXCEPTION_MESSAGE + WRONG_BONUS_COUNT_EXCEPTION) + inputBonusNumber() + } + return bonus + } + + fun validationBonusDuplication(bonus: Int, winningNumber: List): Int { + try { + validationBonusDuplicationException(bonus, winningNumber) + } catch (e: IllegalArgumentException) { + println(EXCEPTION_MESSAGE + DUPLYCATE_BONUS_EXCEPTION) + inputBonusNumber() + } + return bonus + } + + fun validationSeparator(number: String): String { + try { + validationSeparatorException(number) + } catch (e: IllegalArgumentException) { + println(EXCEPTION_MESSAGE + WRONG_SEPARATOR) + inputWinningNumber() + } + return number + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/presentation/LottoDecisionView.kt b/src/main/kotlin/lotto/presentation/LottoDecisionView.kt new file mode 100644 index 000000000..a0756080c --- /dev/null +++ b/src/main/kotlin/lotto/presentation/LottoDecisionView.kt @@ -0,0 +1,28 @@ +package lotto.presentation + +import camp.nextstep.edu.missionutils.Console +import lotto.domain.Validation +import lotto.util.BONUS_NUMBER_TEXT +import lotto.util.WINNING_NUMBER_TEXT + +object LottoDecisionView { + fun printWinningNumber() { + println(WINNING_NUMBER_TEXT) + } + + fun inputWinningNumber(): List { + val winningNumbers = Console.readLine().trim() + Validation().validationSeparator(winningNumbers) + return winningNumbers.split(",").map { it.toInt() } + } + + fun printBonusNumber() { + println(BONUS_NUMBER_TEXT) + } + + fun inputBonusNumber(): Int { + val bonus = Console.readLine().trim() + Validation().validationBonusCount(bonus) + return bonus.toInt() + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/presentation/LottoPurchaseView.kt b/src/main/kotlin/lotto/presentation/LottoPurchaseView.kt new file mode 100644 index 000000000..078b1a44c --- /dev/null +++ b/src/main/kotlin/lotto/presentation/LottoPurchaseView.kt @@ -0,0 +1,23 @@ +package lotto.presentation + +import camp.nextstep.edu.missionutils.Console +import lotto.domain.LottoCount +import lotto.util.PURCHASE_NUMBER_TEXT +import lotto.util.PURCHASE_PRICE_TEXT + +object LottoPurchaseView { + fun printLottoPurchase() { + println(PURCHASE_PRICE_TEXT) + } + + fun inputLottoPurchase(): String { + return Console.readLine().trim() + } + + fun outputPurchaseCount(amount: Int): Int { + val count = LottoCount(amount).calculate() + println() + println("$count$PURCHASE_NUMBER_TEXT") + return count + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/presentation/LottoWinningView.kt b/src/main/kotlin/lotto/presentation/LottoWinningView.kt new file mode 100644 index 000000000..770834ee3 --- /dev/null +++ b/src/main/kotlin/lotto/presentation/LottoWinningView.kt @@ -0,0 +1,40 @@ +package lotto.presentation + +import lotto.util.PROFIT_RATE_TEXT +import lotto.util.WINNING_RESULT_FIVE_BONUS_TEXT +import lotto.util.WINNING_RESULT_FIVE_TEXT +import lotto.util.WINNING_RESULT_FOUR_TEXT +import lotto.util.WINNING_RESULT_SIX_TEXT +import lotto.util.WINNING_RESULT_THREE_TEXT +import lotto.util.WINNING_STATISTICS_TEXT + +object LottoWinningView { + fun printWinningStatic() { + println("$WINNING_STATISTICS_TEXT\n---") + } + + fun outputThreeWinningResult(winningCount: Int) { + println("$WINNING_RESULT_THREE_TEXT${winningCount}개") + } + + fun outputFourWinningResult(winningCount: Int) { + println("$WINNING_RESULT_FOUR_TEXT${winningCount}개") + } + + fun outputFiveWinningResult(winningCount: Int) { + println("$WINNING_RESULT_FIVE_TEXT${winningCount}개") + } + + fun outputFiveBonusWinningResult(winningCount: Int) { + println("${WINNING_RESULT_FIVE_BONUS_TEXT}${winningCount}개") + } + + fun outputSixWinningResult(winningCount: Int) { + println("$WINNING_RESULT_SIX_TEXT${winningCount}개") + } + + fun outputProfitRate(profit: String) { + println(PROFIT_RATE_TEXT.format(profit)) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/util/Constant.kt b/src/main/kotlin/lotto/util/Constant.kt new file mode 100644 index 000000000..076f958ea --- /dev/null +++ b/src/main/kotlin/lotto/util/Constant.kt @@ -0,0 +1,33 @@ +package lotto.util + +const val PURCHASE_PRICE_TEXT = "구입금액을 입력해 주세요." +const val PURCHASE_NUMBER_TEXT = "개를 구매했습니다." +const val WINNING_NUMBER_TEXT = "당첨 번호를 입력해 주세요." +const val BONUS_NUMBER_TEXT = "보너스 번호를 입력해 주세요." +const val WINNING_STATISTICS_TEXT = "당첨 통계" +const val WINNING_RESULT_THREE_TEXT = "3개 일치 (5,000원) - " +const val WINNING_RESULT_FOUR_TEXT = "4개 일치 (50,000원) - " +const val WINNING_RESULT_FIVE_TEXT = "5개 일치 (1,500,000원) - " +const val WINNING_RESULT_FIVE_BONUS_TEXT = "5개 일치, 보너스 볼 일치 (30,000,000원) - " +const val WINNING_RESULT_SIX_TEXT = "6개 일치 (2,000,000,000원) - " +const val PROFIT_RATE_TEXT = "총 수익률은 %s입니다." + +const val LOTTO_NUMBER_MIN = 1 +const val LOTTO_NUMBER_MAX = 45 +const val LOTTO_NUMBER_COUNT = 6 +const val LOTTO_BONUS_COUNT = 1 +const val LOTTO_PRICE_STANDARD = 1000 +const val ZERO = 0 + +const val LOTTO_NUMBER_SEPARATOR = "," + +const val EXCEPTION_MESSAGE = "[ERROR] " +const val WRONG_UNIT_EXCEPTION = "잘못된 단위의 금액 입니다. 1,000원으로 나누어 떨어 지도록 입력해 주세요." +const val WRONG_NUMBER_EXCEPTION = "잘못된 입력 형식 입니다. 숫자를 입력해 주세요." +const val WRONG_RANGE_NEGATIVE_EXCEPTION = "잘못된 입력값 입니다. 양수를 입력해 주세요." +const val WRONG_RANGE_EXCEPTION = "잘못된 입력값 입니다. 범위(1~45)에 맞게 입력해 주세요." +const val WRONG_COUNT_EXCEPTION = "잘못된 개수의 입력값 입니다. 6개 입력해 주세요." +const val WRONG_BONUS_COUNT_EXCEPTION = "잘못된 개수의 입력값 입니다. 1개 입력해 주세요." +const val WRONG_SEPARATOR = "잘못된 기호 입니다. 번호 구분용 기호로 쉼표(,)를 입력해 주세요." +const val DUPLICATE_NUMBER_EXCEPTION = "잘못된 입력값 입니다. 중복값 없도록 입력해 주세요." +const val DUPLYCATE_BONUS_EXCEPTION = "잘못된 입력값 입니다. 로또 당첨 번호와 중복하지 않는 값을 입력해 주세요." diff --git a/src/main/kotlin/lotto/util/Exception.kt b/src/main/kotlin/lotto/util/Exception.kt new file mode 100644 index 000000000..8a1f630c6 --- /dev/null +++ b/src/main/kotlin/lotto/util/Exception.kt @@ -0,0 +1,37 @@ +package lotto.util + +object Exception { + fun validateTypeException(amount: String) { + requireNotNull(amount.toIntOrNull()) { EXCEPTION_MESSAGE + WRONG_NUMBER_EXCEPTION } + } + + fun validateNegativeException(amount: Int) { + require(amount >= ZERO) { EXCEPTION_MESSAGE + WRONG_RANGE_NEGATIVE_EXCEPTION } + } + + fun validateUnitException(amount: Int) { + require(amount % 1000 == 0 && amount > 0) { EXCEPTION_MESSAGE + WRONG_UNIT_EXCEPTION } + } + + fun validationRangeException(number: Int) { + require(number in LOTTO_NUMBER_MIN..LOTTO_NUMBER_MAX) { EXCEPTION_MESSAGE + WRONG_RANGE_EXCEPTION } + } + + fun validationDuplicationException(lotto: List, number: Int) { + if (lotto.count { it == number } != LOTTO_BONUS_COUNT) throw IllegalArgumentException( + DUPLICATE_NUMBER_EXCEPTION + ) + } + + fun validationSeparatorException(number: String) { + require(number.contains(LOTTO_NUMBER_SEPARATOR)) { EXCEPTION_MESSAGE + WRONG_SEPARATOR } + } + + fun validationBonusCountException(bonus: String) { + require(!bonus.contains(LOTTO_NUMBER_SEPARATOR)) { EXCEPTION_MESSAGE + WRONG_BONUS_COUNT_EXCEPTION } + } + + fun validationBonusDuplicationException(bonus: Int, winningNumber: List) { + require(!winningNumber.contains(bonus)) { EXCEPTION_MESSAGE + DUPLYCATE_BONUS_EXCEPTION } + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/LottoTest.kt b/src/test/kotlin/lotto/LottoTest.kt index 11d85ac2c..0a26c0beb 100644 --- a/src/test/kotlin/lotto/LottoTest.kt +++ b/src/test/kotlin/lotto/LottoTest.kt @@ -1,5 +1,6 @@ package lotto +import lotto.domain.Lotto import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows diff --git a/src/test/kotlin/lotto/domain/LottoCompareTest.kt b/src/test/kotlin/lotto/domain/LottoCompareTest.kt new file mode 100644 index 000000000..b2f4d7bf5 --- /dev/null +++ b/src/test/kotlin/lotto/domain/LottoCompareTest.kt @@ -0,0 +1,23 @@ +package lotto.domain + +import org.junit.jupiter.api.Assertions.* + +import org.junit.jupiter.api.Test + +class LottoCompareTest { + @Test + fun `당첨 로또 번호와 랜덤 번호를 비교 한다`() { + val winning = mutableListOf(1, 2, 3, 4, 5, 6) + val lotto = mutableListOf(Lotto(listOf(1, 7, 8, 9, 10, 11))) + val result = LottoCompare(lotto).compare(winning) + assertTrue(result.size == 1) + } + + @Test + fun `보너스 로또 번호와 랜덤 번호 비교 한다`() { + val bonus = 10 + val lotto = mutableListOf(Lotto(listOf(1, 7, 8, 9, 10, 11))) + val result = LottoCompare(lotto).compareBonus(bonus) + assertTrue(result == 1) + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/domain/LottoMakeTest.kt b/src/test/kotlin/lotto/domain/LottoMakeTest.kt new file mode 100644 index 000000000..e8d117f88 --- /dev/null +++ b/src/test/kotlin/lotto/domain/LottoMakeTest.kt @@ -0,0 +1,14 @@ +package lotto.domain + +import org.junit.jupiter.api.Assertions.* + +import org.junit.jupiter.api.Test + +class LottoMakeTest { + @Test + fun `입력받은 금액만큼 로또를 발행한다`() { + val amount = 5000 + val lotto = LottoMake().resultLottoNumber(amount / 1000) + assertTrue(lotto.size == amount / 1000) + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/domain/LottoTest.kt b/src/test/kotlin/lotto/domain/LottoTest.kt new file mode 100644 index 000000000..3cff9a268 --- /dev/null +++ b/src/test/kotlin/lotto/domain/LottoTest.kt @@ -0,0 +1,16 @@ +package lotto.domain + +import org.junit.jupiter.api.Assertions.* + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class LottoTest { + @Test + fun `로또 번호의 개수가 6개가 아닌 경우`() { + assertThrows { + Lotto(listOf(1, 2, 3, 4, 5, 6, 7)) + } + } + +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/domain/LottoWinningTest.kt b/src/test/kotlin/lotto/domain/LottoWinningTest.kt new file mode 100644 index 000000000..542f0a274 --- /dev/null +++ b/src/test/kotlin/lotto/domain/LottoWinningTest.kt @@ -0,0 +1,17 @@ +package lotto.domain + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test + +class LottoWinningTest { + @Test + fun `로또 구매 금액과 로또 번호 일치 정도로 수익률 구한다`() { + val amount = 8000 + val winning = mutableListOf(3, 0, 3, 0, 0, 0, 3, 3) + val winningCount = winning.count { it == 3 } + val bonus = 1 + val profit = LottoWinning(winning, bonus).profit(amount) + val result = 5000 * winningCount + assertTrue(profit != String.format("%.1f", result.toDouble() / amount * 100) + "%") + } +} \ No newline at end of file