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

com.natpryce.hamkrest.core_matchers.kt Maven / Gradle / Ivy

@file:JvmName("CoreMatchers")

package com.natpryce.hamkrest

/**
 * A [Matcher] that matches anything, always returning [MatchResult.Match].
 */
@JvmField
val anything = object : Matcher.Primitive() {
    override fun invoke(actual: Any): MatchResult = MatchResult.Match
    override fun description(): String = "anything"
    override fun negatedDescription(): String = "nothing"
}

/**
 * A [Matcher] that matches nothing, always returning a [MatchResult.Mismatch].
 */
@JvmField
val nothing = !anything


/**
 * Returns a matcher that reports if a value is equal to an [expected] value.
 */
fun  equalTo(expected: T): Matcher =
        object : Matcher.Primitive() {
            override fun invoke(actual: T): MatchResult = match(actual == expected) { "was ${describe(actual)}" }
            override fun description() = "is equal to ${describe(expected)}"
            override fun negatedDescription() = "is not equal to ${describe(expected)}"
        }

/**
 * Returns a matcher that reports if a value is the same instance as [expected] value.
 */
fun  sameInstance(expected: T): Matcher =
        object : Matcher.Primitive() {
            override fun invoke(actual: T): MatchResult = match(actual === expected) { "was ${describe(actual)}" }
            override fun description() = "is same instance as ${describe(expected)}"
            override fun negatedDescription() = "is not same instance as ${describe(expected)}"
        }


/**
 * Returns a matcher that reports if a value is null.
 */
fun  absent(): Matcher = object : Matcher.Primitive() {
    override fun invoke(actual: T?): MatchResult = match(actual == null) { "was ${describe(actual)}" }
    override fun description(): String = "null"
}

/**
 * Returns a matcher that reports if a value is not null and meets the criteria of the [valueMatcher]
 */
fun  present(valueMatcher: Matcher): Matcher =
        object : Matcher.Primitive() {
            override fun invoke(actual: T?): MatchResult {
                return when (actual) {
                    null -> MatchResult.Mismatch("was null")
                    else -> valueMatcher(actual)
                }
            }

            override fun description(): String {
                return "is not null & " + valueMatcher.description()
            }
        }

/**
 * Returns a matcher that reports if a value of [Any] type is of a type compatible with [downcastMatcher] and, if so,
 * if the value meets its criteria.
 */
inline fun  cast(downcastMatcher: Matcher): Matcher {
    return object : Matcher.Primitive() {
        override fun invoke(actual: Any): MatchResult {
            return when (actual) {
                is T -> {
                    downcastMatcher(actual)
                }
                else -> {
                    MatchResult.Mismatch("had type ${actual.javaClass.kotlin.qualifiedName}")
                }
            }
        }

        override fun description(): String {
            return "has type " + T::class.qualifiedName + " & " + downcastMatcher.description()
        }
    }
}

/**
 * Returns a matcher that reports if a [Comparable] value is greater than [n]
 */
fun > greaterThan(n: N) = _comparesAs("greater than", n) { it > 0 }

/**
 * Returns a matcher that reports if a [Comparable] value is greater than or equal to [n]
 */
fun > greaterThanOrEqualTo(n: N) = _comparesAs("greater than or equal to", n) { it >= 0 }

/**
 * Returns a matcher that reports if a [Comparable] value is less than [n]
 */
fun > lessThan(n: N) = _comparesAs("less than", n) { it < 0 }

/**
 * Returns a matcher that reports if a [Comparable] value is less than or equal to [n]
 */
fun > lessThanOrEqualTo(n: N) = _comparesAs("less than or equal to", n) { it <= 0 }

private fun > _comparesAs(description: String, n: N, expectedSignum: (Int) -> Boolean): Matcher {
    return object : Matcher.Primitive() {
        override fun invoke(actual: N): MatchResult =
                match(expectedSignum(actual.compareTo(n))) { "was ${describe(actual)}" }

        override fun description(): String {
            return "is ${description} ${describe(n)}"
        }
    }
}

/**
 * Returns a matcher that reports if a [kotlin.Comparable] value falls within the given [range].
 *
 * @param range The range that contains matching values.
 */
fun > isWithin(range: ClosedRange): Matcher {
    fun _isWithin(actual: T, range: ClosedRange): Boolean {
        return range.contains(actual)
    }

    return Matcher.Companion(::_isWithin, range)
}


/**
 * Returns a matcher that reports if a block throws an exception of type [T] and, if [exceptionCriteria] is given,
 * the exception matches the [exceptionCriteria].
 */
inline fun  throws(exceptionCriteria: Matcher? = null): Matcher<() -> Unit> {
    val exceptionName = T::class.qualifiedName

    return object : Matcher.Primitive<() -> Unit>() {
        override fun invoke(actual: () -> Unit): MatchResult =
                try {
                    actual()
                    MatchResult.Mismatch("did not throw")
                } catch (e: Throwable) {
                    if (e is T) {
                        exceptionCriteria?.invoke(e) ?: MatchResult.Match
                    }
                    else {
                        MatchResult.Mismatch("threw ${e.javaClass.kotlin.qualifiedName}")
                    }
                }

        override fun description() = "throws ${exceptionName}${exceptionCriteria?.let{" that ${describe(it)}"}?:""}"
        override fun negatedDescription() = "does not throw ${exceptionName}${exceptionCriteria?.let{" that ${describe(it)}"}?:""}"
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy