Skip to content

Commit

Permalink
#292 show only failing for inOrder.only if more than 10 elements
Browse files Browse the repository at this point in the history
I decided that I will apply a default heuristic so that (I hope) most
users don't have to change reporting options.
  • Loading branch information
robstoll committed Jul 12, 2021
1 parent aa259d7 commit 8a39f3a
Show file tree
Hide file tree
Showing 45 changed files with 685 additions and 196 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1062,9 +1062,7 @@ This makes of course only sense if your `Iterable` contains nullable elements.
Atrium provides also a `notToContain` shortcut function.
Furthermore, it provides aliases for `toContain` and `notToContain` named `toHaveNextAndAny` and `toHaveNextAndNone`,
which might be a better choice if you think in terms of: expect a predicate holds.
These two are completed with an `toHaveNextAndAll` assertion function.

<!-- TODO 0.17.0 add text about notToHaveNextOrAll -->
These two are completed with an `toHaveNextAndAll` assertion function.

Following each in action:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package ch.tutteli.atrium.api.fluent.en_GB

import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.logic.creating.typeutils.IterableLike
import ch.tutteli.atrium.logic.*
import ch.tutteli.atrium.logic.creating.iterable.contains.IterableLikeContains
import ch.tutteli.atrium.logic.creating.iterable.contains.creators.entriesInOrderOnly
import ch.tutteli.atrium.logic.creating.iterable.contains.creators.valuesInOrderOnly
import ch.tutteli.atrium.logic.creating.iterable.contains.reporting.InOrderOnlyReportingOptions
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.NoOpSearchBehaviour
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.NotSearchBehaviour
import ch.tutteli.atrium.logic.creating.iterable.contains.steps.NotCheckerStep
import ch.tutteli.atrium.logic.creating.typeutils.IterableLike
import ch.tutteli.atrium.logic.utils.toVarArg
import ch.tutteli.kbox.glue
import ch.tutteli.kbox.identity

