diff --git a/src/main/kotlin/racingcar/CarName.kt b/src/main/kotlin/racingcar/CarName.kt deleted file mode 100644 index a2a8ee8a4d..0000000000 --- a/src/main/kotlin/racingcar/CarName.kt +++ /dev/null @@ -1,12 +0,0 @@ -package racingcar - -@JvmInline -value class CarName( - val value: String, -) { - init { check(this.value.length <= MAX_NAME_LENGTH) { "자동차 이름은 5 글자를 초과할 수 없습니다." } } - - companion object { - private const val MAX_NAME_LENGTH = 5 - } -} diff --git a/src/main/kotlin/racingcar/README.md b/src/main/kotlin/racingcar/README.md index a48db46e4d..82c183f963 100644 --- a/src/main/kotlin/racingcar/README.md +++ b/src/main/kotlin/racingcar/README.md @@ -13,3 +13,8 @@ - [x] 경주 결과를 출력할 때 우승자도 같이 표시한다. pobi, honux가 최종 우승했습니다. - [x] 우승자는 한명 이상이 될 수 있다. - [x] 자동차 이름은 5자를 초과할 수 없다. +- [x] 패키지를 비즈니스 로직을 가지는 domain 패키지와 화면을 그리는 view 패키지로 나눈다. +- [ ] mvc 패턴 기반으로 리팩토링한다. +- [x] 기존의 자동차를 통해 새로운 자동차를 만들 수 있다. +- [x] 자동차는 move 이후 새로운 자동차를 반환한다. +- diff --git a/src/main/kotlin/racingcar/RacingGame.kt b/src/main/kotlin/racingcar/RacingGame.kt index 330d0e18a8..3138ffc0c6 100644 --- a/src/main/kotlin/racingcar/RacingGame.kt +++ b/src/main/kotlin/racingcar/RacingGame.kt @@ -1,8 +1,8 @@ package racingcar -import racingcar.component.CarNameInputComponent -import racingcar.component.RacingResultComponent -import racingcar.component.RoundInputComponent +import racingcar.view.component.CarNameInputComponent +import racingcar.view.component.RacingResultComponent +import racingcar.view.component.RoundInputComponent object RacingGame { fun run() { diff --git a/src/main/kotlin/racingcar/Round.kt b/src/main/kotlin/racingcar/Round.kt deleted file mode 100644 index 8e937a11a4..0000000000 --- a/src/main/kotlin/racingcar/Round.kt +++ /dev/null @@ -1,9 +0,0 @@ -package racingcar - -class Round(val id: Int) { - fun start(carGroup: CarGroup): RoundResult { - carGroup.move() - val carPositions = carGroup.getPositions() - return RoundResult(carPositions = carPositions) - } -} diff --git a/src/main/kotlin/racingcar/RoundResult.kt b/src/main/kotlin/racingcar/RoundResult.kt deleted file mode 100644 index e3f635ef55..0000000000 --- a/src/main/kotlin/racingcar/RoundResult.kt +++ /dev/null @@ -1,5 +0,0 @@ -package racingcar - -data class RoundResult( - val carPositions: List -) diff --git a/src/main/kotlin/racingcar/component/CarNameComponent.kt b/src/main/kotlin/racingcar/component/CarNameComponent.kt deleted file mode 100644 index ccc3c7cc38..0000000000 --- a/src/main/kotlin/racingcar/component/CarNameComponent.kt +++ /dev/null @@ -1,11 +0,0 @@ -package racingcar.component - -import racingcar.ui.Span - -class CarNameComponent( - private val name: String, -) : Component { - override fun render() { - Span(text = "$name : ").draw() - } -} diff --git a/src/main/kotlin/racingcar/component/DistanceComponent.kt b/src/main/kotlin/racingcar/component/DistanceComponent.kt deleted file mode 100644 index 864a97b601..0000000000 --- a/src/main/kotlin/racingcar/component/DistanceComponent.kt +++ /dev/null @@ -1,12 +0,0 @@ -package racingcar.component - -import racingcar.Position -import racingcar.ui.Span - -class DistanceComponent( - private val position: Position, -) : Component { - override fun render() { - repeat(position.value) { Span(text = "-").draw() } - } -} diff --git a/src/main/kotlin/racingcar/component/RacingResultComponent.kt b/src/main/kotlin/racingcar/component/RacingResultComponent.kt deleted file mode 100644 index a1e880f64f..0000000000 --- a/src/main/kotlin/racingcar/component/RacingResultComponent.kt +++ /dev/null @@ -1,22 +0,0 @@ -package racingcar.component - -import racingcar.store.CarGroupStore -import racingcar.store.RoundStore -import racingcar.ui.Br - -class RacingResultComponent : Component { - override fun render() { - val carGroup = CarGroupStore.getState() - val rounds = RoundStore.getState() - - rounds.forEach { round -> - val roundResult = round.start(carGroup = carGroup) - RoundOrderComponent(id = round.id).render() - RoundResultComponent(roundResult = roundResult).render() - Br().draw() - Thread.sleep(1000) - } - val winners = carGroup.getWinners() - WinnerComponent(winners = winners).render() - } -} diff --git a/src/main/kotlin/racingcar/component/RoundOrderComponent.kt b/src/main/kotlin/racingcar/component/RoundOrderComponent.kt deleted file mode 100644 index 9f2b8c893f..0000000000 --- a/src/main/kotlin/racingcar/component/RoundOrderComponent.kt +++ /dev/null @@ -1,11 +0,0 @@ -package racingcar.component - -import racingcar.ui.Span - -class RoundOrderComponent( - private val id: Int, -) : Component { - override fun render() { - Span(text = "$id 라운드", block = true) - } -} diff --git a/src/main/kotlin/racingcar/component/RoundResultComponent.kt b/src/main/kotlin/racingcar/component/RoundResultComponent.kt deleted file mode 100644 index cf65a6392c..0000000000 --- a/src/main/kotlin/racingcar/component/RoundResultComponent.kt +++ /dev/null @@ -1,16 +0,0 @@ -package racingcar.component - -import racingcar.RoundResult -import racingcar.ui.Br - -class RoundResultComponent( - private val roundResult: RoundResult, -) : Component { - override fun render() { - roundResult.carPositions.forEach { carPosition -> - CarNameComponent(name = carPosition.name.value).render() - DistanceComponent(position = carPosition.position).render() - Br().draw() - } - } -} diff --git a/src/main/kotlin/racingcar/Car.kt b/src/main/kotlin/racingcar/domain/Car.kt similarity index 53% rename from src/main/kotlin/racingcar/Car.kt rename to src/main/kotlin/racingcar/domain/Car.kt index 04ca439740..8b982801c3 100644 --- a/src/main/kotlin/racingcar/Car.kt +++ b/src/main/kotlin/racingcar/domain/Car.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain class Car( val id: Int, @@ -7,9 +7,17 @@ class Car( ) { var position = position private set - fun move(movePolicy: MovePolicy) { + + constructor(car: Car) : this( + id = car.id, + name = car.name, + position = car.position, + ) + + fun move(movePolicy: MovePolicy): Car { if (movePolicy.canMove()) { this.position = this.position.forward() } + return Car(car = this) } } diff --git a/src/main/kotlin/racingcar/CarFactory.kt b/src/main/kotlin/racingcar/domain/CarFactory.kt similarity index 74% rename from src/main/kotlin/racingcar/CarFactory.kt rename to src/main/kotlin/racingcar/domain/CarFactory.kt index 0b0f1a1508..5d40412997 100644 --- a/src/main/kotlin/racingcar/CarFactory.kt +++ b/src/main/kotlin/racingcar/domain/CarFactory.kt @@ -1,6 +1,6 @@ -package racingcar +package racingcar.domain -import racingcar.dto.CarCreateDto +import racingcar.domain.dto.CarCreateDto object CarFactory { fun createMany(dtos: List): List { diff --git a/src/main/kotlin/racingcar/CarGroup.kt b/src/main/kotlin/racingcar/domain/CarGroup.kt similarity index 78% rename from src/main/kotlin/racingcar/CarGroup.kt rename to src/main/kotlin/racingcar/domain/CarGroup.kt index d53b21bb2a..0b512fd864 100644 --- a/src/main/kotlin/racingcar/CarGroup.kt +++ b/src/main/kotlin/racingcar/domain/CarGroup.kt @@ -1,8 +1,8 @@ -package racingcar +package racingcar.domain -class CarGroup(private val cars: List) { +class CarGroup(private var cars: List) { fun move() { - this.cars.forEach { car -> + this.cars = this.cars.map { car -> val oil = OilStation.generateOilRandomly() car.move(movePolicy = OilPolicy(oil = oil)) } diff --git a/src/main/kotlin/racingcar/domain/CarName.kt b/src/main/kotlin/racingcar/domain/CarName.kt new file mode 100644 index 0000000000..1f1bdc4524 --- /dev/null +++ b/src/main/kotlin/racingcar/domain/CarName.kt @@ -0,0 +1,15 @@ +package racingcar.domain + +@JvmInline +value class CarName( + val value: String, +) { + init { + require(this.value.isNullOrBlank().not()) { "자동차 이름은 비어 있을 수 없습니다." } + require(this.value.length <= MAX_NAME_LENGTH) { "자동차 이름은 5 글자를 초과할 수 없습니다." } + } + + companion object { + private const val MAX_NAME_LENGTH = 5 + } +} diff --git a/src/main/kotlin/racingcar/CarNameSplitter.kt b/src/main/kotlin/racingcar/domain/CarNameSplitter.kt similarity index 92% rename from src/main/kotlin/racingcar/CarNameSplitter.kt rename to src/main/kotlin/racingcar/domain/CarNameSplitter.kt index 613a1b5372..bebaec0e28 100644 --- a/src/main/kotlin/racingcar/CarNameSplitter.kt +++ b/src/main/kotlin/racingcar/domain/CarNameSplitter.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain object CarNameSplitter { private const val CAR_NAME_DELIMITER = "," diff --git a/src/main/kotlin/racingcar/CarPosition.kt b/src/main/kotlin/racingcar/domain/CarPosition.kt similarity index 92% rename from src/main/kotlin/racingcar/CarPosition.kt rename to src/main/kotlin/racingcar/domain/CarPosition.kt index b30a6641be..97f4d8acd2 100644 --- a/src/main/kotlin/racingcar/CarPosition.kt +++ b/src/main/kotlin/racingcar/domain/CarPosition.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain data class CarPosition private constructor( val name: CarName, diff --git a/src/main/kotlin/racingcar/MovePolicy.kt b/src/main/kotlin/racingcar/domain/MovePolicy.kt similarity index 67% rename from src/main/kotlin/racingcar/MovePolicy.kt rename to src/main/kotlin/racingcar/domain/MovePolicy.kt index 25434ca5b5..2d94fcc59a 100644 --- a/src/main/kotlin/racingcar/MovePolicy.kt +++ b/src/main/kotlin/racingcar/domain/MovePolicy.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain interface MovePolicy { fun canMove(): Boolean diff --git a/src/main/kotlin/racingcar/Oil.kt b/src/main/kotlin/racingcar/domain/Oil.kt similarity index 85% rename from src/main/kotlin/racingcar/Oil.kt rename to src/main/kotlin/racingcar/domain/Oil.kt index fb29acacb4..e062566486 100644 --- a/src/main/kotlin/racingcar/Oil.kt +++ b/src/main/kotlin/racingcar/domain/Oil.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain @JvmInline value class Oil(val amount: Int) { diff --git a/src/main/kotlin/racingcar/OilPolicy.kt b/src/main/kotlin/racingcar/domain/OilPolicy.kt similarity index 89% rename from src/main/kotlin/racingcar/OilPolicy.kt rename to src/main/kotlin/racingcar/domain/OilPolicy.kt index e10d668272..e4616263e6 100644 --- a/src/main/kotlin/racingcar/OilPolicy.kt +++ b/src/main/kotlin/racingcar/domain/OilPolicy.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain class OilPolicy( private val oil: Oil, diff --git a/src/main/kotlin/racingcar/OilStation.kt b/src/main/kotlin/racingcar/domain/OilStation.kt similarity index 86% rename from src/main/kotlin/racingcar/OilStation.kt rename to src/main/kotlin/racingcar/domain/OilStation.kt index ba5df2f9e9..8c5e9a9ffa 100644 --- a/src/main/kotlin/racingcar/OilStation.kt +++ b/src/main/kotlin/racingcar/domain/OilStation.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain object OilStation { private val RANDOM_RANGE = (0..9) diff --git a/src/main/kotlin/racingcar/Position.kt b/src/main/kotlin/racingcar/domain/Position.kt similarity index 84% rename from src/main/kotlin/racingcar/Position.kt rename to src/main/kotlin/racingcar/domain/Position.kt index ef1b9946b9..3747071c77 100644 --- a/src/main/kotlin/racingcar/Position.kt +++ b/src/main/kotlin/racingcar/domain/Position.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain @JvmInline value class Position(val value: Int) { diff --git a/src/main/kotlin/racingcar/domain/Round.kt b/src/main/kotlin/racingcar/domain/Round.kt new file mode 100644 index 0000000000..861014e49f --- /dev/null +++ b/src/main/kotlin/racingcar/domain/Round.kt @@ -0,0 +1,7 @@ +package racingcar.domain + +class Round(val id: Int) { + fun start(carGroup: CarGroup) { + carGroup.move() + } +} diff --git a/src/main/kotlin/racingcar/RoundFactory.kt b/src/main/kotlin/racingcar/domain/RoundFactory.kt similarity index 86% rename from src/main/kotlin/racingcar/RoundFactory.kt rename to src/main/kotlin/racingcar/domain/RoundFactory.kt index 9974a76562..fc2bcbcaee 100644 --- a/src/main/kotlin/racingcar/RoundFactory.kt +++ b/src/main/kotlin/racingcar/domain/RoundFactory.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain object RoundFactory { fun createMany(amount: Int): List { diff --git a/src/main/kotlin/racingcar/Winner.kt b/src/main/kotlin/racingcar/domain/Winner.kt similarity index 60% rename from src/main/kotlin/racingcar/Winner.kt rename to src/main/kotlin/racingcar/domain/Winner.kt index 81af7126a2..a3bcb35c40 100644 --- a/src/main/kotlin/racingcar/Winner.kt +++ b/src/main/kotlin/racingcar/domain/Winner.kt @@ -1,3 +1,3 @@ -package racingcar +package racingcar.domain data class Winner(val name: CarName) diff --git a/src/main/kotlin/racingcar/WinnerCalculator.kt b/src/main/kotlin/racingcar/domain/WinnerCalculator.kt similarity index 91% rename from src/main/kotlin/racingcar/WinnerCalculator.kt rename to src/main/kotlin/racingcar/domain/WinnerCalculator.kt index cbcc40fbd9..7c54c63225 100644 --- a/src/main/kotlin/racingcar/WinnerCalculator.kt +++ b/src/main/kotlin/racingcar/domain/WinnerCalculator.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain object WinnerCalculator { fun execute(cars: List): List { diff --git a/src/main/kotlin/racingcar/domain/dto/CarCreateDto.kt b/src/main/kotlin/racingcar/domain/dto/CarCreateDto.kt new file mode 100644 index 0000000000..a89b02907d --- /dev/null +++ b/src/main/kotlin/racingcar/domain/dto/CarCreateDto.kt @@ -0,0 +1,7 @@ +package racingcar.domain.dto + +import racingcar.domain.CarName + +data class CarCreateDto( + val name: CarName, +) diff --git a/src/main/kotlin/racingcar/dto/CarCreateDto.kt b/src/main/kotlin/racingcar/dto/CarCreateDto.kt deleted file mode 100644 index 74229bd654..0000000000 --- a/src/main/kotlin/racingcar/dto/CarCreateDto.kt +++ /dev/null @@ -1,7 +0,0 @@ -package racingcar.dto - -import racingcar.CarName - -data class CarCreateDto( - val name: CarName, -) diff --git a/src/main/kotlin/racingcar/store/CarGroupStore.kt b/src/main/kotlin/racingcar/store/CarGroupStore.kt deleted file mode 100644 index 99210b902a..0000000000 --- a/src/main/kotlin/racingcar/store/CarGroupStore.kt +++ /dev/null @@ -1,15 +0,0 @@ -package racingcar.store - -import racingcar.CarGroup - -object CarGroupStore : Store { - private var carGroup = CarGroup(cars = listOf()) - - override fun getState(): CarGroup { - return this.carGroup - } - - override fun setState(state: CarGroup) { - this.carGroup = state - } -} diff --git a/src/main/kotlin/racingcar/store/RoundStore.kt b/src/main/kotlin/racingcar/store/RoundStore.kt deleted file mode 100644 index 60395f1b95..0000000000 --- a/src/main/kotlin/racingcar/store/RoundStore.kt +++ /dev/null @@ -1,15 +0,0 @@ -package racingcar.store - -import racingcar.Round - -object RoundStore : Store> { - private var rounds = listOf() - - override fun getState(): List { - return rounds - } - - override fun setState(state: List) { - rounds = state - } -} diff --git a/src/main/kotlin/racingcar/store/Store.kt b/src/main/kotlin/racingcar/store/Store.kt deleted file mode 100644 index 4e377d32a2..0000000000 --- a/src/main/kotlin/racingcar/store/Store.kt +++ /dev/null @@ -1,6 +0,0 @@ -package racingcar.store - -interface Store { - fun getState(): T - fun setState(state: T) -} diff --git a/src/main/kotlin/racingcar/view/component/CarDistanceComponent.kt b/src/main/kotlin/racingcar/view/component/CarDistanceComponent.kt new file mode 100644 index 0000000000..435242c0df --- /dev/null +++ b/src/main/kotlin/racingcar/view/component/CarDistanceComponent.kt @@ -0,0 +1,12 @@ +package racingcar.view.component + +import racingcar.domain.Position +import racingcar.view.ui.Span + +class CarDistanceComponent( + private val position: Position, +) : Component { + override fun render() { + repeat(this.position.value) { Span(text = "-").draw() } + } +} diff --git a/src/main/kotlin/racingcar/view/component/CarNameComponent.kt b/src/main/kotlin/racingcar/view/component/CarNameComponent.kt new file mode 100644 index 0000000000..2d8385ab12 --- /dev/null +++ b/src/main/kotlin/racingcar/view/component/CarNameComponent.kt @@ -0,0 +1,11 @@ +package racingcar.view.component + +import racingcar.view.ui.Span + +class CarNameComponent( + private val name: String, +) : Component { + override fun render() { + Span(text = "${this.name} : ").draw() + } +} diff --git a/src/main/kotlin/racingcar/component/CarNameInputComponent.kt b/src/main/kotlin/racingcar/view/component/CarNameInputComponent.kt similarity index 72% rename from src/main/kotlin/racingcar/component/CarNameInputComponent.kt rename to src/main/kotlin/racingcar/view/component/CarNameInputComponent.kt index 77d0501c44..c03547e493 100644 --- a/src/main/kotlin/racingcar/component/CarNameInputComponent.kt +++ b/src/main/kotlin/racingcar/view/component/CarNameInputComponent.kt @@ -1,13 +1,13 @@ -package racingcar.component +package racingcar.view.component -import racingcar.CarFactory -import racingcar.CarGroup -import racingcar.CarName -import racingcar.CarNameSplitter -import racingcar.dto.CarCreateDto -import racingcar.store.CarGroupStore -import racingcar.ui.Input -import racingcar.ui.Span +import racingcar.domain.CarFactory +import racingcar.domain.CarGroup +import racingcar.domain.CarName +import racingcar.domain.CarNameSplitter +import racingcar.domain.dto.CarCreateDto +import racingcar.view.store.CarGroupStore +import racingcar.view.ui.Input +import racingcar.view.ui.Span class CarNameInputComponent : Component { private val span = Span(text = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).", block = true) diff --git a/src/main/kotlin/racingcar/view/component/CarPositionComponent.kt b/src/main/kotlin/racingcar/view/component/CarPositionComponent.kt new file mode 100644 index 0000000000..1b5ba57906 --- /dev/null +++ b/src/main/kotlin/racingcar/view/component/CarPositionComponent.kt @@ -0,0 +1,14 @@ +package racingcar.view.component + +import racingcar.domain.CarPosition +import racingcar.view.ui.Br + +class CarPositionComponent(private val carPositions: List) : Component { + override fun render() { + this.carPositions.forEach { carPosition -> + CarNameComponent(name = carPosition.name.value).render() + CarDistanceComponent(position = carPosition.position).render() + Br().draw() + } + } +} diff --git a/src/main/kotlin/racingcar/component/Component.kt b/src/main/kotlin/racingcar/view/component/Component.kt similarity index 56% rename from src/main/kotlin/racingcar/component/Component.kt rename to src/main/kotlin/racingcar/view/component/Component.kt index 664e8692f1..7529d0ffe8 100644 --- a/src/main/kotlin/racingcar/component/Component.kt +++ b/src/main/kotlin/racingcar/view/component/Component.kt @@ -1,4 +1,4 @@ -package racingcar.component +package racingcar.view.component interface Component { fun render() diff --git a/src/main/kotlin/racingcar/view/component/RacingResultComponent.kt b/src/main/kotlin/racingcar/view/component/RacingResultComponent.kt new file mode 100644 index 0000000000..465b4d9283 --- /dev/null +++ b/src/main/kotlin/racingcar/view/component/RacingResultComponent.kt @@ -0,0 +1,11 @@ +package racingcar.view.component + +import racingcar.view.container.RoundListContainer +import racingcar.view.container.WinnerContainer + +class RacingResultComponent : Component { + override fun render() { + RoundListContainer().render() + WinnerContainer().render() + } +} diff --git a/src/main/kotlin/racingcar/component/RoundInputComponent.kt b/src/main/kotlin/racingcar/view/component/RoundInputComponent.kt similarity index 72% rename from src/main/kotlin/racingcar/component/RoundInputComponent.kt rename to src/main/kotlin/racingcar/view/component/RoundInputComponent.kt index e35f7bc7b1..f393b75573 100644 --- a/src/main/kotlin/racingcar/component/RoundInputComponent.kt +++ b/src/main/kotlin/racingcar/view/component/RoundInputComponent.kt @@ -1,9 +1,9 @@ -package racingcar.component +package racingcar.view.component -import racingcar.RoundFactory -import racingcar.store.RoundStore -import racingcar.ui.Input -import racingcar.ui.Span +import racingcar.domain.RoundFactory +import racingcar.view.store.RoundStore +import racingcar.view.ui.Input +import racingcar.view.ui.Span class RoundInputComponent : Component { private val span = Span("시도할 횟수는 몇 회인가요?", block = true) diff --git a/src/main/kotlin/racingcar/view/component/RoundOrderComponent.kt b/src/main/kotlin/racingcar/view/component/RoundOrderComponent.kt new file mode 100644 index 0000000000..3a42eb0cc9 --- /dev/null +++ b/src/main/kotlin/racingcar/view/component/RoundOrderComponent.kt @@ -0,0 +1,11 @@ +package racingcar.view.component + +import racingcar.view.ui.Span + +class RoundOrderComponent( + private val id: Int, +) : Component { + override fun render() { + Span(text = "${this.id} 라운드", block = true) + } +} diff --git a/src/main/kotlin/racingcar/component/WinnerComponent.kt b/src/main/kotlin/racingcar/view/component/WinnerComponent.kt similarity index 79% rename from src/main/kotlin/racingcar/component/WinnerComponent.kt rename to src/main/kotlin/racingcar/view/component/WinnerComponent.kt index 838fccd3da..36678e1627 100644 --- a/src/main/kotlin/racingcar/component/WinnerComponent.kt +++ b/src/main/kotlin/racingcar/view/component/WinnerComponent.kt @@ -1,7 +1,7 @@ -package racingcar.component +package racingcar.view.component -import racingcar.Winner -import racingcar.ui.Span +import racingcar.domain.Winner +import racingcar.view.ui.Span class WinnerComponent(private val winners: List) : Component { private fun getWinnerText(winners: List): String { diff --git a/src/main/kotlin/racingcar/view/container/CarPositionContainer.kt b/src/main/kotlin/racingcar/view/container/CarPositionContainer.kt new file mode 100644 index 0000000000..c60e8e74e1 --- /dev/null +++ b/src/main/kotlin/racingcar/view/container/CarPositionContainer.kt @@ -0,0 +1,12 @@ +package racingcar.view.container + +import racingcar.view.component.CarPositionComponent +import racingcar.view.store.CarGroupStore + +class CarPositionContainer : Container { + override fun render() { + val carGroup = CarGroupStore.getState() + val carPositions = carGroup.getPositions() + CarPositionComponent(carPositions = carPositions).render() + } +} diff --git a/src/main/kotlin/racingcar/view/container/Container.kt b/src/main/kotlin/racingcar/view/container/Container.kt new file mode 100644 index 0000000000..d7acbbd5a6 --- /dev/null +++ b/src/main/kotlin/racingcar/view/container/Container.kt @@ -0,0 +1,5 @@ +package racingcar.view.container + +import racingcar.view.component.Component + +interface Container : Component diff --git a/src/main/kotlin/racingcar/view/container/RoundContainer.kt b/src/main/kotlin/racingcar/view/container/RoundContainer.kt new file mode 100644 index 0000000000..2edfc92de0 --- /dev/null +++ b/src/main/kotlin/racingcar/view/container/RoundContainer.kt @@ -0,0 +1,21 @@ +package racingcar.view.container + +import racingcar.domain.Round +import racingcar.view.component.RoundOrderComponent +import racingcar.view.store.CarGroupStore +import racingcar.view.ui.Br + +class RoundContainer(private val round: Round) : Container { + init { this.roundStart() } + private fun roundStart() { + val carGroup = CarGroupStore.getState() + this.round.start(carGroup = carGroup) + CarGroupStore.setState(state = carGroup) + } + override fun render() { + RoundOrderComponent(id = round.id).render() + CarPositionContainer().render() + Br().draw() + Thread.sleep(1000) + } +} diff --git a/src/main/kotlin/racingcar/view/container/RoundListContainer.kt b/src/main/kotlin/racingcar/view/container/RoundListContainer.kt new file mode 100644 index 0000000000..09941183ca --- /dev/null +++ b/src/main/kotlin/racingcar/view/container/RoundListContainer.kt @@ -0,0 +1,12 @@ +package racingcar.view.container + +import racingcar.view.store.RoundStore + +class RoundListContainer : Container { + override fun render() { + val rounds = RoundStore.getState() + rounds.forEach { + RoundContainer(round = it).render() + } + } +} diff --git a/src/main/kotlin/racingcar/view/container/WinnerContainer.kt b/src/main/kotlin/racingcar/view/container/WinnerContainer.kt new file mode 100644 index 0000000000..e06af4923d --- /dev/null +++ b/src/main/kotlin/racingcar/view/container/WinnerContainer.kt @@ -0,0 +1,13 @@ +package racingcar.view.container + +import racingcar.view.component.WinnerComponent +import racingcar.view.store.CarGroupStore + +class WinnerContainer : Container { + + override fun render() { + val carGroup = CarGroupStore.getState() + val winners = carGroup.getWinners() + WinnerComponent(winners = winners).render() + } +} diff --git a/src/main/kotlin/racingcar/view/store/CarGroupStore.kt b/src/main/kotlin/racingcar/view/store/CarGroupStore.kt new file mode 100644 index 0000000000..03ed25d9d9 --- /dev/null +++ b/src/main/kotlin/racingcar/view/store/CarGroupStore.kt @@ -0,0 +1,5 @@ +package racingcar.view.store + +import racingcar.domain.CarGroup + +object CarGroupStore : Store(initialState = CarGroup(cars = listOf())) diff --git a/src/main/kotlin/racingcar/view/store/RoundStore.kt b/src/main/kotlin/racingcar/view/store/RoundStore.kt new file mode 100644 index 0000000000..d8a7f82087 --- /dev/null +++ b/src/main/kotlin/racingcar/view/store/RoundStore.kt @@ -0,0 +1,5 @@ +package racingcar.view.store + +import racingcar.domain.Round + +object RoundStore : Store>(initialState = listOf()) diff --git a/src/main/kotlin/racingcar/view/store/Store.kt b/src/main/kotlin/racingcar/view/store/Store.kt new file mode 100644 index 0000000000..d5a7901ecc --- /dev/null +++ b/src/main/kotlin/racingcar/view/store/Store.kt @@ -0,0 +1,21 @@ +package racingcar.view.store + +typealias Listener = () -> Unit +typealias UnSubscribe = () -> Unit + +open class Store(initialState: T) { + private var state = initialState + private val listeners = HashSet() + + fun getState(): T { + return this.state + } + fun setState(state: T) { + this.state = state + this.listeners.forEach { listener -> listener() } + } + fun subscribe(listener: Listener): UnSubscribe { + listeners.add(listener) + return { listeners.remove(listener) } + } +} diff --git a/src/main/kotlin/racingcar/ui/Br.kt b/src/main/kotlin/racingcar/view/ui/Br.kt similarity index 67% rename from src/main/kotlin/racingcar/ui/Br.kt rename to src/main/kotlin/racingcar/view/ui/Br.kt index fec7c3013d..953fc2a389 100644 --- a/src/main/kotlin/racingcar/ui/Br.kt +++ b/src/main/kotlin/racingcar/view/ui/Br.kt @@ -1,4 +1,4 @@ -package racingcar.ui +package racingcar.view.ui class Br : UI { override fun draw() = println() diff --git a/src/main/kotlin/racingcar/ui/Input.kt b/src/main/kotlin/racingcar/view/ui/Input.kt similarity index 92% rename from src/main/kotlin/racingcar/ui/Input.kt rename to src/main/kotlin/racingcar/view/ui/Input.kt index 33c4953142..d2c0683427 100644 --- a/src/main/kotlin/racingcar/ui/Input.kt +++ b/src/main/kotlin/racingcar/view/ui/Input.kt @@ -1,4 +1,4 @@ -package racingcar.ui +package racingcar.view.ui class Input(onCommand: (value: String) -> Unit = {}) : UI { var onCommand = onCommand diff --git a/src/main/kotlin/racingcar/ui/Span.kt b/src/main/kotlin/racingcar/view/ui/Span.kt similarity index 89% rename from src/main/kotlin/racingcar/ui/Span.kt rename to src/main/kotlin/racingcar/view/ui/Span.kt index 81c2bdf36f..460588d043 100644 --- a/src/main/kotlin/racingcar/ui/Span.kt +++ b/src/main/kotlin/racingcar/view/ui/Span.kt @@ -1,4 +1,4 @@ -package racingcar.ui +package racingcar.view.ui class Span( private val text: String, diff --git a/src/main/kotlin/racingcar/ui/UI.kt b/src/main/kotlin/racingcar/view/ui/UI.kt similarity index 55% rename from src/main/kotlin/racingcar/ui/UI.kt rename to src/main/kotlin/racingcar/view/ui/UI.kt index 9825c93886..e44c1ce186 100644 --- a/src/main/kotlin/racingcar/ui/UI.kt +++ b/src/main/kotlin/racingcar/view/ui/UI.kt @@ -1,4 +1,4 @@ -package racingcar.ui +package racingcar.view.ui interface UI { fun draw() diff --git a/src/test/kotlin/racingcar/CarTest.kt b/src/test/kotlin/racingcar/CarTest.kt deleted file mode 100644 index 2a386fcc9e..0000000000 --- a/src/test/kotlin/racingcar/CarTest.kt +++ /dev/null @@ -1,32 +0,0 @@ -package racingcar - -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.shouldBe - -class CarTest : FunSpec({ - context("자동차 주행 테스트") { - context("연료가 충분하면") { - test("자동차는 움직일 수 있다.") { - // given - val sut = Car(id = 1, name = CarName(value = "동구")) - val 충분한_연료 = Oil(amount = 4) - // when - sut.move(movePolicy = OilPolicy(oil = 충분한_연료)) - // - sut.position shouldBe Position(value = 1) - } - } - - context("연료가 부족하면") { - test("자동차는 움직일 수 없다.") { - // given - val sut = Car(id = 1, name = CarName(value = "동구")) - val 부족한_연료 = Oil(amount = 3) - // when - sut.move(movePolicy = OilPolicy(oil = 부족한_연료)) - // then - sut.position shouldBe Position(value = 0) - } - } - } -}) diff --git a/src/test/kotlin/racingcar/RoundTest.kt b/src/test/kotlin/racingcar/RoundTest.kt deleted file mode 100644 index 1000e4d940..0000000000 --- a/src/test/kotlin/racingcar/RoundTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -package racingcar - -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.collections.shouldHaveSize -import racingcar.fixture.CarCreateDtoFixture - -class RoundTest : FunSpec({ - context("라운드 시작 테스트") { - context("라운드 시작이 완료되면") { - test("라운드 결과를 반환한다.") { - // given - val sut = Round(id = 1) - val cars = CarFactory.createMany(dtos = CarCreateDtoFixture.getMany(amount = 3)) - // when - val actual = sut.start(carGroup = CarGroup(cars = cars)) - // then - actual.carPositions shouldHaveSize 3 - } - } - } -}) diff --git a/src/test/kotlin/racingcar/CarFactoryTest.kt b/src/test/kotlin/racingcar/domain/CarFactoryTest.kt similarity index 89% rename from src/test/kotlin/racingcar/CarFactoryTest.kt rename to src/test/kotlin/racingcar/domain/CarFactoryTest.kt index 1c556483e4..d195d734c8 100644 --- a/src/test/kotlin/racingcar/CarFactoryTest.kt +++ b/src/test/kotlin/racingcar/domain/CarFactoryTest.kt @@ -1,8 +1,8 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldHaveSize -import racingcar.fixture.CarCreateDtoFixture +import racingcar.domain.fixture.CarCreateDtoFixture class CarFactoryTest : FunSpec({ val sut = CarFactory diff --git a/src/test/kotlin/racingcar/CarGroupTest.kt b/src/test/kotlin/racingcar/domain/CarGroupTest.kt similarity index 98% rename from src/test/kotlin/racingcar/CarGroupTest.kt rename to src/test/kotlin/racingcar/domain/CarGroupTest.kt index 236183489f..2d2a9c4712 100644 --- a/src/test/kotlin/racingcar/CarGroupTest.kt +++ b/src/test/kotlin/racingcar/domain/CarGroupTest.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldContainExactly diff --git a/src/test/kotlin/racingcar/CarNameSplitterTest.kt b/src/test/kotlin/racingcar/domain/CarNameSplitterTest.kt similarity index 97% rename from src/test/kotlin/racingcar/CarNameSplitterTest.kt rename to src/test/kotlin/racingcar/domain/CarNameSplitterTest.kt index 2e92e48786..006b114565 100644 --- a/src/test/kotlin/racingcar/CarNameSplitterTest.kt +++ b/src/test/kotlin/racingcar/domain/CarNameSplitterTest.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldContainExactly diff --git a/src/test/kotlin/racingcar/CarNameTest.kt b/src/test/kotlin/racingcar/domain/CarNameTest.kt similarity index 53% rename from src/test/kotlin/racingcar/CarNameTest.kt rename to src/test/kotlin/racingcar/domain/CarNameTest.kt index e1614f6cac..0bbc2c149e 100644 --- a/src/test/kotlin/racingcar/CarNameTest.kt +++ b/src/test/kotlin/racingcar/domain/CarNameTest.kt @@ -1,8 +1,9 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import org.junit.jupiter.api.assertThrows +import java.lang.IllegalArgumentException class CarNameTest : FunSpec({ context("자동차 이름 생성 테스트") { @@ -14,10 +15,17 @@ class CarNameTest : FunSpec({ } context("5 글자 초과의 이름이면") { - test("IllegalStateException 이 발생한다.") { - val exception = assertThrows { CarName(value = "relkimm") } + test("IllegalArgumentException 이 발생한다.") { + val exception = assertThrows { CarName(value = "relkimm") } exception.message shouldBe "자동차 이름은 5 글자를 초과할 수 없습니다." } } + + context("이름이 비어 있으면") { + test("IllegalArgumentException 이 발생한다.") { + val exception = assertThrows { CarName(value = "") } + exception.message shouldBe "자동차 이름은 비어 있을 수 없습니다." + } + } } }) diff --git a/src/test/kotlin/racingcar/domain/CarTest.kt b/src/test/kotlin/racingcar/domain/CarTest.kt new file mode 100644 index 0000000000..182c008177 --- /dev/null +++ b/src/test/kotlin/racingcar/domain/CarTest.kt @@ -0,0 +1,66 @@ +package racingcar.domain + +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe + +class CarTest : FunSpec({ + context("자동차 주행 테스트") { + context("연료가 충분하면") { + test("자동차는 움직일 수 있다.") { + // given + val sut = Car(id = 1, name = CarName(value = "동구")) + val 충분한_연료 = Oil(amount = 4) + // when + sut.move(movePolicy = OilPolicy(oil = 충분한_연료)) + // + sut.position shouldBe Position(value = 1) + } + } + + context("연료가 부족하면") { + test("자동차는 움직일 수 없다.") { + // given + val sut = Car(id = 1, name = CarName(value = "동구")) + val 부족한_연료 = Oil(amount = 3) + // when + sut.move(movePolicy = OilPolicy(oil = 부족한_연료)) + // then + sut.position shouldBe Position(value = 0) + } + } + + context("주행하고 나면") { + test("주행한 위치를 가지는 새로운 자동차를 반환할 수 있다.") { + // given + val car = Car(id = 1, name = CarName(value = "동구")) + val 충분한_연료 = Oil(amount = 6) + // when + val actual = car.move(movePolicy = OilPolicy(oil = 충분한_연료)) + // then + actual shouldNotBe car + with(actual) { + this.id shouldBe car.id + this.name shouldBe car.name + this.position shouldBe Position(value = 1) + } + } + } + } + + context("자동차 생성 테스트") { + test("기존의 자동차를 통해 새로운 자동차를 생성할 수 있다.") { + // given + val car = Car(id = 1, name = CarName(value = "동구"), position = Position(value = 3)) + // when + val actual = Car(car = car) + // then + actual shouldNotBe car + with(actual) { + this.id shouldBe car.id + this.name shouldBe car.name + this.position shouldBe car.position + } + } + } +}) diff --git a/src/test/kotlin/racingcar/OilPolicyTest.kt b/src/test/kotlin/racingcar/domain/OilPolicyTest.kt similarity index 96% rename from src/test/kotlin/racingcar/OilPolicyTest.kt rename to src/test/kotlin/racingcar/domain/OilPolicyTest.kt index a82f89162c..3af08cf487 100644 --- a/src/test/kotlin/racingcar/OilPolicyTest.kt +++ b/src/test/kotlin/racingcar/domain/OilPolicyTest.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe diff --git a/src/test/kotlin/racingcar/OilStationTest.kt b/src/test/kotlin/racingcar/domain/OilStationTest.kt similarity index 93% rename from src/test/kotlin/racingcar/OilStationTest.kt rename to src/test/kotlin/racingcar/domain/OilStationTest.kt index f61ef9ed24..483d182989 100644 --- a/src/test/kotlin/racingcar/OilStationTest.kt +++ b/src/test/kotlin/racingcar/domain/OilStationTest.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.ints.shouldBeInRange diff --git a/src/test/kotlin/racingcar/OilTest.kt b/src/test/kotlin/racingcar/domain/OilTest.kt similarity index 97% rename from src/test/kotlin/racingcar/OilTest.kt rename to src/test/kotlin/racingcar/domain/OilTest.kt index 208928088d..22f1344907 100644 --- a/src/test/kotlin/racingcar/OilTest.kt +++ b/src/test/kotlin/racingcar/domain/OilTest.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe diff --git a/src/test/kotlin/racingcar/PositionTest.kt b/src/test/kotlin/racingcar/domain/PositionTest.kt similarity index 93% rename from src/test/kotlin/racingcar/PositionTest.kt rename to src/test/kotlin/racingcar/domain/PositionTest.kt index cad860876b..4d19fa7ada 100644 --- a/src/test/kotlin/racingcar/PositionTest.kt +++ b/src/test/kotlin/racingcar/domain/PositionTest.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe diff --git a/src/test/kotlin/racingcar/RoundFactoryTest.kt b/src/test/kotlin/racingcar/domain/RoundFactoryTest.kt similarity index 95% rename from src/test/kotlin/racingcar/RoundFactoryTest.kt rename to src/test/kotlin/racingcar/domain/RoundFactoryTest.kt index 73325213f2..3bee36ac51 100644 --- a/src/test/kotlin/racingcar/RoundFactoryTest.kt +++ b/src/test/kotlin/racingcar/domain/RoundFactoryTest.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldHaveSize diff --git a/src/test/kotlin/racingcar/WinnerCalculatorTest.kt b/src/test/kotlin/racingcar/domain/WinnerCalculatorTest.kt similarity index 98% rename from src/test/kotlin/racingcar/WinnerCalculatorTest.kt rename to src/test/kotlin/racingcar/domain/WinnerCalculatorTest.kt index 808a94d45b..b64ce69eb3 100644 --- a/src/test/kotlin/racingcar/WinnerCalculatorTest.kt +++ b/src/test/kotlin/racingcar/domain/WinnerCalculatorTest.kt @@ -1,4 +1,4 @@ -package racingcar +package racingcar.domain import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldContainExactly diff --git a/src/test/kotlin/racingcar/fixture/CarCreateDtoFixture.kt b/src/test/kotlin/racingcar/domain/fixture/CarCreateDtoFixture.kt similarity index 61% rename from src/test/kotlin/racingcar/fixture/CarCreateDtoFixture.kt rename to src/test/kotlin/racingcar/domain/fixture/CarCreateDtoFixture.kt index 85f2df0fb9..4ce5c3cdc5 100644 --- a/src/test/kotlin/racingcar/fixture/CarCreateDtoFixture.kt +++ b/src/test/kotlin/racingcar/domain/fixture/CarCreateDtoFixture.kt @@ -1,7 +1,7 @@ -package racingcar.fixture +package racingcar.domain.fixture -import racingcar.CarName -import racingcar.dto.CarCreateDto +import racingcar.domain.CarName +import racingcar.domain.dto.CarCreateDto object CarCreateDtoFixture { fun getMany(amount: Int): List { diff --git a/src/test/kotlin/racingcar/component/CarNameInputComponentTest.kt b/src/test/kotlin/racingcar/view/component/CarNameInputComponentTest.kt similarity index 89% rename from src/test/kotlin/racingcar/component/CarNameInputComponentTest.kt rename to src/test/kotlin/racingcar/view/component/CarNameInputComponentTest.kt index 3e6212cb83..cf3ab18256 100644 --- a/src/test/kotlin/racingcar/component/CarNameInputComponentTest.kt +++ b/src/test/kotlin/racingcar/view/component/CarNameInputComponentTest.kt @@ -1,8 +1,8 @@ -package racingcar.component +package racingcar.view.component import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldHaveSize -import racingcar.store.CarGroupStore +import racingcar.view.store.CarGroupStore class CarNameInputComponentTest : FunSpec({ context("입력 이벤트 리스너 테스트") { diff --git a/src/test/kotlin/racingcar/component/InputTest.kt b/src/test/kotlin/racingcar/view/component/InputTest.kt similarity index 91% rename from src/test/kotlin/racingcar/component/InputTest.kt rename to src/test/kotlin/racingcar/view/component/InputTest.kt index e72ce3a933..d3f033f8cd 100644 --- a/src/test/kotlin/racingcar/component/InputTest.kt +++ b/src/test/kotlin/racingcar/view/component/InputTest.kt @@ -1,8 +1,8 @@ -package racingcar.component +package racingcar.view.component import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe -import racingcar.ui.Input +import racingcar.view.ui.Input class InputTest : FunSpec({ context("Input") { diff --git a/src/test/kotlin/racingcar/component/RoundInputComponentTest.kt b/src/test/kotlin/racingcar/view/component/RoundInputComponentTest.kt similarity index 89% rename from src/test/kotlin/racingcar/component/RoundInputComponentTest.kt rename to src/test/kotlin/racingcar/view/component/RoundInputComponentTest.kt index 4b94a82979..6c3d93b6f9 100644 --- a/src/test/kotlin/racingcar/component/RoundInputComponentTest.kt +++ b/src/test/kotlin/racingcar/view/component/RoundInputComponentTest.kt @@ -1,8 +1,8 @@ -package racingcar.component +package racingcar.view.component import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldHaveSize -import racingcar.store.RoundStore +import racingcar.view.store.RoundStore class RoundInputComponentTest : FunSpec({ context("커멘드 이벤트 리스너 테스트") { diff --git a/src/test/kotlin/racingcar/store/CarGroupStoreTest.kt b/src/test/kotlin/racingcar/view/store/CarGroupStoreTest.kt similarity index 79% rename from src/test/kotlin/racingcar/store/CarGroupStoreTest.kt rename to src/test/kotlin/racingcar/view/store/CarGroupStoreTest.kt index 6c67f90736..ddb77bb0f7 100644 --- a/src/test/kotlin/racingcar/store/CarGroupStoreTest.kt +++ b/src/test/kotlin/racingcar/view/store/CarGroupStoreTest.kt @@ -1,11 +1,11 @@ -package racingcar.store +package racingcar.view.store import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe -import racingcar.Car -import racingcar.CarGroup -import racingcar.CarName -import racingcar.Position +import racingcar.domain.Car +import racingcar.domain.CarGroup +import racingcar.domain.CarName +import racingcar.domain.Position class CarGroupStoreTest : FunSpec({ context("자동차 그룹 저장 및 조회 테스트") { diff --git a/src/test/kotlin/racingcar/store/RoundStoreTest.kt b/src/test/kotlin/racingcar/view/store/RoundStoreTest.kt similarity index 89% rename from src/test/kotlin/racingcar/store/RoundStoreTest.kt rename to src/test/kotlin/racingcar/view/store/RoundStoreTest.kt index 1c8c693fa9..b270b3088c 100644 --- a/src/test/kotlin/racingcar/store/RoundStoreTest.kt +++ b/src/test/kotlin/racingcar/view/store/RoundStoreTest.kt @@ -1,8 +1,8 @@ -package racingcar.store +package racingcar.view.store import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldContainExactly -import racingcar.RoundFactory +import racingcar.domain.RoundFactory class RoundStoreTest : FunSpec({ context("라운드 저장 및 조회 테스트") { diff --git a/src/test/kotlin/racingcar/view/store/StoreTest.kt b/src/test/kotlin/racingcar/view/store/StoreTest.kt new file mode 100644 index 0000000000..3df12fb562 --- /dev/null +++ b/src/test/kotlin/racingcar/view/store/StoreTest.kt @@ -0,0 +1,35 @@ +package racingcar.view.store + +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import racingcar.domain.CarName + +class StoreTest : FunSpec({ + context("getState 메서드는") { + test("저장하고 있는 state 를 반환한다.") { + // given + CarNameStore.setState(CarName(value = "재혁")) + // when + val actual = CarNameStore.getState() + // then + actual shouldBe CarName(value = "재혁") + } + } + + context("setState 메서드는") { + test("저장하고 있는 state 를 변경하고 listener 에게 변경을 알린다.") { + // given + val listener = { + val state = CarNameStore.getState() + state shouldBe CarName(value = "상근") + } + CarNameStore.subscribe(listener) + // when + CarNameStore.setState(CarName(value = "상근")) + // then + CarNameStore.getState() shouldBe CarName(value = "상근") + } + } +}) + +object CarNameStore : Store(initialState = CarName(value = "동구"))