From 79471b049d9dae0268c68b10839b88d19a40cedf Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sat, 19 Nov 2022 14:17:03 +0900 Subject: [PATCH 01/10] chore(test): fix ktlint format --- src/test/kotlin/study/PersonKoTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/kotlin/study/PersonKoTest.kt b/src/test/kotlin/study/PersonKoTest.kt index 4475df756b..023eef3466 100644 --- a/src/test/kotlin/study/PersonKoTest.kt +++ b/src/test/kotlin/study/PersonKoTest.kt @@ -1,8 +1,8 @@ package study import io.kotest.core.spec.style.StringSpec -import io.kotest.matchers.shouldBe import io.kotest.matchers.nulls.shouldBeNull +import io.kotest.matchers.shouldBe class PersonKoTest : StringSpec({ "이름 붙인 인자" { From bb6825f2be3cb992cc4955d1830b2abdd6ad204e Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 01:59:20 +0900 Subject: [PATCH 02/10] docs(racingcar): update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 자동차 경주 관련 기능 요구사항 추가 - 자동차 경주 관련 기능 구현사항 추가 - 자동차 경주 관련 프로그래밍 요구사항 추가 --- README.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 114c56b31e..8cd9c2a79d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ # kotlin-racingcar -###기능 요구 사항 +## 문자열 계산기 + +### 기능 요구 사항 - 사용자가 입력한 문자열 값에 따라 사칙 연산을 수행할 수 있는 계산기를 구현해야 한다. - 문자열 계산기는 사칙 연산의 계산 우선순위가 아닌 입력 값에 따라 계산 순서가 결정된다. - 예를 들어 "2 + 3 * 4 / 2"와 같은 문자열을 입력할 경우 (2 + 3) * 4 / 2 실행 결과인 10을 출력해야 한다. -###기능 구현 사항 +### 기능 구현 사항 - [X] 덧셈 연산을 할 수 있다. - [X] 뺄셈 연산을 할 수 있다. - [X] 곱셈 연산을 할 수 있다. @@ -14,5 +16,27 @@ - [X] 입력값이 사칙연산 기호가 아닌 경우 오류가 발생해야 한다. - [X] 사칙 연산을 모두 포함하는 기능을 구현해야 한다. -###프로그래밍 요구 사항 +### 프로그래밍 요구 사항 - 메서드가 너무 많은 일을 하지 않도록 분리하기 위해 노력한다. + +## 자동차 경주 + +### 기능 요구 사항 +초간단 자동차 경주 게임을 구현한다. +- 주어진 횟수 동안 N대의 자동차는 전진 또는 멈출 수 있다. +- 사용자는 몇 대의 자동차로 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. +- 전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다. +- 자동차의 상태를 화면에 출력한다. 어느 시점에 출력할 것인지에 대한 제약은 없다. + +### 기능 구현 사항 +- [ ] 사용자로부터 자동차 대수와 시도 횟수를 입력받는다. +- [ ] 경주 게임은 입력값만큼의 자동차를 생성한다. +- [ ] 경주 게임은 0에서 9 사이에서 무작위 값을 구한다. +- [ ] 자동차는 무작위 값이 4 이상일 경우 전진한다. +- [ ] 자동차는 무작위 값이 4 미만일 경우 정지한다. +- [ ] 자동차는 이동거리를 가지며, 전진할 수 있다. +- [ ] 경주 게임의 결과를 결과 화면을 통해 출력한다. + +### 프로그래밍 요구 사항 +- [ ] 모든 로직에 단위 테스트를 구현한다. +- [ ] 핵심 로직을 구현하는 코드와 UI를 담당하는 로직(InputView, ResultView)을 구분한다. From 645cad32b0e1a0d0beabed26953e5d9b65aeb1c2 Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 05:18:23 +0900 Subject: [PATCH 03/10] feat(view): add input view --- README.md | 2 +- src/main/kotlin/racingcar/InputView.kt | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/racingcar/InputView.kt diff --git a/README.md b/README.md index 8cd9c2a79d..48975471c3 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ - 자동차의 상태를 화면에 출력한다. 어느 시점에 출력할 것인지에 대한 제약은 없다. ### 기능 구현 사항 -- [ ] 사용자로부터 자동차 대수와 시도 횟수를 입력받는다. - [ ] 경주 게임은 입력값만큼의 자동차를 생성한다. +- [X] 사용자로부터 자동차 대수와 시도 횟수를 입력받는다. - [ ] 경주 게임은 0에서 9 사이에서 무작위 값을 구한다. - [ ] 자동차는 무작위 값이 4 이상일 경우 전진한다. - [ ] 자동차는 무작위 값이 4 미만일 경우 정지한다. diff --git a/src/main/kotlin/racingcar/InputView.kt b/src/main/kotlin/racingcar/InputView.kt new file mode 100644 index 0000000000..f778c57060 --- /dev/null +++ b/src/main/kotlin/racingcar/InputView.kt @@ -0,0 +1,12 @@ +package racingcar + +class InputView { + fun view(): Pair { + println("자동차 대수는 몇 대인가요?") + val numberOfCars = readLine()!!.toInt() + println("시도할 횟수는 몇 회인가요?") + val count = readLine()!!.toInt() + + return numberOfCars to count + } +} From 4a2852b9f8ad925539299754538c691610678460 Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 05:21:19 +0900 Subject: [PATCH 04/10] feat(game): add set() that create list of cars --- README.md | 2 +- src/main/kotlin/racingcar/Car.kt | 5 +++++ src/main/kotlin/racingcar/RacingGame.kt | 12 ++++++++++++ src/test/kotlin/racingcar/RacingGameTest.kt | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/racingcar/Car.kt create mode 100644 src/main/kotlin/racingcar/RacingGame.kt create mode 100644 src/test/kotlin/racingcar/RacingGameTest.kt diff --git a/README.md b/README.md index 48975471c3..8ab8ab53c7 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ - 자동차의 상태를 화면에 출력한다. 어느 시점에 출력할 것인지에 대한 제약은 없다. ### 기능 구현 사항 -- [ ] 경주 게임은 입력값만큼의 자동차를 생성한다. - [X] 사용자로부터 자동차 대수와 시도 횟수를 입력받는다. +- [X] 경주 게임은 입력값만큼의 자동차를 생성한다. - [ ] 경주 게임은 0에서 9 사이에서 무작위 값을 구한다. - [ ] 자동차는 무작위 값이 4 이상일 경우 전진한다. - [ ] 자동차는 무작위 값이 4 미만일 경우 정지한다. diff --git a/src/main/kotlin/racingcar/Car.kt b/src/main/kotlin/racingcar/Car.kt new file mode 100644 index 0000000000..3b522a5619 --- /dev/null +++ b/src/main/kotlin/racingcar/Car.kt @@ -0,0 +1,5 @@ +package racingcar + +class Car { + +} diff --git a/src/main/kotlin/racingcar/RacingGame.kt b/src/main/kotlin/racingcar/RacingGame.kt new file mode 100644 index 0000000000..dbb7537a30 --- /dev/null +++ b/src/main/kotlin/racingcar/RacingGame.kt @@ -0,0 +1,12 @@ +package racingcar + +import java.util.Collections + +class RacingGame { + var carList: List = listOf() + private set + + fun set(numberOfCars: Int) { + carList = Collections.nCopies(numberOfCars, Car()) + } +} diff --git a/src/test/kotlin/racingcar/RacingGameTest.kt b/src/test/kotlin/racingcar/RacingGameTest.kt new file mode 100644 index 0000000000..20664598b2 --- /dev/null +++ b/src/test/kotlin/racingcar/RacingGameTest.kt @@ -0,0 +1,18 @@ +package racingcar + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class RacingGameTest { + @Test + fun `경주 게임은 입력값만큼의 자동차를 생성한다`() { + // given + val racingGame = RacingGame() + + // when + racingGame.set(3) + + // then + assertThat(racingGame.carList.size).isEqualTo(3) + } +} From 52ae783a8312836aec3d4526ab27aaed07770f23 Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 06:35:03 +0900 Subject: [PATCH 05/10] feat(game): add random() that generate random number between 0 and 9 --- README.md | 2 +- src/main/kotlin/racingcar/RacingGame.kt | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ab8ab53c7..fe359bb85e 100644 --- a/README.md +++ b/README.md @@ -31,10 +31,10 @@ ### 기능 구현 사항 - [X] 사용자로부터 자동차 대수와 시도 횟수를 입력받는다. - [X] 경주 게임은 입력값만큼의 자동차를 생성한다. -- [ ] 경주 게임은 0에서 9 사이에서 무작위 값을 구한다. - [ ] 자동차는 무작위 값이 4 이상일 경우 전진한다. - [ ] 자동차는 무작위 값이 4 미만일 경우 정지한다. - [ ] 자동차는 이동거리를 가지며, 전진할 수 있다. +- [X] 경주 게임은 0에서 9 사이에서 무작위 값을 구한다. - [ ] 경주 게임의 결과를 결과 화면을 통해 출력한다. ### 프로그래밍 요구 사항 diff --git a/src/main/kotlin/racingcar/RacingGame.kt b/src/main/kotlin/racingcar/RacingGame.kt index dbb7537a30..60a0705b66 100644 --- a/src/main/kotlin/racingcar/RacingGame.kt +++ b/src/main/kotlin/racingcar/RacingGame.kt @@ -1,6 +1,7 @@ package racingcar import java.util.Collections +import kotlin.random.Random class RacingGame { var carList: List = listOf() @@ -9,4 +10,12 @@ class RacingGame { fun set(numberOfCars: Int) { carList = Collections.nCopies(numberOfCars, Car()) } + + private fun random(): Int { + return Random.nextInt(MAX_RANDOM_NUMBER) + } + + companion object { + private const val MAX_RANDOM_NUMBER: Int = 9 + } } From b85e84043076e749beff8db87075d1b6589b06f8 Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 06:36:58 +0900 Subject: [PATCH 06/10] feat(car): add move() that move when value is greater than or equal to 4 --- README.md | 5 ++--- src/main/kotlin/racingcar/Car.kt | 10 +++++++++ src/test/kotlin/racingcar/CarTest.kt | 33 ++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 src/test/kotlin/racingcar/CarTest.kt diff --git a/README.md b/README.md index fe359bb85e..1ef471a277 100644 --- a/README.md +++ b/README.md @@ -31,10 +31,9 @@ ### 기능 구현 사항 - [X] 사용자로부터 자동차 대수와 시도 횟수를 입력받는다. - [X] 경주 게임은 입력값만큼의 자동차를 생성한다. -- [ ] 자동차는 무작위 값이 4 이상일 경우 전진한다. -- [ ] 자동차는 무작위 값이 4 미만일 경우 정지한다. -- [ ] 자동차는 이동거리를 가지며, 전진할 수 있다. - [X] 경주 게임은 0에서 9 사이에서 무작위 값을 구한다. +- [X] 자동차는 무작위 값이 4 이상일 경우 전진한다. +- [X] 자동차는 무작위 값이 4 미만일 경우 정지한다. - [ ] 경주 게임의 결과를 결과 화면을 통해 출력한다. ### 프로그래밍 요구 사항 diff --git a/src/main/kotlin/racingcar/Car.kt b/src/main/kotlin/racingcar/Car.kt index 3b522a5619..310b9733db 100644 --- a/src/main/kotlin/racingcar/Car.kt +++ b/src/main/kotlin/racingcar/Car.kt @@ -1,5 +1,15 @@ package racingcar class Car { + var position: Int = DEFAULT_POSITION + private set + fun move(value: Int) { + if (value >= FORWARD_NUMBER) position++ + } + + companion object { + private const val DEFAULT_POSITION = 0 + private const val FORWARD_NUMBER = 4 + } } diff --git a/src/test/kotlin/racingcar/CarTest.kt b/src/test/kotlin/racingcar/CarTest.kt new file mode 100644 index 0000000000..69e5bc9b72 --- /dev/null +++ b/src/test/kotlin/racingcar/CarTest.kt @@ -0,0 +1,33 @@ +package racingcar + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +class CarTest { + @ParameterizedTest + @ValueSource(ints = [4, 5, 6]) + fun `자동차는 무작위 값이 4 이상일 경우 전진한다`(input: Int) { + // given + val car = Car() + + // when + car.move(input) + + // then + assertThat(car.position).isEqualTo(1) + } + + @ParameterizedTest + @ValueSource(ints = [1, 2, 3]) + fun `자동차는 무작위 값이 4 미만일 경우 정지한다`(input: Int) { + // given + val car = Car() + + // when + car.move(input) + + // then + assertThat(car.position).isEqualTo(0) + } +} From 3690e9dfbb78e6fef042ff1d5459951b8f963611 Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 06:46:27 +0900 Subject: [PATCH 07/10] refactor(game): fix set() to prevent shallow copy --- src/main/kotlin/racingcar/RacingGame.kt | 11 +++++++---- src/test/kotlin/racingcar/RacingGameTest.kt | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/racingcar/RacingGame.kt b/src/main/kotlin/racingcar/RacingGame.kt index 60a0705b66..7934dbaabc 100644 --- a/src/main/kotlin/racingcar/RacingGame.kt +++ b/src/main/kotlin/racingcar/RacingGame.kt @@ -1,14 +1,17 @@ package racingcar -import java.util.Collections import kotlin.random.Random class RacingGame { - var carList: List = listOf() + lateinit var carList: List private set - fun set(numberOfCars: Int) { - carList = Collections.nCopies(numberOfCars, Car()) + fun set(numberOfCars: Int, count: Int) { + val carMList: MutableList = mutableListOf() + for (i in 1..numberOfCars) { + carMList.add(Car()) + } + carList = carMList.toList() } private fun random(): Int { diff --git a/src/test/kotlin/racingcar/RacingGameTest.kt b/src/test/kotlin/racingcar/RacingGameTest.kt index 20664598b2..87a1d9d582 100644 --- a/src/test/kotlin/racingcar/RacingGameTest.kt +++ b/src/test/kotlin/racingcar/RacingGameTest.kt @@ -10,7 +10,7 @@ class RacingGameTest { val racingGame = RacingGame() // when - racingGame.set(3) + racingGame.set(3, 5) // then assertThat(racingGame.carList.size).isEqualTo(3) From 6c6bfb58572c89d0452953f7f9778caf3038efbb Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 06:48:07 +0900 Subject: [PATCH 08/10] feat(game): add run() that take random number for all cars --- README.md | 1 + src/main/kotlin/racingcar/RacingGame.kt | 13 +++++++++++++ src/test/kotlin/racingcar/RacingGameTest.kt | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/README.md b/README.md index 1ef471a277..530d19b735 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ - [X] 경주 게임은 0에서 9 사이에서 무작위 값을 구한다. - [X] 자동차는 무작위 값이 4 이상일 경우 전진한다. - [X] 자동차는 무작위 값이 4 미만일 경우 정지한다. +- [X] 경주 게임은 모든 자동차에 대해 무작위 값을 구하여 이동시킨다. - [ ] 경주 게임의 결과를 결과 화면을 통해 출력한다. ### 프로그래밍 요구 사항 diff --git a/src/main/kotlin/racingcar/RacingGame.kt b/src/main/kotlin/racingcar/RacingGame.kt index 7934dbaabc..8298430b32 100644 --- a/src/main/kotlin/racingcar/RacingGame.kt +++ b/src/main/kotlin/racingcar/RacingGame.kt @@ -5,6 +5,9 @@ import kotlin.random.Random class RacingGame { lateinit var carList: List private set + lateinit var randomNumberList: Array + private set + private var times: Int = 0 fun set(numberOfCars: Int, count: Int) { val carMList: MutableList = mutableListOf() @@ -12,6 +15,16 @@ class RacingGame { carMList.add(Car()) } carList = carMList.toList() + randomNumberList = Array(count) { IntArray(numberOfCars) } + } + + fun run() { + for (i in carList.indices) { + val randomNumber = random() + carList[i].move(randomNumber) + randomNumberList[times][i] = randomNumber + } + times++ } private fun random(): Int { diff --git a/src/test/kotlin/racingcar/RacingGameTest.kt b/src/test/kotlin/racingcar/RacingGameTest.kt index 87a1d9d582..05fa79f611 100644 --- a/src/test/kotlin/racingcar/RacingGameTest.kt +++ b/src/test/kotlin/racingcar/RacingGameTest.kt @@ -15,4 +15,23 @@ class RacingGameTest { // then assertThat(racingGame.carList.size).isEqualTo(3) } + + @Test + fun `경주 게임은 모든 자동차에 대해 무작위 값을 구하여 이동시킨다`() { + // given + val racingGame = RacingGame() + racingGame.set(3, 1) + + // when + racingGame.run() + + // then + val cars = racingGame.carList + val numbers = racingGame.randomNumberList[0] + + for (i in cars.indices) { + if (numbers[i] >= 4) assertThat(cars[i].position).isEqualTo(1) + else assertThat(cars[i].position).isEqualTo(0) + } + } } From f79be883ae05a1a454f7bc0008cc1bd382d81ee1 Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 10:33:45 +0900 Subject: [PATCH 09/10] feat(view): add result view --- README.md | 6 +++--- src/main/kotlin/racingcar/InputView.kt | 15 +++++++++------ src/main/kotlin/racingcar/Main.kt | 13 +++++++++++++ src/main/kotlin/racingcar/ResultView.kt | 13 +++++++++++++ 4 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/racingcar/Main.kt create mode 100644 src/main/kotlin/racingcar/ResultView.kt diff --git a/README.md b/README.md index 530d19b735..2f8723853e 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ - [X] 자동차는 무작위 값이 4 이상일 경우 전진한다. - [X] 자동차는 무작위 값이 4 미만일 경우 정지한다. - [X] 경주 게임은 모든 자동차에 대해 무작위 값을 구하여 이동시킨다. -- [ ] 경주 게임의 결과를 결과 화면을 통해 출력한다. +- [X] 경주 게임의 결과를 결과 화면을 통해 출력한다. ### 프로그래밍 요구 사항 -- [ ] 모든 로직에 단위 테스트를 구현한다. -- [ ] 핵심 로직을 구현하는 코드와 UI를 담당하는 로직(InputView, ResultView)을 구분한다. +- [X] 모든 로직에 단위 테스트를 구현한다. +- [X] 핵심 로직을 구현하는 코드와 UI를 담당하는 로직(InputView, ResultView)을 구분한다. diff --git a/src/main/kotlin/racingcar/InputView.kt b/src/main/kotlin/racingcar/InputView.kt index f778c57060..7a39670a98 100644 --- a/src/main/kotlin/racingcar/InputView.kt +++ b/src/main/kotlin/racingcar/InputView.kt @@ -1,12 +1,15 @@ package racingcar class InputView { - fun view(): Pair { - println("자동차 대수는 몇 대인가요?") - val numberOfCars = readLine()!!.toInt() - println("시도할 횟수는 몇 회인가요?") - val count = readLine()!!.toInt() + companion object { + fun view(): Pair { + println("자동차 대수는 몇 대인가요?") + val numberOfCars = readLine()!!.toInt() + println("시도할 횟수는 몇 회인가요?") + val count = readLine()!!.toInt() + println("실행 결과") - return numberOfCars to count + return numberOfCars to count + } } } diff --git a/src/main/kotlin/racingcar/Main.kt b/src/main/kotlin/racingcar/Main.kt new file mode 100644 index 0000000000..4f63fb803c --- /dev/null +++ b/src/main/kotlin/racingcar/Main.kt @@ -0,0 +1,13 @@ +package racingcar + +fun main() { + val racingGame = RacingGame() + + val (numberOfCars, count) = InputView.view() + racingGame.set(numberOfCars, count) + + for (i in 1..count) { + racingGame.run() + ResultView.view(racingGame.carList) + } +} diff --git a/src/main/kotlin/racingcar/ResultView.kt b/src/main/kotlin/racingcar/ResultView.kt new file mode 100644 index 0000000000..9c063fd6cc --- /dev/null +++ b/src/main/kotlin/racingcar/ResultView.kt @@ -0,0 +1,13 @@ +package racingcar + +class ResultView { + companion object { + fun view(cars: List) { + for (car in cars) { + if (car.position == 0) println("x") + else println("-".repeat(car.position)) + } + println() + } + } +} From 0d178d883e21630ca37cc87345265bafca648b5d Mon Sep 17 00:00:00 2001 From: ajy9844 Date: Sun, 20 Nov 2022 13:53:17 +0900 Subject: [PATCH 10/10] feat(racingcar): add feedback --- src/main/kotlin/racingcar/feedback/Car.kt | 37 ++++++++++++++++ src/main/kotlin/racingcar/feedback/Numbers.kt | 19 +++++++++ src/test/kotlin/racingcar/feedback/CarTest.kt | 42 +++++++++++++++++++ .../kotlin/racingcar/feedback/JavaTest.java | 13 ++++++ 4 files changed, 111 insertions(+) create mode 100644 src/main/kotlin/racingcar/feedback/Car.kt create mode 100644 src/main/kotlin/racingcar/feedback/Numbers.kt create mode 100644 src/test/kotlin/racingcar/feedback/CarTest.kt create mode 100644 src/test/kotlin/racingcar/feedback/JavaTest.java diff --git a/src/main/kotlin/racingcar/feedback/Car.kt b/src/main/kotlin/racingcar/feedback/Car.kt new file mode 100644 index 0000000000..f8b18e9924 --- /dev/null +++ b/src/main/kotlin/racingcar/feedback/Car.kt @@ -0,0 +1,37 @@ +package racingcar.feedback + +// 상수를 최상위 수준과 동반 객체 중 무엇으로 정의하느냐는 상수를 사용하는 클래스의 범위에 따라 다르다! +// 만약에 상수를 최상위 수준에서 선언하면 코틀린은 CarKt 이라는 클래스 파일을 생성하여 모아둔다. +// private const val ... + +object Numbers { + // 최상위 수준으로 선언했을 때의 단점은 개발자가 직접 상수 이름을 알아야 한다는 것이다. + // 그래서 object 안에 상수를 선언해서 사용하기도 한다. + const val MAXIMUM_NAME_LENGTH: Int = 5 +} + +class Car(val name: String, position: Int = DEFAULT_POSITION) { + var position: Int = position + private set // 커스텀 게터와 세터는 생성자에서 바로 사용할 수 없다! + /* + private var _position: Int = position + val position: Int + get() = _position + */ + + init { + require(name.length <= Numbers.MAXIMUM_NAME_LENGTH) { "자동차 이름은 5글자를 넘길 수 없습니다." } + } + + fun move() { + position++ + } + + companion object { + private const val DEFAULT_POSITION: Int = 0 + + @JvmField + val DEFAULT_CAR: Car = Car("") + fun of(name: String): Car = Car(name) + } +} diff --git a/src/main/kotlin/racingcar/feedback/Numbers.kt b/src/main/kotlin/racingcar/feedback/Numbers.kt new file mode 100644 index 0000000000..a611ce485a --- /dev/null +++ b/src/main/kotlin/racingcar/feedback/Numbers.kt @@ -0,0 +1,19 @@ +@file:JvmName("NumberUtils") + +package racingcar.feedback + +const val FORWARD_NUMBER: Int = 4 + +fun calculate(text: String?): Int { + require(!text.isNullOrBlank()) { "입력값이 null 또는 빈 문자열일 수 없습니다." } + run(!text.isNullOrBlank()) { "예외가 발생했습니다." } // 커스텀 예외에 대해서 직접 만들어 써보자! + // ... + return 0 +} + +fun run(value: Boolean, lazyMessage: () -> Any) { + if (!value) { + val message = lazyMessage() + throw RuntimeException(message.toString()) + } +} diff --git a/src/test/kotlin/racingcar/feedback/CarTest.kt b/src/test/kotlin/racingcar/feedback/CarTest.kt new file mode 100644 index 0000000000..a38708e7a3 --- /dev/null +++ b/src/test/kotlin/racingcar/feedback/CarTest.kt @@ -0,0 +1,42 @@ +package racingcar.feedback + +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatExceptionOfType +import org.junit.jupiter.api.Test + +class CarTest { + @Test + fun `자동차를 생성한다`() { + val car = Car("jason", 0) + assertThat(car.name).isEqualTo("jason") + assertThat(car.position).isEqualTo(0) + } + + @Test + fun `기본 인자를 활용하여 자동차를 생성한다`() { + val car = Car("jason") + assertThat(car.name).isEqualTo("jason") + assertThat(car.position).isEqualTo(0) + } + + @Test + fun `자동차의 이름이 5글자를 초과하면 오류를 발생시킨다`() { + assertThatExceptionOfType(IllegalArgumentException::class.java).isThrownBy { + Car("가나다라마바사") + } + } + + @Test + fun `팩토리 함수를 이용하여 자동차를 생성한다`() { + val car = Car.of("jason") + assertThat(car.name).isEqualTo("jason") + assertThat(car.position).isEqualTo(0) + } + + @Test + fun `정적 변수를 사용한다`() { + val car = Car.DEFAULT_CAR + assertThat(car.name).isEqualTo("") + assertThat(car.position).isEqualTo(0) + } +} diff --git a/src/test/kotlin/racingcar/feedback/JavaTest.java b/src/test/kotlin/racingcar/feedback/JavaTest.java new file mode 100644 index 0000000000..c01ce9788a --- /dev/null +++ b/src/test/kotlin/racingcar/feedback/JavaTest.java @@ -0,0 +1,13 @@ +package racingcar.feedback; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class NumberUtilsTest { + @Test + void 코틀린상수() { + assertThat(NumberUtils.FORWARD_NUMBER).isEqualTo(4); + Car defaultCar = Car.DEFAULT_CAR; + } +}