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

commonMain.ch.tutteli.atrium.creating.Expect.kt Maven / Gradle / Ivy

Go to download

Core module of Atrium, containing all contracts/interfaces and default implementations

There is a newer version: 1.2.0
Show newest version
package ch.tutteli.atrium.creating

import ch.tutteli.atrium.assertions.Assertion

/**
 * The internal type which we work with which combines [Expect], [AssertionContainer] and [ExpectGrouping].
 *
 * In theory, [Expect] should extend [ExpectGrouping] but due to Kotlin type inference/overload resolution bugs, we have
 * to split it. One benefit of it, we can define extensions for [ExpectGrouping] which are not visible for [Expect].
 *
 * Similarly, we separate [Expect] from [AssertionContainer] so that we can provide extension functions for
 * [AssertionContainer] which are more or less identical to the ones defined for api-fluent but don't return an [Expect]
 * but [Assertion] etc.
 *
 * Also, we separate [Expect] form [AssertionContainer] since a lot of functionality defined for AssertionContainer is
 * not relevant for newcomers to Atrium (see [https://github.com/robstoll/atrium-roadmap/wiki/Requirements#personas](https://github.com/robstoll/atrium-roadmap/wiki/Requirements#personas)
 * for more information about the personas).
 */
interface ExpectInternal : Expect, AssertionContainer, ExpectGrouping

/**
 * Represents the extension point for expectation functions and sophisticated builders for subjects of type [T].
 *
 * Following a simple example, see [Write own Expectation Functions](https://github.com/robstoll/atrium?tab=readme-ov-file#write-own-expectation-functions)
 * for more help:
 * ```kotlin
 * val  Expect.errorCode: FeatureExpect
 *     get() = feature(SQLException::getErrorCode)
 * ```
 *
 * Note, that we have used a type parameter and not `Expect`. This is due to the fact that `Expect`
 * is [invariant](https://kotlinlang.org/docs/reference/generics.html#variance) which means without type parameter
 * something like the following would result in a compile error
 * ```kotlin
 * expect {
 *   ...
 * }.toThrow {
 *   errorCode.toEqual(23000)
 *   // compile error: None of the following candidates is applicable because of receiver type mismatch:
 * }
 * ```
 * Besides, we would need to return a `FeatureExpect` and would therefore lose the information
 * that the thrown Exception was a `BatchUpdateException` and would first need to use `toBeAnInstanceOf`
 * if we want to assert something which is specific to `BatchUpdateException`. With the type parameter we don't and
 * could therefore then also write something like the following within the `toThrow` block:
 * ```kotlin
 *   feature(BatchUpdateException::getUpdateCounts).toEqual(intArrayOf(3, 2))
 * ```
 *
 * In general, you should always use the type parameter approach, the only exception is if you deal with final classes
 * (e.g. data classes) which don't have a type parameter itself. In such a case there is no benefit to have a type
 * parameter but on the other hand, it also doesn't hurt -- less to think about
 * (your IDE might warn you that it is not necessary though).
 *
 * As a side notice, we have not defined `Expect` as covariant on purpose (switched to invariant in v0.9.0),
 * because if we did, then things like `expect(1).toEqual(1.0)` would no longer be a compile error.
 * And Atrium's goal is exactly to prevent users from pitfalls like that.
 *
 * @param T The type of the subject of `this` expectation.
 */
interface Expect
typealias ExpectationCreator = Expect.() -> Unit

/**
 * Represents a group of expectations including nested groups of expectations (nested [ExpectGrouping]).
 *
 * It's the extension point for groups of expectations with unrelated subjects.
 *
 * @since 1.1.0
 */
interface ExpectGrouping




© 2015 - 2024 Weber Informatics LLC | Privacy Policy