refactor: migrate all tests to kotest

This commit is contained in:
Harsh Shandilya 2022-11-30 01:47:17 +05:30
parent 8eec09e832
commit eba5d64998
No known key found for this signature in database
6 changed files with 125 additions and 144 deletions

View file

@ -25,8 +25,8 @@ dependencies {
implementation(libs.dagger) implementation(libs.dagger)
implementation(libs.javax.inject) implementation(libs.javax.inject)
testImplementation(testFixtures(libs.eithernet)) testImplementation(testFixtures(libs.eithernet))
testImplementation(kotlin("test-junit")) testImplementation(libs.kotest.assertions.core)
testImplementation(libs.kotlinx.coroutines.core) testImplementation(libs.kotest.runner.junit5)
testImplementation(libs.kotlinx.serialization.json) testImplementation(libs.kotlinx.serialization.json)
testImplementation(libs.retrofit.kotlinxSerializationConverter) testImplementation(libs.retrofit.kotlinxSerializationConverter)
} }

View file

@ -11,42 +11,40 @@ import com.slack.eithernet.test.newEitherNetController
import dev.msfjarvis.claw.model.LobstersPost import dev.msfjarvis.claw.model.LobstersPost
import dev.msfjarvis.claw.model.LobstersPostDetails import dev.msfjarvis.claw.model.LobstersPostDetails
import dev.msfjarvis.claw.model.User import dev.msfjarvis.claw.model.User
import kotlin.test.Test import io.kotest.core.spec.style.FunSpec
import kotlin.test.assertEquals import io.kotest.matchers.collections.shouldHaveSize
import kotlin.test.assertIs import io.kotest.matchers.shouldBe
import kotlinx.coroutines.runBlocking import io.kotest.matchers.types.shouldBeTypeOf
class ApiTest { class ApiTest : FunSpec() {
private val wrapper = ApiWrapper(newEitherNetController()) private val wrapper = ApiWrapper(newEitherNetController())
private val api private val api
get() = wrapper.api get() = wrapper.api
@Test init {
fun `api gets correct number of items`() = runBlocking { test("api gets correct number of items") {
val posts = api.getHottestPosts(1) val posts = api.getHottestPosts(1)
assertIs<Success<List<LobstersPost>>>(posts) posts.shouldBeTypeOf<Success<List<LobstersPost>>>()
assertEquals(25, posts.value.size) posts.value shouldHaveSize 25
} }
@Test test("posts with no urls") {
fun `posts with no urls`() = runBlocking { val posts = api.getHottestPosts(1)
val posts = api.getHottestPosts(1) posts.shouldBeTypeOf<Success<List<LobstersPost>>>()
assertIs<Success<List<LobstersPost>>>(posts) val commentsOnlyPosts = posts.value.asSequence().filter { it.url.isEmpty() }.toSet()
val commentsOnlyPosts = posts.value.asSequence().filter { it.url.isEmpty() }.toSet() commentsOnlyPosts shouldHaveSize 2
assertEquals(2, commentsOnlyPosts.size) }
}
@Test test("post details with comments") {
fun `post details with comments`() = runBlocking { val postDetails = api.getPostDetails("tdfoqh")
val postDetails = api.getPostDetails("tdfoqh") postDetails.shouldBeTypeOf<Success<LobstersPostDetails>>()
assertIs<Success<LobstersPostDetails>>(postDetails) postDetails.value.comments shouldHaveSize 7
assertEquals(7, postDetails.value.comments.size) }
}
@Test test("get user details") {
fun `get user details`() = runBlocking { val user = api.getUser("msfjarvis")
val user = api.getUser("msfjarvis") user.shouldBeTypeOf<Success<User>>()
assertIs<Success<User>>(user) user.value.username shouldBe "msfjarvis"
assertEquals("msfjarvis", user.value.username) }
} }
} }

View file

