Skip to content

Commit

Permalink
Merge pull request #35
Browse files Browse the repository at this point in the history
Refactoring
  • Loading branch information
hwolf committed Dec 19, 2021
2 parents 9bba569 + cbc6858 commit 4fcd9cf
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 19 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ The validation logic must be within an extension function of
For example:

```kotlin
fun ConstraintBuilder<String>.hasMinLength(min: Int) =
validate(MinLength(min)) {
it >= min
}
fun <T> ValidationBuilder<T, String>.hasMinLength(min: Int) =
validate(MinLength(min)) { v, _ ->
v.length >= min
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ fun Assertion.Builder<ValidationResult>.isValid() =
}
}

fun Assertion.Builder<ValidationResult>.hasViolations(vararg violations: ConstraintViolation) =
get { errors }.contains(*violations)
fun Assertion.Builder<ValidationResult>.hasViolations(vararg expected: ConstraintViolation) =
get { violations }.contains(*expected)
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@ package hwolf.kvalidation
* @property constraint the violated constraint
*/
data class ConstraintViolation(
val violationId: String,
val propertyName: String,
val propertyType: String?,
val propertyValue: Any?,
val constraint: Constraint
)
) {
constructor(
propertyName: String,
propertyType: String?,
propertyValue: Any?,
constraint: Constraint
) : this(constraint.messageKey, propertyName, propertyType, propertyValue, constraint)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ class ValidationContext<T> private constructor(
val errors get() = errs.toList()

internal fun constraintViolation(constraint: Constraint, propertyValue: Any?) {
constraintViolation(constraint.messageKey, constraint, propertyValue)
}

internal fun constraintViolation(violationId: String, constraint: Constraint, propertyValue: Any?) {
errs.add(ConstraintViolation(
violationId = violationId,
propertyName = propertyName,
propertyType = propertyType,
propertyValue = propertyValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ package hwolf.kvalidation
/**
* The result of a validation.
*
* @property errors List of [ConstraintViolation] found during validation
* @property violations List of [ConstraintViolation] found during validation
* @property isValid `true` when no [ConstraintViolation] was found, otherwise `false`
*/
data class ValidationResult(
val errors: List<ConstraintViolation>
data class ValidationResult(
val violations: List<ConstraintViolation>
) {
val isValid = errors.isEmpty()
private val violationMap: Map<String, List<ConstraintViolation>> by lazy {
violations.groupBy { it.propertyName }
}

val isValid = violations.isEmpty()

operator fun get(property: String): List<ConstraintViolation> =
violationMap[property] ?: emptyList()
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import strikt.assertions.hasEntry
import strikt.assertions.isEqualTo

@Testable
fun `Constraint`() = rootContext<TestConstraint> {
fun testsConstraint() = rootContext<TestConstraint> {
given {
TestConstraint(prop1 = "Value 1", prop2 = null)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ValidationBuilderTest {
TestBean::prop { isEqual("xx") messageKey "message-key" }
}
val actual = validator.validate(TestBean("xy"))
expectThat(actual.errors).map { it.constraint.messageKey }.contains("message-key")
expectThat(actual.violations).map { it.constraint.messageKey }.contains("message-key")
}

@Test
Expand All @@ -24,7 +24,7 @@ class ValidationBuilderTest {
TestBean::prop { isEqual(TestBean::prop2) messageKey "message-key-x" }
}
val actual = validator.validate(TestBean("xy", prop2 = "yx"))
expectThat(actual.errors).map { it.constraint.messageKey }.contains("message-key-x")
expectThat(actual.violations).map { it.constraint.messageKey }.contains("message-key-x")
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@file:Suppress("unused")

package hwolf.kvalidation

import dev.minutest.given
import dev.minutest.rootContext
import dev.minutest.test
import org.junit.platform.commons.annotation.Testable
import strikt.api.expectThat
import strikt.assertions.contains
import strikt.assertions.containsExactly
import strikt.assertions.doesNotContain
import strikt.assertions.isEmpty
import strikt.assertions.map

@Testable
fun testsValidationResult() = rootContext<ValidationResult> {

fun violation(property: String, constraint: Constraint) = ConstraintViolation(
propertyName = property,
propertyType = "Any",
propertyValue = null,
constraint = constraint)

given {
ValidationResult(listOf(
violation("prop1", Required),
violation("prop1", NotBlank),
violation("otherProp", Empty)))
}
test("Operator [] should return all violations for a property") {
expectThat(this["prop1"]) {
containsExactly(
violation("prop1", Required),
violation("prop1", NotBlank))
}
}
test("Operator [] should return only violations for a property") {
expectThat(this["prop1"]) {
map(ConstraintViolation::propertyName)
.contains("prop1")
.doesNotContain("otherProp")
}
}
test("Operator [] should return empty list for unknown property") {
expectThat(this["unknownProp"]) {
isEmpty()
}
}
}
4 changes: 2 additions & 2 deletions kvalidation-core/src/test/kotlin/hwolf/kvalidation/tests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fun Assertion.Builder<ValidationResult>.isValid() =
}

fun Assertion.Builder<ValidationResult>.hasViolations(vararg violations: ConstraintViolation) =
get { errors }.contains(*violations)
get { this.violations }.contains(*violations)

fun Assertion.Builder<ValidationResult>.hasExactlyViolations(vararg violations: ConstraintViolation) =
get { errors }.containsExactly(*violations)
get { this.violations }.containsExactly(*violations)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package hwolf.kvalidation.samples.constraints

import hwolf.kvalidation.Constraint
import hwolf.kvalidation.ValidationBuilder
import hwolf.kvalidation.validate

data class MinLength<T>(val min: T) : Constraint

fun <T> ValidationBuilder<T, String>.hasMinLength(min: Int) =
validate(MinLength(min)) { v, _ ->
v.length >= min
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package hwolf.kvalidation.samples.userprofile

import hwolf.kvalidation.*
import hwolf.kvalidation.common.isEmail
import hwolf.kvalidation.hasLength
import hwolf.kvalidation.isEqual
import hwolf.kvalidation.isGreaterOrEqual
import hwolf.kvalidation.isNotBlank
import hwolf.kvalidation.samples.constraints.hasMinLength
import hwolf.kvalidation.validator

data class UserProfile(
val name: String,
Expand All @@ -14,7 +19,7 @@ data class UserProfile(
val userProfileValidator = validator<UserProfile> {
UserProfile::name {
isNotBlank()
hasLength(6, 20)
hasMinLength(6)
}
UserProfile::age required {
isGreaterOrEqual(18)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ class UserProfileTests {

expectThat(result.isValid).isFalse()
}
}
}

0 comments on commit 4fcd9cf

Please sign in to comment.