Skip to content

Commit

Permalink
test(analyzer): use kotlin mock
Browse files Browse the repository at this point in the history
  • Loading branch information
tassiluca committed Feb 27, 2024
1 parent c4b46a0 commit c4f0ac4
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.github.tassiLuca.analyzer.client

import io.github.tassiLuca.analyzer.commons.client.AppController
import io.github.tassiLuca.analyzer.lib.Analyzer
import io.github.tassiLuca.analyzer.lib.GitHubRepositoryProvider
import io.github.tassiLuca.analyzer.lib.RepositoryReport
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -13,7 +14,7 @@ import kotlin.coroutines.CoroutineContext
/** The analyzer application controller. */
class AnalyzerAppController : AppController, CoroutineScope {
private val view = AnalyzerGUI(this)
private val analyzer = Analyzer.ofGitHub()
private val analyzer = Analyzer.ofGitHub(GitHubRepositoryProvider())
private var currentComputation: Job? = null

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ interface Analyzer {

companion object {
/** Creates a new GitHub organization [Analyzer]. */
fun ofGitHub(): Analyzer = GitHubAnalyzer()
fun ofGitHub(gitHubProvider: GitHubRepositoryProvider): Analyzer = GitHubAnalyzer(gitHubProvider)
}
}

private class GitHubAnalyzer : Analyzer {

private val gitHubProvider = GitHubRepositoryProvider(GitHubService.create())
private class GitHubAnalyzer(private val gitHubProvider: GitHubRepositoryProvider) : Analyzer {

override suspend fun analyze(
organizationName: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ import retrofit2.Response
import retrofit2.awaitResponse

/** A facade for the [GitHubService]. */
class GitHubRepositoryProvider(private val gitHubService: GitHubService) {
class GitHubRepositoryProvider {

private val gitHubService: GitHubService = GitHubService.create()

/** Returns the repositories of the given [organizationName]. */
suspend fun repositoriesOf(organizationName: String): Result<List<Repository>> =
paginatedRequest { gitHubService.organizationRepositories(organizationName, it).awaitResponse() }
paginatedRequest { gitHubService.repositoriesOf(organizationName, it).awaitResponse() }

/** Returns the repositories of the given [organizationName] as [Flow]. */
fun flowingRepositoriesOf(organizationName: String): Flow<List<Repository>> =
paginatedFlowRequest { gitHubService.organizationRepositories(organizationName, it).awaitResponse() }
paginatedFlowRequest { gitHubService.repositoriesOf(organizationName, it).awaitResponse() }

/** Returns the contributors of the given [organizationName] and [repositoryName]. */
suspend fun contributorsOf(organizationName: String, repositoryName: String): Result<List<Contribution>> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface GitHubService {

/** @return the repositories of the organization with the given name. */
@GET("orgs/{organizationName}/repos")
fun organizationRepositories(
fun repositoriesOf(
@Path("organizationName") organizationName: String,
@Query("page") page: Int = 1,
): Call<List<Repository>>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package io.github.tassiLuca.analyzer.lib

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldBeEmpty
import io.kotest.matchers.collections.shouldContainAll
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.runBlocking
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`

class AnalyzerTest : FunSpec() {

private val dummiesData: Map<Repository, Pair<Set<Contribution>, Release?>> = mapOf(
Repository(0, "dse/test-1", 100, 10) to
Pair(setOf(Contribution("mrossi", 56)), Release("v0.1", "2024-02-21")),
Repository(1, "dse/test-2", 123, 198) to
Pair(setOf(Contribution("mrossi", 11), Contribution("averdi", 98)), null),
)

init {
test("Analyzer should return the correct results if given in input an existing organization") {
var incrementalResults = emptySet<RepositoryReport>()
runBlocking {
val service = successfulService()
val allResults = service.analyze("dse") {
incrementalResults = incrementalResults + it
}
allResults.isSuccess shouldBe true
allResults.getOrThrow() shouldContainAll expectedResults()
incrementalResults shouldContainAll expectedResults()
}
}

test("Analyzer should return a failure if given in input a non-existing organization") {
var incrementalResults = emptySet<RepositoryReport>()
runBlocking {
val service = failingService()
val allResults = service.analyze("dse") {
incrementalResults = incrementalResults + it
}
allResults.isFailure shouldBe true
incrementalResults.shouldBeEmpty()
}
}
}

private fun expectedResults() = dummiesData.map {
RepositoryReport(it.key.name, it.key.issues, it.key.stars, it.value.first.toList(), it.value.second)
}.toSet()

private suspend fun successfulService(): Analyzer {
val gitHubProvider = mock<GitHubRepositoryProvider>()
`when`(gitHubProvider.repositoriesOf("dse"))
.thenReturn(Result.success(dummiesData.keys.toList()))
dummiesData.forEach { (repo, data) ->
`when`(gitHubProvider.contributorsOf(repo.organization, repo.name))
.thenReturn(Result.success(data.first.toList()))
`when`(gitHubProvider.lastReleaseOf(repo.organization, repo.name))
.thenReturn(Result.success(data.second))
}
return Analyzer.ofGitHub(gitHubProvider)
}

private suspend fun failingService(): Analyzer {
val gitHubProvider = mock<GitHubRepositoryProvider>()
`when`(gitHubProvider.repositoriesOf("dse"))
.thenReturn(Result.failure(RuntimeException("404, not found")))
return Analyzer.ofGitHub(gitHubProvider)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import kotlinx.coroutines.runBlocking

class GitHubRepositoryProviderTest : FreeSpec() {

private val gitHubRepositoryProvider = GitHubRepositoryProvider(GitHubService.create())
private val gitHubRepositoryProvider = GitHubRepositoryProvider()

init {
"The github repository provider" - {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@ class AnalyzerTest extends AnyFlatSpec with Matchers with MockFactory {
Repository(1, "dse/test-2", 123, 198) -> (Seq(Contribution("mrossi", 11), Contribution("averdi", 98)), None),
)

val gitHubService: GitHubService = mock[GitHubService]
val analyzer: Analyzer = Analyzer.of(gitHubService)

"Analyzer" should "return the correct results if given in input an existing organization" in {
var incrementalResults = Set[RepositoryReport]()
Async.blocking:
configureSuccessfulService()
val analyzer = successfulService()
val allResults = analyzer.analyze("dse") { report =>
incrementalResults += report
}
Expand All @@ -34,7 +31,7 @@ class AnalyzerTest extends AnyFlatSpec with Matchers with MockFactory {
"Analyzer" should "return a failure in case the given organization doesn't exists" in {
var incrementalResults = Set[RepositoryReport]()
Async.blocking:
configureFailureService()
val analyzer = failingService()
val allResults = analyzer.analyze("non-existing") { report =>
incrementalResults += report
}
Expand All @@ -46,7 +43,8 @@ class AnalyzerTest extends AnyFlatSpec with Matchers with MockFactory {
RepositoryReport(repo.name, repo.issues, repo.stars, data._1, data._2)
}.toSet

private def configureSuccessfulService(): Unit =
private def successfulService(): Analyzer =
val gitHubService: GitHubService = mock[GitHubService]
when(gitHubService.repositoriesOf(_: String)(using _: Async)).expects("dse", *)
.returning(Right(dummiesData.keys.toSeq))
dummiesData.foreach { (repo, data) =>
Expand All @@ -55,8 +53,11 @@ class AnalyzerTest extends AnyFlatSpec with Matchers with MockFactory {
when(gitHubService.lastReleaseOf(_: String, _: String)(using _: Async)).expects(repo.organization, repo.name, *)
.returning(data._2.toRight("404, not found"))
}
Analyzer.of(gitHubService)

private def configureFailureService(): Unit =
private def failingService(): Analyzer =
val gitHubService: GitHubService = mock[GitHubService]
when(gitHubService.repositoriesOf(_: String)(using _: Async)).expects("non-existing", *)
.returning(Left("404, not found"))
Analyzer.of(gitHubService)
}

0 comments on commit c4f0ac4

Please sign in to comment.