Fix test failures

This commit is contained in:
William Brawner 2024-03-27 21:28:52 -06:00
parent be0e06d77e
commit c3e566ba1c
6 changed files with 142 additions and 44 deletions

View file

@ -40,30 +40,31 @@ jobs:
path: "*/build/test-results/*/*.xml"
reporter: java-junit
fail-on-error: true
ui_tests:
runs-on: ubuntu-latest
name: Run UI Tests
needs:
- validate
steps:
- uses: actions/checkout@v3
- name: set up JDK
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Build with Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: assembleDebug assembleDebugAndroidTest
- name: Grant execute permission for flank_auth.sh
run: chmod +x flank_auth.sh
- name: Add auth for flank
env:
GCLOUD_KEY: ${{ secrets.GCLOUD_KEY }}
run: |
./flank_auth.sh
- name: Run UI tests
uses: gradle/gradle-build-action@v2
with:
arguments: runFlank
# TODO: Uncomment the UI test workflow when I actually have UI tests
# ui_tests:
# runs-on: ubuntu-latest
# name: Run UI Tests
# needs:
# - validate
# steps:
# - uses: actions/checkout@v3
# - name: set up JDK
# uses: actions/setup-java@v3
# with:
# distribution: 'zulu'
# java-version: '17'
# - name: Build with Gradle
# uses: gradle/gradle-build-action@v2
# with:
# arguments: assembleDebug assembleDebugAndroidTest
# - name: Grant execute permission for flank_auth.sh
# run: chmod +x flank_auth.sh
# - name: Add auth for flank
# env:
# GCLOUD_KEY: ${{ secrets.GCLOUD_KEY }}
# run: |
# ./flank_auth.sh
# - name: Run UI tests
# uses: gradle/gradle-build-action@v2
# with:
# arguments: runFlank

View file

@ -56,8 +56,9 @@ ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negoti
ktor-client-serialization = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }

View file

@ -29,6 +29,7 @@ kotlin {
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(libs.kotlinx.coroutines.test)
}
}

View file

@ -1,54 +1,54 @@
package com.wbrawner.twigs.shared
import com.russhwolf.settings.Settings
import com.wbrawner.twigs.shared.budget.BudgetAction
import com.wbrawner.twigs.shared.budget.BudgetReducer
import com.wbrawner.twigs.shared.budget.BudgetRepository
import com.wbrawner.twigs.shared.user.Permission
import com.wbrawner.twigs.shared.user.UserPermission
import kotlinx.datetime.toInstant
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.test.setMain
import kotlin.test.BeforeTest
import kotlin.test.DefaultAsserter.assertEquals
import kotlin.test.DefaultAsserter.assertTrue
import kotlin.test.Test
import kotlin.test.assertFalse
import kotlin.test.assertNull
import kotlin.test.assertTrue
class BudgetReducerTests {
lateinit var reducer: BudgetReducer
lateinit var dispatchedActions: MutableList<Action>
lateinit var budgetRepository: FakeBudgetRepository
lateinit var settings: Settings
@OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
@BeforeTest
fun setup() {
Dispatchers.setMain(newSingleThreadContext("main"))
dispatchedActions = mutableListOf()
budgetRepository = FakeBudgetRepository()
reducer = BudgetReducer(budgetRepository)
settings = FakeSettings()
reducer = BudgetReducer(budgetRepository, settings)
reducer.dispatch = { dispatchedActions.add(it) }
}
@Test
fun goBackWhileEditingTest() {
val state = State(editingBudget = true, selectedBudget = "test")
val newState = reducer.reduce(Action.Back, state)
val newState = reducer.reduce(Action.Back) { state }
assertFalse(newState.editingBudget)
assertEquals("selectedBudget should still be set", "test", newState.selectedBudget)
}
@Test
fun goBackWhileViewingTest() {
val state = State(selectedBudget = "test")
val newState = reducer.reduce(Action.Back, state)
assertNull(newState.selectedBudget)
}
@Test
fun createBudgetTest() {
val state = State()
val users = listOf(UserPermission("user", Permission.OWNER))
assertFalse(state.loading)
val newState = reducer.reduce(BudgetAction.CreateBudget("test", "description", users), state)
assertTrue(state.loading)
val newState = reducer.reduce(BudgetAction.CreateBudget("test", "description", users)) { state }
assertTrue(newState.loading)
assertNull(newState.selectedBudget)
}
}

View file

@ -2,11 +2,12 @@ package com.wbrawner.twigs.shared
import com.wbrawner.twigs.shared.budget.Budget
import com.wbrawner.twigs.shared.budget.BudgetRepository
import kotlinx.datetime.Instant
class FakeBudgetRepository: BudgetRepository {
val budgets = mutableListOf<Budget>()
override suspend fun getBalance(id: String): Long {
override suspend fun getBalance(id: String, from: Instant, to: Instant): Long {
return 0
}

View file

@ -0,0 +1,94 @@
package com.wbrawner.twigs.shared
import com.russhwolf.settings.Settings
class FakeSettings: Settings {
override val keys: Set<String>
get() = TODO("Not yet implemented")
override val size: Int
get() = TODO("Not yet implemented")
override fun clear() {
TODO("Not yet implemented")
}
override fun getBoolean(key: String, defaultValue: Boolean): Boolean {
TODO("Not yet implemented")
}
override fun getBooleanOrNull(key: String): Boolean? {
TODO("Not yet implemented")
}
override fun getDouble(key: String, defaultValue: Double): Double {
TODO("Not yet implemented")
}
override fun getDoubleOrNull(key: String): Double? {
TODO("Not yet implemented")
}
override fun getFloat(key: String, defaultValue: Float): Float {
TODO("Not yet implemented")
}
override fun getFloatOrNull(key: String): Float? {
TODO("Not yet implemented")
}
override fun getInt(key: String, defaultValue: Int): Int {
TODO("Not yet implemented")
}
override fun getIntOrNull(key: String): Int? {
TODO("Not yet implemented")
}
override fun getLong(key: String, defaultValue: Long): Long {
TODO("Not yet implemented")
}
override fun getLongOrNull(key: String): Long? {
TODO("Not yet implemented")
}
override fun getString(key: String, defaultValue: String): String {
TODO("Not yet implemented")
}
override fun getStringOrNull(key: String): String? {
TODO("Not yet implemented")
}
override fun hasKey(key: String): Boolean {
TODO("Not yet implemented")
}
override fun putBoolean(key: String, value: Boolean) {
TODO("Not yet implemented")
}
override fun putDouble(key: String, value: Double) {
TODO("Not yet implemented")
}
override fun putFloat(key: String, value: Float) {
TODO("Not yet implemented")
}
override fun putInt(key: String, value: Int) {
TODO("Not yet implemented")
}
override fun putLong(key: String, value: Long) {
TODO("Not yet implemented")
}
override fun putString(key: String, value: String) {
TODO("Not yet implemented")
}
override fun remove(key: String) {
TODO("Not yet implemented")
}
}