/**
Expand Down Expand Up @@ -119,8 +124,16 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.toContain(
*
* @since 0.17.0
*/
fun <E, T : Iterable<E>> Expect<T>.toContainExactly(expected: E, vararg otherExpected: E): Expect<T> =
toContain.inOrder.only.values(expected, *otherExpected)
fun <E, T : Iterable<E>> Expect<T>.toContainExactly(
expected: E,
vararg otherExpected: E,
report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> =
//TODO 0.18.0 use the following
//toContain.inOrder.only.values(expected, *otherExpected, report = report)
toContain.inOrder.only._logicAppend {
valuesInOrderOnly(expected glue otherExpected, report)
}

/**
* Expects that the subject of `this` expectation (an [Iterable]) contains only an entry holding
Expand Down Expand Up @@ -172,8 +185,16 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.toContainExactly(assertionCreatorOrNul
*/
fun <E : Any, T : Iterable<E?>> Expect<T>.toContainExactly(
assertionCreatorOrNull: (Expect<E>.() -> Unit)?,
vararg otherAssertionCreatorsOrNulls: (Expect<E>.() -> Unit)?
): Expect<T> = toContain.inOrder.only.entries(assertionCreatorOrNull, *otherAssertionCreatorsOrNulls)
vararg otherAssertionCreatorsOrNulls: (Expect<E>.() -> Unit)?,
report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> =
//TODO 0.18.0 use the following
//toContain.inOrder.only.entries(assertionCreatorOrNull, *otherAssertionCreatorsOrNulls, report = report)
toContain.inOrder.only._logicAppend {
entriesInOrderOnly(
assertionCreatorOrNull glue otherAssertionCreatorsOrNulls,
report)
}

/**
* Expects that the subject of `this` expectation (an [Iterable]) contains only elements of [expectedIterableLike]
Expand All @@ -195,8 +216,13 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.toContainExactly(
* @since 0.17.0
*/
inline fun <reified E, T : Iterable<E>> Expect<T>.toContainExactlyElementsOf(
expectedIterableLike: IterableLike
): Expect<T> = toContain.inOrder.only.elementsOf(expectedIterableLike)
expectedIterableLike: IterableLike,
noinline report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> =
//TODO 0.18.0 use the following
// toContain.inOrder.only.elementsOf(expectedIterableLike)
toContain.inOrder.only._logic.toVarArg<E>(expectedIterableLike)
.let { (first, rest) -> toContain.inOrder.only._logicAppend { valuesInOrderOnly(first glue rest, report) } }

/** Expects that the subject of `this` expectation (an [Iterable]) contains all elements of [expectedIterableLike].
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ch.tutteli.atrium.logic._logicAppend
import ch.tutteli.atrium.logic.creating.iterable.contains.IterableLikeContains.EntryPointStep
import ch.tutteli.atrium.logic.creating.iterable.contains.creators.entriesInOrderOnly
import ch.tutteli.atrium.logic.creating.iterable.contains.creators.valuesInOrderOnly
import ch.tutteli.atrium.logic.creating.iterable.contains.reporting.InOrderOnlyReportingOptions
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlySearchBehaviour
import ch.tutteli.atrium.logic.creating.typeutils.IterableLike
import ch.tutteli.atrium.logic.creating.typeutils.IterableLikeToIterableTransformer
Expand Down Expand Up @@ -51,7 +52,9 @@ fun <E, T : IterableLike> EntryPointStep<E, T, InOrderOnlySearchBehaviour>.value
fun <E, T : IterableLike> EntryPointStep<E, T, InOrderOnlySearchBehaviour>.values(
expected: E,
vararg otherExpected: E
): Expect<T> = _logicAppend { valuesInOrderOnly(expected glue otherExpected) }
//TODO use the following with 0.18.0
//report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> = _logicAppend { valuesInOrderOnly(expected glue otherExpected, {}) }

/**
* Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike])
Expand Down Expand Up @@ -100,7 +103,9 @@ fun <E : Any, T : IterableLike> EntryPointStep<out E?, T, InOrderOnlySearchBehav
fun <E : Any, T : IterableLike> EntryPointStep<out E?, T, InOrderOnlySearchBehaviour>.entries(
assertionCreatorOrNull: (Expect<E>.() -> Unit)?,
vararg otherAssertionCreatorsOrNulls: (Expect<E>.() -> Unit)?
): Expect<T> = _logicAppend { entriesInOrderOnly(assertionCreatorOrNull glue otherAssertionCreatorsOrNulls) }
//TODO 0.18.0 add the following
//report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> = _logicAppend { entriesInOrderOnly(assertionCreatorOrNull glue otherAssertionCreatorsOrNulls, {}) }

/**
* Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike])
Expand All @@ -127,4 +132,6 @@ fun <E : Any, T : IterableLike> EntryPointStep<out E?, T, InOrderOnlySearchBehav
*/
inline fun <reified E, T : IterableLike> EntryPointStep<E, T, InOrderOnlySearchBehaviour>.elementsOf(
expectedIterableLike: IterableLike
//TODO 0.18.0 add the following
//noinline report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> = _logic.toVarArg<E>(expectedIterableLike).let { (first, rest) -> values(first, *rest) }
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import ch.tutteli.atrium.logic._logicAppend
import ch.tutteli.atrium.logic.creating.iterable.contains.IterableLikeContains.EntryPointStep
import ch.tutteli.atrium.logic.creating.iterable.contains.creators.entriesInOrderOnlyGrouped
import ch.tutteli.atrium.logic.creating.iterable.contains.creators.valuesInOrderOnlyGrouped
import ch.tutteli.atrium.logic.creating.iterable.contains.reporting.InOrderOnlyReportingOptions
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlyGroupedWithinSearchBehaviour
import kotlin.jvm.JvmName

Expand All @@ -30,11 +31,15 @@ import kotlin.jvm.JvmName
*
* @since 0.14.0 -- API existed for [Iterable] but not for [IterableLike].
*/
fun <E, T: IterableLike> EntryPointStep<E, T, InOrderOnlyGroupedWithinSearchBehaviour>.inAnyOrder(
fun <E, T : IterableLike> EntryPointStep<E, T, InOrderOnlyGroupedWithinSearchBehaviour>.inAnyOrder(
firstGroup: Group<E>,
secondGroup: Group<E>,
vararg otherExpectedGroups: Group<E>
): Expect<T> = _logicAppend { valuesInOrderOnlyGrouped(groupsToList(firstGroup, secondGroup, otherExpectedGroups)) }
//TODO 0.18.0 add the following
//report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> = _logicAppend {
valuesInOrderOnlyGrouped(groupsToList(firstGroup, secondGroup, otherExpectedGroups), {})
}

/**
* Finishes the specification of the sophisticated `contains` assertion where the expected [firstGroup] as well as
Expand All @@ -56,8 +61,12 @@ fun <E, T: IterableLike> EntryPointStep<E, T, InOrderOnlyGroupedWithinSearchBeha
* @since 0.14.0 -- API existed for [Iterable] but not for [IterableLike].
*/
@JvmName("inAnyOrderEntries")
fun <E : Any, T: IterableLike> EntryPointStep<out E?, T, InOrderOnlyGroupedWithinSearchBehaviour>.inAnyOrder(
fun <E : Any, T : IterableLike> EntryPointStep<out E?, T, InOrderOnlyGroupedWithinSearchBehaviour>.inAnyOrder(
firstGroup: Group<(Expect<E>.() -> Unit)?>,
secondGroup: Group<(Expect<E>.() -> Unit)?>,
vararg otherExpectedGroups: Group<(Expect<E>.() -> Unit)?>
): Expect<T> = _logicAppend { entriesInOrderOnlyGrouped(groupsToList(firstGroup, secondGroup, otherExpectedGroups)) }
//TODO 0.18.0 add the following
//report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> = _logicAppend {
entriesInOrderOnlyGrouped(groupsToList(firstGroup, secondGroup, otherExpectedGroups), {})
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import kotlin.reflect.KClass
fun <K, V, T : MapLike> EntryPointStep<K, V, T, InAnyOrderOnlySearchBehaviour>.entry(keyValuePair: Pair<K, V>): Expect<T> =
entries(keyValuePair)

// TODO 0.17.0 implement https://github.com/robstoll/atrium/issues/292 for the new function in ...Expectations.kt file
/**
* Finishes the specification of the sophisticated `contains` assertion where the subject (a [MapLike])
* needs to contain only the given [keyValuePair] as well as the [otherPairs] where it does not matter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.logic._logic
import ch.tutteli.atrium.logic._logicAppend
import ch.tutteli.atrium.logic.creating.iterable.contains.reporting.InOrderOnlyReportingOptions
import ch.tutteli.atrium.logic.creating.maplike.contains.MapLikeContains.EntryPointStep
import ch.tutteli.atrium.logic.creating.maplike.contains.creators.keyValuePairsInOrderOnly
import ch.tutteli.atrium.logic.creating.maplike.contains.creators.keyWithValueAssertionsInOrderOnly
Expand All @@ -29,7 +30,6 @@ import kotlin.reflect.KClass
fun <K, V, T : MapLike> EntryPointStep<K, V, T, InOrderOnlySearchBehaviour>.entry(keyValuePair: Pair<K, V>): Expect<T> =
entries(keyValuePair)

// TODO 0.17.0 implement https://github.com/robstoll/atrium/issues/292 for the new function in ...Expectations.kt file
/**
* Finishes the specification of the sophisticated `contains` assertion where the subject (a [MapLike])
* needs to contain only the given [keyValuePair] as well as the [otherPairs] in the specified order.
Expand All @@ -41,7 +41,9 @@ fun <K, V, T : MapLike> EntryPointStep<K, V, T, InOrderOnlySearchBehaviour>.entr
fun <K, V, T : MapLike> EntryPointStep<K, V, T, InOrderOnlySearchBehaviour>.entries(
keyValuePair: Pair<K, V>,
vararg otherPairs: Pair<K, V>
): Expect<T> = _logicAppend { keyValuePairsInOrderOnly(keyValuePair glue otherPairs) }
//TODO 0.18.0 add the following
//report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> = _logicAppend { keyValuePairsInOrderOnly(keyValuePair glue otherPairs, {}) }


/**
Expand Down Expand Up @@ -83,11 +85,12 @@ inline fun <K, reified V : Any, T : MapLike> EntryPointStep<K, out V?, T, InOrde
internal fun <K, V : Any, T : MapLike> EntryPointStep<K, out V?, T, InOrderOnlySearchBehaviour>.entries(
kClass: KClass<V>,
keyValues: List<KeyValue<K, V>>
//TODO 0.18.0 add the following
//report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> = _logicAppend {
keyWithValueAssertionsInOrderOnly(kClass, keyValues.map { it.toPair() })
keyWithValueAssertionsInOrderOnly(kClass, keyValues.map { it.toPair() }, { })
}

// TODO 0.17.0 implement https://github.com/robstoll/atrium/issues/292 for the new function in ...Expectations.kt file
/**
* Finishes the specification of the sophisticated `contains` assertion where the subject (a [MapLike])
* needs to contain only and all entries of the given [expectedMapLike] in the specified order.
Expand All @@ -108,5 +111,7 @@ internal fun <K, V : Any, T : MapLike> EntryPointStep<K, out V?, T, InOrderOnlyS
*/
fun <K, V, T : MapLike> EntryPointStep<K, V, T, InOrderOnlySearchBehaviour>.entriesOf(
expectedMapLike: MapLike
//TODO 0.18.0 add the following
//report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<T> = _logic.toVarArgPairs<K, V>(expectedMapLike).let { (first, rest) -> entries(first, *rest) }

Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package ch.tutteli.atrium.api.fluent.en_GB

import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.logic._logicAppend
import ch.tutteli.atrium.logic.creating.iterable.contains.creators.valuesInOrderOnly
import ch.tutteli.atrium.logic.creating.iterable.contains.reporting.InOrderOnlyReportingOptions
import ch.tutteli.atrium.specs.integration.IterableToContainSpecBase.Companion.emptyInOrderOnlyReportOptions
import ch.tutteli.atrium.specs.notImplemented
import ch.tutteli.atrium.specs.withNullableSuffix
import org.spekframework.spek2.Spek
Expand Down Expand Up @@ -45,26 +49,36 @@ class IterableToContainInOrderOnlyElementsOfExpectationsSpec : Spek({
fun toContainInOrderOnlyValues(
expect: Expect<Iterable<Double>>,
a: Double,
aX: Array<out Double>
): Expect<Iterable<Double>> = expect.toContain.inOrder.only.elementsOf(listOf(a, *aX))
aX: Array<out Double>,
report: InOrderOnlyReportingOptions.() -> Unit
): Expect<Iterable<Double>> =
//TODO 0.18.0 remove if once implemented
if (report === emptyInOrderOnlyReportOptions) expect.toContain.inOrder.only.elementsOf(listOf(a, *aX))
else expect.toContain.inOrder.only._logicAppend { valuesInOrderOnly(listOf(a, *aX), report) }

private fun toContainInOrderOnlyNullableValues(
expect: Expect<Iterable<Double?>>,
a: Double?,
aX: Array<out Double?>
): Expect<Iterable<Double?>> = expect.toContain.inOrder.only.elementsOf(sequenceOf(a, *aX))
aX: Array<out Double?>,
report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<Iterable<Double?>> =
//TODO 0.18.0 remove if once implemented
if (report === emptyInOrderOnlyReportOptions) expect.toContain.inOrder.only.elementsOf(sequenceOf(a, *aX))
else expect.toContain.inOrder.only._logicAppend { valuesInOrderOnly(listOf(a, *aX), report) }

private fun toContainExactlyElementsOfShortcut(
expect: Expect<Iterable<Double>>,
a: Double,
aX: Array<out Double>
): Expect<Iterable<Double>> = expect.toContainExactlyElementsOf(arrayOf(a, *aX))
aX: Array<out Double>,
report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<Iterable<Double>> = expect.toContainExactlyElementsOf(arrayOf(a, *aX), report)

private fun toContainExactlyElementsOfNullableShortcut(
expect: Expect<Iterable<Double?>>,
a: Double?,
aX: Array<out Double?>
): Expect<Iterable<Double?>> = expect.toContainExactlyElementsOf(sequenceOf(a, *aX).asIterable())
aX: Array<out Double?>,
report: InOrderOnlyReportingOptions.() -> Unit = {}
): Expect<Iterable<Double?>> = expect.toContainExactlyElementsOf(sequenceOf(a, *aX).asIterable(), report)
}


Expand All @@ -79,17 +93,22 @@ class IterableToContainInOrderOnlyElementsOfExpectationsSpec : Spek({
nList = nList.toContain.inOrder.only.elementsOf(listOf<Int>())
subList = subList.toContain.inOrder.only.elementsOf(listOf<Int>())
star = star.toContain.inOrder.only.elementsOf(listOf<Int>())

list = list.toContainExactlyElementsOf(1)
nList = nList.toContainExactlyElementsOf(1)
subList = subList.toContainExactlyElementsOf(1)
star = star.toContainExactlyElementsOf(1)

list = list.toContainExactlyElementsOf(listOf(1, 1.2))
nList = nList.toContainExactlyElementsOf(listOf(1, 1.2))
subList = subList.toContainExactlyElementsOf(listOf(1, 2.2))
subList = subList.toContainExactlyElementsOf(listOf(1))
star = star.toContainExactlyElementsOf(listOf(1, 1.2, "asdf"))
//TODO use the following with 0.18.0
// list = list.toContain.inOrder.only.elementsOf(listOf<Int>(), report = { showAlwaysSummary() })
// nList = nList.toContain.inOrder.only.elementsOf(listOf<Int>(), report = { showOnlyFailing() })
// subList = subList.toContain.inOrder.only.elementsOf(listOf<Int>(), report = { })
// star = star.toContain.inOrder.only.elementsOf(listOf<Int>(), report = { })

list = list.toContainExactlyElementsOf(1, report = { })
nList = nList.toContainExactlyElementsOf(1, report = { })
subList = subList.toContainExactlyElementsOf(1, report = { })
star = star.toContainExactlyElementsOf(1, report = { })

list = list.toContainExactlyElementsOf(listOf(1, 1.2), report = { })
nList = nList.toContainExactlyElementsOf(listOf(1, 1.2), report = { })
subList = subList.toContainExactlyElementsOf(listOf(1, 2.2), report = { })
subList = subList.toContainExactlyElementsOf(listOf(1), report = { })
star = star.toContainExactlyElementsOf(listOf(1, 1.2, "asdf"), report = { })
}
}

Loading

0 comments on commit 8a39f3a

Please sign in to comment.