All Downloads are FREE. Search and download functionalities are using the official Maven repository.

run.qontract.core.Result.kt Maven / Gradle / Ivy

package run.qontract.core

import run.qontract.core.Result.*
import run.qontract.core.pattern.Pattern
import run.qontract.core.value.Value

sealed class Result {
    var scenario: Scenario? = null

    fun updateScenario(scenario: Scenario): Result {
        this.scenario = scenario
        return this
    }

    abstract fun isTrue(): Boolean

    abstract fun ifSuccess(function: () -> Result): Result

    class Success : Result() {
        override fun isTrue() = true
        override fun ifSuccess(function: () -> Result) = function()
    }

    data class Failure(val message: String="", var cause: Failure? = null, val breadCrumb: String = "", val failureReason: FailureReason? = null) : Result() {
        override fun ifSuccess(function: () -> Result) = this

        fun reason(errorMessage: String) = Failure(errorMessage, this)
        fun breadCrumb(breadCrumb: String) = Failure(cause = this, breadCrumb = breadCrumb)

        fun report(): FailureReport =
            (cause?.report() ?: FailureReport()).let { reason ->
                when {
                    message.isNotEmpty() -> reason.copy(errorMessages = listOf(message).plus(reason.errorMessages))
                    else -> reason
                }
            }.let { reason ->
                when {
                    breadCrumb.isNotEmpty() -> reason.copy(breadCrumbs = listOf(breadCrumb).plus(reason.breadCrumbs))
                    else -> reason
                }
            }

        override fun isTrue() = false
    }

}

enum class FailureReason {
    PartNameMisMatch,
    URLPathMisMatch
}

fun Result.breadCrumb(breadCrumb: String): Result =
    when(this) {
        is Failure -> this.breadCrumb(breadCrumb)
        else -> this
    }

data class FailureReport(val breadCrumbs: List = emptyList(), val errorMessages: List = emptyList())

fun mismatchResult(expected: String, actual: String): Failure = Failure("Expected $expected, actual was $actual")
fun mismatchResult(expected: String, actual: Value?): Failure = mismatchResult(expected, valueError(actual) ?: "null")
fun mismatchResult(expected: Value, actual: Value?): Result = mismatchResult(valueError(expected) ?: "null", valueError(actual) ?: "nothing")
fun mismatchResult(expected: Pattern, actual: String): Failure = mismatchResult(expected.typeName, actual)
fun mismatchResult(pattern: Pattern, sampleData: Value?): Failure = mismatchResult(pattern, sampleData?.toStringValue() ?: "null")
fun mismatchResult(thisPattern: Pattern, otherPattern: Pattern): Failure {
    return mismatchResult(thisPattern.typeName, otherPattern.typeName)
}

fun valueError(value: Value?): String? {
    return value?.let { "${it.displayableType()}: ${it.displayableValue()}" }
}

fun resultReport(result: Result, scenarioMessage: String? = null): String {
    return when (result) {
        is Failure -> {
            val firstLine = when(val scenario = result.scenario) {
                null -> ""
                else -> {
                    """${scenarioMessage ?: "In scenario"} "${scenario.name}""""
                }
            }

            val report = result.report().let { (breadCrumbs, errorMessages) ->
                val breadCrumbString =
                        breadCrumbs
                                .filter { it.isNotBlank() }
                                .joinToString(".") { it.trim() }
                                .let {
                                    when {
                                        it.isNotBlank() -> ">> $it"
                                        else -> ""
                                    }
                                }
                val errorMessagesString = errorMessages.map { it.trim() }.filter { it.isNotEmpty() }.joinToString("\n")
                "$breadCrumbString\n\n$errorMessagesString".trim()
            }

            "$firstLine\n$report"
        }
        else -> ""
    }.trim()
}

fun shouldBeIgnored(result: Result): Boolean {
    return when(result) {
        is Success -> false
        is Failure -> result.scenario?.ignoreFailure == true
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy