Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 56a286bf1f | |||
| 1bca38e632 | |||
| 7b14c58230 |
13 changed files with 550 additions and 0 deletions
|
|
@ -12,10 +12,19 @@ kotlin {
|
||||||
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
|
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.kotlin.reflect)
|
implementation(libs.kotlin.reflect)
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
|
|
||||||
|
testImplementation(platform("org.junit:junit-bom:5.14.4"))
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter:5.14.4")
|
||||||
|
testImplementation("org.amshove.kluent:kluent:1.71")
|
||||||
|
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.11.0")
|
||||||
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(from = "$rootDir/scripts/publish-root.gradle.kts")
|
apply(from = "$rootDir/scripts/publish-root.gradle.kts")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
package de.thetadev.formconductor.builder
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FieldResult
|
||||||
|
import de.thetadev.formconductor.FormField
|
||||||
|
import de.thetadev.formconductor.FormFieldImpl
|
||||||
|
import de.thetadev.formconductor.FormImpl
|
||||||
|
import de.thetadev.formconductor.annotations.Form
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.amshove.kluent.should
|
||||||
|
import org.amshove.kluent.`should be`
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.amshove.kluent.`should be instance of`
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class FormBuilderTest {
|
||||||
|
@Form
|
||||||
|
data class MockForm(
|
||||||
|
val arg1: String = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `form builder function returns correct instance`() {
|
||||||
|
val form = form(MockForm::class)
|
||||||
|
form `should be instance of` FormImpl::class
|
||||||
|
form `should be instance of` de.thetadev.formconductor.Form::class
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `form builder function returns correct builder scope`() = runTest {
|
||||||
|
form(MockForm::class) {
|
||||||
|
this `should be instance of` FormBuilderScopeImpl::class
|
||||||
|
this `should be instance of` FormBuilderScope::class
|
||||||
|
this.formState `should be instance of` Flow::class
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `form builder scope functions properly`() = runTest {
|
||||||
|
form(MockForm::class) {
|
||||||
|
this.registerField(MockForm::arg1) `should be instance of` FormFieldImpl::class
|
||||||
|
this.registerField(MockForm::arg1) `should be instance of` FormField::class
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `field builder function returns correct result`() = runTest {
|
||||||
|
form(MockForm::class) {
|
||||||
|
val field = field(MockForm::arg1)
|
||||||
|
field `should be instance of` FormField::class
|
||||||
|
field.fieldName.trim() `should be equal to` MockForm::arg1.name.trim()
|
||||||
|
field.isFieldOptional() `should be` false
|
||||||
|
field.resultStream `should be instance of` MutableStateFlow::class
|
||||||
|
field.valueStream `should be instance of` MutableStateFlow::class
|
||||||
|
field.value should {
|
||||||
|
this == "" || this == null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `field builder scope functions properly`() = runTest {
|
||||||
|
form(MockForm::class) {
|
||||||
|
field(MockForm::arg1) {
|
||||||
|
this.setField("Test")
|
||||||
|
this.resultState.value `should be equal to` FieldResult.Success
|
||||||
|
this.state.value `should be equal to` "Test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `field builder extension functions returns correct result`() = runTest {
|
||||||
|
val form = form(MockForm::class) {}
|
||||||
|
val field = form.field(MockForm::arg1)
|
||||||
|
field `should be instance of` FormField::class
|
||||||
|
field.fieldName.trim() `should be equal to` MockForm::arg1.name.trim()
|
||||||
|
field.isFieldOptional() `should be` false
|
||||||
|
field.resultStream `should be instance of` MutableStateFlow::class
|
||||||
|
field.valueStream `should be instance of` MutableStateFlow::class
|
||||||
|
field.value should {
|
||||||
|
this == "" || this == null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `field builder extension scope functions properly`() = runTest {
|
||||||
|
val form = form(MockForm::class) {}
|
||||||
|
form.field(MockForm::arg1) {
|
||||||
|
this.setField("Test")
|
||||||
|
this.resultState.value `should be equal to` FieldResult.Success
|
||||||
|
this.state.value `should be equal to` "Test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
package de.thetadev.formconductor.form
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FormField
|
||||||
|
import de.thetadev.formconductor.FormImpl
|
||||||
|
import de.thetadev.formconductor.FormResult
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.amshove.kluent.should
|
||||||
|
import org.amshove.kluent.`should be`
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.amshove.kluent.`should be instance of`
|
||||||
|
import org.amshove.kluent.`should not be`
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Nested
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
import org.junit.jupiter.api.assertThrows
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class FormImplBehaviorTest {
|
||||||
|
|
||||||
|
private lateinit var form: FormImpl<TestForm>
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setUp() {
|
||||||
|
form = FormImpl(TestForm::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
inner class DataStreams {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `form data stream emits a non-null value as first item`() = runTest {
|
||||||
|
form.formDataStream.firstOrNull() `should not be` null
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `form data stream emits NoInput as first item`() = runTest {
|
||||||
|
val firstEmittedItem = form.formDataStream.firstOrNull()
|
||||||
|
firstEmittedItem `should be` FormResult.NoInput
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
inner class FormConstruction {
|
||||||
|
/*
|
||||||
|
* Type checks
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
fun `form construction should fail on field type and annotation mismatch`() {
|
||||||
|
assertThrows<IllegalArgumentException> {
|
||||||
|
FormImpl(MockedForms.AnnotationPropertyTypeMismatch::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `form construction should fail on field type and annotation multiple mismatches`() {
|
||||||
|
assertThrows<IllegalArgumentException> {
|
||||||
|
FormImpl(MockedForms.AnnotationPropertyTypeMismatch2::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
inner class FieldHandling {
|
||||||
|
@Test
|
||||||
|
fun `registerField returns correct field`() {
|
||||||
|
val field = form.registerField(TestForm::integerField)
|
||||||
|
|
||||||
|
field `should be instance of` FormField::class
|
||||||
|
field.fieldName.trim() `should be equal to` TestForm::integerField.name.trim()
|
||||||
|
field.isFieldOptional() `should be` false
|
||||||
|
field.resultStream `should be instance of` MutableStateFlow::class
|
||||||
|
field.valueStream `should be instance of` MutableStateFlow::class
|
||||||
|
field.value should {
|
||||||
|
this == 0 || this == null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `registerField returns correct field 2`() {
|
||||||
|
val field = form.registerField(TestForm::stringField)
|
||||||
|
|
||||||
|
field `should be instance of` FormField::class
|
||||||
|
field.fieldName.trim() `should be equal to` TestForm::stringField.name.trim()
|
||||||
|
field.isFieldOptional() `should be` false
|
||||||
|
field.resultStream `should be instance of` MutableStateFlow::class
|
||||||
|
field.valueStream `should be instance of` MutableStateFlow::class
|
||||||
|
field.value should {
|
||||||
|
this == "" || this == null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package de.thetadev.formconductor.form
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FormImpl
|
||||||
|
import de.thetadev.formconductor.FormResult
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.amshove.kluent.`should be instance of`
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class FormResultTest {
|
||||||
|
|
||||||
|
private lateinit var form: FormImpl<TestForm>
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setUp() {
|
||||||
|
form = FormImpl(TestForm::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `submit returns correct result for no input`() {
|
||||||
|
form.validate() `should be instance of` FormResult.Error::class
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `submit returns success result for valid input`() = runTest {
|
||||||
|
val expectedResult = FormResult.Valid(TestForm(stringField = "Test", integerField = 10))
|
||||||
|
form.setField(TestForm::stringField, "Test")
|
||||||
|
form.setField(TestForm::integerField, 10)
|
||||||
|
val result = form.validate()
|
||||||
|
result `should be equal to` expectedResult
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `submit returns error result for invalid input`() = runTest {
|
||||||
|
form.setField(TestForm::stringField, "Test")
|
||||||
|
form.setField(TestForm::integerField, 9)
|
||||||
|
val result = form.validate()
|
||||||
|
result `should be instance of` FormResult.Error::class
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package de.thetadev.formconductor.form
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.annotations.EmailAddress
|
||||||
|
import de.thetadev.formconductor.annotations.IntegerRange
|
||||||
|
|
||||||
|
object MockedForms {
|
||||||
|
data class AnnotationPropertyTypeMismatch(
|
||||||
|
@IntegerRange(0, 1)
|
||||||
|
val arg1: String = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
data class AnnotationPropertyTypeMismatch2(
|
||||||
|
val arg1: String = "",
|
||||||
|
@EmailAddress
|
||||||
|
val arg2: Int = 0,
|
||||||
|
@IntegerRange(0, 1)
|
||||||
|
val arg3: String = ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package de.thetadev.formconductor.form
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.annotations.IntegerRange
|
||||||
|
|
||||||
|
data class TestForm(
|
||||||
|
val stringField: String = "",
|
||||||
|
@IntegerRange(min = 10, max = 100)
|
||||||
|
val integerField: Int = 0
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package de.thetadev.formconductor.validation
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FormImpl
|
||||||
|
import de.thetadev.formconductor.FormResult
|
||||||
|
import de.thetadev.formconductor.annotations.EmailAddress
|
||||||
|
import de.thetadev.formconductor.annotations.Form
|
||||||
|
import de.thetadev.formconductor.annotations.OptionalField
|
||||||
|
import de.thetadev.formconductor.validation.rules.EmailAddressRule
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class EmailAddressRuleTest {
|
||||||
|
|
||||||
|
@Form
|
||||||
|
data class MockForm(
|
||||||
|
@EmailAddress
|
||||||
|
val email: String = "",
|
||||||
|
@EmailAddress
|
||||||
|
@OptionalField
|
||||||
|
val emailOpt: String? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
private lateinit var form: FormImpl<MockForm>
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setUp() {
|
||||||
|
form = FormImpl(MockForm::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule yields correct success result for annotated validations`() = runTest {
|
||||||
|
val formData = MockForm(email = "hello@example.com")
|
||||||
|
form.setValues(formData)
|
||||||
|
form.validate() `should be equal to` FormResult.Valid(formData)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule yields correct success result for both annotated validations`() = runTest {
|
||||||
|
val formData = MockForm(email = "hello@example.com", emailOpt = "bye@example.com")
|
||||||
|
form.setValues(formData)
|
||||||
|
form.validate() `should be equal to` FormResult.Valid(formData)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule yields correct error result for annotated validations`() = runTest {
|
||||||
|
val formData = MockForm(email = "hello")
|
||||||
|
form.setValues(formData)
|
||||||
|
form.validate() `should be equal to` FormResult.Error(setOf(EmailAddressRule))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule yields correct error result for opt annotated validation`() = runTest {
|
||||||
|
val formData = MockForm(email = "hello@example.com", emailOpt = "bye")
|
||||||
|
form.setValues(formData)
|
||||||
|
form.validate() `should be equal to` FormResult.Error(setOf(EmailAddressRule))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package de.thetadev.formconductor.validation
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FieldResult
|
||||||
|
import de.thetadev.formconductor.annotations.FloatRange
|
||||||
|
import de.thetadev.formconductor.validation.rules.FloatRangeRule
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class FloatRangeRuleTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule return success for correct values`() {
|
||||||
|
val options = FloatRange(min = 0.0, max = 1.0)
|
||||||
|
|
||||||
|
FloatRangeRule.validate(0.0f, options) `should be equal to` FieldResult.Success
|
||||||
|
|
||||||
|
FloatRangeRule.validate(0.1f, options) `should be equal to` FieldResult.Success
|
||||||
|
|
||||||
|
FloatRangeRule.validate(1.0f, options) `should be equal to` FieldResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule return error for invalid values`() {
|
||||||
|
val options = FloatRange(min = 0.0, max = 1.0)
|
||||||
|
|
||||||
|
FloatRangeRule.validate(
|
||||||
|
-0.1f,
|
||||||
|
options
|
||||||
|
) `should be equal to` FieldResult.Error("Value out of range", FloatRangeRule)
|
||||||
|
|
||||||
|
FloatRangeRule.validate(
|
||||||
|
10f,
|
||||||
|
options
|
||||||
|
) `should be equal to` FieldResult.Error("Value out of range", FloatRangeRule)
|
||||||
|
|
||||||
|
FloatRangeRule.validate(
|
||||||
|
1.001f,
|
||||||
|
options
|
||||||
|
) `should be equal to` FieldResult.Error("Value out of range", FloatRangeRule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package de.thetadev.formconductor.validation
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FieldResult
|
||||||
|
import de.thetadev.formconductor.annotations.IntegerRange
|
||||||
|
import de.thetadev.formconductor.validation.rules.IntegerRangeRule
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class IntegerRangeRuleTest {
|
||||||
|
@Test
|
||||||
|
fun `rule return success for correct values`() {
|
||||||
|
val options = IntegerRange(min = 0, max = 10)
|
||||||
|
|
||||||
|
IntegerRangeRule.validate(0, options) `should be equal to` FieldResult.Success
|
||||||
|
|
||||||
|
IntegerRangeRule.validate(5, options) `should be equal to` FieldResult.Success
|
||||||
|
|
||||||
|
IntegerRangeRule.validate(10, options) `should be equal to` FieldResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule return error for invalid values`() {
|
||||||
|
val options = IntegerRange(min = 0, max = 10)
|
||||||
|
|
||||||
|
IntegerRangeRule.validate(
|
||||||
|
-1,
|
||||||
|
options
|
||||||
|
) `should be equal to` FieldResult.Error("Value out of range", IntegerRangeRule)
|
||||||
|
|
||||||
|
IntegerRangeRule.validate(
|
||||||
|
11,
|
||||||
|
options
|
||||||
|
) `should be equal to` FieldResult.Error("Value out of range", IntegerRangeRule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package de.thetadev.formconductor.validation
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FieldResult
|
||||||
|
import de.thetadev.formconductor.annotations.IsChecked
|
||||||
|
import de.thetadev.formconductor.validation.rules.IsCheckedRule
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class IsCheckedRuleTest {
|
||||||
|
private val options = IsChecked()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule returns success for correct input`() {
|
||||||
|
IsCheckedRule.validate(true, options) `should be equal to` FieldResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule returns error for invalid input`() {
|
||||||
|
val expectedResult =
|
||||||
|
FieldResult.Error("This field is required to be checked", IsCheckedRule)
|
||||||
|
IsCheckedRule.validate(false, options) `should be equal to` expectedResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package de.thetadev.formconductor.validation
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FieldResult
|
||||||
|
import de.thetadev.formconductor.annotations.MaxLength
|
||||||
|
import de.thetadev.formconductor.validation.rules.MaxLengthRule
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class MaxLengthRuleTest {
|
||||||
|
@Test
|
||||||
|
fun `rule returns success for correct input`() {
|
||||||
|
val options = MaxLength(5)
|
||||||
|
MaxLengthRule.validate("12345", options) `should be equal to` FieldResult.Success
|
||||||
|
MaxLengthRule.validate("1234", options) `should be equal to` FieldResult.Success
|
||||||
|
MaxLengthRule.validate("1", options) `should be equal to` FieldResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule returns error for invalid input`() {
|
||||||
|
val options = MaxLength(5)
|
||||||
|
val expectedResult =
|
||||||
|
FieldResult.Error("Value shouldn't be longer than ${options.value}.", MaxLengthRule)
|
||||||
|
MaxLengthRule.validate("123456", options) `should be equal to` expectedResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package de.thetadev.formconductor.validation
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FieldResult
|
||||||
|
import de.thetadev.formconductor.annotations.MinLength
|
||||||
|
import de.thetadev.formconductor.validation.rules.MinLengthRule
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class MinLengthRuleTest {
|
||||||
|
@Test
|
||||||
|
fun `rule returns success for correct input`() {
|
||||||
|
val options = MinLength(5)
|
||||||
|
MinLengthRule.validate("123456", options) `should be equal to` FieldResult.Success
|
||||||
|
MinLengthRule.validate("12345", options) `should be equal to` FieldResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule returns error for invalid input`() {
|
||||||
|
val options = MinLength(5)
|
||||||
|
val expectedResult =
|
||||||
|
FieldResult.Error("Value shouldn't be shorter than ${options.value}.", MinLengthRule)
|
||||||
|
|
||||||
|
MinLengthRule.validate("1234", options) `should be equal to` expectedResult
|
||||||
|
MinLengthRule.validate("1", options) `should be equal to` expectedResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package de.thetadev.formconductor.validation
|
||||||
|
|
||||||
|
import de.thetadev.formconductor.FieldResult
|
||||||
|
import de.thetadev.formconductor.annotations.WebUrl
|
||||||
|
import de.thetadev.formconductor.validation.rules.WebUrlRule
|
||||||
|
import org.amshove.kluent.`should be equal to`
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
internal class WebUrlRuleTest {
|
||||||
|
@Test
|
||||||
|
fun `rule returns success result for correct url input`() {
|
||||||
|
val options = WebUrl()
|
||||||
|
WebUrlRule.validate("https://google.com", options) `should be equal to` FieldResult.Success
|
||||||
|
WebUrlRule.validate("www.google.com", options) `should be equal to` FieldResult.Success
|
||||||
|
WebUrlRule.validate("google.com", options) `should be equal to` FieldResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule returns error for invalid url input`() {
|
||||||
|
val options = WebUrl()
|
||||||
|
val expectedResult = FieldResult.Error("Invalid URL", WebUrlRule)
|
||||||
|
WebUrlRule.validate("https://abc", options) `should be equal to` expectedResult
|
||||||
|
WebUrlRule.validate("random", options) `should be equal to` expectedResult
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule returns success result for correct https url input`() {
|
||||||
|
val options = WebUrl(httpRequired = true)
|
||||||
|
WebUrlRule.validate("https://google.com", options) `should be equal to` FieldResult.Success
|
||||||
|
WebUrlRule.validate("http://google.com", options) `should be equal to` FieldResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `rule returns error for invalid https url input`() {
|
||||||
|
val options = WebUrl(true)
|
||||||
|
val expectedResult = FieldResult.Error("Invalid URL", WebUrlRule)
|
||||||
|
WebUrlRule.validate("https://abc", options) `should be equal to` expectedResult
|
||||||
|
WebUrlRule.validate("random", options) `should be equal to` expectedResult
|
||||||
|
WebUrlRule.validate("google.com", options) `should be equal to` expectedResult
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue