diff --git a/README.md b/README.md index 47aecff..8fb04aa 100644 --- a/README.md +++ b/README.md @@ -1 +1,23 @@ -휴 이제야 됐네요! \ No newline at end of file +# 기능 +- 로또 티켓 자동 발급 가능 +- 로또 티켓 수동 발급 가능 (공백으로 구분한 6개의 숫자) +- 당첨 번호 직접 설정 가능 (공백으로 구분한 7개의 숫자) +- 당첨 번호와 티켓 비교 후 결과 출력 + +# Money 클래스 테스트 +- [x] 돈이 음수가 될 수 없다 +- [x] plus가 제대로 작동하는지 테스트 +- [x] minus가 제대로 작동하는지 테스트 + +# LottoNumber 클래스 테스트 +- [x] 입력된 숫자가 1~45 사이여야한다 (기본 생성자 테스트) +- [x] of 함수가 제대로 작동하는지 테스트 + +# LottoTicket 클래스 테스트 +- [x] 로또 번호가 여섯개여야한다 + - [x] 기본 생성자로 테스트 + - [x] vararg numbers: Int를 넘겼을 때 잘 생성되는지 테스트 + - [x] numbers: List를 넘겼을 때 잘 생성되는지 테스트 +- [ ] has 함수가 제대로 작동하는지 테스트 +- [x] countMatchingNumbers 함수가 제대로 작동하는지 테스트 +- [x] toString 함수가 제대로 작동하는지 테스트 \ No newline at end of file diff --git a/domain/src/main/java/com/malibin/study/domain/lotto/LottoNumber.kt b/domain/src/main/java/com/malibin/study/domain/lotto/LottoNumber.kt index 5b7c7bf..02c1be4 100644 --- a/domain/src/main/java/com/malibin/study/domain/lotto/LottoNumber.kt +++ b/domain/src/main/java/com/malibin/study/domain/lotto/LottoNumber.kt @@ -2,7 +2,7 @@ package com.malibin.study.domain.lotto @JvmInline value class LottoNumber private constructor( - val number: Int, + val number: Int ) { init { require(number in RANGE) { "입력 숫자 ($number)는 로또 숫자 범위(1 ~ 45) 내의 숫자가 아닙니다." } diff --git a/domain/src/main/java/com/malibin/study/domain/lotto/cal/AverageCalculator.kt b/domain/src/main/java/com/malibin/study/domain/lotto/cal/AverageCalculator.kt new file mode 100644 index 0000000..f3d807d --- /dev/null +++ b/domain/src/main/java/com/malibin/study/domain/lotto/cal/AverageCalculator.kt @@ -0,0 +1,7 @@ +package com.malibin.study.domain.lotto.cal + +class AverageCalculator { + fun calculateAverage(numbers: List): Int { + return numbers.sum() / numbers.size + } +} diff --git a/domain/src/main/java/com/malibin/study/domain/lotto/ticket/LottoTicket.kt b/domain/src/main/java/com/malibin/study/domain/lotto/ticket/LottoTicket.kt index e913894..d57aac1 100644 --- a/domain/src/main/java/com/malibin/study/domain/lotto/ticket/LottoTicket.kt +++ b/domain/src/main/java/com/malibin/study/domain/lotto/ticket/LottoTicket.kt @@ -3,7 +3,7 @@ package com.malibin.study.domain.lotto.ticket import com.malibin.study.domain.lotto.LottoNumber data class LottoTicket( - val lottoNumbers: Set, + val lottoNumbers: Set ) { init { require(lottoNumbers.size == LOTTO_NUMBERS_AMOUNT) { "로또 티켓에 번호는 6개만 넣을 수 있습니다. 입력 값 : $lottoNumbers" } diff --git a/domain/src/test/java/com/malibin/study/domain/lotto/LottoNumberTest.kt b/domain/src/test/java/com/malibin/study/domain/lotto/LottoNumberTest.kt new file mode 100644 index 0000000..02ee473 --- /dev/null +++ b/domain/src/test/java/com/malibin/study/domain/lotto/LottoNumberTest.kt @@ -0,0 +1,29 @@ +package com.malibin.study.domain.lotto + +import com.google.common.truth.Truth.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +class LottoNumberTest { + + @ValueSource(ints = [0, 46]) + @ParameterizedTest + fun `1~45가 아닐 때 에러가 발생하는지에 대한 테스트`(number: Int) { + // when + val exception = kotlin.runCatching { LottoNumber.of(number) }.exceptionOrNull() + + // then + assertThat(exception).isInstanceOf(Exception::class.java) + assertThat(exception).hasMessageThat().contains("돈의 액수는 음수가 될 수 없습니다. 입력 값 : $number") + } + + @ValueSource(ints = [1, 2, 3]) + @ParameterizedTest + fun `of 함수 테스트`(number: Int) { + // when + val lottoNumber = LottoNumber.of(number) + + // then + assertThat(lottoNumber.number).isEqualTo(number) + } +} diff --git a/domain/src/test/java/com/malibin/study/domain/lotto/cal/AverageCalculatorTest.kt b/domain/src/test/java/com/malibin/study/domain/lotto/cal/AverageCalculatorTest.kt new file mode 100644 index 0000000..73b941a --- /dev/null +++ b/domain/src/test/java/com/malibin/study/domain/lotto/cal/AverageCalculatorTest.kt @@ -0,0 +1,82 @@ +package com.malibin.study.domain.lotto.cal + +import com.google.common.truth.Truth.assertThat +import com.malibin.study.domain.lotto.ticket.LottoTicket +import org.junit.jupiter.api.Test +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.CsvSource +import org.junit.jupiter.params.provider.MethodSource +import org.junit.jupiter.params.provider.ValueSource + +internal class AverageCalculatorTest { + @Test + fun `평균을 구할 수 있다`() { + // given + val integers = listOf(1, 2, 3, 4, 5) + val averageCalculator = AverageCalculator() + + // when + val actualAverage = averageCalculator.calculateAverage(integers) + + // then + assertThat(actualAverage).isEqualTo(3) + } + + @ValueSource(strings = ["Heart", "Diamond", "Clover", "Spade"]) + @ParameterizedTest + fun `value에 맞는 올바른 Suit를 찾을 수 있다`(suitValue: String) { + // given + + // when + val actualSuit = Suit.find(suitValue) + + // then + assertThat(actualSuit.value).isEqualTo(suitValue) + } + + @CsvSource(value = ["Heart,HEART", "Diamond,DIAMOND", "Clover,CLOVER", "Spade,SPADE"]) + @ParameterizedTest + fun `Enum클래스로 직접 비교하여 value에 맞는 올바른 Suit를 찾을 수 있다`(suitValue: String, expectedSuit: Suit) { + // given + + // when + val actualSuit = Suit.find(suitValue) + + // then + assertThat(actualSuit).isEqualTo(expectedSuit) + } + + @MethodSource("providesLottoTickets") + @ParameterizedTest + fun `좀 더 어려운 인자를 넣어주는 테스트`() { + // given + val ticket = LottoTicket(1, 2, 3, 4, 5, 6) + + // when + + // then + } + + companion object { + // 여러 자료형들을 아래처럼 인자로 넘길 수 있다!! + // 위의 MethodSource를 이용해서 넣어준다~! + // 하지만 가독성이 최악이니 최후의 수단이라고 생각하자 + fun providesLottoTickets(): List = listOf( + Arguments.of(LottoTicket(1, 2, 3, 4, 5, 6), 1, ""), + Arguments.of(LottoTicket(1, 2, 3, 4, 5, 6), 1, ""), + Arguments.of(LottoTicket(1, 2, 3, 4, 5, 6), 1, "") + ) + } + + enum class Suit(val id: Int, val value: String) { + HEART(0, "Heart"), + DIAMOND(1, "Diamond"), + CLOVER(2, "Clover"), + SPADE(3, "Spade"); + + companion object { + fun find(value: String): Suit = values().first() { it.value == value } + } + } +} diff --git a/domain/src/test/java/com/malibin/study/domain/lotto/result/MoneyTest.kt b/domain/src/test/java/com/malibin/study/domain/lotto/result/MoneyTest.kt new file mode 100644 index 0000000..8ee7170 --- /dev/null +++ b/domain/src/test/java/com/malibin/study/domain/lotto/result/MoneyTest.kt @@ -0,0 +1,44 @@ +package com.malibin.study.domain.lotto.result + +import com.google.common.truth.Truth.assertThat +import org.junit.jupiter.api.Test + +class MoneyTest { + @Test + fun `양수만 받는지 테스트`() { + // when + val exception = kotlin.runCatching { Money(-1) }.exceptionOrNull() + + // given + assertThat(exception).isInstanceOf(Exception::class.java) + assertThat(exception).hasMessageThat().contains("돈의 액수는 음수가 될 수 없습니다. 입력 값 : -1") + } + + @Test + fun `plus 함수가 제대로 작동하는지 테스트`() { + // given + val money1 = Money(1) + val money2 = Money(2) + val money3 = Money(3) + + // when + val resultMoney = money1 + money2 + + // then + assertThat(resultMoney.amount).isEqualTo(money3.amount) + } + + @Test + fun `minus 함수가 제대로 작동하는지 테스트`() { + // given + val money1 = Money(1) + val money2 = Money(2) + val money3 = Money(3) + + // when + val resultMoney = money3 - money2 + + // then + assertThat(resultMoney.amount).isEqualTo(money1.amount) + } +} diff --git a/domain/src/test/java/com/malibin/study/domain/lotto/ticket/LottoTicketTest.kt b/domain/src/test/java/com/malibin/study/domain/lotto/ticket/LottoTicketTest.kt new file mode 100644 index 0000000..e8b2c51 --- /dev/null +++ b/domain/src/test/java/com/malibin/study/domain/lotto/ticket/LottoTicketTest.kt @@ -0,0 +1,188 @@ +package com.malibin.study.domain.lotto.ticket + +import com.google.common.truth.Truth.assertThat +import com.malibin.study.domain.lotto.LottoNumber +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 + +internal class LottoTicketTest { + @Test + fun `로또 번호가 여섯개가 아닐 때 에러 메시지 확인 - 기본 생성자`() { + // given + val lottoNumbers = setOf(LottoNumber.of(1), LottoNumber.of(2)) + val errorMessage: String = "로또 티켓에 번호는 6개만 넣을 수 있습니다. 입력 값 : [1, 2]" + + // when + // val e: IllegalArgumentException = assertThrows { LottoTicket(lottoNumbers) } + val exception = kotlin.runCatching { LottoTicket(lottoNumbers) }.exceptionOrNull() + + // then + assertThat(exception).hasMessageThat().contains(errorMessage) + assertThat(exception).isInstanceOf(Exception::class.java) + } + + @Test + fun `로또 번호가 여섯 개일 때 잘 생성되는지 확인 - 기본 생성자`() { + // given + val lottoNumbers = setOf( + LottoNumber.of(1), + LottoNumber.of(2), + LottoNumber.of(3), + LottoNumber.of(4), + LottoNumber.of(5), + LottoNumber.of(6) + ) + + // when + val lottoTicket = LottoTicket(lottoNumbers) + + // then + assertThat(lottoTicket).isInstanceOf(LottoTicket::class.java) + } + + @Test + fun `로또 번호가 여섯개가 아닐 때 에러 메시지 확인 - 보조 생성자1`() { + // given + val n1 = 1 + val n2 = 2 + val n3 = 3 + val n4 = 4 + val errorMessage: String = "로또 티켓에 번호는 6개만 넣을 수 있습니다. 입력 값 : [1, 2, 3, 4]" + + // when + val exception = kotlin.runCatching { LottoTicket(n1, n2, n3, n4) }.exceptionOrNull() + + // then + assertThat(exception).hasMessageThat().contains(errorMessage) + assertThat(exception).isInstanceOf(Exception::class.java) + } + + @Test + fun `로또 번호가 여섯 개일 때 잘 생성되는지 확인 - 보조 생성자1`() { + // given + val n1 = 1 + val n2 = 2 + val n3 = 3 + val n4 = 4 + val n5 = 5 + val n6 = 6 + + // when + val lottoTicket = LottoTicket(n1, n2, n3, n4, n5, n6) + + // then + assertThat(lottoTicket).isInstanceOf(LottoTicket::class.java) + } + + @Test + fun `로또 번호가 여섯개가 아닐 때 에러 메시지 확인 - 보조 생성자2`() { + // given + val lottoNumbers = listOf(LottoNumber.of(1), LottoNumber.of(2)) + val errorMessage: String = "로또 티켓에 번호는 6개만 넣을 수 있습니다. 입력 값 : [1, 2]" + + // when + val exception = kotlin.runCatching { LottoTicket(lottoNumbers) }.exceptionOrNull() + + // then + assertThat(exception).hasMessageThat().contains(errorMessage) + assertThat(exception).isInstanceOf(Exception::class.java) + } + + @Test + fun `로또 번호가 여섯 개일 때 잘 생성되는지 확인 - 보조 생성자2`() { + // given + val lottoNumbers = listOf( + LottoNumber.of(1), + LottoNumber.of(2), + LottoNumber.of(3), + LottoNumber.of(4), + LottoNumber.of(5), + LottoNumber.of(6) + ) + + // when + val lottoTicket = LottoTicket(lottoNumbers) + + // then + assertThat(lottoTicket).isInstanceOf(LottoTicket::class.java) + } + + /*@MethodSource("providesLottoNumbers") + @ParameterizedTest + fun `has 함수 작동 테스트`(lottoValue: LottoNumber, expectedResult: Boolean) { + // given + val lottoNumbers = listOf(1, 2, 3, 4, 5, 6).map { LottoNumber.of(it) } + val lottoTicket = LottoTicket(lottoNumbers) + + // when + val actualResult = lottoTicket.has(lottoValue) + + // then + assertThat(actualResult).isEqualTo(expectedResult) + }*/ + + @MethodSource("providesLottoTickets") + @ParameterizedTest + fun `countMatchingNumbers 함수 작동 테스트`(otherLottoTickets: LottoTicket, expectedResult: Int) { + // given + val lottoNumbers = listOf(1, 2, 3, 4, 5, 6).map { LottoNumber.of(it) } + val lottoTicket = LottoTicket(lottoNumbers) + + // when + val actualResult = lottoTicket.countMatchingNumbers(otherLottoTickets) + + // then + assertThat(actualResult).isEqualTo(expectedResult) + } + + @Test + fun `toString 함수 작동 테스트`() { + // given + val lottoNumbers = listOf(1, 2, 3, 4, 5, 6).map { LottoNumber.of(it) } + val lottoTicket = LottoTicket(lottoNumbers) + val expectedResult = "1, 2, 3, 4, 5, 6" + + // when + val actualResult = lottoTicket.toString() + + // then + assertThat(actualResult).isEqualTo(expectedResult) + } + + companion object { + @JvmStatic + fun providesLottoNumbers(): List { + return listOf( + Arguments.of(LottoNumber.of(1), true), + Arguments.of(LottoNumber.of(2), true), + Arguments.of(LottoNumber.of(3), true), + Arguments.of(LottoNumber.of(4), true), + Arguments.of(LottoNumber.of(5), true), + Arguments.of(LottoNumber.of(6), true), + Arguments.of(LottoNumber.of(7), false) + ) + } + + @JvmStatic + fun providesLottoTickets(): List { + val lottoNumbers1 = listOf(1, 2, 3, 4, 5, 6).map { LottoNumber.of(it) } + val lottoNumbers2 = listOf(2, 3, 4, 5, 6, 7).map { LottoNumber.of(it) } + val lottoNumbers3 = listOf(3, 4, 5, 6, 7, 8).map { LottoNumber.of(it) } + val lottoNumbers4 = listOf(4, 5, 6, 7, 8, 9).map { LottoNumber.of(it) } + + val lottoTicket1 = LottoTicket(lottoNumbers1) + val lottoTicket2 = LottoTicket(lottoNumbers2) + val lottoTicket3 = LottoTicket(lottoNumbers3) + val lottoTicket4 = LottoTicket(lottoNumbers4) + + return listOf( + Arguments.of(lottoTicket1, 6), + Arguments.of(lottoTicket2, 5), + Arguments.of(lottoTicket3, 4), + Arguments.of(lottoTicket4, 3) + ) + } + } +}