diff --git a/src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderAny.kt b/src/commonMain/kotlin/io/konform/validation/constraints/AnyConstraints.kt similarity index 100% rename from src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderAny.kt rename to src/commonMain/kotlin/io/konform/validation/constraints/AnyConstraints.kt diff --git a/src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderEnum.kt b/src/commonMain/kotlin/io/konform/validation/constraints/EnumConstraints.kt similarity index 100% rename from src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderEnum.kt rename to src/commonMain/kotlin/io/konform/validation/constraints/EnumConstraints.kt diff --git a/src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderIterable.kt b/src/commonMain/kotlin/io/konform/validation/constraints/IterableConstraints.kt similarity index 70% rename from src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderIterable.kt rename to src/commonMain/kotlin/io/konform/validation/constraints/IterableConstraints.kt index 61dda58..02fffe1 100644 --- a/src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderIterable.kt +++ b/src/commonMain/kotlin/io/konform/validation/constraints/IterableConstraints.kt @@ -2,29 +2,33 @@ package io.konform.validation.constraints import io.konform.validation.Constraint import io.konform.validation.ValidationBuilder +import kotlin.jvm.JvmName -public fun ValidationBuilder>.minItems(minSize: Int): Constraint> = +public fun > ValidationBuilder.minItems(minSize: Int): Constraint = addConstraint("must have at least {0} items", minSize.toString()) { it.count() >= minSize } +@JvmName("arrayMinItems") public fun ValidationBuilder>.minItems(minSize: Int): Constraint> = addConstraint("must have at least {0} items", minSize.toString()) { it.count() >= minSize } -public fun ValidationBuilder>.maxItems(maxSize: Int): Constraint> = +public fun > ValidationBuilder.maxItems(maxSize: Int): Constraint = addConstraint("must have at most {0} items", maxSize.toString()) { it.count() <= maxSize } +@JvmName("arrayMaxItems") public fun ValidationBuilder>.maxItems(maxSize: Int): Constraint> = addConstraint("must have at most {0} items", maxSize.toString()) { it.count() <= maxSize } -public fun ValidationBuilder>.uniqueItems(unique: Boolean): Constraint> = +public fun > ValidationBuilder.uniqueItems(unique: Boolean = true): Constraint = addConstraint("all items must be unique") { !unique || it.distinct().count() == it.count() } -public fun ValidationBuilder>.uniqueItems(unique: Boolean): Constraint> = +@JvmName("arrayUniqueItems") +public fun ValidationBuilder>.uniqueItems(unique: Boolean = true): Constraint> = addConstraint("all items must be unique") { !unique || it.distinct().count() == it.count() } diff --git a/src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderMap.kt b/src/commonMain/kotlin/io/konform/validation/constraints/MapConstraints.kt similarity index 95% rename from src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderMap.kt rename to src/commonMain/kotlin/io/konform/validation/constraints/MapConstraints.kt index 0f971b6..f3565eb 100644 --- a/src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderMap.kt +++ b/src/commonMain/kotlin/io/konform/validation/constraints/MapConstraints.kt @@ -19,7 +19,7 @@ public fun ValidationBuilder>.minProperties(minSize: Int): Cons public fun ValidationBuilder>.maxProperties(maxSize: Int): Constraint> = maxItems(maxSize) hint "must have at most {0} properties" -public fun ValidationBuilder>.uniqueItems(unique: Boolean): Constraint> = +public fun ValidationBuilder>.uniqueItems(unique: Boolean = true): Constraint> = addConstraint("all items must be unique") { !unique || it.values.distinct().count() == it.count() } diff --git a/src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderNumber.kt b/src/commonMain/kotlin/io/konform/validation/constraints/NumberConstraints.kt similarity index 100% rename from src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderNumber.kt rename to src/commonMain/kotlin/io/konform/validation/constraints/NumberConstraints.kt diff --git a/src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderString.kt b/src/commonMain/kotlin/io/konform/validation/constraints/StringConstraints.kt similarity index 100% rename from src/commonMain/kotlin/io/konform/validation/constraints/ValidationBuilderString.kt rename to src/commonMain/kotlin/io/konform/validation/constraints/StringConstraints.kt diff --git a/src/commonMain/kotlin/io/konform/validation/jsonschema/JsonSchema.kt b/src/commonMain/kotlin/io/konform/validation/jsonschema/JsonSchema.kt index 0df1b57..7565a47 100644 --- a/src/commonMain/kotlin/io/konform/validation/jsonschema/JsonSchema.kt +++ b/src/commonMain/kotlin/io/konform/validation/jsonschema/JsonSchema.kt @@ -6,65 +6,74 @@ import io.konform.validation.constraints.const as movedConst import io.konform.validation.constraints.enum as movedEnum import io.konform.validation.constraints.exclusiveMaximum as movedExclusiveMaximum import io.konform.validation.constraints.exclusiveMinimum as movedExclusiveMinimum -import io.konform.validation.constraints.maxItems as movedMaxItems import io.konform.validation.constraints.maxLength as movedMaxLength import io.konform.validation.constraints.maxProperties as movedMaxProperties import io.konform.validation.constraints.maximum as movedMaximum -import io.konform.validation.constraints.minItems as movedMinItems import io.konform.validation.constraints.minLength as movedMinLength import io.konform.validation.constraints.minProperties as movedMinProperties import io.konform.validation.constraints.minimum as movedMinimum import io.konform.validation.constraints.multipleOf as movedMultipleOf import io.konform.validation.constraints.pattern as movedPattern import io.konform.validation.constraints.type as movedType -import io.konform.validation.constraints.uniqueItems as movedUniqueItems import io.konform.validation.constraints.uuid as movedUuid -@Deprecated("Moved to io.konform.validation.constraints", ReplaceWith("type()", "io.konform.validation.constraints.type")) +@Deprecated( + "Moved to io.konform.validation.constraints", + ReplaceWith("io.konform.validation.constraints.type()", "io.konform.validation.constraints.type"), +) public inline fun ValidationBuilder<*>.type(): Constraint<*> = movedType() -@Deprecated("Moved to io.konform.validation.constraints", ReplaceWith("enum(*allowed)", "io.konform.validation.constraints.enum")) +@Deprecated( + "Moved to io.konform.validation.constraints", + ReplaceWith("io.konform.validation.constraints.enum(*allowed)", "io.konform.validation.constraints.enum"), +) public fun ValidationBuilder.enum(vararg allowed: T): Constraint = movedEnum(*allowed) -@Deprecated("Moved to io.konform.validation.constraints", ReplaceWith("enum()", "io.konform.validation.constraints.enum")) +@Deprecated( + "Moved to io.konform.validation.constraints", + ReplaceWith("io.konform.validation.constraints.enum()", "io.konform.validation.constraints.enum"), +) public inline fun > ValidationBuilder.enum(): Constraint = movedEnum() -@Deprecated("Moved to io.konform.validation.constraints", ReplaceWith("const(expected)", "io.konform.validation.constraints.const")) +@Deprecated( + "Moved to io.konform.validation.constraints", + ReplaceWith("io.konform.validation.constraints.const(expected)", "io.konform.validation.constraints.const"), +) public fun ValidationBuilder.const(expected: T): Constraint = movedConst(expected) @Deprecated( "Moved to io.konform.validation.constraints", - ReplaceWith("minLength(length)", imports = ["io.konform.validation.constraints.minLength"]), + ReplaceWith("io.konform.validation.constraints.minLength(length)", "io.konform.validation.constraints.minLength"), ) public fun ValidationBuilder.minLength(length: Int): Constraint = movedMinLength(length) @Deprecated( "Moved to io.konform.validation.constraints", - ReplaceWith("maxLength(length)", imports = ["io.konform.validation.constraints.maxLength"]), + ReplaceWith("io.konform.validation.constraints.maxLength(length)", "io.konform.validation.constraints.maxLength"), ) public fun ValidationBuilder.maxLength(length: Int): Constraint = movedMaxLength(length) @Deprecated( "Moved to io.konform.validation.constraints", - ReplaceWith("pattern(length)", imports = ["io.konform.validation.constraints.pattern"]), + ReplaceWith("pattern(length)", "io.konform.validation.constraints.pattern"), ) public fun ValidationBuilder.pattern(pattern: String): Constraint = movedPattern(pattern) @Deprecated( "Moved to io.konform.validation.constraints", - ReplaceWith("uuid()", imports = ["io.konform.validation.constraints.uuid"]), + ReplaceWith("uuid()", "io.konform.validation.constraints.uuid"), ) public fun ValidationBuilder.uuid(): Constraint = movedUuid() @Deprecated( "Moved to io.konform.validation.constraints", - ReplaceWith("pattern(pattern)", imports = ["io.konform.validation.constraints.pattern"]), + ReplaceWith("pattern(pattern)", "io.konform.validation.constraints.pattern"), ) public fun ValidationBuilder.pattern(pattern: Regex): Constraint = movedPattern(pattern) @Deprecated( "Moved to io.konform.validation.constraints", - ReplaceWith("multipleOf(factor)", imports = ["io.konform.validation.constraints.multipleOf"]), + ReplaceWith("multipleOf(factor)", "io.konform.validation.constraints.multipleOf"), ) public fun ValidationBuilder.multipleOf(factor: Number): Constraint = movedMultipleOf(factor) @@ -100,24 +109,33 @@ public fun ValidationBuilder.exclusiveMinimum(minimumExclusive: ReplaceWith("minItems(minSize)", "io.konform.validation.constraints.minItems"), ) public inline fun ValidationBuilder.minItems(minSize: Int): Constraint = - when (T::class) { - is Iterable<*> -> (this as ValidationBuilder>).movedMinItems(minSize) as Constraint - is Array<*> -> (this as ValidationBuilder>).movedMinItems(minSize) as Constraint - is Map<*, *> -> (this as ValidationBuilder>).movedMinItems(minSize) as Constraint - else -> throw IllegalStateException("minItems can not be applied to type ${T::class}") + addConstraint( + "must have at least {0} items", + minSize.toString(), + ) { + when (it) { + is Iterable<*> -> it.count() >= minSize + is Array<*> -> it.count() >= minSize + is Map<*, *> -> it.count() >= minSize + else -> throw IllegalStateException("minItems can not be applied to type ${T::class}") + } } -@Suppress("UNCHECKED_CAST") @Deprecated( "Moved to io.konform.validation.constraints", ReplaceWith("maxItems(maxSize)", "io.konform.validation.constraints.maxItems"), ) public inline fun ValidationBuilder.maxItems(maxSize: Int): Constraint = - when (T::class) { - is Iterable<*> -> (this as ValidationBuilder>).movedMaxItems(maxSize) as Constraint - is Array<*> -> (this as ValidationBuilder>).movedMaxItems(maxSize) as Constraint - is Map<*, *> -> (this as ValidationBuilder>).movedMaxItems(maxSize) as Constraint - else -> throw IllegalStateException("maxItems can not be applied to type ${T::class}") + addConstraint( + "must have at most {0} items", + maxSize.toString(), + ) { + when (it) { + is Iterable<*> -> it.count() <= maxSize + is Array<*> -> it.count() <= maxSize + is Map<*, *> -> it.count() <= maxSize + else -> throw IllegalStateException("maxItems can not be applied to type ${T::class}") + } } @Deprecated( @@ -134,15 +152,18 @@ public fun ValidationBuilder>.minProperties(minSize: Int): Cons public fun ValidationBuilder>.maxProperties(maxSize: Int): Constraint> = movedMaxProperties(maxSize) hint "must have at most {0} properties" -@Suppress("UNCHECKED_CAST") @Deprecated( "Moved to io.konform.validation.constraints", ReplaceWith("uniqueItems(unique)", "io.konform.validation.constraints.uniqueItems"), ) public inline fun ValidationBuilder.uniqueItems(unique: Boolean): Constraint = - when (T::class) { - is Iterable<*> -> (this as ValidationBuilder>).movedUniqueItems(unique) as Constraint - is Array<*> -> (this as ValidationBuilder>).movedUniqueItems(unique) as Constraint - is Map<*, *> -> (this as ValidationBuilder>).movedUniqueItems(unique) as Constraint - else -> throw IllegalStateException("uniqueItems can not be applied to type ${T::class}") + addConstraint( + "all items must be unique", + ) { + !unique || + when (it) { + is Iterable<*> -> it.distinct().count() == it.count() + is Array<*> -> it.distinct().count() == it.count() + else -> throw IllegalStateException("uniqueItems can not be applied to type ${T::class}") + } } diff --git a/src/commonTest/kotlin/io/konform/validation/ListValidationTest.kt b/src/commonTest/kotlin/io/konform/validation/ListValidationTest.kt index 2235aec..f20fe9e 100644 --- a/src/commonTest/kotlin/io/konform/validation/ListValidationTest.kt +++ b/src/commonTest/kotlin/io/konform/validation/ListValidationTest.kt @@ -1,6 +1,6 @@ package io.konform.validation -import io.konform.validation.jsonschema.minimum +import io.konform.validation.constraints.minimum import io.konform.validation.types.EmptyValidation import io.konform.validation.types.ValidateAll import io.kotest.assertions.konform.shouldBeInvalid diff --git a/src/commonTest/kotlin/io/konform/validation/ReadmeExampleTest.kt b/src/commonTest/kotlin/io/konform/validation/ReadmeExampleTest.kt index e8c28ff..a6b6867 100644 --- a/src/commonTest/kotlin/io/konform/validation/ReadmeExampleTest.kt +++ b/src/commonTest/kotlin/io/konform/validation/ReadmeExampleTest.kt @@ -1,12 +1,12 @@ package io.konform.validation -import io.konform.validation.jsonschema.maxItems -import io.konform.validation.jsonschema.maxLength -import io.konform.validation.jsonschema.maximum -import io.konform.validation.jsonschema.minItems -import io.konform.validation.jsonschema.minLength -import io.konform.validation.jsonschema.minimum -import io.konform.validation.jsonschema.pattern +import io.konform.validation.constraints.maxItems +import io.konform.validation.constraints.maxLength +import io.konform.validation.constraints.maximum +import io.konform.validation.constraints.minItems +import io.konform.validation.constraints.minLength +import io.konform.validation.constraints.minimum +import io.konform.validation.constraints.pattern import io.kotest.assertions.konform.shouldBeInvalid import io.kotest.assertions.konform.shouldBeValid import io.kotest.assertions.konform.shouldContainError diff --git a/src/commonTest/kotlin/io/konform/validation/JSONSchemaStyleConstraintsTest.kt b/src/commonTest/kotlin/io/konform/validation/constraints/ConstraintsTest.kt similarity index 90% rename from src/commonTest/kotlin/io/konform/validation/JSONSchemaStyleConstraintsTest.kt rename to src/commonTest/kotlin/io/konform/validation/constraints/ConstraintsTest.kt index 9bfb0bb..a2acae8 100644 --- a/src/commonTest/kotlin/io/konform/validation/JSONSchemaStyleConstraintsTest.kt +++ b/src/commonTest/kotlin/io/konform/validation/constraints/ConstraintsTest.kt @@ -1,30 +1,33 @@ -package io.konform.validation - -import io.konform.validation.JSONSchemaStyleConstraintsTest.TCPPacket.ACK -import io.konform.validation.JSONSchemaStyleConstraintsTest.TCPPacket.SYN -import io.konform.validation.JSONSchemaStyleConstraintsTest.TCPPacket.SYNACK -import io.konform.validation.enum.enum -import io.konform.validation.jsonschema.const -import io.konform.validation.jsonschema.exclusiveMaximum -import io.konform.validation.jsonschema.exclusiveMinimum -import io.konform.validation.jsonschema.maxItems -import io.konform.validation.jsonschema.maxLength -import io.konform.validation.jsonschema.maxProperties -import io.konform.validation.jsonschema.maximum -import io.konform.validation.jsonschema.minItems -import io.konform.validation.jsonschema.minLength -import io.konform.validation.jsonschema.minProperties -import io.konform.validation.jsonschema.minimum -import io.konform.validation.jsonschema.multipleOf -import io.konform.validation.jsonschema.pattern -import io.konform.validation.jsonschema.type -import io.konform.validation.jsonschema.uniqueItems -import io.konform.validation.jsonschema.uuid +package io.konform.validation.constraints + +import io.konform.validation.Valid +import io.konform.validation.Validation +import io.konform.validation.ValidationResult +import io.konform.validation.constraints.ConstraintsTest.TCPPacket.ACK +import io.konform.validation.constraints.ConstraintsTest.TCPPacket.SYN +import io.konform.validation.constraints.ConstraintsTest.TCPPacket.SYNACK +import io.konform.validation.constraints.const +import io.konform.validation.constraints.exclusiveMaximum +import io.konform.validation.constraints.exclusiveMinimum +import io.konform.validation.constraints.maxItems +import io.konform.validation.constraints.maxLength +import io.konform.validation.constraints.maxProperties +import io.konform.validation.constraints.maximum +import io.konform.validation.constraints.minItems +import io.konform.validation.constraints.minLength +import io.konform.validation.constraints.minProperties +import io.konform.validation.constraints.minimum +import io.konform.validation.constraints.multipleOf +import io.konform.validation.constraints.pattern +import io.konform.validation.constraints.type +import io.konform.validation.constraints.uniqueItems +import io.konform.validation.constraints.uuid +import io.konform.validation.countFieldsWithErrors import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith -class JSONSchemaStyleConstraintsTest { +class ConstraintsTest { @Test fun typeConstraint() { val anyValidation = Validation { type() } @@ -42,8 +45,8 @@ class JSONSchemaStyleConstraintsTest { assertEquals(1, countFieldsWithErrors(anyNumberValidation("String"))) assertEquals(1, countFieldsWithErrors(anyNumberValidation(true))) - assertEquals("must be of the correct type", anyValidation(1).get()!![0]) - assertEquals("must be of the correct type", anyNumberValidation("String").get()!![0]) + assertEquals("must be of type 'String'", anyValidation(1).get()!![0]) + assertEquals("must be of type 'Int'", anyNumberValidation("String").get()!![0]) } @Test @@ -61,7 +64,7 @@ class JSONSchemaStyleConstraintsTest { @Test fun stringEnumConstraint() { - val validation = Validation { this.enum("OK", "CANCEL") } + val validation = Validation { enum("OK", "CANCEL") } assertEquals(Valid("OK"), validation("OK")) assertEquals(Valid("CANCEL"), validation("CANCEL")) assertEquals(1, countFieldsWithErrors(validation("???"))) @@ -110,7 +113,7 @@ class JSONSchemaStyleConstraintsTest { assertEquals(1, countFieldsWithErrors(nullableConstValidation("Konverse"))) assertEquals("must be 'Konform'", validation("Konverse").get()!![0]) - assertEquals("must be null", nullableConstNullValidation("Konform").get()!![0]) + assertEquals("must be 'null'", nullableConstNullValidation("Konform").get()!![0]) assertEquals("must be 'Konform'", nullableConstValidation(null).get()!![0]) } diff --git a/src/commonTest/kotlin/io/konform/validation/validationbuilder/InstanceOfTest.kt b/src/commonTest/kotlin/io/konform/validation/validationbuilder/InstanceOfTest.kt index 47a08fb..6ac3b8d 100644 --- a/src/commonTest/kotlin/io/konform/validation/validationbuilder/InstanceOfTest.kt +++ b/src/commonTest/kotlin/io/konform/validation/validationbuilder/InstanceOfTest.kt @@ -2,7 +2,7 @@ package io.konform.validation.validationbuilder import io.konform.validation.PropertyValidationError import io.konform.validation.Validation -import io.konform.validation.string.notBlank +import io.konform.validation.constraints.notBlank import io.kotest.assertions.konform.shouldBeInvalid import io.kotest.assertions.konform.shouldBeValid import io.kotest.assertions.konform.shouldContainExactlyErrors