diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 21b0d53..0f93175 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -12,19 +12,10 @@ kotlin { jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 } } -tasks.test { - useJUnitPlatform() -} dependencies { implementation(libs.kotlin.reflect) 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") diff --git a/core/src/test/kotlin/de/thetadev/formconductor/builder/FormBuilderTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/builder/FormBuilderTest.kt deleted file mode 100644 index 2790352..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/builder/FormBuilderTest.kt +++ /dev/null @@ -1,100 +0,0 @@ -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" - } - } -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/form/FormImplBehaviorTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/form/FormImplBehaviorTest.kt deleted file mode 100644 index 741bc33..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/form/FormImplBehaviorTest.kt +++ /dev/null @@ -1,101 +0,0 @@ -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 - - @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 { - FormImpl(MockedForms.AnnotationPropertyTypeMismatch::class) - } - } - - @Test - fun `form construction should fail on field type and annotation multiple mismatches`() { - assertThrows { - 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 - } - } - } - -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/form/FormResultTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/form/FormResultTest.kt deleted file mode 100644 index 83a6c22..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/form/FormResultTest.kt +++ /dev/null @@ -1,45 +0,0 @@ -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 - - @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 - } -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/form/MockedForms.kt b/core/src/test/kotlin/de/thetadev/formconductor/form/MockedForms.kt deleted file mode 100644 index 56be062..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/form/MockedForms.kt +++ /dev/null @@ -1,19 +0,0 @@ -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 = "" - ) -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/form/TestForm.kt b/core/src/test/kotlin/de/thetadev/formconductor/form/TestForm.kt deleted file mode 100644 index 7a6a784..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/form/TestForm.kt +++ /dev/null @@ -1,9 +0,0 @@ -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 -) diff --git a/core/src/test/kotlin/de/thetadev/formconductor/validation/EmailAddressRuleTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/validation/EmailAddressRuleTest.kt deleted file mode 100644 index b7a7f5e..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/validation/EmailAddressRuleTest.kt +++ /dev/null @@ -1,63 +0,0 @@ -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 - - @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)) - } -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/validation/FloatRangeRuleTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/validation/FloatRangeRuleTest.kt deleted file mode 100644 index 3462fc5..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/validation/FloatRangeRuleTest.kt +++ /dev/null @@ -1,44 +0,0 @@ -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) - } -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/validation/IntegerRangeRuleTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/validation/IntegerRangeRuleTest.kt deleted file mode 100644 index 153fa7c..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/validation/IntegerRangeRuleTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -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) - } -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/validation/IsCheckedRuleTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/validation/IsCheckedRuleTest.kt deleted file mode 100644 index 3af5f8a..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/validation/IsCheckedRuleTest.kt +++ /dev/null @@ -1,25 +0,0 @@ -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 - } -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/validation/MaxLengthRuleTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/validation/MaxLengthRuleTest.kt deleted file mode 100644 index b9f8394..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/validation/MaxLengthRuleTest.kt +++ /dev/null @@ -1,27 +0,0 @@ -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 - } -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/validation/MinLengthRuleTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/validation/MinLengthRuleTest.kt deleted file mode 100644 index 7a21a27..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/validation/MinLengthRuleTest.kt +++ /dev/null @@ -1,28 +0,0 @@ -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 - } -} diff --git a/core/src/test/kotlin/de/thetadev/formconductor/validation/WebUrlRuleTest.kt b/core/src/test/kotlin/de/thetadev/formconductor/validation/WebUrlRuleTest.kt deleted file mode 100644 index 6360b5c..0000000 --- a/core/src/test/kotlin/de/thetadev/formconductor/validation/WebUrlRuleTest.kt +++ /dev/null @@ -1,43 +0,0 @@ -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 - } -}