Skip to content

Getting Started

MrKekovich edited this page Oct 28, 2024 · 3 revisions

Installation

Replace VERSION with the actual one (can be found here).

Gradle (Kotlin DSL)

dependencies {
    // Core library (required)
    implementation("io.github.kverify:kverify-core:VERSION")

    // Optional modules
    implementation("io.github.kverify:kverify-coroutine-core:VERSION")      // Coroutine support  
    implementation("io.github.kverify:kverify-rule-set:VERSION")            // Pre-built rules  
    implementation("io.github.kverify:kverify-named-value:VERSION")         // Named values  
    implementation("io.github.kverify:kverify-named-rule-set:VERSION")      // Named rules  
    implementation("io.github.kverify:kverify-typed-violation-set:VERSION") // Typed violations
}

Gradle (Groovy)

dependencies {
    // Core library (required)
    implementation 'io.github.kverify:kverify-core:VERSION'

    // Optional modules
    implementation 'io.github.kverify:kverify-coroutine-core:VERSION'       // Coroutine support
    implementation 'io.github.kverify:kverify-rule-set:VERSION'             // Pre-built rules
    implementation 'io.github.kverify:kverify-named-value:VERSION'          // Named values
    implementation 'io.github.kverify:kverify-named-rule-set:VERSION'       // Named rules
    implementation 'io.github.kverify:kverify-typed-violation-set:VERSION'  // Typed violations
}

Maven

<dependencies>
    <!-- Core library (required) -->
    <dependency>
        <groupId>io.github.kverify</groupId>
        <artifactId>kverify-core</artifactId>
        <version>VERSION</version>
    </dependency>

    <!-- Optional modules -->
    <dependency>
        <groupId>io.github.kverify</groupId>
        <artifactId>kverify-coroutine-core</artifactId>
        <version>VERSION</version>
    </dependency>

    <dependency>
        <groupId>io.github.kverify</groupId>
        <artifactId>kverify-rule-set</artifactId>
        <version>VERSION</version>
    </dependency>

    <dependency>
        <groupId>io.github.kverify</groupId>
        <artifactId>kverify-named-value</artifactId>
        <version>VERSION</version>
    </dependency>

    <dependency>
        <groupId>io.github.kverify</groupId>
        <artifactId>kverify-named-rule-set</artifactId>
        <version>VERSION</version>
    </dependency>

    <dependency>
        <groupId>io.github.kverify</groupId>
        <artifactId>kverify-typed-violation-set</artifactId>
        <version>VERSION</version>
    </dependency>
</dependencies>

Usage Example

This example assumes you have installed the following modules:

  • io.github.kverify:kverify-core
  • io.github.kverify:kverify-rule-set
  • io.github.kverify:kverify-named-value
  • io.github.kverify:kverify-named-rule-set

Create Rule Providers

import io.github.kverify.named.rule.set.provider.*
import io.github.kverify.rule.set.provider.*
import io.github.kverify.violation.set.provider.*

object CollectionRules :
    CollectionRuleProvider by DefaultCollectionRuleProvider(),
    NamedCollectionRuleProvider by DefaultNamedCollectionRuleProvider() {
    override val collectionViolationProvider: CollectionViolationProvider = CollectionViolationProvider.Default
}

object ComparableRules :
    ComparableRuleProvider by DefaultComparableRuleProvider(),
    NamedComparableRuleProvider by DefaultNamedComparableRuleProvider() {
    override val comparableViolationProvider: ComparableViolationProvider = ComparableViolationProvider.Default
}

object StringRules :
    StringRuleProvider by DefaultStringRuleProvider(),
    NamedStringRuleProvider by DefaultNamedStringRuleProvider() {
    override val stringViolationProvider: StringViolationProvider = StringViolationProvider.Default
}

Validate Anything

import io.github.kverify.core.context.verifyCollecting
import io.github.kverify.core.model.ValidationResult
import io.github.kverify.named.model.toNamed
import io.github.kverify.named.model.withName
import io.github.kverify.named.model.withValue
import java.util.UUID

data class SignInRequest(
    val login: String,
    val age: Int,
    val tags: List<UUID>,
) {
    fun validate(): ValidationResult = verifyCollecting {
        // Using withName
        login.withName("login").verifyWith(
            StringRules.namedNotBlank(),
            StringRules.namedLengthBetween(3..20),
            StringRules.namedAlphanumeric(),
        )

        // Using withValue and infix notation
        "age" withValue age verifyWith ComparableRules.namedBetween(13..130)

        // Using reflection (JVM only)
        ::tags.toNamed() verifyWith CollectionRules.namedSizeBetween(3..200)
    }
}

Process The ValidationResult

val request = SignInRequest("ab", 5, emptyList())
val result = request.validate()

result.fold(
    { println("Success!") },
    { violations ->
        println("Failure:")
        violations.forEach { println("\t- ${it.reason}") }
    },
)

Common Mistakes

If you see this error:

None of the following candidates is applicable:

fun <T> T.verifyWith(rule: Rule<T>): T:
Argument type mismatch: actual type is 'Rule<Int>', but 'Rule<uninferred T (of fun <T> T.verifyWith)>' was expected.

fun <T> T.verifyWith(rules: Iterable<Rule<T>>): T:
Argument type mismatch: actual type is 'Rule<Int>', but 'Iterable<Rule<uninferred T (of fun <T> T.verifyWith)>>' was expected.

fun <T> T.verifyWith(vararg rules: Rule<T>): T:
Argument type mismatch: actual type is 'Rule<Int>', but 'Rule<uninferred T (of fun <T> T.verifyWith)>' was expected.
'infix' modifier is required on 'fun <T> T.verifyWith(vararg rules: Rule<T>): T'.

You're likely mixing named rules with regular values, or regular rules with named values.

Solution:

// ❌ Wrong: Named value with regular rule
age.withName("age").verifyWith(
    ComparableRules.between(13..130)
)

// ✅ Correct: Named value with named rule
age.withName("age").verifyWith(
    ComparableRules.namedBetween(13..130) // Notice "named" prefix
)

// ❌ Wrong: Regular value with named rule
age.verifyWith(
    ComparableRules.namedBetween(13..130)
)

// ✅ Correct: Regular value with regular rule
age.verifyWith(
    ComparableRules.between(13..130) // No "named" prefix
)

Next steps

Use the wiki navigation menu to explore other topics!

Clone this wiki locally