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

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

Go to download

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

The newest version!
@file:Suppress("NOTHING_TO_INLINE")

package ch.tutteli.atrium.creating

import ch.tutteli.atrium._coreAppend
import ch.tutteli.atrium.core.None
import ch.tutteli.atrium.core.Option
import ch.tutteli.atrium.core.Some
import ch.tutteli.atrium.creating.proofs.Proof
import ch.tutteli.atrium.creating.proofs.ProofGroup
import ch.tutteli.atrium.creating.proofs.builders.buildProof
import ch.tutteli.atrium.creating.transformers.TransformationExecutionStep
import ch.tutteli.atrium.reporting.reportables.Reportable
import ch.tutteli.kbox.mapFirst

/**
 * Use this function if you want to state expectations about a feature of the subject or you perform a
 * type transformation or any other action which results in an [Expect] being created for a different subject than the
 * current and you do not require this resulting [Expect] but are only interested in the resulting proofs.
 *
 * Or in other words, you do not want to state further expectations about the resulting subject in the resulting sub
 * [Expect].
 *
 * Note that a proof will be added which fails in case the given [expectationCreatorWithUsageHints] does not append a single
 * [Proof].
 *
 * It uses the [ProofContainer.maybeSubject] as subject of the given [ExpectationCreatorWithUsageHints.expectationCreator]
 * and delegates to [collectBasedOnGivenSubject].
 *
 * @param expectationCreatorWithUsageHints defines the [ExpectationCreator]-lambda as well as the usage hints which
 *   are shown in case no expectation is created within the lambda.
 *
 * @return The collected proof
 */
inline fun  ProofContainer.collect(
    expectationCreatorWithUsageHints: ExpectationCreatorWithUsageHints
): Proof = collectBasedOnGivenSubject(maybeSubject, expectationCreatorWithUsageHints)


//TODO 1.3.0 KDOC (see next function) and check if Boolean flag is used somewhere
/**
 * @since 1.3.0
 */
inline fun  ProofContainer<*>.collectForFailureHint(
    expectationCreatorWithUsageHints: ExpectationCreatorWithUsageHints
): Pair, Boolean> =
    collectForCompositionBasedOnGivenSubject(None, expectationCreatorWithUsageHints).mapFirst { collectedProofs ->
        maybeSubject.fold({
            // already in a proofExplanation group no need to wrap again
            collectedProofs
        }, {
            listOf(buildProof {
                invisibleFixedClaimGroup(holds = false) {
                    proofExplanation { addAll(collectedProofs) }
                }
            })
        })
    }

/**
 * Use this function if you want to collect [Proof]s and use it as part of another [Proof] (e.g. as part
 * of a [ProofGroup]).
 *
 * Note that a proof will be added which fails in case the given [expectationCreatorWithUsageHints] does not append a single
 * [Proof].
 *
 * It uses the [ProofContainer.maybeSubject] as subject of the given [ExpectationCreatorWithUsageHints.expectationCreator]
 * and delegates to [collectBasedOnGivenSubject].
 *
 * @param expectationCreatorWithUsageHints defines the [ExpectationCreator]-lambda as well as the usage hints which
 *   are shown in case no expectation is created within the lambda.
 *
 * @return The collected proofs and a boolean flag indicating whether at least one proof was appended or not.
 */
//TODO 1.3.0 better rename to collectForFailureHint as well?
inline fun  ProofContainer.collectForComposition(
    expectationCreatorWithUsageHints: ExpectationCreatorWithUsageHints
): Pair, Boolean> =
    collectForCompositionBasedOnGivenSubject(maybeSubject, expectationCreatorWithUsageHints)