@ -27,7 +27,7 @@ class ApiWrapper(controller: EitherNetController<LobstersApi>) {
init { init {
controller.enqueue(LobstersApi::getHottestPosts) { success(hottest) } controller.enqueue(LobstersApi::getHottestPosts) { success(hottest) }
controller.enqueue(LobstersApi::getNewestPosts) { success(hottest) } controller.enqueue(LobstersApi::getHottestPosts) { success(hottest) }
controller.enqueue(LobstersApi::getPostDetails) { success(postDetails) } controller.enqueue(LobstersApi::getPostDetails) { success(postDetails) }
controller.enqueue(LobstersApi::getUser) { success(user) } controller.enqueue(LobstersApi::getUser) { success(user) }
} }

View file

@ -37,6 +37,7 @@ class KotlinCommonPlugin : Plugin<Project> {
withType<Test>().configureEach { withType<Test>().configureEach {
maxParallelForks = Runtime.getRuntime().availableProcessors() * 2 maxParallelForks = Runtime.getRuntime().availableProcessors() * 2
testLogging { events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED) } testLogging { events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED) }
useJUnitPlatform()
} }
} }
} }

View file

@ -33,7 +33,8 @@ dependencies {
implementation(projects.core) implementation(projects.core)
implementation(libs.sqldelight.androidDriver) implementation(libs.sqldelight.androidDriver)
implementation(libs.sqldelight.primitiveAdapters) implementation(libs.sqldelight.primitiveAdapters)
testImplementation(libs.sqldelight.jvmDriver) testImplementation(libs.kotest.assertions.core)
testImplementation(libs.kotest.runner.junit5)
testImplementation(libs.kotlinx.coroutines.core) testImplementation(libs.kotlinx.coroutines.core)
testImplementation(kotlin("test-junit")) testImplementation(libs.sqldelight.jvmDriver)
} }

View file

