From 99369f0cdc2b81d2bd18ce7cff2195db1e715f5d Mon Sep 17 00:00:00 2001 From: Hwang Sangwook Date: Tue, 3 Dec 2024 16:23:55 +0900 Subject: [PATCH 01/27] =?UTF-8?q?feat:=20Lotto=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B0=8F=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/kotlin/lotto/LottoTest.kt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/kotlin/lotto/LottoTest.kt diff --git a/src/test/kotlin/lotto/LottoTest.kt b/src/test/kotlin/lotto/LottoTest.kt new file mode 100644 index 000000000..cda755be5 --- /dev/null +++ b/src/test/kotlin/lotto/LottoTest.kt @@ -0,0 +1,28 @@ +package lotto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +data class LottoNumber(val number: Int) { + init { + require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } + } +} + + + +class LottoTest { + @ParameterizedTest + @ValueSource(ints = [0, -10, 46, 100]) + fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { + shouldThrow { + LottoNumber(number) + }.also { + it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" + } + } +} + + From 005d6e4375d14e8db90415b5ae4d913ed452669c Mon Sep 17 00:00:00 2001 From: Hwang Sangwook Date: Sat, 7 Dec 2024 16:50:40 +0900 Subject: [PATCH 02/27] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8,=20=ED=8B=B0=EC=BC=93=20=EB=B0=9C=EA=B8=89=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/kotlin/lotto/LottoTest.kt | 122 +++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 8 deletions(-) diff --git a/src/test/kotlin/lotto/LottoTest.kt b/src/test/kotlin/lotto/LottoTest.kt index cda755be5..e0e40b12b 100644 --- a/src/test/kotlin/lotto/LottoTest.kt +++ b/src/test/kotlin/lotto/LottoTest.kt @@ -2,17 +2,12 @@ package lotto import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe +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.MethodSource import org.junit.jupiter.params.provider.ValueSource -data class LottoNumber(val number: Int) { - init { - require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } - } -} - - - class LottoTest { @ParameterizedTest @ValueSource(ints = [0, -10, 46, 100]) @@ -23,6 +18,117 @@ class LottoTest { it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } } + + @ParameterizedTest + @MethodSource("providedDuplicationNumbers") + fun `로또 티켓은 중복된 번호로 생성되면 예외가 발생한다`(numbers: List) { + shouldThrow { + LottoTicket(numbers) + }.also { + it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" + } + } + + @ParameterizedTest + @MethodSource("providedWrongCountOfNumbers") + fun `로또 티켓 번호는 6개가 아니면 예외가 발생한다`(numbers: List) { + shouldThrow { + LottoTicket(numbers) + }.also { + it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" + } + } + + @Test + fun `로또 티켓은 한장 이상 구입 해야 한다`() { + shouldThrow { + LottoTickets(listOf()) + }.also { + it.message shouldBe "로또 티켓은 한장 이상 구입해야 합니다" + } + } + + @Test + fun `로또 티켓을 구입 금액에 맞게 발급한다`() { + val amount = 5_000 + val lottoTickets = LottoTickets.purchase(amount) + lottoTickets.tickets.size shouldBe 5 + } + + @Test + fun `로또 티켓을 생성하면 6개의 번호가 들어있다`() { + val lottoTicket = LottoTicket.generateLottoNumber() + lottoTicket.lottoNumbers.size shouldBe 6 + } + + companion object { + @JvmStatic + fun providedDuplicationNumbers() = + listOf( + Arguments.arguments(listOf(1, 1, 2, 3, 4, 5)), + Arguments.arguments(listOf(5, 5, 12, 13, 34, 35)), + Arguments.arguments(listOf(11, 19, 24, 33, 44, 44)), + ) + + @JvmStatic + fun providedWrongCountOfNumbers() = + listOf( + Arguments.arguments(listOf(1, 2, 3, 4, 5, 6, 7)), + Arguments.arguments(listOf(3, 5, 7, 8, 9)), + Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), + ) + } +} + +data class LottoNumber(val number: Int) { + init { + require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } + } +} + +class LottoTicket(numbers: List) { + private val _lottoNumbers: Set + val lottoNumbers: Set + get() = _lottoNumbers.toSet() + + init { + require(numbers.size == 6 && numbers.toSet().size == 6) { "로또 티켓 번호가 잘못 입력되었습니다" } + _lottoNumbers = numbers.toSortedSet() + } + + companion object { + fun generateLottoNumber(): LottoTicket { + val lottoNumbers = + (1..45) // .map { LottoNumber(it.first) } + .shuffled() + .take(6) + return LottoTicket(lottoNumbers) + } + } } +class LottoTickets(lottoTickets: List) : Iterable { + private val _tickets: List + val tickets: List + get() = _tickets + init { + require(lottoTickets.isNotEmpty()) { "로또 티켓은 한장 이상 구입해야 합니다" } + _tickets = lottoTickets + } + + override fun iterator(): Iterator { + return _tickets.iterator() + } + + companion object { + fun purchase(amount: Int): LottoTickets { + val quantity = amount / 1000 + var lottoTickets = ArrayList() + repeat(quantity) { + lottoTickets.add(LottoTicket.generateLottoNumber()) + } + return LottoTickets(lottoTickets) + } + } +} From e7da511e671121d68b24cb062f583d6544172630 Mon Sep 17 00:00:00 2001 From: wook Date: Sun, 8 Dec 2024 20:37:17 -0800 Subject: [PATCH 03/27] =?UTF-8?q?refactor:=20Test=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=82=B4=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?Class=20=EB=B6=84=EB=A6=AC=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/LottoNumber.kt | 7 ++ src/main/kotlin/lotto/LottoTicket.kt | 22 ++++ src/main/kotlin/lotto/LottoTickets.kt | 27 +++++ src/test/kotlin/lotto/LottoNumberTest.kt | 18 +++ src/test/kotlin/lotto/LottoTest.kt | 134 ---------------------- src/test/kotlin/lotto/LottoTicketTest.kt | 54 +++++++++ src/test/kotlin/lotto/LottoTicketsTest.kt | 24 ++++ 7 files changed, 152 insertions(+), 134 deletions(-) create mode 100644 src/main/kotlin/lotto/LottoNumber.kt create mode 100644 src/main/kotlin/lotto/LottoTicket.kt create mode 100644 src/main/kotlin/lotto/LottoTickets.kt create mode 100644 src/test/kotlin/lotto/LottoNumberTest.kt delete mode 100644 src/test/kotlin/lotto/LottoTest.kt create mode 100644 src/test/kotlin/lotto/LottoTicketTest.kt create mode 100644 src/test/kotlin/lotto/LottoTicketsTest.kt diff --git a/src/main/kotlin/lotto/LottoNumber.kt b/src/main/kotlin/lotto/LottoNumber.kt new file mode 100644 index 000000000..0b7f4b02e --- /dev/null +++ b/src/main/kotlin/lotto/LottoNumber.kt @@ -0,0 +1,7 @@ +package lotto + +data class LottoNumber(val number: Int) { + init { + require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/LottoTicket.kt b/src/main/kotlin/lotto/LottoTicket.kt new file mode 100644 index 000000000..3ec927c02 --- /dev/null +++ b/src/main/kotlin/lotto/LottoTicket.kt @@ -0,0 +1,22 @@ +package lotto + +class LottoTicket(numbers: List) { + private val _lottoNumbers: Set + val lottoNumbers: Set + get() = _lottoNumbers.toSet() + + init { + require(numbers.size == 6 && numbers.toSet().size == 6) { "로또 티켓 번호가 잘못 입력되었습니다" } + _lottoNumbers = numbers.toSortedSet() + } + + companion object { + fun generateLottoNumber(): LottoTicket { + val lottoNumbers = + (1..45) // .map { LottoNumber(it.first) } + .shuffled() + .take(6) + return LottoTicket(lottoNumbers) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/LottoTickets.kt b/src/main/kotlin/lotto/LottoTickets.kt new file mode 100644 index 000000000..a6fc82756 --- /dev/null +++ b/src/main/kotlin/lotto/LottoTickets.kt @@ -0,0 +1,27 @@ +package lotto + +class LottoTickets(lottoTickets: List) : Iterable { + private val _tickets: List + val tickets: List + get() = _tickets + + init { + require(lottoTickets.isNotEmpty()) { "로또 티켓은 한장 이상 구입해야 합니다" } + _tickets = lottoTickets + } + + override fun iterator(): Iterator { + return _tickets.iterator() + } + + companion object { + fun purchase(amount: Int): LottoTickets { + val quantity = amount / 1000 + var lottoTickets = ArrayList() + repeat(quantity) { + lottoTickets.add(LottoTicket.generateLottoNumber()) + } + return LottoTickets(lottoTickets) + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/LottoNumberTest.kt b/src/test/kotlin/lotto/LottoNumberTest.kt new file mode 100644 index 000000000..c08b5ee03 --- /dev/null +++ b/src/test/kotlin/lotto/LottoNumberTest.kt @@ -0,0 +1,18 @@ +package lotto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +class LottoNumberTest { + @ParameterizedTest + @ValueSource(ints = [0, -10, 46, 100]) + fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { + shouldThrow { + LottoNumber(number) + }.also { + it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/LottoTest.kt b/src/test/kotlin/lotto/LottoTest.kt deleted file mode 100644 index e0e40b12b..000000000 --- a/src/test/kotlin/lotto/LottoTest.kt +++ /dev/null @@ -1,134 +0,0 @@ -package lotto - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -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.MethodSource -import org.junit.jupiter.params.provider.ValueSource - -class LottoTest { - @ParameterizedTest - @ValueSource(ints = [0, -10, 46, 100]) - fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { - shouldThrow { - LottoNumber(number) - }.also { - it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" - } - } - - @ParameterizedTest - @MethodSource("providedDuplicationNumbers") - fun `로또 티켓은 중복된 번호로 생성되면 예외가 발생한다`(numbers: List) { - shouldThrow { - LottoTicket(numbers) - }.also { - it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" - } - } - - @ParameterizedTest - @MethodSource("providedWrongCountOfNumbers") - fun `로또 티켓 번호는 6개가 아니면 예외가 발생한다`(numbers: List) { - shouldThrow { - LottoTicket(numbers) - }.also { - it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" - } - } - - @Test - fun `로또 티켓은 한장 이상 구입 해야 한다`() { - shouldThrow { - LottoTickets(listOf()) - }.also { - it.message shouldBe "로또 티켓은 한장 이상 구입해야 합니다" - } - } - - @Test - fun `로또 티켓을 구입 금액에 맞게 발급한다`() { - val amount = 5_000 - val lottoTickets = LottoTickets.purchase(amount) - lottoTickets.tickets.size shouldBe 5 - } - - @Test - fun `로또 티켓을 생성하면 6개의 번호가 들어있다`() { - val lottoTicket = LottoTicket.generateLottoNumber() - lottoTicket.lottoNumbers.size shouldBe 6 - } - - companion object { - @JvmStatic - fun providedDuplicationNumbers() = - listOf( - Arguments.arguments(listOf(1, 1, 2, 3, 4, 5)), - Arguments.arguments(listOf(5, 5, 12, 13, 34, 35)), - Arguments.arguments(listOf(11, 19, 24, 33, 44, 44)), - ) - - @JvmStatic - fun providedWrongCountOfNumbers() = - listOf( - Arguments.arguments(listOf(1, 2, 3, 4, 5, 6, 7)), - Arguments.arguments(listOf(3, 5, 7, 8, 9)), - Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), - ) - } -} - -data class LottoNumber(val number: Int) { - init { - require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } - } -} - -class LottoTicket(numbers: List) { - private val _lottoNumbers: Set - val lottoNumbers: Set - get() = _lottoNumbers.toSet() - - init { - require(numbers.size == 6 && numbers.toSet().size == 6) { "로또 티켓 번호가 잘못 입력되었습니다" } - _lottoNumbers = numbers.toSortedSet() - } - - companion object { - fun generateLottoNumber(): LottoTicket { - val lottoNumbers = - (1..45) // .map { LottoNumber(it.first) } - .shuffled() - .take(6) - return LottoTicket(lottoNumbers) - } - } -} - -class LottoTickets(lottoTickets: List) : Iterable { - private val _tickets: List - val tickets: List - get() = _tickets - - init { - require(lottoTickets.isNotEmpty()) { "로또 티켓은 한장 이상 구입해야 합니다" } - _tickets = lottoTickets - } - - override fun iterator(): Iterator { - return _tickets.iterator() - } - - companion object { - fun purchase(amount: Int): LottoTickets { - val quantity = amount / 1000 - var lottoTickets = ArrayList() - repeat(quantity) { - lottoTickets.add(LottoTicket.generateLottoNumber()) - } - return LottoTickets(lottoTickets) - } - } -} diff --git a/src/test/kotlin/lotto/LottoTicketTest.kt b/src/test/kotlin/lotto/LottoTicketTest.kt new file mode 100644 index 000000000..3cd40d5bd --- /dev/null +++ b/src/test/kotlin/lotto/LottoTicketTest.kt @@ -0,0 +1,54 @@ +package lotto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +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.MethodSource + +class LottoTicketTest { + @ParameterizedTest + @MethodSource("providedDuplicationNumbers") + fun `로또 티켓은 중복된 번호로 생성되면 예외가 발생한다`(numbers: List) { + shouldThrow { + LottoTicket(numbers) + }.also { + it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" + } + } + + @ParameterizedTest + @MethodSource("providedWrongCountOfNumbers") + fun `로또 티켓 번호는 6개가 아니면 예외가 발생한다`(numbers: List) { + shouldThrow { + LottoTicket(numbers) + }.also { + it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" + } + } + + @Test + fun `로또 티켓을 생성하면 6개의 번호가 들어있다`() { + val lottoTicket = LottoTicket.generateLottoNumber() + lottoTicket.lottoNumbers.size shouldBe 6 + } + + companion object { + @JvmStatic + fun providedDuplicationNumbers() = + listOf( + Arguments.arguments(listOf(1, 1, 2, 3, 4, 5)), + Arguments.arguments(listOf(5, 5, 12, 13, 34, 35)), + Arguments.arguments(listOf(11, 19, 24, 33, 44, 44)), + ) + + @JvmStatic + fun providedWrongCountOfNumbers() = + listOf( + Arguments.arguments(listOf(1, 2, 3, 4, 5, 6, 7)), + Arguments.arguments(listOf(3, 5, 7, 8, 9)), + Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), + ) + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/LottoTicketsTest.kt b/src/test/kotlin/lotto/LottoTicketsTest.kt new file mode 100644 index 000000000..27c4ceec1 --- /dev/null +++ b/src/test/kotlin/lotto/LottoTicketsTest.kt @@ -0,0 +1,24 @@ +package lotto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test + +class LottoTicketsTest { + @Test + fun `로또 티켓은 한장 이상 구입 해야 한다`() { + shouldThrow { + LottoTickets(listOf()) + }.also { + it.message shouldBe "로또 티켓은 한장 이상 구입해야 합니다" + } + } + + @Test + fun `로또 티켓을 구입 금액에 맞게 발급한다`() { + val amount = 5_000 + val lottoTickets = LottoTickets.purchase(amount) + lottoTickets.tickets.size shouldBe 5 + } +} + From bce5ce945d8811a91753894d0552a7925ede2aac Mon Sep 17 00:00:00 2001 From: wook Date: Mon, 9 Dec 2024 13:14:58 -0800 Subject: [PATCH 04/27] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/LottoNumber.kt | 2 +- src/main/kotlin/lotto/LottoRank.kt | 12 +++++ src/main/kotlin/lotto/LottoTicket.kt | 2 +- src/main/kotlin/lotto/LottoTickets.kt | 4 +- src/main/kotlin/lotto/WinningLotto.kt | 14 +++++ src/test/kotlin/lotto/LottoNumberTest.kt | 2 +- src/test/kotlin/lotto/LottoRankTest.kt | 62 +++++++++++++++++++++++ src/test/kotlin/lotto/LottoTicketTest.kt | 2 +- src/test/kotlin/lotto/LottoTicketsTest.kt | 1 - src/test/kotlin/lotto/WinningLottoTest.kt | 39 ++++++++++++++ 10 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 src/main/kotlin/lotto/LottoRank.kt create mode 100644 src/main/kotlin/lotto/WinningLotto.kt create mode 100644 src/test/kotlin/lotto/LottoRankTest.kt create mode 100644 src/test/kotlin/lotto/WinningLottoTest.kt diff --git a/src/main/kotlin/lotto/LottoNumber.kt b/src/main/kotlin/lotto/LottoNumber.kt index 0b7f4b02e..a15f1a637 100644 --- a/src/main/kotlin/lotto/LottoNumber.kt +++ b/src/main/kotlin/lotto/LottoNumber.kt @@ -4,4 +4,4 @@ data class LottoNumber(val number: Int) { init { require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/lotto/LottoRank.kt b/src/main/kotlin/lotto/LottoRank.kt new file mode 100644 index 000000000..017abef28 --- /dev/null +++ b/src/main/kotlin/lotto/LottoRank.kt @@ -0,0 +1,12 @@ +package lotto + +enum class LottoRank( + val matchCount: Int, + val prize: Int, +) { + FIRST_PLACE(6, 2_000_000_000), + SECOND_PLACE(5, 1_500_000), + THIRD_PLACE(4, 50_000), + FOURTH_PLACE(3, 5_000), + BLANK_PLACE(0, 0), +} diff --git a/src/main/kotlin/lotto/LottoTicket.kt b/src/main/kotlin/lotto/LottoTicket.kt index 3ec927c02..5332024e1 100644 --- a/src/main/kotlin/lotto/LottoTicket.kt +++ b/src/main/kotlin/lotto/LottoTicket.kt @@ -19,4 +19,4 @@ class LottoTicket(numbers: List) { return LottoTicket(lottoNumbers) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/lotto/LottoTickets.kt b/src/main/kotlin/lotto/LottoTickets.kt index a6fc82756..efea1583b 100644 --- a/src/main/kotlin/lotto/LottoTickets.kt +++ b/src/main/kotlin/lotto/LottoTickets.kt @@ -17,11 +17,11 @@ class LottoTickets(lottoTickets: List) : Iterable { companion object { fun purchase(amount: Int): LottoTickets { val quantity = amount / 1000 - var lottoTickets = ArrayList() + val lottoTickets = ArrayList() repeat(quantity) { lottoTickets.add(LottoTicket.generateLottoNumber()) } return LottoTickets(lottoTickets) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/lotto/WinningLotto.kt b/src/main/kotlin/lotto/WinningLotto.kt new file mode 100644 index 000000000..d9606f156 --- /dev/null +++ b/src/main/kotlin/lotto/WinningLotto.kt @@ -0,0 +1,14 @@ +package lotto + +class WinningLotto(numbers: List) { + private val _lottoNumbers: Set = numbers.toSortedSet() + val lottoNumbers: Set + get() = _lottoNumbers.toSet() + + constructor() : this(LottoTicket.generateLottoNumber().lottoNumbers.toList()) + + fun matchedCount(lottoTicket: LottoTicket): LottoRank { + val matchCount = lottoNumbers.intersect(lottoTicket.lottoNumbers).size + return LottoRank.entries.find { it.matchCount == matchCount } ?: LottoRank.BLANK_PLACE + } +} diff --git a/src/test/kotlin/lotto/LottoNumberTest.kt b/src/test/kotlin/lotto/LottoNumberTest.kt index c08b5ee03..9fb849806 100644 --- a/src/test/kotlin/lotto/LottoNumberTest.kt +++ b/src/test/kotlin/lotto/LottoNumberTest.kt @@ -15,4 +15,4 @@ class LottoNumberTest { it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } } -} \ No newline at end of file +} diff --git a/src/test/kotlin/lotto/LottoRankTest.kt b/src/test/kotlin/lotto/LottoRankTest.kt new file mode 100644 index 000000000..66cb78550 --- /dev/null +++ b/src/test/kotlin/lotto/LottoRankTest.kt @@ -0,0 +1,62 @@ +package lotto + +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test + +class LottoRankTest { + @Test + fun `로또 티켓의 번호와 당첨 티켓이 6개 모두 일치하면 1등이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 5, 6))) + matchRank shouldBe LottoRank.FIRST_PLACE + matchRank.prize shouldBe 2_000_000_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 5개 일치하면 2등이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 5, 16))) + matchRank shouldBe LottoRank.SECOND_PLACE + matchRank.prize shouldBe 1_500_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 4개 일치하면 3등이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 15, 16))) + matchRank shouldBe LottoRank.THIRD_PLACE + matchRank.prize shouldBe 50_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 3개 일치하면 4등이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 14, 15, 16))) + matchRank shouldBe LottoRank.FOURTH_PLACE + matchRank.prize shouldBe 5_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 2개 일치하면 꽝이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 13, 14, 15, 16))) + matchRank shouldBe LottoRank.BLANK_PLACE + matchRank.prize shouldBe 0 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 1개 일치하면 꽝이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 12, 13, 14, 15, 16))) + matchRank shouldBe LottoRank.BLANK_PLACE + matchRank.prize shouldBe 0 + } + + @Test + fun `로또 티켓의 번호가 당첨 티켓 번호와 하나도 일치하지 않으면 꽝이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(11, 12, 13, 14, 15, 16))) + matchRank shouldBe LottoRank.BLANK_PLACE + matchRank.prize shouldBe 0 + } +} diff --git a/src/test/kotlin/lotto/LottoTicketTest.kt b/src/test/kotlin/lotto/LottoTicketTest.kt index 3cd40d5bd..28ebcc22e 100644 --- a/src/test/kotlin/lotto/LottoTicketTest.kt +++ b/src/test/kotlin/lotto/LottoTicketTest.kt @@ -51,4 +51,4 @@ class LottoTicketTest { Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), ) } -} \ No newline at end of file +} diff --git a/src/test/kotlin/lotto/LottoTicketsTest.kt b/src/test/kotlin/lotto/LottoTicketsTest.kt index 27c4ceec1..f1f4d3785 100644 --- a/src/test/kotlin/lotto/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/LottoTicketsTest.kt @@ -21,4 +21,3 @@ class LottoTicketsTest { lottoTickets.tickets.size shouldBe 5 } } - diff --git a/src/test/kotlin/lotto/WinningLottoTest.kt b/src/test/kotlin/lotto/WinningLottoTest.kt new file mode 100644 index 000000000..19f622af0 --- /dev/null +++ b/src/test/kotlin/lotto/WinningLottoTest.kt @@ -0,0 +1,39 @@ +package lotto + +import io.kotest.matchers.shouldBe +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.MethodSource + +class WinningLottoTest { + @Test + fun `당첨 티켓은 6개의 로또 번호로 생성된다`() { + val winningLotto = WinningLotto() + winningLotto.lottoNumbers.size shouldBe 6 + } + + @ParameterizedTest + @MethodSource("generateWiningLotto") + fun `로또 티켓이 당첨 티켓과 몇개가 일치하는지 확인 할 수 있다`( + lottoTicket: LottoTicket, + winningLotto: WinningLotto, + matchCount: Int, + ) { + val count = winningLotto.matchedCount(lottoTicket) + matchCount shouldBe count + } + + companion object { + @JvmStatic + fun generateWiningLotto() = + listOf( + Arguments.arguments(LottoTicket(listOf(1, 12, 13, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 1), + Arguments.arguments(LottoTicket(listOf(1, 2, 13, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 2), + Arguments.arguments(LottoTicket(listOf(1, 2, 3, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 3), + Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 4), + Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 5, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 5), + Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 5, 6)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 6), + ) + } +} From 89f9d1c09e96c6f891d29cb3e0f9a321c3305421 Mon Sep 17 00:00:00 2001 From: wook Date: Tue, 10 Dec 2024 17:04:27 -0800 Subject: [PATCH 05/27] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC,=20=EC=9E=85=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EB=B7=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/LottoNumber.kt | 7 --- src/main/kotlin/lotto/LottoRank.kt | 12 ---- src/main/kotlin/lotto/LottoTicket.kt | 22 ------- src/main/kotlin/lotto/LottoTickets.kt | 27 -------- src/main/kotlin/lotto/WinningLotto.kt | 14 ----- src/main/kotlin/lotto/domain/WinningLotto.kt | 19 ++++++ src/test/kotlin/lotto/LottoNumberTest.kt | 18 ------ src/test/kotlin/lotto/LottoRankTest.kt | 62 ------------------- src/test/kotlin/lotto/LottoTicketTest.kt | 54 ---------------- src/test/kotlin/lotto/LottoTicketsTest.kt | 23 ------- .../lotto/{ => domain}/WinningLottoTest.kt | 16 ++++- 11 files changed, 32 insertions(+), 242 deletions(-) delete mode 100644 src/main/kotlin/lotto/LottoNumber.kt delete mode 100644 src/main/kotlin/lotto/LottoRank.kt delete mode 100644 src/main/kotlin/lotto/LottoTicket.kt delete mode 100644 src/main/kotlin/lotto/LottoTickets.kt delete mode 100644 src/main/kotlin/lotto/WinningLotto.kt create mode 100644 src/main/kotlin/lotto/domain/WinningLotto.kt delete mode 100644 src/test/kotlin/lotto/LottoNumberTest.kt delete mode 100644 src/test/kotlin/lotto/LottoRankTest.kt delete mode 100644 src/test/kotlin/lotto/LottoTicketTest.kt delete mode 100644 src/test/kotlin/lotto/LottoTicketsTest.kt rename src/test/kotlin/lotto/{ => domain}/WinningLottoTest.kt (76%) diff --git a/src/main/kotlin/lotto/LottoNumber.kt b/src/main/kotlin/lotto/LottoNumber.kt deleted file mode 100644 index a15f1a637..000000000 --- a/src/main/kotlin/lotto/LottoNumber.kt +++ /dev/null @@ -1,7 +0,0 @@ -package lotto - -data class LottoNumber(val number: Int) { - init { - require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } - } -} diff --git a/src/main/kotlin/lotto/LottoRank.kt b/src/main/kotlin/lotto/LottoRank.kt deleted file mode 100644 index 017abef28..000000000 --- a/src/main/kotlin/lotto/LottoRank.kt +++ /dev/null @@ -1,12 +0,0 @@ -package lotto - -enum class LottoRank( - val matchCount: Int, - val prize: Int, -) { - FIRST_PLACE(6, 2_000_000_000), - SECOND_PLACE(5, 1_500_000), - THIRD_PLACE(4, 50_000), - FOURTH_PLACE(3, 5_000), - BLANK_PLACE(0, 0), -} diff --git a/src/main/kotlin/lotto/LottoTicket.kt b/src/main/kotlin/lotto/LottoTicket.kt deleted file mode 100644 index 5332024e1..000000000 --- a/src/main/kotlin/lotto/LottoTicket.kt +++ /dev/null @@ -1,22 +0,0 @@ -package lotto - -class LottoTicket(numbers: List) { - private val _lottoNumbers: Set - val lottoNumbers: Set - get() = _lottoNumbers.toSet() - - init { - require(numbers.size == 6 && numbers.toSet().size == 6) { "로또 티켓 번호가 잘못 입력되었습니다" } - _lottoNumbers = numbers.toSortedSet() - } - - companion object { - fun generateLottoNumber(): LottoTicket { - val lottoNumbers = - (1..45) // .map { LottoNumber(it.first) } - .shuffled() - .take(6) - return LottoTicket(lottoNumbers) - } - } -} diff --git a/src/main/kotlin/lotto/LottoTickets.kt b/src/main/kotlin/lotto/LottoTickets.kt deleted file mode 100644 index efea1583b..000000000 --- a/src/main/kotlin/lotto/LottoTickets.kt +++ /dev/null @@ -1,27 +0,0 @@ -package lotto - -class LottoTickets(lottoTickets: List) : Iterable { - private val _tickets: List - val tickets: List - get() = _tickets - - init { - require(lottoTickets.isNotEmpty()) { "로또 티켓은 한장 이상 구입해야 합니다" } - _tickets = lottoTickets - } - - override fun iterator(): Iterator { - return _tickets.iterator() - } - - companion object { - fun purchase(amount: Int): LottoTickets { - val quantity = amount / 1000 - val lottoTickets = ArrayList() - repeat(quantity) { - lottoTickets.add(LottoTicket.generateLottoNumber()) - } - return LottoTickets(lottoTickets) - } - } -} diff --git a/src/main/kotlin/lotto/WinningLotto.kt b/src/main/kotlin/lotto/WinningLotto.kt deleted file mode 100644 index d9606f156..000000000 --- a/src/main/kotlin/lotto/WinningLotto.kt +++ /dev/null @@ -1,14 +0,0 @@ -package lotto - -class WinningLotto(numbers: List) { - private val _lottoNumbers: Set = numbers.toSortedSet() - val lottoNumbers: Set - get() = _lottoNumbers.toSet() - - constructor() : this(LottoTicket.generateLottoNumber().lottoNumbers.toList()) - - fun matchedCount(lottoTicket: LottoTicket): LottoRank { - val matchCount = lottoNumbers.intersect(lottoTicket.lottoNumbers).size - return LottoRank.entries.find { it.matchCount == matchCount } ?: LottoRank.BLANK_PLACE - } -} diff --git a/src/main/kotlin/lotto/domain/WinningLotto.kt b/src/main/kotlin/lotto/domain/WinningLotto.kt new file mode 100644 index 000000000..b7d1d8734 --- /dev/null +++ b/src/main/kotlin/lotto/domain/WinningLotto.kt @@ -0,0 +1,19 @@ +package lotto.domain + +import lotto.domain.LottoTicket.Companion.LOTTO_TICKET_SIZE + +class WinningLotto(numbers: List) { + private val _lottoNumbers: Set = numbers.toSortedSet() + val lottoNumbers: Set + get() = _lottoNumbers.toSet() + + constructor() : this(LottoTicket.generateLottoNumber().lottoNumbers.toList()) + + init { + require(numbers.size == LOTTO_TICKET_SIZE) { "당첨 번호 입력이 유효하지 않습니다" } + } + + fun calculateMatchCount(lottoTicket: LottoTicket): Int { + return lottoNumbers.intersect(lottoTicket.lottoNumbers).size + } +} diff --git a/src/test/kotlin/lotto/LottoNumberTest.kt b/src/test/kotlin/lotto/LottoNumberTest.kt deleted file mode 100644 index 9fb849806..000000000 --- a/src/test/kotlin/lotto/LottoNumberTest.kt +++ /dev/null @@ -1,18 +0,0 @@ -package lotto - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.ValueSource - -class LottoNumberTest { - @ParameterizedTest - @ValueSource(ints = [0, -10, 46, 100]) - fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { - shouldThrow { - LottoNumber(number) - }.also { - it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" - } - } -} diff --git a/src/test/kotlin/lotto/LottoRankTest.kt b/src/test/kotlin/lotto/LottoRankTest.kt deleted file mode 100644 index 66cb78550..000000000 --- a/src/test/kotlin/lotto/LottoRankTest.kt +++ /dev/null @@ -1,62 +0,0 @@ -package lotto - -import io.kotest.matchers.shouldBe -import org.junit.jupiter.api.Test - -class LottoRankTest { - @Test - fun `로또 티켓의 번호와 당첨 티켓이 6개 모두 일치하면 1등이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 5, 6))) - matchRank shouldBe LottoRank.FIRST_PLACE - matchRank.prize shouldBe 2_000_000_000 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 5개 일치하면 2등이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 5, 16))) - matchRank shouldBe LottoRank.SECOND_PLACE - matchRank.prize shouldBe 1_500_000 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 4개 일치하면 3등이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 15, 16))) - matchRank shouldBe LottoRank.THIRD_PLACE - matchRank.prize shouldBe 50_000 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 3개 일치하면 4등이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 14, 15, 16))) - matchRank shouldBe LottoRank.FOURTH_PLACE - matchRank.prize shouldBe 5_000 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 2개 일치하면 꽝이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 13, 14, 15, 16))) - matchRank shouldBe LottoRank.BLANK_PLACE - matchRank.prize shouldBe 0 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 1개 일치하면 꽝이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 12, 13, 14, 15, 16))) - matchRank shouldBe LottoRank.BLANK_PLACE - matchRank.prize shouldBe 0 - } - - @Test - fun `로또 티켓의 번호가 당첨 티켓 번호와 하나도 일치하지 않으면 꽝이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(11, 12, 13, 14, 15, 16))) - matchRank shouldBe LottoRank.BLANK_PLACE - matchRank.prize shouldBe 0 - } -} diff --git a/src/test/kotlin/lotto/LottoTicketTest.kt b/src/test/kotlin/lotto/LottoTicketTest.kt deleted file mode 100644 index 28ebcc22e..000000000 --- a/src/test/kotlin/lotto/LottoTicketTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -package lotto - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -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.MethodSource - -class LottoTicketTest { - @ParameterizedTest - @MethodSource("providedDuplicationNumbers") - fun `로또 티켓은 중복된 번호로 생성되면 예외가 발생한다`(numbers: List) { - shouldThrow { - LottoTicket(numbers) - }.also { - it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" - } - } - - @ParameterizedTest - @MethodSource("providedWrongCountOfNumbers") - fun `로또 티켓 번호는 6개가 아니면 예외가 발생한다`(numbers: List) { - shouldThrow { - LottoTicket(numbers) - }.also { - it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" - } - } - - @Test - fun `로또 티켓을 생성하면 6개의 번호가 들어있다`() { - val lottoTicket = LottoTicket.generateLottoNumber() - lottoTicket.lottoNumbers.size shouldBe 6 - } - - companion object { - @JvmStatic - fun providedDuplicationNumbers() = - listOf( - Arguments.arguments(listOf(1, 1, 2, 3, 4, 5)), - Arguments.arguments(listOf(5, 5, 12, 13, 34, 35)), - Arguments.arguments(listOf(11, 19, 24, 33, 44, 44)), - ) - - @JvmStatic - fun providedWrongCountOfNumbers() = - listOf( - Arguments.arguments(listOf(1, 2, 3, 4, 5, 6, 7)), - Arguments.arguments(listOf(3, 5, 7, 8, 9)), - Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), - ) - } -} diff --git a/src/test/kotlin/lotto/LottoTicketsTest.kt b/src/test/kotlin/lotto/LottoTicketsTest.kt deleted file mode 100644 index f1f4d3785..000000000 --- a/src/test/kotlin/lotto/LottoTicketsTest.kt +++ /dev/null @@ -1,23 +0,0 @@ -package lotto - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -import org.junit.jupiter.api.Test - -class LottoTicketsTest { - @Test - fun `로또 티켓은 한장 이상 구입 해야 한다`() { - shouldThrow { - LottoTickets(listOf()) - }.also { - it.message shouldBe "로또 티켓은 한장 이상 구입해야 합니다" - } - } - - @Test - fun `로또 티켓을 구입 금액에 맞게 발급한다`() { - val amount = 5_000 - val lottoTickets = LottoTickets.purchase(amount) - lottoTickets.tickets.size shouldBe 5 - } -} diff --git a/src/test/kotlin/lotto/WinningLottoTest.kt b/src/test/kotlin/lotto/domain/WinningLottoTest.kt similarity index 76% rename from src/test/kotlin/lotto/WinningLottoTest.kt rename to src/test/kotlin/lotto/domain/WinningLottoTest.kt index 19f622af0..cd6ed1c43 100644 --- a/src/test/kotlin/lotto/WinningLottoTest.kt +++ b/src/test/kotlin/lotto/domain/WinningLottoTest.kt @@ -1,5 +1,6 @@ -package lotto +package lotto.domain +import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test import org.junit.jupiter.params.ParameterizedTest @@ -13,14 +14,23 @@ class WinningLottoTest { winningLotto.lottoNumbers.size shouldBe 6 } + @Test + fun `당첨 티켓의 번호는 6개가 아니면 에러가 발생한다`() { + shouldThrow { + WinningLotto(listOf(1, 2, 3, 4)) + }.also { + it.message shouldBe "당첨 번호 입력이 유효하지 않습니다" + } + } + @ParameterizedTest @MethodSource("generateWiningLotto") fun `로또 티켓이 당첨 티켓과 몇개가 일치하는지 확인 할 수 있다`( lottoTicket: LottoTicket, winningLotto: WinningLotto, - matchCount: Int, + count: Int, ) { - val count = winningLotto.matchedCount(lottoTicket) + val matchCount = winningLotto.calculateMatchCount(lottoTicket) matchCount shouldBe count } From d978556d7ed45060234e123717eee4ba08f65046 Mon Sep 17 00:00:00 2001 From: wook Date: Wed, 11 Dec 2024 10:32:56 -0800 Subject: [PATCH 06/27] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=EB=B0=B1?= =?UTF-8?q?=20=EB=B0=98=EC=98=81,=20LottoTickets.calculateLottoRank=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 --- .../kotlin/lotto/domain/LottoTicketsTest.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index 6d3289d91..6880fbc91 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -42,4 +42,25 @@ class LottoTicketsTest { sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE sortedResults[2].count shouldBe 1 } + + @Test + fun `당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { + val lottoTickets = + LottoTickets( + listOf( + LottoTicket(listOf(1, 2, 3, 4, 5, 7)), + LottoTicket(listOf(1, 2, 3, 4, 5, 9)), + LottoTicket(listOf(1, 2, 3, 4, 8, 9)), + ), + ) + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val lottoResults = lottoTickets.calculateLottoRank(winningLotto) + val sortedResults = lottoResults.findAllSortedByMatchCount() + sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE + sortedResults[0].count shouldBe 0 + sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE + sortedResults[1].count shouldBe 2 + sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE + sortedResults[2].count shouldBe 1 + } } From 847f352ba35dc22e05b8cf1b7cbef0a50a08bca4 Mon Sep 17 00:00:00 2001 From: wook Date: Fri, 13 Dec 2024 18:19:12 +0900 Subject: [PATCH 07/27] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=EB=B0=B1?= =?UTF-8?q?=20=EB=B0=98=EC=98=81=201.=20WinningLotto=20=EC=A0=9C=EA=B1=B0?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20=EB=8B=B4=EB=8B=B9=ED=95=98=EB=8D=98=20?= =?UTF-8?q?=EC=B1=85=EC=9E=84=20LottoTicket=20=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=202.=20LottoTicket=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=8D=BC=ED=8B=B0=20=EB=B3=80=EA=B2=BD=20:=20List=20->=20?= =?UTF-8?q?Set=203.=20LottoTicket=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=8D=BC=ED=8B=B0=20=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9C=84=EC=9E=84=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD,=20=EB=B6=80=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=204.=20LottoTicket=20=EC=A0=95=EC=A0=81=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/domain/WinningLotto.kt | 19 ------- .../kotlin/lotto/domain/WinningLottoTest.kt | 49 ------------------- 2 files changed, 68 deletions(-) delete mode 100644 src/main/kotlin/lotto/domain/WinningLotto.kt delete mode 100644 src/test/kotlin/lotto/domain/WinningLottoTest.kt diff --git a/src/main/kotlin/lotto/domain/WinningLotto.kt b/src/main/kotlin/lotto/domain/WinningLotto.kt deleted file mode 100644 index b7d1d8734..000000000 --- a/src/main/kotlin/lotto/domain/WinningLotto.kt +++ /dev/null @@ -1,19 +0,0 @@ -package lotto.domain - -import lotto.domain.LottoTicket.Companion.LOTTO_TICKET_SIZE - -class WinningLotto(numbers: List) { - private val _lottoNumbers: Set = numbers.toSortedSet() - val lottoNumbers: Set - get() = _lottoNumbers.toSet() - - constructor() : this(LottoTicket.generateLottoNumber().lottoNumbers.toList()) - - init { - require(numbers.size == LOTTO_TICKET_SIZE) { "당첨 번호 입력이 유효하지 않습니다" } - } - - fun calculateMatchCount(lottoTicket: LottoTicket): Int { - return lottoNumbers.intersect(lottoTicket.lottoNumbers).size - } -} diff --git a/src/test/kotlin/lotto/domain/WinningLottoTest.kt b/src/test/kotlin/lotto/domain/WinningLottoTest.kt deleted file mode 100644 index cd6ed1c43..000000000 --- a/src/test/kotlin/lotto/domain/WinningLottoTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -package lotto.domain - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -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.MethodSource - -class WinningLottoTest { - @Test - fun `당첨 티켓은 6개의 로또 번호로 생성된다`() { - val winningLotto = WinningLotto() - winningLotto.lottoNumbers.size shouldBe 6 - } - - @Test - fun `당첨 티켓의 번호는 6개가 아니면 에러가 발생한다`() { - shouldThrow { - WinningLotto(listOf(1, 2, 3, 4)) - }.also { - it.message shouldBe "당첨 번호 입력이 유효하지 않습니다" - } - } - - @ParameterizedTest - @MethodSource("generateWiningLotto") - fun `로또 티켓이 당첨 티켓과 몇개가 일치하는지 확인 할 수 있다`( - lottoTicket: LottoTicket, - winningLotto: WinningLotto, - count: Int, - ) { - val matchCount = winningLotto.calculateMatchCount(lottoTicket) - matchCount shouldBe count - } - - companion object { - @JvmStatic - fun generateWiningLotto() = - listOf( - Arguments.arguments(LottoTicket(listOf(1, 12, 13, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 1), - Arguments.arguments(LottoTicket(listOf(1, 2, 13, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 2), - Arguments.arguments(LottoTicket(listOf(1, 2, 3, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 3), - Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 4), - Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 5, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 5), - Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 5, 6)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 6), - ) - } -} From 86bc2a45e427a961cc3cd4fad91ddfb5e92d55f3 Mon Sep 17 00:00:00 2001 From: Sangwook <45926559+goodbyeyo@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:07:59 +0900 Subject: [PATCH 08/27] =?UTF-8?q?Step3=20=EB=A1=9C=EB=98=90=202=EB=93=B1?= =?UTF-8?q?=20(#1131)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Lotto 도메인 테스트 및 구현 * feat: 로또 번호, 티켓 발급 기능 구현 및 테스트 * refactor: Test 코드 내 도메인 로직 Class 분리 리팩토링 * feat: 당첨 로또 기능 구현 * feat: 로또 컨트롤러, 입출력 뷰 구현 * refactor: 피드백 반영, LottoTickets.calculateLottoRank 테스트 추가 * refactor: 피드백 반영 1. WinningLotto 제거하고 담당하던 책임 LottoTicket 으로 이동 2. LottoTicket 프로퍼티 변경 : List -> Set 3. LottoTicket 프로퍼티 기반으로 위임하도록 변경, 부생성자 추가 4. LottoTicket 정적팩토리메서드 추가 * doc: STEP3 로또2등 요구구사항 정리 * feat: 보너스번호 도메인 구현 * feat: 보너스 번호 일치여부 구현 * feat: 로또 2등 기능 구현 1. LottoRank : 로또 랭크 판단 조건, 상금 변경 2. LottoTicket : 당첨 로또 계산 위임(WinningLotto) 3. LottoTicket : data class 변경 (피드백 반영) 4. 당첨 로또 계산 시 보너스 번호가 포함된 WinningLotto 전달 5. 당첨 결과 출력 보너스 번호 일치 여부 출력 6. 테스트 코드 2등 로또 반영 * refactor: 피드백 반영 1. BonusNumber 제거하고 WinningLotto 가 직접 책임을 담당하도록 변경 2. WinningLotto 생성자 인자 팩토리 메서드(동반 객체 메서드) 구조로 전달 3. LottoNumber 정적 팩터리 메서드 추가 --- README.md | 42 ++++++++++++ .../lotto/controller/LottoController.kt | 4 +- src/main/kotlin/lotto/domain/LottoNumber.kt | 12 ++-- src/main/kotlin/lotto/domain/LottoRank.kt | 18 +++-- src/main/kotlin/lotto/domain/LottoResults.kt | 2 +- src/main/kotlin/lotto/domain/LottoTicket.kt | 28 ++------ src/main/kotlin/lotto/domain/LottoTickets.kt | 2 +- src/main/kotlin/lotto/domain/WinningLotto.kt | 18 +++++ src/main/kotlin/lotto/view/InputView.kt | 9 ++- src/main/kotlin/lotto/view/OutputView.kt | 20 ++++-- .../lotto/controller/LottoControllerTest.kt | 6 +- .../kotlin/lotto/domain/LottoNumberTest.kt | 25 +++++-- src/test/kotlin/lotto/domain/LottoRankTest.kt | 31 +++++---- .../kotlin/lotto/domain/LottoResultsTest.kt | 4 +- .../kotlin/lotto/domain/LottoTicketTest.kt | 67 ++++++++----------- .../kotlin/lotto/domain/LottoTicketsTest.kt | 18 +++-- .../kotlin/lotto/domain/WinningLottoTest.kt | 45 +++++++++++++ 17 files changed, 241 insertions(+), 110 deletions(-) create mode 100644 src/main/kotlin/lotto/domain/WinningLotto.kt create mode 100644 src/test/kotlin/lotto/domain/WinningLottoTest.kt diff --git a/README.md b/README.md index 8a4606c2e..b47169a70 100644 --- a/README.md +++ b/README.md @@ -80,3 +80,45 @@ - [x] 당첨 랭크별 일치 개수 표시(3개~6개) - [x] 당첨 통계 수익률 표시 + --- +### Step3. 로또(2등) + +##### `기능 요구사항` +- 2등을 위해 추가 번호를 하나 더 추첨한다. +- 당첨 통계에 2등도 추가해야 한다. + +##### `실행 결과` +```text +[... 생략 ...] + +지난 주 당첨 번호를 입력해 주세요. +1, 2, 3, 4, 5, 6 +보너스 볼을 입력해 주세요. +7 + +당첨 통계 +--------- +3개 일치 (5000원)- 1개 +4개 일치 (50000원)- 0개 +5개 일치 (1500000원)- 0개 +5개 일치, 보너스 볼 일치(30000000원) - 0개 +6개 일치 (2000000000원)- 0개 +총 수익률은 0.35입니다.(기준이 1이기 때문에 결과적으로 손해라는 의미임) +``` + +##### `요구사항 정리` +- 보너스 볼 + - [ ] 보너스 볼을 입력 받을수 있다 + - [ ] 보너스 볼은 당첨 로또 티켓의 6개 번호와 중복 될 수 없다 +- 당첨 로또 + - [ ] 당첨 로또는 1개의 로또 티켓과 1개의 보너스 번호를 가진다 + - [ ] 로또 랭크 계산 역할을 담당한다 +- 로또 티켓 + - [ ] 로또 랭크 계산 역할을 당첨 로또에게 위임한다 +- 로또 랭크 + - [ ] 당첨번호와 5개 일치하고 보너스 번호도 같으면 2등이다, + - [ ] 당첨번호와 5개 일치하고 보너스 번호가 다르면 3등이다 + - [ ] 로또 2등의 당첨금액은 1_500_000원 -> 30_000_000원 + - [ ] 로또 3등의 당첨금액은 50_000원 -> 1_500_000원 + - [ ] 로또 4등의 당첨금액은 5_000원 -> 50_000원 + - [ ] 로또 5등의 당첨금액은 5_000원 diff --git a/src/main/kotlin/lotto/controller/LottoController.kt b/src/main/kotlin/lotto/controller/LottoController.kt index 39fa793cb..996d3c762 100644 --- a/src/main/kotlin/lotto/controller/LottoController.kt +++ b/src/main/kotlin/lotto/controller/LottoController.kt @@ -1,8 +1,8 @@ package lotto.controller import lotto.domain.LottoResults -import lotto.domain.LottoTicket import lotto.domain.LottoTickets +import lotto.domain.WinningLotto object LottoController { fun purchaseLotto(amount: Int): LottoTickets { @@ -11,7 +11,7 @@ object LottoController { fun calculateLottoRank( lottoTickets: LottoTickets, - winningLotto: LottoTicket, + winningLotto: WinningLotto, ): LottoResults { return lottoTickets.calculateLottoRank(winningLotto) } diff --git a/src/main/kotlin/lotto/domain/LottoNumber.kt b/src/main/kotlin/lotto/domain/LottoNumber.kt index 66219d151..1c15a4f74 100644 --- a/src/main/kotlin/lotto/domain/LottoNumber.kt +++ b/src/main/kotlin/lotto/domain/LottoNumber.kt @@ -1,19 +1,17 @@ package lotto.domain data class LottoNumber(val number: Int) { - init { - require(number in LOTTO_MIN_NUMBER..LOTTO_MAX_NUMBER) { - "로또 번호는 1보다 적거나 45보다 클 수 없습니다" - } - } - companion object { const val LOTTO_MIN_NUMBER = 1 const val LOTTO_MAX_NUMBER = 45 private val LOTTO_NUMBER_POOL = (LOTTO_MIN_NUMBER..LOTTO_MAX_NUMBER).associateWith { LottoNumber(it) } fun from(number: Int): LottoNumber { - return LOTTO_NUMBER_POOL[number] ?: throw IllegalArgumentException("유효하지 않은 번호입니다") + return LOTTO_NUMBER_POOL[number] ?: throw IllegalArgumentException("로또 번호는 1보다 적거나 45보다 클 수 없습니다") + } + + fun from(number: String): LottoNumber { + return from(number.toIntOrNull() ?: throw IllegalArgumentException("유효하지 않은 번호입니다")) } } } diff --git a/src/main/kotlin/lotto/domain/LottoRank.kt b/src/main/kotlin/lotto/domain/LottoRank.kt index 0ff2f218e..f554e62d9 100644 --- a/src/main/kotlin/lotto/domain/LottoRank.kt +++ b/src/main/kotlin/lotto/domain/LottoRank.kt @@ -5,13 +5,23 @@ enum class LottoRank( val prize: Int, ) { FIRST_PLACE(6, 2_000_000_000), - SECOND_PLACE(5, 1_500_000), - THIRD_PLACE(4, 50_000), - FOURTH_PLACE(3, 5_000), + SECOND_PLACE(5, 30_000_000), + THIRD_PLACE(5, 1_500_000), + FOURTH_PLACE(4, 50_000), + FIFTH_PLACE(3, 5_000), BLANK_PLACE(0, 0), ; companion object { - fun getRank(matchedCount: Int): LottoRank { + fun getRank( + matchedCount: Int, + isMatchedBonus: Boolean, + ): LottoRank { + if (matchedCount == 5 && isMatchedBonus) { + return SECOND_PLACE + } + if (matchedCount == 5) { + return THIRD_PLACE + } return entries.find { it.matchCount == matchedCount } ?: BLANK_PLACE } } diff --git a/src/main/kotlin/lotto/domain/LottoResults.kt b/src/main/kotlin/lotto/domain/LottoResults.kt index cd337e63d..6f5ee75c6 100644 --- a/src/main/kotlin/lotto/domain/LottoResults.kt +++ b/src/main/kotlin/lotto/domain/LottoResults.kt @@ -10,5 +10,5 @@ data class LottoResults(private val results: List) { return results.associate { it.rank to it.count } } - fun findAllSortedByMatchCount(): List = results.sortedByDescending { it.rank.matchCount } + fun findAllSortedByPrize(): List = results.sortedBy { it.rank.prize } } diff --git a/src/main/kotlin/lotto/domain/LottoTicket.kt b/src/main/kotlin/lotto/domain/LottoTicket.kt index 5abf9f293..2a6094245 100644 --- a/src/main/kotlin/lotto/domain/LottoTicket.kt +++ b/src/main/kotlin/lotto/domain/LottoTicket.kt @@ -3,33 +3,17 @@ package lotto.domain import lotto.domain.LottoNumber.Companion.LOTTO_MAX_NUMBER import lotto.domain.LottoNumber.Companion.LOTTO_MIN_NUMBER -class LottoTicket(private val numbers: Set) : Collection by numbers { +data class LottoTicket(private val numbers: Set) : Collection by numbers { constructor(numbers: List) : this(numbers.toSet()) init { require(numbers.size == LOTTO_TICKET_SIZE) { "로또 티켓 번호가 잘못 입력되었습니다" } } - fun calculateRank(winningLotto: LottoTicket): LottoRank { - val matchCount = calculateMatchCount(winningLotto) - return LottoRank.getRank(matchCount) - } - - fun calculateMatchCount(winningLotto: LottoTicket): Int { - return numbers.intersect(winningLotto).size - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as LottoTicket - - return numbers == other.numbers - } - - override fun hashCode(): Int { - return numbers.hashCode() + fun calculateRank(winningLotto: WinningLotto): LottoRank { + val matchCount = winningLotto.calculateMatchCount(numbers) + val isMatchedBonus = winningLotto.isMatchedBonusNumber(numbers) + return LottoRank.getRank(matchCount, isMatchedBonus) } companion object { @@ -46,7 +30,7 @@ class LottoTicket(private val numbers: Set) : Collection): LottoTicket { - return LottoTicket(numbers.map { LottoNumber.from(it) }.toSet()) + return LottoTicket(numbers.map { LottoNumber(it) }.toSet()) } } } diff --git a/src/main/kotlin/lotto/domain/LottoTickets.kt b/src/main/kotlin/lotto/domain/LottoTickets.kt index c43689a25..112aaedb6 100644 --- a/src/main/kotlin/lotto/domain/LottoTickets.kt +++ b/src/main/kotlin/lotto/domain/LottoTickets.kt @@ -1,7 +1,7 @@ package lotto.domain class LottoTickets(private val lottoTickets: List) : Collection by lottoTickets { - fun calculateLottoRank(winningLotto: LottoTicket): LottoResults { + fun calculateLottoRank(winningLotto: WinningLotto): LottoResults { val rankCount = lottoTickets .map { lotto -> lotto.calculateRank(winningLotto) } diff --git a/src/main/kotlin/lotto/domain/WinningLotto.kt b/src/main/kotlin/lotto/domain/WinningLotto.kt new file mode 100644 index 000000000..c620a4191 --- /dev/null +++ b/src/main/kotlin/lotto/domain/WinningLotto.kt @@ -0,0 +1,18 @@ +package lotto.domain + +class WinningLotto( + private val winningLotto: LottoTicket, + private val bonusNumber: LottoNumber, +) { + init { + require(!winningLotto.contains(bonusNumber)) { "보너스 번호는 로또 티켓의 번호와 중복될 수 없습니다" } + } + + fun calculateMatchCount(numbers: Set): Int { + return winningLotto.intersect(numbers).size + } + + fun isMatchedBonusNumber(numbers: Set): Boolean { + return numbers.contains(bonusNumber) + } +} diff --git a/src/main/kotlin/lotto/view/InputView.kt b/src/main/kotlin/lotto/view/InputView.kt index 9ea90db16..dfc956b97 100644 --- a/src/main/kotlin/lotto/view/InputView.kt +++ b/src/main/kotlin/lotto/view/InputView.kt @@ -1,6 +1,8 @@ package lotto.view +import lotto.domain.LottoNumber import lotto.domain.LottoTicket +import lotto.domain.WinningLotto object InputView { fun getUserAmount(): Int { @@ -9,10 +11,13 @@ object InputView { return amount.toIntOrNull() ?: throw IllegalArgumentException("구입 금액이 유효하지 않습니다. 숫자를 입력해주세요") } - fun getUserWinningLotto(): LottoTicket { + fun getUserWinningLotto(): WinningLotto { println("지난 주 당첨 번호를 입력해 주세요.") val winningLottoNumbers: String = readln() val numbers = winningLottoNumbers.split(",").map { it.toInt() }.toSet() - return LottoTicket.from(numbers) + + println("보너스 볼을 입력해 주세요.") + val bonusNumber: String = readln() + return WinningLotto(LottoTicket.from(numbers), LottoNumber.from(bonusNumber)) } } diff --git a/src/main/kotlin/lotto/view/OutputView.kt b/src/main/kotlin/lotto/view/OutputView.kt index 2a338e371..a4e093945 100644 --- a/src/main/kotlin/lotto/view/OutputView.kt +++ b/src/main/kotlin/lotto/view/OutputView.kt @@ -1,6 +1,7 @@ package lotto.view import lotto.domain.LottoRank +import lotto.domain.LottoResult import lotto.domain.LottoResults import lotto.domain.LottoTickets @@ -9,7 +10,7 @@ object OutputView { val ticketCount = lottoTickets.size println(message = "$ticketCount 개를 구매했습니다.") for (lottoTicket in lottoTickets) { - println(lottoTicket) + println(lottoTicket.map { it.number }) } } @@ -17,20 +18,29 @@ object OutputView { results: LottoResults, amount: Int, ) { + println() println("당첨 통계") println("---------") - results.findAllSortedByMatchCount() + results.findAllSortedByPrize() .filter { it.rank != LottoRank.BLANK_PLACE } .forEach { result -> - println("${result.rank.matchCount}개 일치 (${result.rank.prize}원)- ${result.count}개") + print("${result.rank.matchCount}개 일치") + printSecondPlace(result) + println("(${result.rank.prize}원)- ${result.count}개") } val totalPrize = results.totalPrize() val rateOfReturn = totalPrize.toDouble() / amount - println("총 수익률은 %.2f 입니다.".format(rateOfReturn)) + print("총 수익률은 %.2f 입니다.".format(rateOfReturn)) if (rateOfReturn < 1) { - println("기준이 1이기 때문에 결과적으로 손해라는 의미임)") + println("(기준이 1이기 때문에 결과적으로 손해라는 의미임)") + } + } + + private fun printSecondPlace(result: LottoResult) { + if (result.rank == LottoRank.SECOND_PLACE) { + print(", 보너스 볼 일치") } } } diff --git a/src/test/kotlin/lotto/controller/LottoControllerTest.kt b/src/test/kotlin/lotto/controller/LottoControllerTest.kt index f9f36a4eb..ae9323ac4 100644 --- a/src/test/kotlin/lotto/controller/LottoControllerTest.kt +++ b/src/test/kotlin/lotto/controller/LottoControllerTest.kt @@ -1,9 +1,11 @@ package lotto.controller import io.kotest.matchers.shouldBe +import lotto.domain.LottoNumber import lotto.domain.LottoRank import lotto.domain.LottoTicket import lotto.domain.LottoTickets +import lotto.domain.WinningLotto import org.junit.jupiter.api.Test class LottoControllerTest { @@ -16,9 +18,9 @@ class LottoControllerTest { @Test fun `로또 티켓 목록과 당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { val lottoTickets = LottoTickets(listOf(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)))) - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) val lottoResults = LottoController.calculateLottoRank(lottoTickets, winningLotto) - lottoResults.findAllSortedByMatchCount() + lottoResults.findAllSortedByPrize() .sortedByDescending { it.count } .take(1) .map { diff --git a/src/test/kotlin/lotto/domain/LottoNumberTest.kt b/src/test/kotlin/lotto/domain/LottoNumberTest.kt index 0089c89c5..d0c5db9e9 100644 --- a/src/test/kotlin/lotto/domain/LottoNumberTest.kt +++ b/src/test/kotlin/lotto/domain/LottoNumberTest.kt @@ -1,24 +1,41 @@ package lotto.domain import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.equals.shouldBeEqual import io.kotest.matchers.shouldBe import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource +import kotlin.test.Test class LottoNumberTest { @ParameterizedTest @ValueSource(ints = [0, -10, 46, 100]) - fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { + fun `로또 번호는 1부터 45사이의 숫자가 아니면 예외가 발생한다`(number: Int) { shouldThrow { - LottoNumber(number) + LottoNumber.from(number) }.also { it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } } @ParameterizedTest - @ValueSource(ints = [0, -10, 46, 100]) - fun `로또 번호는 1부터 45사의의 숫자가 아니면 예외가 발생한다`(number: Int) { + @ValueSource(strings = ["0", "-10", "46", "100"]) + fun `로또 번호는 1부터 45사이의 숫자 문자열이 아니면 예외가 발생한다`(number: String) { + shouldThrow { + LottoNumber.from(number) + }.also { + it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" + } + } + + @Test + fun `숫자 생성자 로또 번호와 문자열 생성자 로또 번호는 같다`() { + LottoNumber.from("1") shouldBeEqual LottoNumber.from(1) + } + + @ParameterizedTest + @ValueSource(strings = ["A", "*", "ㄱ", "숫자"]) + fun `로또 번호는 숫자가 아닌 문자열을 전달하면 예외가 발생한다`(number: String) { shouldThrow { LottoNumber.from(number) }.also { diff --git a/src/test/kotlin/lotto/domain/LottoRankTest.kt b/src/test/kotlin/lotto/domain/LottoRankTest.kt index 143b0d59f..390a15340 100644 --- a/src/test/kotlin/lotto/domain/LottoRankTest.kt +++ b/src/test/kotlin/lotto/domain/LottoRankTest.kt @@ -6,49 +6,56 @@ import org.junit.jupiter.api.Test class LottoRankTest { @Test fun `로또 티켓의 번호가 6개 모두 일치하면 1등이다`() { - val rank = LottoRank.getRank(6) + val rank = LottoRank.getRank(6, true) rank shouldBe LottoRank.FIRST_PLACE rank.prize shouldBe 2_000_000_000 } @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 5개 일치하면 2등이다`() { - val rank = LottoRank.getRank(5) + fun `로또 티켓의 번호와 당첨 티켓 번호가 5개 일치하고 보너스번호도 일치하면 2등이다`() { + val rank = LottoRank.getRank(5, true) rank shouldBe LottoRank.SECOND_PLACE - rank.prize shouldBe 1_500_000 + rank.prize shouldBe 30_000_000 } @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 4개 일치하면 3등이다`() { - val rank = LottoRank.getRank(4) + fun `로또 티켓의 번호와 당첨 티켓 번호가 4개 일치하고 보너스번호가 일치하지 않으면 3등이다`() { + val rank = LottoRank.getRank(5, false) rank shouldBe LottoRank.THIRD_PLACE - rank.prize shouldBe 50_000 + rank.prize shouldBe 1_500_000 } @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 3개 일치하면 4등이다`() { - val rank = LottoRank.getRank(3) + fun `로또 티켓의 번호와 당첨 티켓 번호가 4개 일치하면 4등이다`() { + val rank = LottoRank.getRank(4, true) rank shouldBe LottoRank.FOURTH_PLACE + rank.prize shouldBe 50_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 3개 일치하면 5등이다`() { + val rank = LottoRank.getRank(3, true) + rank shouldBe LottoRank.FIFTH_PLACE rank.prize shouldBe 5_000 } @Test fun `로또 티켓의 번호와 당첨 티켓 번호가 2개 일치하면 꽝이다`() { - val rank = LottoRank.getRank(2) + val rank = LottoRank.getRank(2, true) rank shouldBe LottoRank.BLANK_PLACE rank.prize shouldBe 0 } @Test fun `로또 티켓의 번호와 당첨 티켓 번호가 1개 일치하면 꽝이다`() { - val rank = LottoRank.getRank(1) + val rank = LottoRank.getRank(1, true) rank shouldBe LottoRank.BLANK_PLACE rank.prize shouldBe 0 } @Test fun `로또 티켓의 번호가 당첨 티켓 번호와 하나도 일치하지 않으면 꽝이다`() { - val rank = LottoRank.getRank(0) + val rank = LottoRank.getRank(0, true) rank shouldBe LottoRank.BLANK_PLACE rank.prize shouldBe 0 } diff --git a/src/test/kotlin/lotto/domain/LottoResultsTest.kt b/src/test/kotlin/lotto/domain/LottoResultsTest.kt index 81afcd56c..14bee0601 100644 --- a/src/test/kotlin/lotto/domain/LottoResultsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoResultsTest.kt @@ -21,8 +21,8 @@ class LottoResultsTest { fun providedDuplicationNumbers() = listOf( Arguments.arguments(LottoResult(LottoRank.FIRST_PLACE, 1), 2_000_000_000), - Arguments.arguments(LottoResult(LottoRank.SECOND_PLACE, 3), 4_500_000), - Arguments.arguments(LottoResult(LottoRank.THIRD_PLACE, 4), 200_000), + Arguments.arguments(LottoResult(LottoRank.SECOND_PLACE, 3), 90_000_000), + Arguments.arguments(LottoResult(LottoRank.THIRD_PLACE, 4), 6_000_000), ) } } diff --git a/src/test/kotlin/lotto/domain/LottoTicketTest.kt b/src/test/kotlin/lotto/domain/LottoTicketTest.kt index 4ea62f18f..a16abdf1d 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketTest.kt @@ -42,20 +42,9 @@ class LottoTicketTest { lottoTicket shouldHaveSize 6 } - @ParameterizedTest - @MethodSource("providedCoupleOfLottoTicket") - fun `로또 티켓이 당첨 티켓과 몇개가 일치하는지 확인 할 수 있다`( - lottoTicket: LottoTicket, - winningLotto: LottoTicket, - count: Int, - ) { - val matchCount = lottoTicket.calculateMatchCount(winningLotto) - matchCount shouldBe count - } - @Test - fun `로또 티켓의 번호가 6개 모두 일치하면 1등이다`() { - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + fun `로또 티켓의 번호가 6개 모두 일치하면 1등이다 `() { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) val lottoTicket = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) val rank = lottoTicket.calculateRank(winningLotto) rank shouldBe LottoRank.FIRST_PLACE @@ -63,35 +52,44 @@ class LottoTicketTest { } @Test - fun `로또 티켓의 번호가 5개 일치하면 2등이다`() { - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) - val lottoTicket = LottoTicket.from(setOf(1, 2, 3, 4, 5, 16)) + fun `로또 티켓의 번호가 5개 일치하고 보너스 번호가 일치하면 2등이다 `() { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) + val lottoTicket = LottoTicket.from(setOf(1, 2, 3, 4, 5, 7)) val rank = lottoTicket.calculateRank(winningLotto) rank shouldBe LottoRank.SECOND_PLACE + rank.prize shouldBe 30_000_000 + } + + @Test + fun `로또 티켓의 번호가 5개 일치하고 보너스 번호가 일치하지 않으면 3등이다 `() { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) + val lottoTicket = LottoTicket.from(setOf(1, 2, 3, 4, 5, 9)) + val rank = lottoTicket.calculateRank(winningLotto) + rank shouldBe LottoRank.THIRD_PLACE rank.prize shouldBe 1_500_000 } @Test - fun `로또 티켓의 번호가 4개 일치하면 3등이다`() { - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + fun `로또 티켓의 번호가 4개 일치하면 3등이다 `() { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) val lottoTicket = LottoTicket.from(setOf(1, 2, 3, 4, 15, 16)) val rank = lottoTicket.calculateRank(winningLotto) - rank shouldBe LottoRank.THIRD_PLACE + rank shouldBe LottoRank.FOURTH_PLACE rank.prize shouldBe 50_000 } @Test - fun `로또 티켓의 번호가 3개 일치하면 4등이다`() { - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + fun `로또 티켓의 번호가 3개 일치하면 4등이다 `() { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) val lottoTicket = LottoTicket.from(setOf(1, 2, 3, 14, 15, 16)) - val rank = winningLotto.calculateRank(lottoTicket) - rank shouldBe LottoRank.FOURTH_PLACE + val rank = lottoTicket.calculateRank(winningLotto) + rank shouldBe LottoRank.FIFTH_PLACE rank.prize shouldBe 5_000 } @Test - fun `로또 티켓의 번호가 2개 일치하면 꽝이다`() { - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + fun `로또 티켓의 번호가 2개 일치하면 꽝이다 `() { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) val lottoTicket = LottoTicket.from(setOf(1, 2, 13, 14, 15, 16)) val rank = lottoTicket.calculateRank(winningLotto) rank shouldBe LottoRank.BLANK_PLACE @@ -99,8 +97,8 @@ class LottoTicketTest { } @Test - fun `로또 티켓의 번호가 1개 일치하면 꽝이다`() { - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + fun `로또 티켓의 번호가 1개 일치하면 꽝이다 `() { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) val lottoTicket = LottoTicket.from(setOf(1, 12, 13, 14, 15, 16)) val rank = lottoTicket.calculateRank(winningLotto) rank shouldBe LottoRank.BLANK_PLACE @@ -108,8 +106,8 @@ class LottoTicketTest { } @Test - fun `로로또 티켓의 번호가 하나도 일치하지 않으면 꽝이다`() { - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + fun `로로또 티켓의 번호가 하나도 일치하지 않으면 꽝이다 `() { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) val lottoTicket = LottoTicket.from(setOf(11, 12, 13, 14, 15, 16)) val rank = lottoTicket.calculateRank(winningLotto) rank shouldBe LottoRank.BLANK_PLACE @@ -132,16 +130,5 @@ class LottoTicketTest { Arguments.arguments(setOf(3, 5, 7, 8, 9)), Arguments.arguments(setOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7)), ) - - @JvmStatic - fun providedCoupleOfLottoTicket() = - listOf( - Arguments.arguments(LottoTicket.from(setOf(1, 12, 13, 14, 15, 16)), LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), 1), - Arguments.arguments(LottoTicket.from(setOf(1, 2, 13, 14, 15, 16)), LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), 2), - Arguments.arguments(LottoTicket.from(setOf(1, 2, 3, 14, 15, 16)), LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), 3), - Arguments.arguments(LottoTicket.from(setOf(1, 2, 3, 4, 15, 16)), LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), 4), - Arguments.arguments(LottoTicket.from(setOf(1, 2, 3, 4, 5, 16)), LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), 5), - Arguments.arguments(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), 6), - ) } } diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index 6880fbc91..b6708d0e4 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -32,15 +32,21 @@ class LottoTicketsTest { LottoTicket.from(setOf(1, 2, 3, 4, 8, 9)), ), ) - val winningLotto = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) val lottoResults = lottoTickets.calculateLottoRank(winningLotto) - val sortedResults = lottoResults.findAllSortedByMatchCount() - sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE + val sortedResults = lottoResults.findAllSortedByPrize() + sortedResults[0].rank shouldBe LottoRank.BLANK_PLACE sortedResults[0].count shouldBe 0 - sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE - sortedResults[1].count shouldBe 2 - sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE + sortedResults[1].rank shouldBe LottoRank.FIFTH_PLACE + sortedResults[1].count shouldBe 0 + sortedResults[2].rank shouldBe LottoRank.FOURTH_PLACE sortedResults[2].count shouldBe 1 + sortedResults[3].rank shouldBe LottoRank.THIRD_PLACE + sortedResults[3].count shouldBe 1 + sortedResults[4].rank shouldBe LottoRank.SECOND_PLACE + sortedResults[4].count shouldBe 1 + sortedResults[5].rank shouldBe LottoRank.FIRST_PLACE + sortedResults[5].count shouldBe 0 } @Test diff --git a/src/test/kotlin/lotto/domain/WinningLottoTest.kt b/src/test/kotlin/lotto/domain/WinningLottoTest.kt new file mode 100644 index 000000000..846326859 --- /dev/null +++ b/src/test/kotlin/lotto/domain/WinningLottoTest.kt @@ -0,0 +1,45 @@ +package lotto.domain + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource +import kotlin.test.Test + +class WinningLottoTest { + @ParameterizedTest + @MethodSource("provideLottoNumbers") + fun `당첨 번호와 일치하는 개수를 비교 할 수 있다`( + numbers: Set, + matchCount: Int, + ) { + val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) + val count = winningLotto.calculateMatchCount(numbers) + count shouldBe matchCount + } + + @Test + fun `보너스 번호는 로또 티켓의 번호와 중복될 수 없다`() { + val lottoTicket = LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)) + val bonusNumber = LottoNumber(6) + shouldThrow { + WinningLotto(lottoTicket, bonusNumber) + }.also { + it.message shouldBe "보너스 번호는 로또 티켓의 번호와 중복될 수 없습니다" + } + } + + companion object { + @JvmStatic + fun provideLottoNumbers() = + listOf( + Arguments.arguments(listOf(1, 12, 13, 14, 15, 16).map { LottoNumber(it) }.toSet(), 1), + Arguments.arguments(listOf(1, 2, 13, 14, 15, 16).map { LottoNumber(it) }.toSet(), 2), + Arguments.arguments(listOf(1, 2, 3, 14, 15, 16).map { LottoNumber(it) }.toSet(), 3), + Arguments.arguments(listOf(1, 2, 3, 4, 15, 16).map { LottoNumber(it) }.toSet(), 4), + Arguments.arguments(listOf(1, 2, 3, 4, 5, 16).map { LottoNumber(it) }.toSet(), 5), + Arguments.arguments(listOf(1, 2, 3, 4, 5, 6).map { LottoNumber(it) }.toSet(), 6), + ) + } +} From 86f695830b369b253947b90c329b779c45959988 Mon Sep 17 00:00:00 2001 From: Sangwook <45926559+goodbyeyo@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:07:59 +0900 Subject: [PATCH 09/27] =?UTF-8?q?Step3=20=EB=A1=9C=EB=98=90=202=EB=93=B1?= =?UTF-8?q?=20(#1131)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Lotto 도메인 테스트 및 구현 * feat: 로또 번호, 티켓 발급 기능 구현 및 테스트 * refactor: Test 코드 내 도메인 로직 Class 분리 리팩토링 * feat: 당첨 로또 기능 구현 * feat: 로또 컨트롤러, 입출력 뷰 구현 * refactor: 피드백 반영, LottoTickets.calculateLottoRank 테스트 추가 * refactor: 피드백 반영 1. WinningLotto 제거하고 담당하던 책임 LottoTicket 으로 이동 2. LottoTicket 프로퍼티 변경 : List -> Set 3. LottoTicket 프로퍼티 기반으로 위임하도록 변경, 부생성자 추가 4. LottoTicket 정적팩토리메서드 추가 * doc: STEP3 로또2등 요구구사항 정리 * feat: 보너스번호 도메인 구현 * feat: 보너스 번호 일치여부 구현 * feat: 로또 2등 기능 구현 1. LottoRank : 로또 랭크 판단 조건, 상금 변경 2. LottoTicket : 당첨 로또 계산 위임(WinningLotto) 3. LottoTicket : data class 변경 (피드백 반영) 4. 당첨 로또 계산 시 보너스 번호가 포함된 WinningLotto 전달 5. 당첨 결과 출력 보너스 번호 일치 여부 출력 6. 테스트 코드 2등 로또 반영 * refactor: 피드백 반영 1. BonusNumber 제거하고 WinningLotto 가 직접 책임을 담당하도록 변경 2. WinningLotto 생성자 인자 팩토리 메서드(동반 객체 메서드) 구조로 전달 3. LottoNumber 정적 팩터리 메서드 추가 --- .../kotlin/lotto/domain/LottoTicketsTest.kt | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index b6708d0e4..4b8aa7add 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -48,25 +48,4 @@ class LottoTicketsTest { sortedResults[5].rank shouldBe LottoRank.FIRST_PLACE sortedResults[5].count shouldBe 0 } - - @Test - fun `당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { - val lottoTickets = - LottoTickets( - listOf( - LottoTicket(listOf(1, 2, 3, 4, 5, 7)), - LottoTicket(listOf(1, 2, 3, 4, 5, 9)), - LottoTicket(listOf(1, 2, 3, 4, 8, 9)), - ), - ) - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val lottoResults = lottoTickets.calculateLottoRank(winningLotto) - val sortedResults = lottoResults.findAllSortedByMatchCount() - sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE - sortedResults[0].count shouldBe 0 - sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE - sortedResults[1].count shouldBe 2 - sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE - sortedResults[2].count shouldBe 1 - } } From caac3eb9257fb645c46c919e495d7aa17e9c9ec6 Mon Sep 17 00:00:00 2001 From: wook Date: Wed, 11 Dec 2024 10:32:56 -0800 Subject: [PATCH 10/27] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=EB=B0=B1?= =?UTF-8?q?=20=EB=B0=98=EC=98=81,=20LottoTickets.calculateLottoRank=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 --- .../kotlin/lotto/domain/LottoTicketsTest.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index 4b8aa7add..b6708d0e4 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -48,4 +48,25 @@ class LottoTicketsTest { sortedResults[5].rank shouldBe LottoRank.FIRST_PLACE sortedResults[5].count shouldBe 0 } + + @Test + fun `당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { + val lottoTickets = + LottoTickets( + listOf( + LottoTicket(listOf(1, 2, 3, 4, 5, 7)), + LottoTicket(listOf(1, 2, 3, 4, 5, 9)), + LottoTicket(listOf(1, 2, 3, 4, 8, 9)), + ), + ) + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val lottoResults = lottoTickets.calculateLottoRank(winningLotto) + val sortedResults = lottoResults.findAllSortedByMatchCount() + sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE + sortedResults[0].count shouldBe 0 + sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE + sortedResults[1].count shouldBe 2 + sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE + sortedResults[2].count shouldBe 1 + } } From 6f6d991cd8c8cadb60ab5836c751de4abf3894b1 Mon Sep 17 00:00:00 2001 From: wook Date: Wed, 18 Dec 2024 14:12:31 +0900 Subject: [PATCH 11/27] =?UTF-8?q?fix:=20upstream=20rebase=20=ED=9B=84=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=9C=20=ED=85=8C=EC=8A=A4=EC=BD=94=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/lotto/domain/LottoTicketsTest.kt | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index b6708d0e4..4b8aa7add 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -48,25 +48,4 @@ class LottoTicketsTest { sortedResults[5].rank shouldBe LottoRank.FIRST_PLACE sortedResults[5].count shouldBe 0 } - - @Test - fun `당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { - val lottoTickets = - LottoTickets( - listOf( - LottoTicket(listOf(1, 2, 3, 4, 5, 7)), - LottoTicket(listOf(1, 2, 3, 4, 5, 9)), - LottoTicket(listOf(1, 2, 3, 4, 8, 9)), - ), - ) - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val lottoResults = lottoTickets.calculateLottoRank(winningLotto) - val sortedResults = lottoResults.findAllSortedByMatchCount() - sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE - sortedResults[0].count shouldBe 0 - sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE - sortedResults[1].count shouldBe 2 - sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE - sortedResults[2].count shouldBe 1 - } } From 57f7cea9d3eab65ee8345e9029cbce30776ee475 Mon Sep 17 00:00:00 2001 From: wook Date: Wed, 18 Dec 2024 15:33:05 +0900 Subject: [PATCH 12/27] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=EB=B0=B1?= =?UTF-8?q?=20=EB=B0=98=EC=98=81=201.=20LottoNumber=20private=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=EB=A1=9C=20=EB=B3=80=EA=B2=BD=202.=20LottoNu?= =?UTF-8?q?mber=20=ED=95=84=EB=93=9C=20=EC=A0=91=EA=B7=BC=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/domain/LottoNumber.kt | 4 +++- src/main/kotlin/lotto/view/OutputView.kt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/lotto/domain/LottoNumber.kt b/src/main/kotlin/lotto/domain/LottoNumber.kt index 1c15a4f74..28729d07b 100644 --- a/src/main/kotlin/lotto/domain/LottoNumber.kt +++ b/src/main/kotlin/lotto/domain/LottoNumber.kt @@ -1,6 +1,8 @@ package lotto.domain -data class LottoNumber(val number: Int) { +data class LottoNumber(private val number: Int) { + fun getNumber() = number + companion object { const val LOTTO_MIN_NUMBER = 1 const val LOTTO_MAX_NUMBER = 45 diff --git a/src/main/kotlin/lotto/view/OutputView.kt b/src/main/kotlin/lotto/view/OutputView.kt index a4e093945..5683a809d 100644 --- a/src/main/kotlin/lotto/view/OutputView.kt +++ b/src/main/kotlin/lotto/view/OutputView.kt @@ -10,7 +10,7 @@ object OutputView { val ticketCount = lottoTickets.size println(message = "$ticketCount 개를 구매했습니다.") for (lottoTicket in lottoTickets) { - println(lottoTicket.map { it.number }) + println(lottoTicket.map { it.getNumber() }) } } From b0d50ffc2926c79d8c1b40e69487372d4b7093ec Mon Sep 17 00:00:00 2001 From: wook Date: Wed, 18 Dec 2024 15:36:28 +0900 Subject: [PATCH 13/27] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=EB=B0=B1?= =?UTF-8?q?=20=EB=B0=98=EC=98=81=20=20-=20LOTTO=5FNUMBER=5FPOLL=20?= =?UTF-8?q?=ED=99=9C=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20LottoNumber=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=EB=8C=80=EC=8B=A0=20=EC=A0=95?= =?UTF-8?q?=EC=A0=81=20=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=ED=98=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/domain/LottoTicket.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/lotto/domain/LottoTicket.kt b/src/main/kotlin/lotto/domain/LottoTicket.kt index 2a6094245..17c108ff3 100644 --- a/src/main/kotlin/lotto/domain/LottoTicket.kt +++ b/src/main/kotlin/lotto/domain/LottoTicket.kt @@ -30,7 +30,7 @@ data class LottoTicket(private val numbers: Set) : Collection): LottoTicket { - return LottoTicket(numbers.map { LottoNumber(it) }.toSet()) + return LottoTicket(numbers.map { LottoNumber.from(it) }.toSet()) } } } From 2eedaa5015e2a9e3f54278876d0c15f2007c0b52 Mon Sep 17 00:00:00 2001 From: wook Date: Thu, 19 Dec 2024 02:44:42 +0900 Subject: [PATCH 14/27] =?UTF-8?q?feat:=20Step4=20=EC=88=98=EB=8F=99=20?= =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 57 ++++++++++++---- src/main/kotlin/lotto/LottoApplication.kt | 9 +-- .../lotto/controller/LottoController.kt | 21 +++--- src/main/kotlin/lotto/domain/LottoTickets.kt | 10 ++- src/main/kotlin/lotto/dto/PurchaseDetail.kt | 25 +++++++ src/main/kotlin/lotto/view/InputView.kt | 34 +++++++++- src/main/kotlin/lotto/view/OutputView.kt | 11 +++- .../lotto/controller/LottoControllerTest.kt | 30 --------- .../kotlin/lotto/domain/LottoTicketsTest.kt | 15 ++--- .../kotlin/lotto/dto/PurchaseDetailTest.kt | 66 +++++++++++++++++++ 10 files changed, 202 insertions(+), 76 deletions(-) create mode 100644 src/main/kotlin/lotto/dto/PurchaseDetail.kt delete mode 100644 src/test/kotlin/lotto/controller/LottoControllerTest.kt create mode 100644 src/test/kotlin/lotto/dto/PurchaseDetailTest.kt diff --git a/README.md b/README.md index b47169a70..561e80927 100644 --- a/README.md +++ b/README.md @@ -108,17 +108,52 @@ ##### `요구사항 정리` - 보너스 볼 - - [ ] 보너스 볼을 입력 받을수 있다 - - [ ] 보너스 볼은 당첨 로또 티켓의 6개 번호와 중복 될 수 없다 + - [x] 보너스 볼을 입력 받을수 있다 + - [x] 보너스 볼은 당첨 로또 티켓의 6개 번호와 중복 될 수 없다 - 당첨 로또 - - [ ] 당첨 로또는 1개의 로또 티켓과 1개의 보너스 번호를 가진다 - - [ ] 로또 랭크 계산 역할을 담당한다 + - [x] 당첨 로또는 1개의 로또 티켓과 1개의 보너스 번호를 가진다 + - [x] 로또 랭크 계산 역할을 담당한다 - 로또 티켓 - - [ ] 로또 랭크 계산 역할을 당첨 로또에게 위임한다 + - [x] 로또 랭크 계산 역할을 당첨 로또에게 위임한다 - 로또 랭크 - - [ ] 당첨번호와 5개 일치하고 보너스 번호도 같으면 2등이다, - - [ ] 당첨번호와 5개 일치하고 보너스 번호가 다르면 3등이다 - - [ ] 로또 2등의 당첨금액은 1_500_000원 -> 30_000_000원 - - [ ] 로또 3등의 당첨금액은 50_000원 -> 1_500_000원 - - [ ] 로또 4등의 당첨금액은 5_000원 -> 50_000원 - - [ ] 로또 5등의 당첨금액은 5_000원 + - [x] 당첨번호와 5개 일치하고 보너스 번호도 같으면 2등이다, + - [x] 당첨번호와 5개 일치하고 보너스 번호가 다르면 3등이다 + - [x] 로또 2등의 당첨금액은 1_500_000원 -> 30_000_000원 + - [x] 로또 3등의 당첨금액은 50_000원 -> 1_500_000원 + - [x] 로또 4등의 당첨금액은 5_000원 -> 50_000원 + - [x] 로또 5등의 당첨금액은 5_000원 + +--- + +### STEP4 로또 수동 + +##### `기능 요구사항` +- 현재 로또 생성기는 자동 생성 기능만 제공한다. +- 사용자가 수동으로 추첨 번호를 입력할 수 있도록 해야 한다. +- 입력한 금액, 자동 생성 숫자, 수동 생성 번호를 입력하도록 해야 한다. + +##### `실행 결과` +```text +구입금액을 입력해 주세요. +14000 + +---------추가부분-------------- +수동으로 구매할 로또 수를 입력해 주세요. +3 + +수동으로 구매할 번호를 입력해 주세요. +8, 21, 23, 41, 42, 43 +3, 5, 11, 16, 32, 38 +7, 11, 16, 35, 36, 44 + +수동으로 3장, 자동으로 11개를 구매했습니다. +-------------------------------- +[8, 21, 23, 41, 42, 43] +지난 주 당첨 번호를 입력해 주세요. +1, 2, 3, 4, 5, 6 +보너스 볼을 입력해 주세요. +7 + +당첨 통계 +[... 생략 ...] +``` diff --git a/src/main/kotlin/lotto/LottoApplication.kt b/src/main/kotlin/lotto/LottoApplication.kt index 35bb002f5..1bf7850bf 100644 --- a/src/main/kotlin/lotto/LottoApplication.kt +++ b/src/main/kotlin/lotto/LottoApplication.kt @@ -1,14 +1,7 @@ package lotto import lotto.controller.LottoController -import lotto.view.InputView -import lotto.view.OutputView fun main() { - val amount = InputView.getUserAmount() - val lottoTickets = LottoController.purchaseLotto(amount) - OutputView.printPurchaseResult(lottoTickets) - val winningLotto = InputView.getUserWinningLotto() - val lottoResults = LottoController.calculateLottoRank(lottoTickets, winningLotto) - OutputView.printResults(lottoResults, amount) + LottoController.startLottoGame() } diff --git a/src/main/kotlin/lotto/controller/LottoController.kt b/src/main/kotlin/lotto/controller/LottoController.kt index 996d3c762..ae23a0ecc 100644 --- a/src/main/kotlin/lotto/controller/LottoController.kt +++ b/src/main/kotlin/lotto/controller/LottoController.kt @@ -1,18 +1,17 @@ package lotto.controller -import lotto.domain.LottoResults import lotto.domain.LottoTickets -import lotto.domain.WinningLotto +import lotto.view.InputView +import lotto.view.OutputView object LottoController { - fun purchaseLotto(amount: Int): LottoTickets { - return LottoTickets.purchase(amount) - } - - fun calculateLottoRank( - lottoTickets: LottoTickets, - winningLotto: WinningLotto, - ): LottoResults { - return lottoTickets.calculateLottoRank(winningLotto) + fun startLottoGame() { + val purchasedDetail = InputView.getPurchaseDetail() + val autoLottoTickets = LottoTickets.generateAutoLottoTickets(purchasedDetail.autoLottoQuantity) + val lottoTickets = LottoTickets(purchasedDetail.manualLottoTickets + autoLottoTickets) + OutputView.printPurchaseResult(lottoTickets, purchasedDetail) + val winningLotto = InputView.getUserWinningLotto() + val lottoResults = lottoTickets.calculateLottoRank(winningLotto) + OutputView.printResults(lottoResults, purchasedDetail.purchaseAmount) } } diff --git a/src/main/kotlin/lotto/domain/LottoTickets.kt b/src/main/kotlin/lotto/domain/LottoTickets.kt index 112aaedb6..72e2dfa52 100644 --- a/src/main/kotlin/lotto/domain/LottoTickets.kt +++ b/src/main/kotlin/lotto/domain/LottoTickets.kt @@ -19,7 +19,7 @@ class LottoTickets(private val lottoTickets: List) : Collection= LOTTO_TICKET_PRICE) { "구입금액은 ${LOTTO_TICKET_PRICE}원 이상이여야 합니다" } @@ -27,5 +27,13 @@ class LottoTickets(private val lottoTickets: List) : Collection 0) { + val lottoTickets = List(autoLottoQuantity) { LottoTicket.generateLottoNumber() } + return LottoTickets(lottoTickets) + } + return LottoTickets(listOf()) + } } } diff --git a/src/main/kotlin/lotto/dto/PurchaseDetail.kt b/src/main/kotlin/lotto/dto/PurchaseDetail.kt new file mode 100644 index 000000000..375265087 --- /dev/null +++ b/src/main/kotlin/lotto/dto/PurchaseDetail.kt @@ -0,0 +1,25 @@ +package lotto.dto + +import lotto.domain.LottoTickets +import lotto.domain.LottoTickets.Companion.LOTTO_TICKET_PRICE + +data class PurchaseDetail( + val purchaseAmount: Int, + val autoLottoQuantity: Int, + val manualLottoQuantity: Int, + val manualLottoTickets: LottoTickets, +) { + init { + require(manualLottoQuantity * LOTTO_TICKET_PRICE <= purchaseAmount) { "수동으로 구입할 로또의 수량이 구입금액보다 많습니다" } + require(autoLottoQuantity <= purchaseAmount / LOTTO_TICKET_PRICE) { "자동으로 구입할 로또의 수량이 구입금액보다 많습니다" } + } + constructor( + purchaseAmount: Int, + manualLottoTickets: LottoTickets, + ) : this( + purchaseAmount, + purchaseAmount / LOTTO_TICKET_PRICE - manualLottoTickets.size, + manualLottoTickets.size, + manualLottoTickets, + ) +} diff --git a/src/main/kotlin/lotto/view/InputView.kt b/src/main/kotlin/lotto/view/InputView.kt index dfc956b97..2a79ccab4 100644 --- a/src/main/kotlin/lotto/view/InputView.kt +++ b/src/main/kotlin/lotto/view/InputView.kt @@ -2,10 +2,40 @@ package lotto.view import lotto.domain.LottoNumber import lotto.domain.LottoTicket +import lotto.domain.LottoTickets import lotto.domain.WinningLotto +import lotto.dto.PurchaseDetail object InputView { - fun getUserAmount(): Int { + private const val DELIMITER = "," + + fun getPurchaseDetail(): PurchaseDetail { + val purchaseAmount = getPurchaseAmount() + val manualLottoQuantity = getManualLottoQuantity() + val manualLottoTickets = getManualLottoTickets(manualLottoQuantity) + return PurchaseDetail(purchaseAmount, manualLottoTickets) + } + + private fun getManualLottoTickets(manualLottoQuantity: Int): LottoTickets { + val manualLottoTickets = mutableListOf() + println("수동으로 구매할 번호를 입력해 주세요.") + repeat(manualLottoQuantity) { + val line = readlnOrNull()?.takeIf { it.isNotBlank() } ?: throw IllegalArgumentException("로또 번호를 입력해주세요.") + val numbers = + line.split(DELIMITER) + .map { it.trim().toIntOrNull() ?: throw IllegalArgumentException("로또 번호는 숫자여야 합니다.") } + manualLottoTickets.add(LottoTicket.from(numbers.toSet())) + } + return LottoTickets(manualLottoTickets) + } + + private fun getManualLottoQuantity(): Int { + println("수동으로 구매할 로또 수를 입력해 주세요.") + val quantity = readln() + return quantity.toIntOrNull() ?: throw IllegalArgumentException("유효한 숫자를 입력해주세요") + } + + private fun getPurchaseAmount(): Int { println("구입 금액을 입력해 주세요.") val amount = readln() return amount.toIntOrNull() ?: throw IllegalArgumentException("구입 금액이 유효하지 않습니다. 숫자를 입력해주세요") @@ -14,7 +44,7 @@ object InputView { fun getUserWinningLotto(): WinningLotto { println("지난 주 당첨 번호를 입력해 주세요.") val winningLottoNumbers: String = readln() - val numbers = winningLottoNumbers.split(",").map { it.toInt() }.toSet() + val numbers = winningLottoNumbers.split(DELIMITER).map { it.toInt() }.toSet() println("보너스 볼을 입력해 주세요.") val bonusNumber: String = readln() diff --git a/src/main/kotlin/lotto/view/OutputView.kt b/src/main/kotlin/lotto/view/OutputView.kt index 5683a809d..05ef112ff 100644 --- a/src/main/kotlin/lotto/view/OutputView.kt +++ b/src/main/kotlin/lotto/view/OutputView.kt @@ -4,11 +4,16 @@ import lotto.domain.LottoRank import lotto.domain.LottoResult import lotto.domain.LottoResults import lotto.domain.LottoTickets +import lotto.dto.PurchaseDetail object OutputView { - fun printPurchaseResult(lottoTickets: LottoTickets) { - val ticketCount = lottoTickets.size - println(message = "$ticketCount 개를 구매했습니다.") + fun printPurchaseResult( + lottoTickets: LottoTickets, + purchasedDetail: PurchaseDetail, + ) { + val manualLottoQuantity = purchasedDetail.manualLottoQuantity + val autoLottoQuantity = purchasedDetail.autoLottoQuantity + println("수동으로 ${manualLottoQuantity}장, 자동으로 ${autoLottoQuantity}개를 구매했습니다.") for (lottoTicket in lottoTickets) { println(lottoTicket.map { it.getNumber() }) } diff --git a/src/test/kotlin/lotto/controller/LottoControllerTest.kt b/src/test/kotlin/lotto/controller/LottoControllerTest.kt deleted file mode 100644 index ae9323ac4..000000000 --- a/src/test/kotlin/lotto/controller/LottoControllerTest.kt +++ /dev/null @@ -1,30 +0,0 @@ -package lotto.controller - -import io.kotest.matchers.shouldBe -import lotto.domain.LottoNumber -import lotto.domain.LottoRank -import lotto.domain.LottoTicket -import lotto.domain.LottoTickets -import lotto.domain.WinningLotto -import org.junit.jupiter.api.Test - -class LottoControllerTest { - @Test - fun `구입 금액을 입력하면 로또 티켓이 천원당 1장으로 여러개의 로또 티켓이 발급된다`() { - val lottoTickets = LottoController.purchaseLotto(10000) - lottoTickets.size shouldBe 10 - } - - @Test - fun `로또 티켓 목록과 당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { - val lottoTickets = LottoTickets(listOf(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)))) - val winningLotto = WinningLotto(LottoTicket.from(setOf(1, 2, 3, 4, 5, 6)), LottoNumber.from(7)) - val lottoResults = LottoController.calculateLottoRank(lottoTickets, winningLotto) - lottoResults.findAllSortedByPrize() - .sortedByDescending { it.count } - .take(1) - .map { - it.rank shouldBe LottoRank.FIRST_PLACE - } - } -} diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index 4b8aa7add..ba248dc53 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -1,24 +1,19 @@ package lotto.domain -import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test class LottoTicketsTest { @Test - fun `로또 티켓은 구입금액은 1_000원 이상이여야 한다`() { - shouldThrow { - LottoTickets.purchase(900) - }.also { - it.message shouldBe "구입금액은 1000원 이상이여야 합니다" - } + fun `자동 로또 티켓은 구입 수량이 0개이상이여야 발급되는 로또 티켓은 0개이다`() { + val autoLottoTickets = LottoTickets.generateAutoLottoTickets(0) + autoLottoTickets.size shouldBe 0 } @Test - fun `로또 티켓을 구입 금액에 맞게 발급한다`() { - val amount = 5_000 - val lottoTickets = LottoTickets.purchase(amount) + fun `로또 티켓을 구입 수량에 맞게 발급한다`() { + val lottoTickets = LottoTickets.generateAutoLottoTickets(5) lottoTickets shouldHaveSize 5 } diff --git a/src/test/kotlin/lotto/dto/PurchaseDetailTest.kt b/src/test/kotlin/lotto/dto/PurchaseDetailTest.kt new file mode 100644 index 000000000..10e0a4bb8 --- /dev/null +++ b/src/test/kotlin/lotto/dto/PurchaseDetailTest.kt @@ -0,0 +1,66 @@ +package lotto.dto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import lotto.domain.LottoTicket +import lotto.domain.LottoTickets +import org.junit.jupiter.api.Test + +class PurchaseDetailTest { + @Test + fun `수동으로 구입할 로또의 수량은 구입금액보다 많을 수 없다`() { + shouldThrow { + PurchaseDetail( + purchaseAmount = 1_000, + manualLottoTickets = + LottoTickets( + listOf( + LottoTicket.from(setOf(1, 2, 3, 4, 5, 7)), + LottoTicket.from(setOf(1, 2, 3, 4, 5, 9)), + LottoTicket.from(setOf(1, 2, 3, 4, 8, 9)), + ), + ), + ) + }.also { + it.message shouldBe "수동으로 구입할 로또의 수량이 구입금액보다 많습니다" + } + } + + @Test + fun `자동으로 구입할 로또의 수량은 구입금액보다 많을 수 없다`() { + shouldThrow { + PurchaseDetail( + purchaseAmount = 5_000, + autoLottoQuantity = 10, + manualLottoQuantity = 3, + manualLottoTickets = + LottoTickets( + listOf( + LottoTicket.from(setOf(1, 2, 3, 4, 5, 7)), + LottoTicket.from(setOf(1, 2, 3, 4, 5, 9)), + LottoTicket.from(setOf(1, 2, 3, 4, 8, 9)), + ), + ), + ) + }.also { + it.message shouldBe "자동으로 구입할 로또의 수량이 구입금액보다 많습니다" + } + } + + @Test + fun `만원 구매금액으로 수동 로또 3장을 구입하면 자동 로또는 7장이다`() { + val purchaseDetail = + PurchaseDetail( + purchaseAmount = 10_000, + manualLottoTickets = + LottoTickets( + listOf( + LottoTicket.from(setOf(1, 2, 3, 4, 5, 7)), + LottoTicket.from(setOf(1, 2, 3, 4, 5, 9)), + LottoTicket.from(setOf(1, 2, 3, 4, 8, 9)), + ), + ), + ) + purchaseDetail.autoLottoQuantity shouldBe 7 + } +} From 74cdcd61cad18381847336f13331cfa75b7ff8cb Mon Sep 17 00:00:00 2001 From: Hwang Sangwook Date: Tue, 3 Dec 2024 16:23:55 +0900 Subject: [PATCH 15/27] =?UTF-8?q?feat:=20Lotto=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B0=8F=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/kotlin/lotto/LottoTest.kt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/kotlin/lotto/LottoTest.kt diff --git a/src/test/kotlin/lotto/LottoTest.kt b/src/test/kotlin/lotto/LottoTest.kt new file mode 100644 index 000000000..cda755be5 --- /dev/null +++ b/src/test/kotlin/lotto/LottoTest.kt @@ -0,0 +1,28 @@ +package lotto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +data class LottoNumber(val number: Int) { + init { + require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } + } +} + + + +class LottoTest { + @ParameterizedTest + @ValueSource(ints = [0, -10, 46, 100]) + fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { + shouldThrow { + LottoNumber(number) + }.also { + it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" + } + } +} + + From 262e88d0f253c6816494814bdd98787fc8f214a2 Mon Sep 17 00:00:00 2001 From: Hwang Sangwook Date: Sat, 7 Dec 2024 16:50:40 +0900 Subject: [PATCH 16/27] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8,=20=ED=8B=B0=EC=BC=93=20=EB=B0=9C=EA=B8=89=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/kotlin/lotto/LottoTest.kt | 122 +++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 8 deletions(-) diff --git a/src/test/kotlin/lotto/LottoTest.kt b/src/test/kotlin/lotto/LottoTest.kt index cda755be5..e0e40b12b 100644 --- a/src/test/kotlin/lotto/LottoTest.kt +++ b/src/test/kotlin/lotto/LottoTest.kt @@ -2,17 +2,12 @@ package lotto import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe +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.MethodSource import org.junit.jupiter.params.provider.ValueSource -data class LottoNumber(val number: Int) { - init { - require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } - } -} - - - class LottoTest { @ParameterizedTest @ValueSource(ints = [0, -10, 46, 100]) @@ -23,6 +18,117 @@ class LottoTest { it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } } + + @ParameterizedTest + @MethodSource("providedDuplicationNumbers") + fun `로또 티켓은 중복된 번호로 생성되면 예외가 발생한다`(numbers: List) { + shouldThrow { + LottoTicket(numbers) + }.also { + it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" + } + } + + @ParameterizedTest + @MethodSource("providedWrongCountOfNumbers") + fun `로또 티켓 번호는 6개가 아니면 예외가 발생한다`(numbers: List) { + shouldThrow { + LottoTicket(numbers) + }.also { + it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" + } + } + + @Test + fun `로또 티켓은 한장 이상 구입 해야 한다`() { + shouldThrow { + LottoTickets(listOf()) + }.also { + it.message shouldBe "로또 티켓은 한장 이상 구입해야 합니다" + } + } + + @Test + fun `로또 티켓을 구입 금액에 맞게 발급한다`() { + val amount = 5_000 + val lottoTickets = LottoTickets.purchase(amount) + lottoTickets.tickets.size shouldBe 5 + } + + @Test + fun `로또 티켓을 생성하면 6개의 번호가 들어있다`() { + val lottoTicket = LottoTicket.generateLottoNumber() + lottoTicket.lottoNumbers.size shouldBe 6 + } + + companion object { + @JvmStatic + fun providedDuplicationNumbers() = + listOf( + Arguments.arguments(listOf(1, 1, 2, 3, 4, 5)), + Arguments.arguments(listOf(5, 5, 12, 13, 34, 35)), + Arguments.arguments(listOf(11, 19, 24, 33, 44, 44)), + ) + + @JvmStatic + fun providedWrongCountOfNumbers() = + listOf( + Arguments.arguments(listOf(1, 2, 3, 4, 5, 6, 7)), + Arguments.arguments(listOf(3, 5, 7, 8, 9)), + Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), + ) + } +} + +data class LottoNumber(val number: Int) { + init { + require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } + } +} + +class LottoTicket(numbers: List) { + private val _lottoNumbers: Set + val lottoNumbers: Set + get() = _lottoNumbers.toSet() + + init { + require(numbers.size == 6 && numbers.toSet().size == 6) { "로또 티켓 번호가 잘못 입력되었습니다" } + _lottoNumbers = numbers.toSortedSet() + } + + companion object { + fun generateLottoNumber(): LottoTicket { + val lottoNumbers = + (1..45) // .map { LottoNumber(it.first) } + .shuffled() + .take(6) + return LottoTicket(lottoNumbers) + } + } } +class LottoTickets(lottoTickets: List) : Iterable { + private val _tickets: List + val tickets: List + get() = _tickets + init { + require(lottoTickets.isNotEmpty()) { "로또 티켓은 한장 이상 구입해야 합니다" } + _tickets = lottoTickets + } + + override fun iterator(): Iterator { + return _tickets.iterator() + } + + companion object { + fun purchase(amount: Int): LottoTickets { + val quantity = amount / 1000 + var lottoTickets = ArrayList() + repeat(quantity) { + lottoTickets.add(LottoTicket.generateLottoNumber()) + } + return LottoTickets(lottoTickets) + } + } +} From e9abd55b5d1a5384722e608a19ca7e059d4eac58 Mon Sep 17 00:00:00 2001 From: wook Date: Sun, 8 Dec 2024 20:37:17 -0800 Subject: [PATCH 17/27] =?UTF-8?q?refactor:=20Test=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=82=B4=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?Class=20=EB=B6=84=EB=A6=AC=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/LottoNumber.kt | 7 ++ src/main/kotlin/lotto/LottoTicket.kt | 22 ++++ src/main/kotlin/lotto/LottoTickets.kt | 27 +++++ src/test/kotlin/lotto/LottoNumberTest.kt | 18 +++ src/test/kotlin/lotto/LottoTest.kt | 134 ---------------------- src/test/kotlin/lotto/LottoTicketTest.kt | 54 +++++++++ src/test/kotlin/lotto/LottoTicketsTest.kt | 24 ++++ 7 files changed, 152 insertions(+), 134 deletions(-) create mode 100644 src/main/kotlin/lotto/LottoNumber.kt create mode 100644 src/main/kotlin/lotto/LottoTicket.kt create mode 100644 src/main/kotlin/lotto/LottoTickets.kt create mode 100644 src/test/kotlin/lotto/LottoNumberTest.kt delete mode 100644 src/test/kotlin/lotto/LottoTest.kt create mode 100644 src/test/kotlin/lotto/LottoTicketTest.kt create mode 100644 src/test/kotlin/lotto/LottoTicketsTest.kt diff --git a/src/main/kotlin/lotto/LottoNumber.kt b/src/main/kotlin/lotto/LottoNumber.kt new file mode 100644 index 000000000..0b7f4b02e --- /dev/null +++ b/src/main/kotlin/lotto/LottoNumber.kt @@ -0,0 +1,7 @@ +package lotto + +data class LottoNumber(val number: Int) { + init { + require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/LottoTicket.kt b/src/main/kotlin/lotto/LottoTicket.kt new file mode 100644 index 000000000..3ec927c02 --- /dev/null +++ b/src/main/kotlin/lotto/LottoTicket.kt @@ -0,0 +1,22 @@ +package lotto + +class LottoTicket(numbers: List) { + private val _lottoNumbers: Set + val lottoNumbers: Set + get() = _lottoNumbers.toSet() + + init { + require(numbers.size == 6 && numbers.toSet().size == 6) { "로또 티켓 번호가 잘못 입력되었습니다" } + _lottoNumbers = numbers.toSortedSet() + } + + companion object { + fun generateLottoNumber(): LottoTicket { + val lottoNumbers = + (1..45) // .map { LottoNumber(it.first) } + .shuffled() + .take(6) + return LottoTicket(lottoNumbers) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/LottoTickets.kt b/src/main/kotlin/lotto/LottoTickets.kt new file mode 100644 index 000000000..a6fc82756 --- /dev/null +++ b/src/main/kotlin/lotto/LottoTickets.kt @@ -0,0 +1,27 @@ +package lotto + +class LottoTickets(lottoTickets: List) : Iterable { + private val _tickets: List + val tickets: List + get() = _tickets + + init { + require(lottoTickets.isNotEmpty()) { "로또 티켓은 한장 이상 구입해야 합니다" } + _tickets = lottoTickets + } + + override fun iterator(): Iterator { + return _tickets.iterator() + } + + companion object { + fun purchase(amount: Int): LottoTickets { + val quantity = amount / 1000 + var lottoTickets = ArrayList() + repeat(quantity) { + lottoTickets.add(LottoTicket.generateLottoNumber()) + } + return LottoTickets(lottoTickets) + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/LottoNumberTest.kt b/src/test/kotlin/lotto/LottoNumberTest.kt new file mode 100644 index 000000000..c08b5ee03 --- /dev/null +++ b/src/test/kotlin/lotto/LottoNumberTest.kt @@ -0,0 +1,18 @@ +package lotto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +class LottoNumberTest { + @ParameterizedTest + @ValueSource(ints = [0, -10, 46, 100]) + fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { + shouldThrow { + LottoNumber(number) + }.also { + it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/LottoTest.kt b/src/test/kotlin/lotto/LottoTest.kt deleted file mode 100644 index e0e40b12b..000000000 --- a/src/test/kotlin/lotto/LottoTest.kt +++ /dev/null @@ -1,134 +0,0 @@ -package lotto - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -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.MethodSource -import org.junit.jupiter.params.provider.ValueSource - -class LottoTest { - @ParameterizedTest - @ValueSource(ints = [0, -10, 46, 100]) - fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { - shouldThrow { - LottoNumber(number) - }.also { - it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" - } - } - - @ParameterizedTest - @MethodSource("providedDuplicationNumbers") - fun `로또 티켓은 중복된 번호로 생성되면 예외가 발생한다`(numbers: List) { - shouldThrow { - LottoTicket(numbers) - }.also { - it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" - } - } - - @ParameterizedTest - @MethodSource("providedWrongCountOfNumbers") - fun `로또 티켓 번호는 6개가 아니면 예외가 발생한다`(numbers: List) { - shouldThrow { - LottoTicket(numbers) - }.also { - it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" - } - } - - @Test - fun `로또 티켓은 한장 이상 구입 해야 한다`() { - shouldThrow { - LottoTickets(listOf()) - }.also { - it.message shouldBe "로또 티켓은 한장 이상 구입해야 합니다" - } - } - - @Test - fun `로또 티켓을 구입 금액에 맞게 발급한다`() { - val amount = 5_000 - val lottoTickets = LottoTickets.purchase(amount) - lottoTickets.tickets.size shouldBe 5 - } - - @Test - fun `로또 티켓을 생성하면 6개의 번호가 들어있다`() { - val lottoTicket = LottoTicket.generateLottoNumber() - lottoTicket.lottoNumbers.size shouldBe 6 - } - - companion object { - @JvmStatic - fun providedDuplicationNumbers() = - listOf( - Arguments.arguments(listOf(1, 1, 2, 3, 4, 5)), - Arguments.arguments(listOf(5, 5, 12, 13, 34, 35)), - Arguments.arguments(listOf(11, 19, 24, 33, 44, 44)), - ) - - @JvmStatic - fun providedWrongCountOfNumbers() = - listOf( - Arguments.arguments(listOf(1, 2, 3, 4, 5, 6, 7)), - Arguments.arguments(listOf(3, 5, 7, 8, 9)), - Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), - ) - } -} - -data class LottoNumber(val number: Int) { - init { - require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } - } -} - -class LottoTicket(numbers: List) { - private val _lottoNumbers: Set - val lottoNumbers: Set - get() = _lottoNumbers.toSet() - - init { - require(numbers.size == 6 && numbers.toSet().size == 6) { "로또 티켓 번호가 잘못 입력되었습니다" } - _lottoNumbers = numbers.toSortedSet() - } - - companion object { - fun generateLottoNumber(): LottoTicket { - val lottoNumbers = - (1..45) // .map { LottoNumber(it.first) } - .shuffled() - .take(6) - return LottoTicket(lottoNumbers) - } - } -} - -class LottoTickets(lottoTickets: List) : Iterable { - private val _tickets: List - val tickets: List - get() = _tickets - - init { - require(lottoTickets.isNotEmpty()) { "로또 티켓은 한장 이상 구입해야 합니다" } - _tickets = lottoTickets - } - - override fun iterator(): Iterator { - return _tickets.iterator() - } - - companion object { - fun purchase(amount: Int): LottoTickets { - val quantity = amount / 1000 - var lottoTickets = ArrayList() - repeat(quantity) { - lottoTickets.add(LottoTicket.generateLottoNumber()) - } - return LottoTickets(lottoTickets) - } - } -} diff --git a/src/test/kotlin/lotto/LottoTicketTest.kt b/src/test/kotlin/lotto/LottoTicketTest.kt new file mode 100644 index 000000000..3cd40d5bd --- /dev/null +++ b/src/test/kotlin/lotto/LottoTicketTest.kt @@ -0,0 +1,54 @@ +package lotto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +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.MethodSource + +class LottoTicketTest { + @ParameterizedTest + @MethodSource("providedDuplicationNumbers") + fun `로또 티켓은 중복된 번호로 생성되면 예외가 발생한다`(numbers: List) { + shouldThrow { + LottoTicket(numbers) + }.also { + it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" + } + } + + @ParameterizedTest + @MethodSource("providedWrongCountOfNumbers") + fun `로또 티켓 번호는 6개가 아니면 예외가 발생한다`(numbers: List) { + shouldThrow { + LottoTicket(numbers) + }.also { + it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" + } + } + + @Test + fun `로또 티켓을 생성하면 6개의 번호가 들어있다`() { + val lottoTicket = LottoTicket.generateLottoNumber() + lottoTicket.lottoNumbers.size shouldBe 6 + } + + companion object { + @JvmStatic + fun providedDuplicationNumbers() = + listOf( + Arguments.arguments(listOf(1, 1, 2, 3, 4, 5)), + Arguments.arguments(listOf(5, 5, 12, 13, 34, 35)), + Arguments.arguments(listOf(11, 19, 24, 33, 44, 44)), + ) + + @JvmStatic + fun providedWrongCountOfNumbers() = + listOf( + Arguments.arguments(listOf(1, 2, 3, 4, 5, 6, 7)), + Arguments.arguments(listOf(3, 5, 7, 8, 9)), + Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), + ) + } +} \ No newline at end of file diff --git a/src/test/kotlin/lotto/LottoTicketsTest.kt b/src/test/kotlin/lotto/LottoTicketsTest.kt new file mode 100644 index 000000000..27c4ceec1 --- /dev/null +++ b/src/test/kotlin/lotto/LottoTicketsTest.kt @@ -0,0 +1,24 @@ +package lotto + +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test + +class LottoTicketsTest { + @Test + fun `로또 티켓은 한장 이상 구입 해야 한다`() { + shouldThrow { + LottoTickets(listOf()) + }.also { + it.message shouldBe "로또 티켓은 한장 이상 구입해야 합니다" + } + } + + @Test + fun `로또 티켓을 구입 금액에 맞게 발급한다`() { + val amount = 5_000 + val lottoTickets = LottoTickets.purchase(amount) + lottoTickets.tickets.size shouldBe 5 + } +} + From 6677340673c50468ec947126dff9d3074d4d3c9f Mon Sep 17 00:00:00 2001 From: wook Date: Mon, 9 Dec 2024 13:14:58 -0800 Subject: [PATCH 18/27] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/LottoNumber.kt | 2 +- src/main/kotlin/lotto/LottoRank.kt | 12 +++++ src/main/kotlin/lotto/LottoTicket.kt | 2 +- src/main/kotlin/lotto/LottoTickets.kt | 4 +- src/main/kotlin/lotto/WinningLotto.kt | 14 +++++ src/test/kotlin/lotto/LottoNumberTest.kt | 2 +- src/test/kotlin/lotto/LottoRankTest.kt | 62 +++++++++++++++++++++++ src/test/kotlin/lotto/LottoTicketTest.kt | 2 +- src/test/kotlin/lotto/LottoTicketsTest.kt | 1 - src/test/kotlin/lotto/WinningLottoTest.kt | 39 ++++++++++++++ 10 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 src/main/kotlin/lotto/LottoRank.kt create mode 100644 src/main/kotlin/lotto/WinningLotto.kt create mode 100644 src/test/kotlin/lotto/LottoRankTest.kt create mode 100644 src/test/kotlin/lotto/WinningLottoTest.kt diff --git a/src/main/kotlin/lotto/LottoNumber.kt b/src/main/kotlin/lotto/LottoNumber.kt index 0b7f4b02e..a15f1a637 100644 --- a/src/main/kotlin/lotto/LottoNumber.kt +++ b/src/main/kotlin/lotto/LottoNumber.kt @@ -4,4 +4,4 @@ data class LottoNumber(val number: Int) { init { require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/lotto/LottoRank.kt b/src/main/kotlin/lotto/LottoRank.kt new file mode 100644 index 000000000..017abef28 --- /dev/null +++ b/src/main/kotlin/lotto/LottoRank.kt @@ -0,0 +1,12 @@ +package lotto + +enum class LottoRank( + val matchCount: Int, + val prize: Int, +) { + FIRST_PLACE(6, 2_000_000_000), + SECOND_PLACE(5, 1_500_000), + THIRD_PLACE(4, 50_000), + FOURTH_PLACE(3, 5_000), + BLANK_PLACE(0, 0), +} diff --git a/src/main/kotlin/lotto/LottoTicket.kt b/src/main/kotlin/lotto/LottoTicket.kt index 3ec927c02..5332024e1 100644 --- a/src/main/kotlin/lotto/LottoTicket.kt +++ b/src/main/kotlin/lotto/LottoTicket.kt @@ -19,4 +19,4 @@ class LottoTicket(numbers: List) { return LottoTicket(lottoNumbers) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/lotto/LottoTickets.kt b/src/main/kotlin/lotto/LottoTickets.kt index a6fc82756..efea1583b 100644 --- a/src/main/kotlin/lotto/LottoTickets.kt +++ b/src/main/kotlin/lotto/LottoTickets.kt @@ -17,11 +17,11 @@ class LottoTickets(lottoTickets: List) : Iterable { companion object { fun purchase(amount: Int): LottoTickets { val quantity = amount / 1000 - var lottoTickets = ArrayList() + val lottoTickets = ArrayList() repeat(quantity) { lottoTickets.add(LottoTicket.generateLottoNumber()) } return LottoTickets(lottoTickets) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/lotto/WinningLotto.kt b/src/main/kotlin/lotto/WinningLotto.kt new file mode 100644 index 000000000..d9606f156 --- /dev/null +++ b/src/main/kotlin/lotto/WinningLotto.kt @@ -0,0 +1,14 @@ +package lotto + +class WinningLotto(numbers: List) { + private val _lottoNumbers: Set = numbers.toSortedSet() + val lottoNumbers: Set + get() = _lottoNumbers.toSet() + + constructor() : this(LottoTicket.generateLottoNumber().lottoNumbers.toList()) + + fun matchedCount(lottoTicket: LottoTicket): LottoRank { + val matchCount = lottoNumbers.intersect(lottoTicket.lottoNumbers).size + return LottoRank.entries.find { it.matchCount == matchCount } ?: LottoRank.BLANK_PLACE + } +} diff --git a/src/test/kotlin/lotto/LottoNumberTest.kt b/src/test/kotlin/lotto/LottoNumberTest.kt index c08b5ee03..9fb849806 100644 --- a/src/test/kotlin/lotto/LottoNumberTest.kt +++ b/src/test/kotlin/lotto/LottoNumberTest.kt @@ -15,4 +15,4 @@ class LottoNumberTest { it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } } -} \ No newline at end of file +} diff --git a/src/test/kotlin/lotto/LottoRankTest.kt b/src/test/kotlin/lotto/LottoRankTest.kt new file mode 100644 index 000000000..66cb78550 --- /dev/null +++ b/src/test/kotlin/lotto/LottoRankTest.kt @@ -0,0 +1,62 @@ +package lotto + +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test + +class LottoRankTest { + @Test + fun `로또 티켓의 번호와 당첨 티켓이 6개 모두 일치하면 1등이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 5, 6))) + matchRank shouldBe LottoRank.FIRST_PLACE + matchRank.prize shouldBe 2_000_000_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 5개 일치하면 2등이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 5, 16))) + matchRank shouldBe LottoRank.SECOND_PLACE + matchRank.prize shouldBe 1_500_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 4개 일치하면 3등이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 15, 16))) + matchRank shouldBe LottoRank.THIRD_PLACE + matchRank.prize shouldBe 50_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 3개 일치하면 4등이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 14, 15, 16))) + matchRank shouldBe LottoRank.FOURTH_PLACE + matchRank.prize shouldBe 5_000 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 2개 일치하면 꽝이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 13, 14, 15, 16))) + matchRank shouldBe LottoRank.BLANK_PLACE + matchRank.prize shouldBe 0 + } + + @Test + fun `로또 티켓의 번호와 당첨 티켓 번호가 1개 일치하면 꽝이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 12, 13, 14, 15, 16))) + matchRank shouldBe LottoRank.BLANK_PLACE + matchRank.prize shouldBe 0 + } + + @Test + fun `로또 티켓의 번호가 당첨 티켓 번호와 하나도 일치하지 않으면 꽝이다`() { + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val matchRank = winningLotto.matchedCount(LottoTicket(listOf(11, 12, 13, 14, 15, 16))) + matchRank shouldBe LottoRank.BLANK_PLACE + matchRank.prize shouldBe 0 + } +} diff --git a/src/test/kotlin/lotto/LottoTicketTest.kt b/src/test/kotlin/lotto/LottoTicketTest.kt index 3cd40d5bd..28ebcc22e 100644 --- a/src/test/kotlin/lotto/LottoTicketTest.kt +++ b/src/test/kotlin/lotto/LottoTicketTest.kt @@ -51,4 +51,4 @@ class LottoTicketTest { Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), ) } -} \ No newline at end of file +} diff --git a/src/test/kotlin/lotto/LottoTicketsTest.kt b/src/test/kotlin/lotto/LottoTicketsTest.kt index 27c4ceec1..f1f4d3785 100644 --- a/src/test/kotlin/lotto/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/LottoTicketsTest.kt @@ -21,4 +21,3 @@ class LottoTicketsTest { lottoTickets.tickets.size shouldBe 5 } } - diff --git a/src/test/kotlin/lotto/WinningLottoTest.kt b/src/test/kotlin/lotto/WinningLottoTest.kt new file mode 100644 index 000000000..19f622af0 --- /dev/null +++ b/src/test/kotlin/lotto/WinningLottoTest.kt @@ -0,0 +1,39 @@ +package lotto + +import io.kotest.matchers.shouldBe +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.MethodSource + +class WinningLottoTest { + @Test + fun `당첨 티켓은 6개의 로또 번호로 생성된다`() { + val winningLotto = WinningLotto() + winningLotto.lottoNumbers.size shouldBe 6 + } + + @ParameterizedTest + @MethodSource("generateWiningLotto") + fun `로또 티켓이 당첨 티켓과 몇개가 일치하는지 확인 할 수 있다`( + lottoTicket: LottoTicket, + winningLotto: WinningLotto, + matchCount: Int, + ) { + val count = winningLotto.matchedCount(lottoTicket) + matchCount shouldBe count + } + + companion object { + @JvmStatic + fun generateWiningLotto() = + listOf( + Arguments.arguments(LottoTicket(listOf(1, 12, 13, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 1), + Arguments.arguments(LottoTicket(listOf(1, 2, 13, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 2), + Arguments.arguments(LottoTicket(listOf(1, 2, 3, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 3), + Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 4), + Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 5, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 5), + Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 5, 6)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 6), + ) + } +} From e2fddbb70b86e252185a33bf7071891273a03ee6 Mon Sep 17 00:00:00 2001 From: wook Date: Tue, 10 Dec 2024 17:04:27 -0800 Subject: [PATCH 19/27] =?UTF-8?q?feat:=20=EB=A1=9C=EB=98=90=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC,=20=EC=9E=85=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EB=B7=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/LottoNumber.kt | 7 --- src/main/kotlin/lotto/LottoRank.kt | 12 ----- src/main/kotlin/lotto/LottoTicket.kt | 22 -------- src/main/kotlin/lotto/LottoTickets.kt | 27 ---------- src/main/kotlin/lotto/WinningLotto.kt | 14 ----- src/test/kotlin/lotto/LottoNumberTest.kt | 18 ------- src/test/kotlin/lotto/LottoRankTest.kt | 62 ----------------------- src/test/kotlin/lotto/LottoTicketTest.kt | 54 -------------------- src/test/kotlin/lotto/LottoTicketsTest.kt | 23 --------- src/test/kotlin/lotto/WinningLottoTest.kt | 39 -------------- 10 files changed, 278 deletions(-) delete mode 100644 src/main/kotlin/lotto/LottoNumber.kt delete mode 100644 src/main/kotlin/lotto/LottoRank.kt delete mode 100644 src/main/kotlin/lotto/LottoTicket.kt delete mode 100644 src/main/kotlin/lotto/LottoTickets.kt delete mode 100644 src/main/kotlin/lotto/WinningLotto.kt delete mode 100644 src/test/kotlin/lotto/LottoNumberTest.kt delete mode 100644 src/test/kotlin/lotto/LottoRankTest.kt delete mode 100644 src/test/kotlin/lotto/LottoTicketTest.kt delete mode 100644 src/test/kotlin/lotto/LottoTicketsTest.kt delete mode 100644 src/test/kotlin/lotto/WinningLottoTest.kt diff --git a/src/main/kotlin/lotto/LottoNumber.kt b/src/main/kotlin/lotto/LottoNumber.kt deleted file mode 100644 index a15f1a637..000000000 --- a/src/main/kotlin/lotto/LottoNumber.kt +++ /dev/null @@ -1,7 +0,0 @@ -package lotto - -data class LottoNumber(val number: Int) { - init { - require(number in 1..45) { "로또 번호는 1보다 적거나 45보다 클 수 없습니다" } - } -} diff --git a/src/main/kotlin/lotto/LottoRank.kt b/src/main/kotlin/lotto/LottoRank.kt deleted file mode 100644 index 017abef28..000000000 --- a/src/main/kotlin/lotto/LottoRank.kt +++ /dev/null @@ -1,12 +0,0 @@ -package lotto - -enum class LottoRank( - val matchCount: Int, - val prize: Int, -) { - FIRST_PLACE(6, 2_000_000_000), - SECOND_PLACE(5, 1_500_000), - THIRD_PLACE(4, 50_000), - FOURTH_PLACE(3, 5_000), - BLANK_PLACE(0, 0), -} diff --git a/src/main/kotlin/lotto/LottoTicket.kt b/src/main/kotlin/lotto/LottoTicket.kt deleted file mode 100644 index 5332024e1..000000000 --- a/src/main/kotlin/lotto/LottoTicket.kt +++ /dev/null @@ -1,22 +0,0 @@ -package lotto - -class LottoTicket(numbers: List) { - private val _lottoNumbers: Set - val lottoNumbers: Set - get() = _lottoNumbers.toSet() - - init { - require(numbers.size == 6 && numbers.toSet().size == 6) { "로또 티켓 번호가 잘못 입력되었습니다" } - _lottoNumbers = numbers.toSortedSet() - } - - companion object { - fun generateLottoNumber(): LottoTicket { - val lottoNumbers = - (1..45) // .map { LottoNumber(it.first) } - .shuffled() - .take(6) - return LottoTicket(lottoNumbers) - } - } -} diff --git a/src/main/kotlin/lotto/LottoTickets.kt b/src/main/kotlin/lotto/LottoTickets.kt deleted file mode 100644 index efea1583b..000000000 --- a/src/main/kotlin/lotto/LottoTickets.kt +++ /dev/null @@ -1,27 +0,0 @@ -package lotto - -class LottoTickets(lottoTickets: List) : Iterable { - private val _tickets: List - val tickets: List - get() = _tickets - - init { - require(lottoTickets.isNotEmpty()) { "로또 티켓은 한장 이상 구입해야 합니다" } - _tickets = lottoTickets - } - - override fun iterator(): Iterator { - return _tickets.iterator() - } - - companion object { - fun purchase(amount: Int): LottoTickets { - val quantity = amount / 1000 - val lottoTickets = ArrayList() - repeat(quantity) { - lottoTickets.add(LottoTicket.generateLottoNumber()) - } - return LottoTickets(lottoTickets) - } - } -} diff --git a/src/main/kotlin/lotto/WinningLotto.kt b/src/main/kotlin/lotto/WinningLotto.kt deleted file mode 100644 index d9606f156..000000000 --- a/src/main/kotlin/lotto/WinningLotto.kt +++ /dev/null @@ -1,14 +0,0 @@ -package lotto - -class WinningLotto(numbers: List) { - private val _lottoNumbers: Set = numbers.toSortedSet() - val lottoNumbers: Set - get() = _lottoNumbers.toSet() - - constructor() : this(LottoTicket.generateLottoNumber().lottoNumbers.toList()) - - fun matchedCount(lottoTicket: LottoTicket): LottoRank { - val matchCount = lottoNumbers.intersect(lottoTicket.lottoNumbers).size - return LottoRank.entries.find { it.matchCount == matchCount } ?: LottoRank.BLANK_PLACE - } -} diff --git a/src/test/kotlin/lotto/LottoNumberTest.kt b/src/test/kotlin/lotto/LottoNumberTest.kt deleted file mode 100644 index 9fb849806..000000000 --- a/src/test/kotlin/lotto/LottoNumberTest.kt +++ /dev/null @@ -1,18 +0,0 @@ -package lotto - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.ValueSource - -class LottoNumberTest { - @ParameterizedTest - @ValueSource(ints = [0, -10, 46, 100]) - fun `로또 번호는 1보다 작거나 45보다 클수 없다`(number: Int) { - shouldThrow { - LottoNumber(number) - }.also { - it.message shouldBe "로또 번호는 1보다 적거나 45보다 클 수 없습니다" - } - } -} diff --git a/src/test/kotlin/lotto/LottoRankTest.kt b/src/test/kotlin/lotto/LottoRankTest.kt deleted file mode 100644 index 66cb78550..000000000 --- a/src/test/kotlin/lotto/LottoRankTest.kt +++ /dev/null @@ -1,62 +0,0 @@ -package lotto - -import io.kotest.matchers.shouldBe -import org.junit.jupiter.api.Test - -class LottoRankTest { - @Test - fun `로또 티켓의 번호와 당첨 티켓이 6개 모두 일치하면 1등이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 5, 6))) - matchRank shouldBe LottoRank.FIRST_PLACE - matchRank.prize shouldBe 2_000_000_000 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 5개 일치하면 2등이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 5, 16))) - matchRank shouldBe LottoRank.SECOND_PLACE - matchRank.prize shouldBe 1_500_000 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 4개 일치하면 3등이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 4, 15, 16))) - matchRank shouldBe LottoRank.THIRD_PLACE - matchRank.prize shouldBe 50_000 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 3개 일치하면 4등이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 3, 14, 15, 16))) - matchRank shouldBe LottoRank.FOURTH_PLACE - matchRank.prize shouldBe 5_000 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 2개 일치하면 꽝이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 2, 13, 14, 15, 16))) - matchRank shouldBe LottoRank.BLANK_PLACE - matchRank.prize shouldBe 0 - } - - @Test - fun `로또 티켓의 번호와 당첨 티켓 번호가 1개 일치하면 꽝이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(1, 12, 13, 14, 15, 16))) - matchRank shouldBe LottoRank.BLANK_PLACE - matchRank.prize shouldBe 0 - } - - @Test - fun `로또 티켓의 번호가 당첨 티켓 번호와 하나도 일치하지 않으면 꽝이다`() { - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val matchRank = winningLotto.matchedCount(LottoTicket(listOf(11, 12, 13, 14, 15, 16))) - matchRank shouldBe LottoRank.BLANK_PLACE - matchRank.prize shouldBe 0 - } -} diff --git a/src/test/kotlin/lotto/LottoTicketTest.kt b/src/test/kotlin/lotto/LottoTicketTest.kt deleted file mode 100644 index 28ebcc22e..000000000 --- a/src/test/kotlin/lotto/LottoTicketTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -package lotto - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -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.MethodSource - -class LottoTicketTest { - @ParameterizedTest - @MethodSource("providedDuplicationNumbers") - fun `로또 티켓은 중복된 번호로 생성되면 예외가 발생한다`(numbers: List) { - shouldThrow { - LottoTicket(numbers) - }.also { - it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" - } - } - - @ParameterizedTest - @MethodSource("providedWrongCountOfNumbers") - fun `로또 티켓 번호는 6개가 아니면 예외가 발생한다`(numbers: List) { - shouldThrow { - LottoTicket(numbers) - }.also { - it.message shouldBe "로또 티켓 번호가 잘못 입력되었습니다" - } - } - - @Test - fun `로또 티켓을 생성하면 6개의 번호가 들어있다`() { - val lottoTicket = LottoTicket.generateLottoNumber() - lottoTicket.lottoNumbers.size shouldBe 6 - } - - companion object { - @JvmStatic - fun providedDuplicationNumbers() = - listOf( - Arguments.arguments(listOf(1, 1, 2, 3, 4, 5)), - Arguments.arguments(listOf(5, 5, 12, 13, 34, 35)), - Arguments.arguments(listOf(11, 19, 24, 33, 44, 44)), - ) - - @JvmStatic - fun providedWrongCountOfNumbers() = - listOf( - Arguments.arguments(listOf(1, 2, 3, 4, 5, 6, 7)), - Arguments.arguments(listOf(3, 5, 7, 8, 9)), - Arguments.arguments(listOf(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)), - ) - } -} diff --git a/src/test/kotlin/lotto/LottoTicketsTest.kt b/src/test/kotlin/lotto/LottoTicketsTest.kt deleted file mode 100644 index f1f4d3785..000000000 --- a/src/test/kotlin/lotto/LottoTicketsTest.kt +++ /dev/null @@ -1,23 +0,0 @@ -package lotto - -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -import org.junit.jupiter.api.Test - -class LottoTicketsTest { - @Test - fun `로또 티켓은 한장 이상 구입 해야 한다`() { - shouldThrow { - LottoTickets(listOf()) - }.also { - it.message shouldBe "로또 티켓은 한장 이상 구입해야 합니다" - } - } - - @Test - fun `로또 티켓을 구입 금액에 맞게 발급한다`() { - val amount = 5_000 - val lottoTickets = LottoTickets.purchase(amount) - lottoTickets.tickets.size shouldBe 5 - } -} diff --git a/src/test/kotlin/lotto/WinningLottoTest.kt b/src/test/kotlin/lotto/WinningLottoTest.kt deleted file mode 100644 index 19f622af0..000000000 --- a/src/test/kotlin/lotto/WinningLottoTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -package lotto - -import io.kotest.matchers.shouldBe -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.MethodSource - -class WinningLottoTest { - @Test - fun `당첨 티켓은 6개의 로또 번호로 생성된다`() { - val winningLotto = WinningLotto() - winningLotto.lottoNumbers.size shouldBe 6 - } - - @ParameterizedTest - @MethodSource("generateWiningLotto") - fun `로또 티켓이 당첨 티켓과 몇개가 일치하는지 확인 할 수 있다`( - lottoTicket: LottoTicket, - winningLotto: WinningLotto, - matchCount: Int, - ) { - val count = winningLotto.matchedCount(lottoTicket) - matchCount shouldBe count - } - - companion object { - @JvmStatic - fun generateWiningLotto() = - listOf( - Arguments.arguments(LottoTicket(listOf(1, 12, 13, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 1), - Arguments.arguments(LottoTicket(listOf(1, 2, 13, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 2), - Arguments.arguments(LottoTicket(listOf(1, 2, 3, 14, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 3), - Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 15, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 4), - Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 5, 16)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 5), - Arguments.arguments(LottoTicket(listOf(1, 2, 3, 4, 5, 6)), WinningLotto(listOf(1, 2, 3, 4, 5, 6)), 6), - ) - } -} From a115791485be801efeb0925dd866235c494be023 Mon Sep 17 00:00:00 2001 From: wook Date: Wed, 11 Dec 2024 10:32:56 -0800 Subject: [PATCH 20/27] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=EB=B0=B1?= =?UTF-8?q?=20=EB=B0=98=EC=98=81,=20LottoTickets.calculateLottoRank=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 --- .../kotlin/lotto/domain/LottoTicketsTest.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index 4b8aa7add..b6708d0e4 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -48,4 +48,25 @@ class LottoTicketsTest { sortedResults[5].rank shouldBe LottoRank.FIRST_PLACE sortedResults[5].count shouldBe 0 } + + @Test + fun `당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { + val lottoTickets = + LottoTickets( + listOf( + LottoTicket(listOf(1, 2, 3, 4, 5, 7)), + LottoTicket(listOf(1, 2, 3, 4, 5, 9)), + LottoTicket(listOf(1, 2, 3, 4, 8, 9)), + ), + ) + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val lottoResults = lottoTickets.calculateLottoRank(winningLotto) + val sortedResults = lottoResults.findAllSortedByMatchCount() + sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE + sortedResults[0].count shouldBe 0 + sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE + sortedResults[1].count shouldBe 2 + sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE + sortedResults[2].count shouldBe 1 + } } From cfee66bcde9d9ac66a8f90406308d9ecfa73dc4f Mon Sep 17 00:00:00 2001 From: Sangwook <45926559+goodbyeyo@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:07:59 +0900 Subject: [PATCH 21/27] =?UTF-8?q?Step3=20=EB=A1=9C=EB=98=90=202=EB=93=B1?= =?UTF-8?q?=20(#1131)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Lotto 도메인 테스트 및 구현 * feat: 로또 번호, 티켓 발급 기능 구현 및 테스트 * refactor: Test 코드 내 도메인 로직 Class 분리 리팩토링 * feat: 당첨 로또 기능 구현 * feat: 로또 컨트롤러, 입출력 뷰 구현 * refactor: 피드백 반영, LottoTickets.calculateLottoRank 테스트 추가 * refactor: 피드백 반영 1. WinningLotto 제거하고 담당하던 책임 LottoTicket 으로 이동 2. LottoTicket 프로퍼티 변경 : List -> Set 3. LottoTicket 프로퍼티 기반으로 위임하도록 변경, 부생성자 추가 4. LottoTicket 정적팩토리메서드 추가 * doc: STEP3 로또2등 요구구사항 정리 * feat: 보너스번호 도메인 구현 * feat: 보너스 번호 일치여부 구현 * feat: 로또 2등 기능 구현 1. LottoRank : 로또 랭크 판단 조건, 상금 변경 2. LottoTicket : 당첨 로또 계산 위임(WinningLotto) 3. LottoTicket : data class 변경 (피드백 반영) 4. 당첨 로또 계산 시 보너스 번호가 포함된 WinningLotto 전달 5. 당첨 결과 출력 보너스 번호 일치 여부 출력 6. 테스트 코드 2등 로또 반영 * refactor: 피드백 반영 1. BonusNumber 제거하고 WinningLotto 가 직접 책임을 담당하도록 변경 2. WinningLotto 생성자 인자 팩토리 메서드(동반 객체 메서드) 구조로 전달 3. LottoNumber 정적 팩터리 메서드 추가 --- .../kotlin/lotto/domain/LottoTicketsTest.kt | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index b6708d0e4..4b8aa7add 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -48,25 +48,4 @@ class LottoTicketsTest { sortedResults[5].rank shouldBe LottoRank.FIRST_PLACE sortedResults[5].count shouldBe 0 } - - @Test - fun `당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { - val lottoTickets = - LottoTickets( - listOf( - LottoTicket(listOf(1, 2, 3, 4, 5, 7)), - LottoTicket(listOf(1, 2, 3, 4, 5, 9)), - LottoTicket(listOf(1, 2, 3, 4, 8, 9)), - ), - ) - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val lottoResults = lottoTickets.calculateLottoRank(winningLotto) - val sortedResults = lottoResults.findAllSortedByMatchCount() - sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE - sortedResults[0].count shouldBe 0 - sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE - sortedResults[1].count shouldBe 2 - sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE - sortedResults[2].count shouldBe 1 - } } From c6f49964987af0827aea491f6fa1055b20c32070 Mon Sep 17 00:00:00 2001 From: wook Date: Wed, 11 Dec 2024 10:32:56 -0800 Subject: [PATCH 22/27] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=EB=B0=B1?= =?UTF-8?q?=20=EB=B0=98=EC=98=81,=20LottoTickets.calculateLottoRank=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 --- .../kotlin/lotto/domain/LottoTicketsTest.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index 4b8aa7add..b6708d0e4 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -48,4 +48,25 @@ class LottoTicketsTest { sortedResults[5].rank shouldBe LottoRank.FIRST_PLACE sortedResults[5].count shouldBe 0 } + + @Test + fun `당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { + val lottoTickets = + LottoTickets( + listOf( + LottoTicket(listOf(1, 2, 3, 4, 5, 7)), + LottoTicket(listOf(1, 2, 3, 4, 5, 9)), + LottoTicket(listOf(1, 2, 3, 4, 8, 9)), + ), + ) + val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) + val lottoResults = lottoTickets.calculateLottoRank(winningLotto) + val sortedResults = lottoResults.findAllSortedByMatchCount() + sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE + sortedResults[0].count shouldBe 0 + sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE + sortedResults[1].count shouldBe 2 + sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE + sortedResults[2].count shouldBe 1 + } } From 3e9cf8697bec00e18e5f7bee339da33a444200cb Mon Sep 17 00:00:00 2001 From: wook Date: Wed, 18 Dec 2024 14:12:31 +0900 Subject: [PATCH 23/27] =?UTF-8?q?fix:=20upstream=20rebase=20=ED=9B=84=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=9C=20=ED=85=8C=EC=8A=A4=EC=BD=94=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/lotto/domain/LottoTicketsTest.kt | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt index b6708d0e4..4b8aa7add 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketsTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketsTest.kt @@ -48,25 +48,4 @@ class LottoTicketsTest { sortedResults[5].rank shouldBe LottoRank.FIRST_PLACE sortedResults[5].count shouldBe 0 } - - @Test - fun `당첨 티켓을 전달하면 당첨 결과를 확인 할 수 있다`() { - val lottoTickets = - LottoTickets( - listOf( - LottoTicket(listOf(1, 2, 3, 4, 5, 7)), - LottoTicket(listOf(1, 2, 3, 4, 5, 9)), - LottoTicket(listOf(1, 2, 3, 4, 8, 9)), - ), - ) - val winningLotto = WinningLotto(listOf(1, 2, 3, 4, 5, 6)) - val lottoResults = lottoTickets.calculateLottoRank(winningLotto) - val sortedResults = lottoResults.findAllSortedByMatchCount() - sortedResults[0].rank shouldBe LottoRank.FIRST_PLACE - sortedResults[0].count shouldBe 0 - sortedResults[1].rank shouldBe LottoRank.SECOND_PLACE - sortedResults[1].count shouldBe 2 - sortedResults[2].rank shouldBe LottoRank.THIRD_PLACE - sortedResults[2].count shouldBe 1 - } } From 07bd5fbfe84111b3ab4cf5ad8ed2d2e536d8614a Mon Sep 17 00:00:00 2001 From: wook Date: Sat, 21 Dec 2024 21:47:44 +0900 Subject: [PATCH 24/27] =?UTF-8?q?refactor=20:=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EB=B0=98=EC=98=81=20-=20InputView=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EC=83=9D=EC=84=B1=20=EC=97=AD=ED=95=A0=20=EC=9C=84?= =?UTF-8?q?=EC=9E=84=20->=20LottoTicket?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/domain/LottoTicket.kt | 8 ++++++++ src/main/kotlin/lotto/view/InputView.kt | 9 ++++----- src/test/kotlin/lotto/domain/LottoTicketTest.kt | 10 ++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/lotto/domain/LottoTicket.kt b/src/main/kotlin/lotto/domain/LottoTicket.kt index 2a6094245..53429862a 100644 --- a/src/main/kotlin/lotto/domain/LottoTicket.kt +++ b/src/main/kotlin/lotto/domain/LottoTicket.kt @@ -18,6 +18,7 @@ data class LottoTicket(private val numbers: Set) : Collection) : Collection): LottoTicket { return LottoTicket(numbers.map { LottoNumber(it) }.toSet()) } diff --git a/src/main/kotlin/lotto/view/InputView.kt b/src/main/kotlin/lotto/view/InputView.kt index 2a79ccab4..a34c8e0ff 100644 --- a/src/main/kotlin/lotto/view/InputView.kt +++ b/src/main/kotlin/lotto/view/InputView.kt @@ -20,13 +20,12 @@ object InputView { val manualLottoTickets = mutableListOf() println("수동으로 구매할 번호를 입력해 주세요.") repeat(manualLottoQuantity) { - val line = readlnOrNull()?.takeIf { it.isNotBlank() } ?: throw IllegalArgumentException("로또 번호를 입력해주세요.") - val numbers = - line.split(DELIMITER) - .map { it.trim().toIntOrNull() ?: throw IllegalArgumentException("로또 번호는 숫자여야 합니다.") } - manualLottoTickets.add(LottoTicket.from(numbers.toSet())) + val readLine = readlnOrNull()?.takeIf { it.isNotBlank() } ?: throw IllegalArgumentException("로또 번호를 입력해주세요.") + val lottoTicket = LottoTicket.makeLottoTicket(readLine) + manualLottoTickets.add(lottoTicket) } return LottoTickets(manualLottoTickets) + } private fun getManualLottoQuantity(): Int { diff --git a/src/test/kotlin/lotto/domain/LottoTicketTest.kt b/src/test/kotlin/lotto/domain/LottoTicketTest.kt index a16abdf1d..b6cced83c 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketTest.kt @@ -2,6 +2,7 @@ package lotto.domain import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.equals.shouldBeEqual import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test import org.junit.jupiter.params.ParameterizedTest @@ -114,6 +115,15 @@ class LottoTicketTest { rank.prize shouldBe 0 } + @Test + fun `같은 숫자와 콤마 구분자로 된 문자열로 생성된 로또 티켓은 동일하다`() { + val numbers = "1,2,3,4,5,6" + val lottoTicket = LottoTicket.makeLottoTicket(numbers) + val number2 = "1,2,3,4,5,6" + val lottoTicket2 = LottoTicket.makeLottoTicket(number2) + lottoTicket shouldBeEqual lottoTicket2 + } + companion object { @JvmStatic fun providedDuplicationNumbers() = From 08c532070e6d39ef8c1fbbf8400d3e071b7c3aad Mon Sep 17 00:00:00 2001 From: wook Date: Sat, 21 Dec 2024 22:09:14 +0900 Subject: [PATCH 25/27] =?UTF-8?q?refactor=20:=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EB=B0=98=EC=98=81=20-=20immutableList=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=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 --- src/main/kotlin/lotto/view/InputView.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/lotto/view/InputView.kt b/src/main/kotlin/lotto/view/InputView.kt index a34c8e0ff..d3ad21664 100644 --- a/src/main/kotlin/lotto/view/InputView.kt +++ b/src/main/kotlin/lotto/view/InputView.kt @@ -17,15 +17,12 @@ object InputView { } private fun getManualLottoTickets(manualLottoQuantity: Int): LottoTickets { - val manualLottoTickets = mutableListOf() println("수동으로 구매할 번호를 입력해 주세요.") - repeat(manualLottoQuantity) { + val manualLottoTickets = List(manualLottoQuantity) { val readLine = readlnOrNull()?.takeIf { it.isNotBlank() } ?: throw IllegalArgumentException("로또 번호를 입력해주세요.") - val lottoTicket = LottoTicket.makeLottoTicket(readLine) - manualLottoTickets.add(lottoTicket) + LottoTicket.makeLottoTicket(readLine) } return LottoTickets(manualLottoTickets) - } private fun getManualLottoQuantity(): Int { From 69535ed835b8bce0ac3180eb58239c84976d381d Mon Sep 17 00:00:00 2001 From: wook Date: Sat, 21 Dec 2024 23:30:12 +0900 Subject: [PATCH 26/27] =?UTF-8?q?refactor=20:=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EB=B0=98=EC=98=81=201.=20purchaseAmount=20?= =?UTF-8?q?=EC=9B=90=EC=8B=9C=EA=B0=92=20=ED=8F=AC=EC=9E=A5=202.=20Purchas?= =?UTF-8?q?eDetail=20=ED=8C=A9=ED=84=B0=EB=A6=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=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 --- src/main/kotlin/lotto/domain/Money.kt | 5 +++++ src/main/kotlin/lotto/dto/PurchaseDetail.kt | 20 ++++++++++++++++--- src/main/kotlin/lotto/view/InputView.kt | 13 +++++------- .../kotlin/lotto/dto/PurchaseDetailTest.kt | 7 ++++--- 4 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 src/main/kotlin/lotto/domain/Money.kt diff --git a/src/main/kotlin/lotto/domain/Money.kt b/src/main/kotlin/lotto/domain/Money.kt new file mode 100644 index 000000000..8cf3e6332 --- /dev/null +++ b/src/main/kotlin/lotto/domain/Money.kt @@ -0,0 +1,5 @@ +package lotto.domain + +class Money(money: String) { + val amount: Int = money.toIntOrNull() ?: throw IllegalArgumentException("구입 금액이 유효하지 않습니다. 숫자를 입력해주세요") +} \ No newline at end of file diff --git a/src/main/kotlin/lotto/dto/PurchaseDetail.kt b/src/main/kotlin/lotto/dto/PurchaseDetail.kt index 375265087..040c24c4e 100644 --- a/src/main/kotlin/lotto/dto/PurchaseDetail.kt +++ b/src/main/kotlin/lotto/dto/PurchaseDetail.kt @@ -2,6 +2,7 @@ package lotto.dto import lotto.domain.LottoTickets import lotto.domain.LottoTickets.Companion.LOTTO_TICKET_PRICE +import lotto.domain.Money data class PurchaseDetail( val purchaseAmount: Int, @@ -14,12 +15,25 @@ data class PurchaseDetail( require(autoLottoQuantity <= purchaseAmount / LOTTO_TICKET_PRICE) { "자동으로 구입할 로또의 수량이 구입금액보다 많습니다" } } constructor( - purchaseAmount: Int, + money: Money, manualLottoTickets: LottoTickets, ) : this( - purchaseAmount, - purchaseAmount / LOTTO_TICKET_PRICE - manualLottoTickets.size, + money.amount, + money.amount / LOTTO_TICKET_PRICE - manualLottoTickets.size, manualLottoTickets.size, manualLottoTickets, ) + companion object { + fun of( + money: Money, + manualLottoTickets: LottoTickets + ): PurchaseDetail { + return PurchaseDetail( + money.amount, + money.amount / LOTTO_TICKET_PRICE - manualLottoTickets.size, + manualLottoTickets.size, + manualLottoTickets, + ) + } + } } diff --git a/src/main/kotlin/lotto/view/InputView.kt b/src/main/kotlin/lotto/view/InputView.kt index d3ad21664..fb23aa107 100644 --- a/src/main/kotlin/lotto/view/InputView.kt +++ b/src/main/kotlin/lotto/view/InputView.kt @@ -1,19 +1,16 @@ package lotto.view -import lotto.domain.LottoNumber -import lotto.domain.LottoTicket -import lotto.domain.LottoTickets -import lotto.domain.WinningLotto +import lotto.domain.* import lotto.dto.PurchaseDetail object InputView { private const val DELIMITER = "," fun getPurchaseDetail(): PurchaseDetail { - val purchaseAmount = getPurchaseAmount() + val money = getPurchaseAmount() val manualLottoQuantity = getManualLottoQuantity() val manualLottoTickets = getManualLottoTickets(manualLottoQuantity) - return PurchaseDetail(purchaseAmount, manualLottoTickets) + return PurchaseDetail.of(money, manualLottoTickets) } private fun getManualLottoTickets(manualLottoQuantity: Int): LottoTickets { @@ -31,10 +28,10 @@ object InputView { return quantity.toIntOrNull() ?: throw IllegalArgumentException("유효한 숫자를 입력해주세요") } - private fun getPurchaseAmount(): Int { + private fun getPurchaseAmount(): Money { println("구입 금액을 입력해 주세요.") val amount = readln() - return amount.toIntOrNull() ?: throw IllegalArgumentException("구입 금액이 유효하지 않습니다. 숫자를 입력해주세요") + return Money(amount) } fun getUserWinningLotto(): WinningLotto { diff --git a/src/test/kotlin/lotto/dto/PurchaseDetailTest.kt b/src/test/kotlin/lotto/dto/PurchaseDetailTest.kt index 10e0a4bb8..eb161d01e 100644 --- a/src/test/kotlin/lotto/dto/PurchaseDetailTest.kt +++ b/src/test/kotlin/lotto/dto/PurchaseDetailTest.kt @@ -4,6 +4,7 @@ import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe import lotto.domain.LottoTicket import lotto.domain.LottoTickets +import lotto.domain.Money import org.junit.jupiter.api.Test class PurchaseDetailTest { @@ -11,7 +12,7 @@ class PurchaseDetailTest { fun `수동으로 구입할 로또의 수량은 구입금액보다 많을 수 없다`() { shouldThrow { PurchaseDetail( - purchaseAmount = 1_000, + money = Money("1000"), manualLottoTickets = LottoTickets( listOf( @@ -50,8 +51,8 @@ class PurchaseDetailTest { @Test fun `만원 구매금액으로 수동 로또 3장을 구입하면 자동 로또는 7장이다`() { val purchaseDetail = - PurchaseDetail( - purchaseAmount = 10_000, + PurchaseDetail.of( + money = Money("10000"), manualLottoTickets = LottoTickets( listOf( From 82770fefc75dd65a0c19dd16a4c1a0872d94214c Mon Sep 17 00:00:00 2001 From: wook Date: Sat, 21 Dec 2024 23:34:02 +0900 Subject: [PATCH 27/27] =?UTF-8?q?refactor=20:=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EB=B0=98=EC=98=81=201.=20purchaseAmount=20?= =?UTF-8?q?=EC=9B=90=EC=8B=9C=EA=B0=92=20=ED=8F=AC=EC=9E=A5=202.=20Purchas?= =?UTF-8?q?eDetail=20=ED=8C=A9=ED=84=B0=EB=A6=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=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 --- src/main/kotlin/lotto/domain/Money.kt | 2 +- src/main/kotlin/lotto/dto/PurchaseDetail.kt | 3 ++- src/main/kotlin/lotto/view/InputView.kt | 15 ++++++++++----- src/test/kotlin/lotto/domain/LottoTicketTest.kt | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/lotto/domain/Money.kt b/src/main/kotlin/lotto/domain/Money.kt index 8cf3e6332..95dadf3d9 100644 --- a/src/main/kotlin/lotto/domain/Money.kt +++ b/src/main/kotlin/lotto/domain/Money.kt @@ -2,4 +2,4 @@ package lotto.domain class Money(money: String) { val amount: Int = money.toIntOrNull() ?: throw IllegalArgumentException("구입 금액이 유효하지 않습니다. 숫자를 입력해주세요") -} \ No newline at end of file +} diff --git a/src/main/kotlin/lotto/dto/PurchaseDetail.kt b/src/main/kotlin/lotto/dto/PurchaseDetail.kt index 040c24c4e..9dd53bd38 100644 --- a/src/main/kotlin/lotto/dto/PurchaseDetail.kt +++ b/src/main/kotlin/lotto/dto/PurchaseDetail.kt @@ -23,10 +23,11 @@ data class PurchaseDetail( manualLottoTickets.size, manualLottoTickets, ) + companion object { fun of( money: Money, - manualLottoTickets: LottoTickets + manualLottoTickets: LottoTickets, ): PurchaseDetail { return PurchaseDetail( money.amount, diff --git a/src/main/kotlin/lotto/view/InputView.kt b/src/main/kotlin/lotto/view/InputView.kt index fb23aa107..d0ae14351 100644 --- a/src/main/kotlin/lotto/view/InputView.kt +++ b/src/main/kotlin/lotto/view/InputView.kt @@ -1,6 +1,10 @@ package lotto.view -import lotto.domain.* +import lotto.domain.LottoNumber +import lotto.domain.LottoTicket +import lotto.domain.LottoTickets +import lotto.domain.Money +import lotto.domain.WinningLotto import lotto.dto.PurchaseDetail object InputView { @@ -15,10 +19,11 @@ object InputView { private fun getManualLottoTickets(manualLottoQuantity: Int): LottoTickets { println("수동으로 구매할 번호를 입력해 주세요.") - val manualLottoTickets = List(manualLottoQuantity) { - val readLine = readlnOrNull()?.takeIf { it.isNotBlank() } ?: throw IllegalArgumentException("로또 번호를 입력해주세요.") - LottoTicket.makeLottoTicket(readLine) - } + val manualLottoTickets = + List(manualLottoQuantity) { + val readLine = readlnOrNull()?.takeIf { it.isNotBlank() } ?: throw IllegalArgumentException("로또 번호를 입력해주세요.") + LottoTicket.makeLottoTicket(readLine) + } return LottoTickets(manualLottoTickets) } diff --git a/src/test/kotlin/lotto/domain/LottoTicketTest.kt b/src/test/kotlin/lotto/domain/LottoTicketTest.kt index b6cced83c..82b30c5c5 100644 --- a/src/test/kotlin/lotto/domain/LottoTicketTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTicketTest.kt @@ -119,7 +119,7 @@ class LottoTicketTest { fun `같은 숫자와 콤마 구분자로 된 문자열로 생성된 로또 티켓은 동일하다`() { val numbers = "1,2,3,4,5,6" val lottoTicket = LottoTicket.makeLottoTicket(numbers) - val number2 = "1,2,3,4,5,6" + val number2 = "1,2,3,4,5,6" val lottoTicket2 = LottoTicket.makeLottoTicket(number2) lottoTicket shouldBeEqual lottoTicket2 }