Skip to content

Commit

Permalink
WTA #44: Added some tests for RecalculateLatestStreakService.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacob3075 committed Oct 28, 2022
1 parent 7b855f4 commit 6732d41
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.jacob.wakatimeapp.home.domain

import arrow.core.Either
import com.jacob.wakatimeapp.core.models.DailyStats
import com.jacob.wakatimeapp.core.models.Error
import com.jacob.wakatimeapp.core.models.Stats
import com.jacob.wakatimeapp.core.models.Time
import com.jacob.wakatimeapp.home.data.network.HomePageNetworkData
import com.jacob.wakatimeapp.home.domain.models.StreakRange
import io.kotest.assertions.asClue
import io.kotest.matchers.shouldBe
import io.mockk.clearMocks
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import kotlinx.datetime.DateTimeUnit
import kotlinx.datetime.LocalDate
import kotlinx.datetime.plus

internal class RecalculateLatestStreakServiceRobot {
private lateinit var service: RecalculateLatestStreakService

private val mockHomePageNetworkData: HomePageNetworkData = mockk()

private var result: Either<Error, StreakRange>? = null

fun buildService() = apply {
clearMocks(mockHomePageNetworkData)
result = null

service = RecalculateLatestStreakService(mockHomePageNetworkData)
}

suspend fun calculate(start: LocalDate, value: Int, unit: DateTimeUnit.DateBased) = apply {
result = service.calculate(
start,
value,
unit,
)
}

fun resultShouldBe(expected: Either<Error, StreakRange>) = apply {
result.asClue {
result shouldBe expected
}
}

fun mockGetDataForRange(start: String, end: String, vararg data: Either<Error, Stats>) = apply {
coEvery { mockHomePageNetworkData.getStatsForRange(start, end) }.returnsMany(*data)
}

fun verifyGetDataForRange(start: String, end: String, count: Int = 1) = apply {
coVerify(exactly = count) { mockHomePageNetworkData.getStatsForRange(start, end) }
}

companion object {
fun createDailyStats(size: Int, days: List<Int>, end: LocalDate) = List(size) {
DailyStats(
timeSpent = if (it in days) Time.fromDecimal(1f) else Time.ZERO,
projectsWorkedOn = emptyList(),
mostUsedLanguage = "",
mostUsedEditor = "",
mostUsedOs = "",
date = end.plus(it + 1, DateTimeUnit.DAY)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.jacob.wakatimeapp.home.domain

import arrow.core.right
import com.jacob.wakatimeapp.core.models.Stats
import com.jacob.wakatimeapp.core.models.StatsRange
import com.jacob.wakatimeapp.core.models.Time
import com.jacob.wakatimeapp.home.domain.RecalculateLatestStreakServiceRobot.Companion.createDailyStats
import com.jacob.wakatimeapp.home.domain.models.StreakRange
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import kotlinx.datetime.DateTimeUnit
import kotlinx.datetime.minus
import kotlinx.datetime.toLocalDate
import org.junit.jupiter.api.Test

@OptIn(ExperimentalCoroutinesApi::class)
internal class RecalculateLatestStreakServiceTest {
private val robot = RecalculateLatestStreakServiceRobot()

@Test
internal fun `when called with duration and there is no valid streak, then return empty streak`() =
runTest {
val start = "2022-03-01"
val end = "2022-02-01"

robot.buildService()
.mockGetDataForRange(
start,
end,
Stats(
totalTime = Time.ZERO,
dailyStats = createDailyStats(30, emptyList(), end.toLocalDate()),
range = StatsRange(start.toLocalDate(), end.toLocalDate())
).right()
)
.calculate(
start = start.toLocalDate(),
value = 1,
unit = DateTimeUnit.MONTH,
)
.resultShouldBe(StreakRange.ZERO.right())
.verifyGetDataForRange(start, end)
}

@Test
internal fun `when there are none continuous stats that include end of the duration, then return latest streak`() =
runTest {
val days = listOf(0, 1, 2, 5, 6, 7, 8, 11, 12, 13)
val start = "2022-03-31"
val end = "2022-03-17"

robot.buildService()
.mockGetDataForRange(
start,
end,
Stats(
totalTime = Time.ZERO,
dailyStats = createDailyStats(
size = 14,
days = days,
end = end.toLocalDate()
),
range = StatsRange(start.toLocalDate(), end.toLocalDate())
).right()
)
.calculate(
start = start.toLocalDate(),
value = 2,
unit = DateTimeUnit.WEEK,
)
.resultShouldBe(
StreakRange(
start = start.toLocalDate().minus(2, DateTimeUnit.DAY),
start.toLocalDate()
).right()
)
.verifyGetDataForRange(start, end)
}

@Test
internal fun `when there are none continuous stats that do not include end of the duration, then return empty streak`() =
runTest {
val days = listOf(0, 1, 2, 5, 6, 7, 8, 10, 11, 12)
val start = "2022-03-31"
val end = "2022-03-17"

robot.buildService()
.mockGetDataForRange(
start,
end,
Stats(
totalTime = Time.ZERO,
dailyStats = createDailyStats(14, days, end.toLocalDate()),
range = StatsRange(start.toLocalDate(), end.toLocalDate())
).right()
)
.calculate(
start = start.toLocalDate(),
value = 2,
unit = DateTimeUnit.WEEK,
)
.resultShouldBe(StreakRange.ZERO.right())
.verifyGetDataForRange(start, end)
}
}

0 comments on commit 6732d41

Please sign in to comment.