@ -10,129 +10,110 @@ import app.cash.sqldelight.adapter.primitive.IntColumnAdapter
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
import dev.msfjarvis.claw.database.LobstersDatabase import dev.msfjarvis.claw.database.LobstersDatabase
import dev.msfjarvis.claw.database.model.TagsAdapter import dev.msfjarvis.claw.database.model.TagsAdapter
import kotlin.test.Test import io.kotest.core.spec.style.FunSpec
import kotlin.test.assertEquals import io.kotest.matchers.collections.shouldBeEmpty
import kotlinx.coroutines.runBlocking import io.kotest.matchers.collections.shouldHaveSize
import org.junit.Before import io.kotest.matchers.shouldBe
class SqlDelightQueriesTest { class SqlDelightQueriesTest : FunSpec() {
private lateinit var postQueries: SavedPostQueries private lateinit var postQueries: SavedPostQueries
@Before init {
fun setUp() { beforeEach {
val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
LobstersDatabase.Schema.create(driver) LobstersDatabase.Schema.create(driver)
val database = val database =
LobstersDatabase( LobstersDatabase(
driver, driver,
SavedPost.Adapter(IntColumnAdapter, TagsAdapter()), SavedPost.Adapter(IntColumnAdapter, TagsAdapter()),
) )
postQueries = database.savedPostQueries postQueries = database.savedPostQueries
}
@Test
fun selectCount() = runBlocking {
val posts = createTestData(5)
posts.forEach { postQueries.insertOrReplacePost(it) }
val postCount = postQueries.selectCount().executeAsOne()
assertEquals(5, postCount)
}
@Test
fun insertIntoDatabase() = runBlocking {
// Get 5 posts
val posts = createTestData(5)
// Insert posts into DB
posts.forEach { postQueries.insertOrReplacePost(it) }
// Check post count
val postsCount = postQueries.selectCount().executeAsOne()
assertEquals(5, postsCount)
}
@Test
fun replaceFromDatabase() = runBlocking {
// Get 1 post
val post = createTestData(1)[0]
// Insert post into DB
postQueries.insertOrReplacePost(post)
// Create a new post and try replacing it
val newPost = post.copy(submitterName = "Fake name")
postQueries.insertOrReplacePost(newPost)
// Check post count
val postsCount = postQueries.selectCount().executeAsOne()
assertEquals(1, postsCount)
// Check if post is updated
val postFromDb = postQueries.selectPost(post.shortId).executeAsOne()
assertEquals("Fake name", postFromDb.submitterName)
}
@Test
fun selectPost() = runBlocking {
// Get 1 post
val post = createTestData(1)[0]
// Insert post into DB
postQueries.insertOrReplacePost(post)
val postFromDb = postQueries.selectAllPosts().executeAsOne()
assertEquals("test_id_1", postFromDb.shortId)
}
@Test
fun selectAllPosts() = runBlocking {
// Get 5 post
val posts = createTestData(5)
// Insert posts into DB
posts.forEach { postQueries.insertOrReplacePost(it) }
val postsFromDb = postQueries.selectAllPosts().executeAsList()
// Check if all posts have correct shortId
for (i in 1..5) {
assertEquals("test_id_$i", postsFromDb[i - 1].shortId)
} }
}
@Test test("add and count posts") {
fun deletePost() = runBlocking { val posts = createTestData(5)
// Create 3 posts and insert them to DB
val posts = createTestData(3)
posts.forEach { postQueries.insertOrReplacePost(it) }
// Delete 2nd post posts.forEach { postQueries.insertOrReplacePost(it) }
postQueries.deletePost("test_id_2")
val postsFromDB = postQueries.selectAllPosts().executeAsList() val postCount = postQueries.selectCount().executeAsOne()
// Check if size is 2, and only the correct post is deleted postCount shouldBe 5
assertEquals(2, postsFromDB.size) }
assertEquals("test_id_1", postsFromDB[0].shortId)
assertEquals("test_id_3", postsFromDB[1].shortId) test("update post in database") {
} // Get 1 post
val post = createTestData(1)[0]
// Insert post into DB
postQueries.insertOrReplacePost(post)
// Create a new post and try replacing it
val newPost = post.copy(submitterName = "Fake name")
postQueries.insertOrReplacePost(newPost)
// Check post count
val postsCount = postQueries.selectCount().executeAsOne()
postsCount shouldBe 1
// Check if post is updated
val postFromDb = postQueries.selectPost(post.shortId).executeAsOne()
postFromDb.submitterName shouldBe "Fake name"
}
test("get post from db") {
// Get 1 post
val post = createTestData(1)[0]
// Insert post into DB
postQueries.insertOrReplacePost(post)
val postFromDb = postQueries.selectAllPosts().executeAsOne()
postFromDb.shortId shouldBe "test_id_1"
}
@Test test("get multiple posts from db") {
fun deleteAllPost() = runBlocking { // Get 5 post
// Create 5 posts and insert them to DB val posts = createTestData(5)
val posts = createTestData(5)
posts.forEach { postQueries.insertOrReplacePost(it) }
// Delete all posts // Insert posts into DB
postQueries.deleteAllPosts() posts.forEach { postQueries.insertOrReplacePost(it) }
val postsCount = postQueries.selectCount().executeAsOne() val postsFromDb = postQueries.selectAllPosts().executeAsList()
// Check if db is empty // Check if all posts have correct shortId
assertEquals(0, postsCount) postsFromDb.forEachIndexed { index, post -> post.shortId shouldBe "test_id_${index.inc()}" }
}
test("delete post") {
// Create 3 posts and insert them to DB
val posts = createTestData(3)
posts.forEach { postQueries.insertOrReplacePost(it) }
// Delete 2nd post
postQueries.deletePost("test_id_2")
val postsFromDB = postQueries.selectAllPosts().executeAsList()
// Check if size is 2, and only the correct post is deleted
postsFromDB shouldHaveSize 2
postsFromDB[0].shortId shouldBe "test_id_1"
postsFromDB[1].shortId shouldBe "test_id_3"
}
test("delete all posts") {
// Create 5 posts and insert them to DB
val posts = createTestData(5)
posts.forEach { postQueries.insertOrReplacePost(it) }
// Delete all posts
postQueries.deleteAllPosts()
val dbPosts = postQueries.selectAllPosts().executeAsList()
dbPosts.shouldBeEmpty()
}
} }
private fun createTestData(count: Int): ArrayList<SavedPost> { private fun createTestData(count: Int): ArrayList<SavedPost> {