Skip to content

Commit

Permalink
Finish up SpeziViews
Browse files Browse the repository at this point in the history
  • Loading branch information
pauljohanneskraft committed Nov 11, 2024
1 parent 37159b8 commit f3f516b
Show file tree
Hide file tree
Showing 49 changed files with 533 additions and 153 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class UserProfileTest {
fun testUserProfile() {
userProfile {
assertUserInitialsExists(true, "PS")
assertUserInitialsExists(false, "LS")
assertUserInitialsExists(true, "LS")
waitUntilUserInitialsDisappear("LS")
assertImageExists()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import edu.stanford.spezi.core.design.component.StringResource
import edu.stanford.spezi.core.design.views.personalInfo.PersonNameComponents
import edu.stanford.spezi.core.design.views.personalInfo.fields.NameFieldRow
import edu.stanford.spezi.core.design.validation.personalInfo.PersonNameComponents
import edu.stanford.spezi.core.design.validation.personalInfo.fields.NameFieldRow

@Composable
fun NameFieldsTestComposable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import edu.stanford.spezi.core.design.component.ImageResource
import edu.stanford.spezi.core.design.views.personalInfo.PersonNameComponents
import edu.stanford.spezi.core.design.views.personalInfo.UserProfileComposable
import edu.stanford.spezi.core.design.validation.personalInfo.PersonNameComponents
import edu.stanford.spezi.core.design.validation.personalInfo.UserProfileComposable
import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.seconds

@Composable
fun UserProfileTestComposable() {
Expand All @@ -20,8 +22,10 @@ fun UserProfileTestComposable() {
)
UserProfileComposable(
Modifier.height(200.dp),
PersonNameComponents(givenName = "Leland", familyName = "Stanford"),
ImageResource.Vector(Icons.Default.Person)
)
PersonNameComponents(givenName = "Leland", familyName = "Stanford")
) {
delay(0.5.seconds)
return@UserProfileComposable ImageResource.Vector(Icons.Default.Person)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package edu.stanford.spezi.core.design.personalInfo.simulators
import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.onAllNodesWithContentDescription
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithText

class UserProfileTestSimulator(
Expand All @@ -19,6 +20,13 @@ class UserProfileTestSimulator(
}
}

fun waitUntilUserInitialsDisappear(text: String, timeoutMillis: Long = 1_000) {
composeTestRule.waitUntil(timeoutMillis = timeoutMillis) {
composeTestRule.onAllNodesWithText(text)
.fetchSemanticsNodes().isEmpty()
}
}

fun assertImageExists() {
composeTestRule
.onAllNodesWithContentDescription("")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package edu.stanford.spezi.core.design.views
package edu.stanford.spezi.core.design.validation

import androidx.compose.ui.test.junit4.createComposeRule
import edu.stanford.spezi.core.design.views.composables.FocusValidationRules
import edu.stanford.spezi.core.design.views.simulators.FocusValidationRulesSimulator
import edu.stanford.spezi.core.design.validation.composables.FocusValidationRules
import edu.stanford.spezi.core.design.validation.simulators.FocusValidationRulesSimulator
import org.junit.Before
import org.junit.Rule
import org.junit.Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package edu.stanford.spezi.core.design.validation.composables

import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import edu.stanford.spezi.core.design.component.StringResource
import edu.stanford.spezi.core.design.validation.validation.Validate
import edu.stanford.spezi.core.design.validation.validation.ValidationRule
import edu.stanford.spezi.core.design.validation.validation.asciiLettersOnly
import edu.stanford.spezi.core.design.validation.validation.mediumPassword
import edu.stanford.spezi.core.design.validation.validation.minimalEmail
import edu.stanford.spezi.core.design.validation.validation.minimalPassword
import edu.stanford.spezi.core.design.validation.validation.nonEmpty
import edu.stanford.spezi.core.design.validation.validation.strongPassword
import edu.stanford.spezi.core.design.validation.validation.unicodeLettersOnly
import edu.stanford.spezi.core.design.validation.validation.views.VerifiableTextField

@Composable
fun DefaultValidationRules() {
val input = remember { mutableStateOf("") }
val rules = remember {
listOf(
ValidationRule.nonEmpty,
ValidationRule.unicodeLettersOnly,
ValidationRule.asciiLettersOnly,
ValidationRule.minimalEmail,
ValidationRule.minimalPassword,
ValidationRule.mediumPassword,
ValidationRule.strongPassword
)
}
Validate(input.value, rules) {
VerifiableTextField(
StringResource("Field"),
text = input
)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package edu.stanford.spezi.core.design.views.composables
package edu.stanford.spezi.core.design.validation.composables

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -9,13 +9,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import edu.stanford.spezi.core.design.component.StringResource
import edu.stanford.spezi.core.design.views.validation.Validate
import edu.stanford.spezi.core.design.views.validation.ValidationRule
import edu.stanford.spezi.core.design.views.validation.minimalPassword
import edu.stanford.spezi.core.design.views.validation.nonEmpty
import edu.stanford.spezi.core.design.views.validation.state.ReceiveValidation
import edu.stanford.spezi.core.design.views.validation.state.ValidationContext
import edu.stanford.spezi.core.design.views.validation.views.VerifiableTextField
import edu.stanford.spezi.core.design.validation.validation.Validate
import edu.stanford.spezi.core.design.validation.validation.ValidationRule
import edu.stanford.spezi.core.design.validation.validation.minimalPassword
import edu.stanford.spezi.core.design.validation.validation.nonEmpty
import edu.stanford.spezi.core.design.validation.validation.state.ReceiveValidation
import edu.stanford.spezi.core.design.validation.validation.state.ValidationContext
import edu.stanford.spezi.core.design.validation.validation.views.VerifiableTextField

enum class Field {
INPUT, NON_EMPTY_INPUT
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package edu.stanford.spezi.core.design.views.simulators
package edu.stanford.spezi.core.design.validation.simulators

import androidx.compose.ui.test.assertHasClickAction
import androidx.compose.ui.test.junit4.ComposeTestRule
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package edu.stanford.spezi.core.design.views

import androidx.compose.ui.test.junit4.createComposeRule
import edu.stanford.spezi.core.design.views.composables.MarkdownTestComposable
import edu.stanford.spezi.core.design.views.simulators.MarkdownTestSimulator
import org.junit.Before
import org.junit.Rule
import org.junit.Test

class MarkdownTest {

@get:Rule
val composeTestRule = createComposeRule()

@Before
fun init() {
composeTestRule.setContent {
MarkdownTestComposable()
}
}

@Test
fun testMarkdown() {
markdown {
waitForTextToAppear(
"This is a markdown example.",
timeoutMillis = 100
)
assertTextExists(
"This is a markdown example taking half a second to load.",
exists = false
)
waitForTextToAppear(
"This is a markdown example taking half a second to load.",
)
}
}

private fun markdown(block: MarkdownTestSimulator.() -> Unit) {
MarkdownTestSimulator(composeTestRule).apply(block)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package edu.stanford.spezi.core.design.views

import androidx.compose.ui.test.junit4.createComposeRule
import edu.stanford.spezi.core.design.views.composables.SuspendButtonTestComposable
import edu.stanford.spezi.core.design.views.simulators.SuspendButtonTestSimulator
import org.junit.Before
import org.junit.Rule
import org.junit.Test

class SuspendButtonTest {

@get:Rule
val composeTestRule = createComposeRule()

@Before
fun init() {
composeTestRule.setContent {
SuspendButtonTestComposable()
}
}

@Test
fun testSuspendButton() {
suspendButton {
clickHelloWorldButton()
waitForHelloWorldButtonAction()
resetHelloWorldButtonAction()

clickHelloThrowingWorldButton()
assertViewStateAlertAppeared("Error was thrown!")
dismissViewStateAlert()
assertHelloThrowingWorldButtonIsEnabled()
}
}

private fun suspendButton(block: SuspendButtonTestSimulator.() -> Unit) {
SuspendButtonTestSimulator(composeTestRule).apply(block)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package edu.stanford.spezi.core.design.views.composables

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import edu.stanford.spezi.core.design.validation.views.views.text.MarkdownBytes
import edu.stanford.spezi.core.design.validation.views.views.text.MarkdownString
import kotlinx.coroutines.delay
import java.nio.charset.StandardCharsets
import kotlin.time.Duration.Companion.milliseconds

@Composable
fun MarkdownTestComposable() {
Column {
MarkdownBytes(
bytes = {
delay(500.milliseconds)
"This is a markdown **example** taking half a second to load."
.toByteArray(StandardCharsets.UTF_8)
}
)

MarkdownString("This is a markdown **example**.")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package edu.stanford.spezi.core.design.views.composables

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import edu.stanford.spezi.core.design.component.StringResource
import edu.stanford.spezi.core.design.validation.views.model.ViewState
import edu.stanford.spezi.core.design.validation.views.viewModifier.viewState.ViewStateAlert
import edu.stanford.spezi.core.design.validation.views.views.button.SuspendButton
import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.milliseconds

class CustomError : Throwable() {
override val message = "Error was thrown!"
}

@Composable
fun SuspendButtonTestComposable() {
var showCompleted by remember { mutableStateOf(false) }
val viewState = remember { mutableStateOf<ViewState>(ViewState.Idle) }

ViewStateAlert(viewState)

Column {
if (showCompleted) {
Text("Action executed")
Button(onClick = { showCompleted = false }) {
Text("Reset")
}
} else {
SuspendButton(StringResource("Hello World")) {
delay(500.milliseconds)
showCompleted = true
}

SuspendButton(StringResource("Hello Throwing World"), viewState) {
throw CustomError()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package edu.stanford.spezi.core.design.views.simulators

import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithText

class MarkdownTestSimulator(
private val composeTestRule: ComposeTestRule,
) {
fun assertTextExists(text: String, exists: Boolean = true) {
val node = composeTestRule.onNodeWithText(text)
if (exists) {
node.assertExists()
} else {
node.assertDoesNotExist()
}
}

fun waitForTextToAppear(text: String, timeoutMillis: Long = 1_000) {
composeTestRule.waitUntil(timeoutMillis) {
composeTestRule.onAllNodesWithText(text)
.fetchSemanticsNodes().isNotEmpty()
}
}
}
Loading

0 comments on commit f3f516b

Please sign in to comment.