/**
 * Use this function if you want to state expectations about a feature of the subject or you perform a
 * type transformation or any other action which results in an [Expect] being created for a different subject than the
 * current and you do not require this resulting [Expect] but are only interested in the resulting proofs.
 *
 * Or in other words, you do not want to state further expectations about the resulting subject in the resulting sub
 * [Expect].
 *
 * Note that a proof will be added which fails in case the given [expectationCreatorWithUsageHints] does not append a single
 * [Proof].
 *
 * @param maybeSubject Either [Some] wrapping the subject of the current expectation or
 *   [None] in case a previous subject transformation was not successful -
 *   this will be used as subject for the given [expectationCreatorWithUsageHints].
 * @param expectationCreatorWithUsageHints defines the [ExpectationCreator]-lambda as well as the usage hints which
 *   are shown in case no expectation is created within the lambda.
 *
 * @return The collected proofs and a boolean flag indicating whether at least one proof was appended or not.
 */
//TODO check if it makes more sense to stay on the core level for expectationCreatorWithUsageHints, i.e. to use ProofContainer.() -> Unit instead of Expect.() -> Unit
//TODO 1.3.0 document params
//TODO 1.3.0 check replaceWith in @Deprecation in atrium-logic, we renamed the function from collectBasedOnSubject to collectBasedOnGivenSubject
inline fun  ProofContainer<*>.collectBasedOnGivenSubject(
    maybeSubject: Option,
    expectationCreatorWithUsageHints: ExpectationCreatorWithUsageHints
): Proof {
    //TODO 1.3.0 check if it makes sense to return a Proof, maybe List would be better?
    val (collectedProofs, _) = collectForCompositionBasedOnGivenSubject(maybeSubject, expectationCreatorWithUsageHints)
    return if (collectedProofs.size > 1) {
        buildProof { invisibleGroup { addAll(collectedProofs) } }
    } else {
        collectedProofs[0]
    }
}


/**
 * Use this function if you want to collect [Proof]s and use it as part of another [Proof] (e.g. as part
 * of a [ProofGroup]).
 *
 * Note that a proof will be added which fails in case the given [expectationCreatorWithUsageHints] does not append a single
 * [Proof].
 *
 * @param maybeSubject Either [Some] wrapping the subject of the current expectation or
 *   [None] in case a previous subject transformation was not successful -
 *   this will be used as subject for the given [expectationCreatorWithUsageHints].
 * @param expectationCreatorWithUsageHints defines the [ExpectationCreator]-lambda as well as the usage hints which
 *   are shown in case no expectation is created within the lambda.
 *
 * @return The collected proofs and a boolean flag indicating whether at least one proof was appended or not.
 */
//TODO 1.3.0 check where the flag is used, we had a todo that we should return a flag but so far I don't see a usage
// where it would make sense
//TODO 1.3.0 check replaceWith of logic, we renamed the function from collectForCompositionBasedOnSubject to collectForCompositionBasedOnGivenSubject
//TODO 1.3.0 better rename to collectForFailureHintBasedOnGivenSubject?
@OptIn(ExperimentalComponentFactoryContainer::class)
inline fun  ProofContainer<*>.collectForCompositionBasedOnGivenSubject(
    maybeSubject: Option,
    expectationCreatorWithUsageHints: ExpectationCreatorWithUsageHints
): Pair, Boolean> = CollectingExpect(maybeSubject, components)
    .appendAsGroupIndicateIfOneCollected(expectationCreatorWithUsageHints).mapFirst { it.getCollectedProofs() }

/**
 * Finishes the transformation process by appending the [Proof]
 * which is returned when calling [TransformationExecutionStep.collectAndAppend] with [_coreAppend]
 * and the given [expectationCreator].
 *
 * See [collectBasedOnGivenSubject] for more information.
 *
 * @return an [Expect] for the subject of this expectation.
 */
//TODO 1.3.0 remove?
fun > TransformationExecutionStep.collectAndDomainAppend(
    usageHintsOverloadWithoutExpectationCreator: List,
    expectationCreator: ProofContainer.() -> Proof
): Expect =
    collectAndAppend(ExpectationCreatorWithUsageHints(usageHintsOverloadWithoutExpectationCreator) {
        _coreAppend(expectationCreator)
    })




© 2015 - 2025 Weber Informatics LLC | Privacy Policy