feat(banner): 배너 카운터와 상태 계약을 추가한다
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.banner
|
||||
|
||||
object BannerCounterFormatter {
|
||||
fun format(currentIndex: Int, count: Int): String {
|
||||
return "%02d / %02d".format(currentIndex + 1, count)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.banner
|
||||
|
||||
data class BannerState(
|
||||
val displayMode: BannerDisplayMode,
|
||||
val currentIndex: Int,
|
||||
private val count: Int
|
||||
) {
|
||||
fun nextIndex(): Int = (currentIndex + 1) % count
|
||||
|
||||
fun previousIndex(): Int = (currentIndex - 1 + count) % count
|
||||
|
||||
companion object {
|
||||
fun from(count: Int, currentIndex: Int): BannerState {
|
||||
val displayMode = when (count) {
|
||||
0 -> BannerDisplayMode.Hidden
|
||||
1 -> BannerDisplayMode.Single
|
||||
else -> BannerDisplayMode.Carousel
|
||||
}
|
||||
val correctedIndex = if (currentIndex in 0 until count) currentIndex else 0
|
||||
return BannerState(
|
||||
displayMode = displayMode,
|
||||
currentIndex = correctedIndex,
|
||||
count = count
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class BannerDisplayMode {
|
||||
Hidden,
|
||||
Single,
|
||||
Carousel
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.banner
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class BannerCounterFormatterTest {
|
||||
|
||||
@Test
|
||||
fun `20개 배너의 첫 번째 아이템은 1부터 시작하는 카운터로 표시한다`() {
|
||||
val text = BannerCounterFormatter.format(currentIndex = 0, count = 20)
|
||||
|
||||
assertEquals("01 / 20", text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `20개 배너의 열 번째 아이템은 1부터 시작하는 카운터로 표시한다`() {
|
||||
val text = BannerCounterFormatter.format(currentIndex = 9, count = 20)
|
||||
|
||||
assertEquals("10 / 20", text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `1개 배너도 formatter는 양쪽을 두 자리로 표시한다`() {
|
||||
val text = BannerCounterFormatter.format(currentIndex = 0, count = 1)
|
||||
|
||||
assertEquals("01 / 01", text)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.banner
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class BannerStateTest {
|
||||
|
||||
@Test
|
||||
fun `배너 개수가 0이면 숨김 모드다`() {
|
||||
val state = BannerState.from(count = 0, currentIndex = 0)
|
||||
|
||||
assertEquals(BannerDisplayMode.Hidden, state.displayMode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `배너 개수가 1이면 단일 모드다`() {
|
||||
val state = BannerState.from(count = 1, currentIndex = 0)
|
||||
|
||||
assertEquals(BannerDisplayMode.Single, state.displayMode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `배너 개수가 2이면 캐러셀 모드다`() {
|
||||
val state = BannerState.from(count = 2, currentIndex = 0)
|
||||
|
||||
assertEquals(BannerDisplayMode.Carousel, state.displayMode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `마지막 배너의 다음 index는 첫 번째로 순환한다`() {
|
||||
val state = BannerState.from(count = 3, currentIndex = 2)
|
||||
|
||||
assertEquals(0, state.nextIndex())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `첫 번째 배너의 이전 index는 마지막으로 순환한다`() {
|
||||
val state = BannerState.from(count = 3, currentIndex = 0)
|
||||
|
||||
assertEquals(2, state.previousIndex())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `현재 index가 범위를 벗어나면 첫 번째로 보정한다`() {
|
||||
val state = BannerState.from(count = 3, currentIndex = 3)
|
||||
|
||||
assertEquals(0, state.currentIndex)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user