diff --git a/README.md b/README.md index e02ead502f..3f96dc7df8 100644 --- a/README.md +++ b/README.md @@ -1167,7 +1167,7 @@ then only failing expectations are shown. 💬 Show only failing expectations/elements earlier than 10 elements? You can use the `report` option to specify when Atrium shall start to show only failing expectations. -Following an example changing the limit to 3 elements by using `showOnlyFailingIfMoreElementsThan` : +Following an example changing the limit to 3 elements by using `showOnlyFailingIfMoreExpectedElementsThan` : @@ -1176,7 +1176,7 @@ expect(listOf(1, 2, 2, 4)).toContainExactly( { toBeLessThan(3) }, { toBeLessThan(2) }, { toBeGreaterThan(1) }, - report = { showOnlyFailingIfMoreElementsThan(3) } + report = { showOnlyFailingIfMoreExpectedElementsThan(2) } ) ``` ↑ [Example](https://github.com/robstoll/atrium/tree/main/misc/tools/readme-examples/src/main/kotlin/readme/examples/MostExamplesSpec.kt#L154) ↓ [Output](#ex-collection-reportOptions-1) diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/iterableLikeToContainInAnyOrderOnlyCreators.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/iterableLikeToContainInAnyOrderOnlyCreators.kt index b74f874297..deba1cbb74 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/iterableLikeToContainInAnyOrderOnlyCreators.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/iterableLikeToContainInAnyOrderOnlyCreators.kt @@ -10,6 +10,8 @@ import ch.tutteli.atrium.logic.creating.iterable.contains.creators.entriesInAnyO import ch.tutteli.atrium.logic.creating.iterable.contains.creators.values import ch.tutteli.atrium.logic.creating.iterable.contains.creators.valuesInAnyOrderOnly import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLikeToIterableTransformer import ch.tutteli.atrium.logic.utils.toVarArg import ch.tutteli.kbox.glue @@ -26,7 +28,7 @@ import ch.tutteli.kbox.glue * * @since 0.14.0 -- API existed for [Iterable] but not for [IterableLike]. */ -fun EntryPointStep.value(expected: E): Expect = +fun EntryPointStep.value(expected: E): Expect = values(expected) /** @@ -36,15 +38,19 @@ fun EntryPointStep.val * * @param expected The value which is expected to be contained within the subject (an [IterableLike]). * @param otherExpected Additional values which are expected to be contained within [IterableLike]. + * @param report The lambda configuring the [InAnyOrderOnlyReportingOptions] -- it is optional where + * the default [InAnyOrderOnlyReportingOptions] apply if not specified. + * since 0.18.0 * * @return an [Expect] for the subject of `this` expectation. * * @since 0.14.0 -- API existed for [Iterable] but not for [IterableLike]. */ -fun EntryPointStep.values( +fun EntryPointStep.values( expected: E, - vararg otherExpected: E -): Expect = _logicAppend { valuesInAnyOrderOnly(expected glue otherExpected) } + vararg otherExpected: E, + report: InAnyOrderOnlyReportingOptions.() -> Unit = {} +): Expect = _logicAppend { valuesInAnyOrderOnly(expected glue otherExpected, report) } /** * Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike]) @@ -61,7 +67,7 @@ fun EntryPointStep.val * * @since 0.14.0 -- API existed for [Iterable] but not for [IterableLike]. */ -fun EntryPointStep.entry( +fun EntryPointStep.entry( assertionCreatorOrNull: (Expect.() -> Unit)? ): Expect = entries(assertionCreatorOrNull) @@ -85,15 +91,19 @@ fun EntryPointStep EntryPointStep.entries( +fun EntryPointStep.entries( assertionCreatorOrNull: (Expect.() -> Unit)?, - vararg otherAssertionCreatorsOrNulls: (Expect.() -> Unit)? -): Expect = _logicAppend { entriesInAnyOrderOnly(assertionCreatorOrNull glue otherAssertionCreatorsOrNulls) } + vararg otherAssertionCreatorsOrNulls: (Expect.() -> Unit)?, + report: InAnyOrderOnlyReportingOptions.() -> Unit = {} +): Expect = _logicAppend { entriesInAnyOrderOnly(assertionCreatorOrNull glue otherAssertionCreatorsOrNulls, report) } /** * Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike]) @@ -106,6 +116,9 @@ fun EntryPointStep EntryPointStep EntryPointStep.elementsOf( - expectedIterableLike: IterableLike -): Expect = _logic.toVarArg(expectedIterableLike).let { (first, rest) -> values(first, *rest) } +inline fun EntryPointStep.elementsOf( + expectedIterableLike: IterableLike, + noinline report: InAnyOrderOnlyReportingOptions.() -> Unit = {} +): Expect = _logic.toVarArg(expectedIterableLike).let { (first, rest) -> values(first, *rest, report = report) } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/iterableLikeToContainInOrderOnlyCreators.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/iterableLikeToContainInOrderOnlyCreators.kt index abfca0a5b1..40562400c3 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/iterableLikeToContainInOrderOnlyCreators.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/iterableLikeToContainInOrderOnlyCreators.kt @@ -37,6 +37,7 @@ fun EntryPointStep.value * @param otherExpected Additional values which are expected to be contained within [IterableLike]. * @param report The lambda configuring the [InOrderOnlyReportingOptions] -- it is optional where * the default [InOrderOnlyReportingOptions] apply if not specified. + * since 0.17.0 * * @return an [Expect] for the subject of `this` expectation. * @@ -81,6 +82,7 @@ fun EntryPointStep EntryPointStep EntryPointStep, secondGroup: Group, vararg otherExpectedGroups: Group, - report: InOrderOnlyReportingOptions.() -> Unit = {} + report: InOrderOnlyReportingOptions.() -> Unit = {}, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit = {} ): Expect = _logicAppend { - valuesInOrderOnlyGrouped(groupsToList(firstGroup, secondGroup, otherExpectedGroups), report) + valuesInOrderOnlyGrouped(groupsToList(firstGroup, secondGroup, otherExpectedGroups), report, reportInGroup) } /** @@ -54,6 +60,10 @@ fun EntryPointStep EntryPointStep.() -> Unit)?>, secondGroup: Group<(Expect.() -> Unit)?>, vararg otherExpectedGroups: Group<(Expect.() -> Unit)?>, - report: InOrderOnlyReportingOptions.() -> Unit = {} + report: InOrderOnlyReportingOptions.() -> Unit = {}, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit = {} ): Expect = _logicAppend { - entriesInOrderOnlyGrouped(groupsToList(firstGroup, secondGroup, otherExpectedGroups), report) + entriesInOrderOnlyGrouped(groupsToList(firstGroup, secondGroup, otherExpectedGroups), report, reportInGroup) } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/mapLikeToContainInOrderOnlyCreators.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/mapLikeToContainInOrderOnlyCreators.kt index 49eb84cd34..615e6e892b 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/mapLikeToContainInOrderOnlyCreators.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/mapLikeToContainInOrderOnlyCreators.kt @@ -33,6 +33,10 @@ fun EntryPointStep.entr * 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. * + * @param report The lambda configuring the [InOrderOnlyReportingOptions] -- it is optional where + * the default [InOrderOnlyReportingOptions] apply if not specified. + * since 0.18.0 + * * @return an [Expect] for the subject of `this` expectation. * * @since 0.15.0 @@ -41,7 +45,7 @@ fun EntryPointStep.entr keyValuePair: Pair, vararg otherPairs: Pair, report: InOrderOnlyReportingOptions.() -> Unit = {} -): Expect = _logicAppend { keyValuePairsInOrderOnly(keyValuePair glue otherPairs,report) } +): Expect = _logicAppend { keyValuePairsInOrderOnly(keyValuePair glue otherPairs, report) } /** @@ -69,6 +73,10 @@ inline fun EntryPointStep EntryPointStep EntryPointStep.entriesOf( expectedMapLike: MapLike, report: InOrderOnlyReportingOptions.() -> Unit = {} -): Expect = _logic.toVarArgPairs(expectedMapLike).let { (first, rest) -> entries(first, *rest, report = report) } +): Expect = + _logic.toVarArgPairs(expectedMapLike).let { (first, rest) -> entries(first, *rest, report = report) } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec.kt index 2b75c0a8df..8db1736beb 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec.kt @@ -43,7 +43,6 @@ class IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec : Spek({ else expect.toContain.inAnyOrder.atLeast(1).entries(a, *aX) } - @Suppress("unused", "UNUSED_VALUE") private fun ambiguityTest() { var list: Expect> = notImplemented() diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderExactlyValuesExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderExactlyValuesExpectationsSpec.kt index b1e5ed5623..7751aa5331 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderExactlyValuesExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderExactlyValuesExpectationsSpec.kt @@ -46,5 +46,4 @@ class IterableToContainInAnyOrderExactlyValuesExpectationsSpec : subList = subList.toContain.inAnyOrder.exactly(2).values(1, 2.2) star = star.toContain.inAnyOrder.exactly(2).values(1, 1.2, "asdf") } - } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec.kt index 774f28a61f..c0bf7a3053 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec.kt @@ -1,6 +1,8 @@ package ch.tutteli.atrium.api.fluent.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.specs.integration.IterableToContainSpecBase.Companion.emptyInAnyOrderOnlyReportOptions import ch.tutteli.atrium.specs.notImplemented import ch.tutteli.atrium.specs.withNullableSuffix import org.spekframework.spek2.Spek @@ -15,11 +17,12 @@ class IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec : Spek({ (functionDescription to C::toContainElementsOfNullable).withNullableSuffix() ) - object BuilderIterableLikeToIterableSpec : ch.tutteli.atrium.specs.integration.IterableLikeToIterableSpec>( - functionDescription, - listOf(1, 2), - { input -> toContain.inAnyOrder.only.elementsOf(input) } - ) + object BuilderIterableLikeToIterableSpec : + ch.tutteli.atrium.specs.integration.IterableLikeToIterableSpec>( + functionDescription, + listOf(1, 2), + { input -> toContain.inAnyOrder.only.elementsOf(input) } + ) companion object : IterableToContainSpecBase() { val functionDescription = "$toContain.$inAnyOrder.$only.$elementsOf" @@ -27,17 +30,24 @@ class IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec : Spek({ private fun toContainElementsOf( expect: Expect>, a: Double, - aX: Array - ): Expect> = expect.toContain.inAnyOrder.only.elementsOf(listOf(a, *aX)) + aX: Array, + report: InAnyOrderOnlyReportingOptions.() -> Unit + ): Expect> = + if (report == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inAnyOrder.only.elementsOf(listOf(a, *aX)) + } else expect.toContain.inAnyOrder.only.elementsOf(listOf(a, *aX), report = report) private fun toContainElementsOfNullable( expect: Expect>, a: Double?, - aX: Array - ): Expect> = expect.toContain.inAnyOrder.only.elementsOf(sequenceOf(a, *aX)) + aX: Array, + report: InAnyOrderOnlyReportingOptions.() -> Unit + ): Expect> = + if (report == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inAnyOrder.only.elementsOf(listOf(a, *aX)) + } else expect.toContain.inAnyOrder.only.elementsOf(listOf(a, *aX), report = report) } - @Suppress("unused", "UNUSED_VALUE") private fun ambiguityTest() { var list: Expect> = notImplemented() @@ -49,5 +59,16 @@ class IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec : Spek({ nList = nList.toContain.inAnyOrder.only.elementsOf(listOf()) subList = subList.toContain.inAnyOrder.only.elementsOf(listOf()) star = star.toContain.inAnyOrder.only.elementsOf(listOf()) + + list = list.toContain.inAnyOrder.only.elementsOf(listOf(), report = {}) + nList = nList.toContain.inAnyOrder.only.elementsOf(listOf(), report = {}) + subList = subList.toContain.inAnyOrder.only.elementsOf(listOf(), report = {}) + star = star.toContain.inAnyOrder.only.elementsOf(listOf(), report = {}) + + nList = nList.toContain.inAnyOrder.only.elementsOf(listOf()) + star = star.toContain.inAnyOrder.only.elementsOf(listOf()) + + list = list.toContain.inAnyOrder.only.elementsOf(listOf(), report = {}) + star = star.toContain.inAnyOrder.only.elementsOf(listOf(), report = {}) } } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt index f3a6b2f58d..62e46d52e6 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.fluent.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.specs.notImplemented import ch.tutteli.atrium.specs.withNullableSuffix @@ -15,21 +16,27 @@ class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec : private fun toContainInAnyOrderOnlyEntries( expect: Expect>, a: Expect.() -> Unit, - aX: Array.() -> Unit> + aX: Array.() -> Unit>, + report: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - if (aX.isEmpty()) expect.toContain.inAnyOrder.only.entry(a) - else expect.toContain.inAnyOrder.only.entries(a, *aX) + if (report === emptyInOrderOnlyReportOptions) { + if (aX.isEmpty()) expect.toContain.inAnyOrder.only.entry(a) + else expect.toContain.inAnyOrder.only.entries(a, *aX) + } else expect.toContain.inAnyOrder.only.entries(a, *aX, report = report) + private fun toContainInAnyOrderOnlyNullableEntries( expect: Expect>, a: (Expect.() -> Unit)?, - aX: Array.() -> Unit)?> + aX: Array.() -> Unit)?>, + report: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - if (aX.isEmpty()) expect.toContain.inAnyOrder.only.entry(a) - else expect.toContain.inAnyOrder.only.entries(a, *aX) + if (report === emptyInOrderOnlyReportOptions) { + if (aX.isEmpty()) expect.toContain.inAnyOrder.only.entry(a) + else expect.toContain.inAnyOrder.only.entries(a, *aX) + } else expect.toContain.inAnyOrder.only.entries(a, *aX, report = report) } - @Suppress("unused", "UNUSED_VALUE") private fun ambiguityTest() { var list: Expect> = notImplemented() @@ -50,7 +57,15 @@ class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec : subList = subList.toContain.inAnyOrder.only.entries({}, {}) star = star.toContain.inAnyOrder.only.entries({}, {}) + list = list.toContain.inAnyOrder.only.entries({}, {}, report = {}) + nList = nList.toContain.inAnyOrder.only.entries({}, {}, report = {}) + subList = subList.toContain.inAnyOrder.only.entries({}, {}, report = {}) + star = star.toContain.inAnyOrder.only.entries({}, {}, report = {}) + nList = nList.toContain.inAnyOrder.only.entries(null, {}, null) star = star.toContain.inAnyOrder.only.entries(null, {}, null) + + nList = nList.toContain.inAnyOrder.only.entries(null, {}, null, report = {}) + star = star.toContain.inAnyOrder.only.entries(null, {}, null, report = {}) } } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt index d87c0c7cc7..326343cbff 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.fluent.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.specs.notImplemented import ch.tutteli.atrium.specs.withNullableSuffix @@ -15,18 +16,24 @@ class IterableToContainInAnyOrderOnlyValuesExpectationsSpec : private fun toContainInAnyOrderOnlyValues( expect: Expect>, a: Double, - aX: Array + aX: Array, + report: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - if (aX.isEmpty()) expect.toContain.inAnyOrder.only.value(a) - else expect.toContain.inAnyOrder.only.values(a, *aX) + if (report === emptyInOrderOnlyReportOptions) { + if (aX.isEmpty()) expect.toContain.inAnyOrder.only.value(a) + else expect.toContain.inAnyOrder.only.values(a, *aX) + } else expect.toContain.inAnyOrder.only.values(a, *aX, report = report) private fun toContainInAnyOrderOnlyNullableValues( expect: Expect>, a: Double?, - aX: Array + aX: Array, + report: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - if (aX.isEmpty()) expect.toContain.inAnyOrder.only.value(a) - else expect.toContain.inAnyOrder.only.values(a, *aX) + if (report === emptyInOrderOnlyReportOptions) { + if (aX.isEmpty()) expect.toContain.inAnyOrder.only.value(a) + else expect.toContain.inAnyOrder.only.values(a, *aX) + } else expect.toContain.inAnyOrder.only.values(a, *aX, report = report) } @Suppress("unused", "UNUSED_VALUE") @@ -45,5 +52,16 @@ class IterableToContainInAnyOrderOnlyValuesExpectationsSpec : nList = nList.toContain.inAnyOrder.only.values(1, 1.2) subList = subList.toContain.inAnyOrder.only.values(1, 2.2) star = star.toContain.inAnyOrder.only.values(1, 1.2, "asdf") + + list = list.toContain.inAnyOrder.only.values(1, 1.2, report = {}) + nList = nList.toContain.inAnyOrder.only.values(1, 1.2, report = {}) + subList = subList.toContain.inAnyOrder.only.values(1, 2.2, report = {}) + star = star.toContain.inAnyOrder.only.values(1, 1.2, "asdf", report = {}) + + nList = nList.toContain.inAnyOrder.only.values(null, 1.2) + star = star.toContain.inAnyOrder.only.values(null, 1.2, "asdf") + + nList = nList.toContain.inAnyOrder.only.values(null, 1.2, report = {}) + star = star.toContain.inAnyOrder.only.values(null, 1.2, "asdf", report = {}) } } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt index e9e5eb585f..a4585dd144 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt @@ -114,7 +114,7 @@ class IterableToContainInOrderOnlyEntriesExpectationsSpec : Spek({ subList = subList.toContainExactly({}, {}) star = star.toContainExactly({}, {}) - list = list.toContainExactly({}, {}, report = { showOnlyFailingIfMoreElementsThan(20) }) + list = list.toContainExactly({}, {}, report = { showOnlyFailingIfMoreExpectedElementsThan(20) }) nList = nList.toContainExactly({}, {}, report = { showOnlyFailing() }) subList = subList.toContainExactly({}, {}, report = { showAlwaysSummary() }) star = star.toContainExactly({}, {}, report = { }) diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt index 6d4ccb8d92..278aeb997e 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt @@ -1,6 +1,8 @@ package ch.tutteli.atrium.api.fluent.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.utils.Group import ch.tutteli.atrium.specs.notImplemented @@ -17,8 +19,26 @@ class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec : expect: Expect>, a1: Group<(Expect.() -> Unit)?>, a2: Group<(Expect.() -> Unit)?>, - aX: Array.() -> Unit)?>> - ): Expect> = expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX) + aX: Array.() -> Unit)?>>, + report: InOrderOnlyReportingOptions.() -> Unit, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit + ): Expect> = + if (report === emptyInOrderOnlyReportOptions && reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX) + } else if (reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX, report = report) + } else if (report == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX, reportInGroup = reportInGroup) + } else { + expect.toContain.inOrder.only.grouped.within.inAnyOrder( + a1, + a2, + *aX, + report = report, + reportInGroup = reportInGroup + ) + } + private fun groupFactory(groups: Array.() -> Unit)?>) = when (groups.size) { @@ -47,7 +67,47 @@ class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec : nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder(Entry {}, Entries({}, {}), report = {}) subList = subList.toContain.inOrder.only.grouped.within.inAnyOrder(Entry {}, Entries({}, {}), report = {}) //TODO check if is still necessary with kotlin 1.4, if so, report a bug - star = star.toContain.inOrder.only.grouped.within.inAnyOrder(Entry {}, Entries({}, {})) + star = star.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry {}, + Entries({}, {}), + report = {} + ) + + list = list.toContain.inOrder.only.grouped.within.inAnyOrder(Entry {}, Entries({}, {}), reportInGroup = {}) + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder(Entry {}, Entries({}, {}), reportInGroup = {}) + subList = subList.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry {}, Entries({}, {}), reportInGroup = {}) + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + star = star.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry {}, + Entries({}, {}), + reportInGroup = {} + ) + + list = list.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry {}, + Entries({}, {}), + report = {}, + reportInGroup = {} + ) + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry {}, + Entries({}, {}), + report = {}, + reportInGroup = {} + ) + subList = subList.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry {}, + Entries({}, {}), + report = {}, + reportInGroup = {} + ) + star = star.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry {}, + Entries({}, {}), + report = {}, + reportInGroup = {} + ) nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder(Entry(null), Entries({}, null)) //TODO check if is still necessary with kotlin 1.4, if so, report a bug @@ -55,6 +115,32 @@ class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec : nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder(Entry(null), Entries({}, null), report = {}) //TODO check if is still necessary with kotlin 1.4, if so, report a bug - star = star.toContain.inOrder.only.grouped.within.inAnyOrder(Entry(null), Entries(null, {})) + star = star.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry(null), + Entries(null, {}), + report = {}) + + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry(null), + Entries({}, null), + reportInGroup = {} + ) + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + star = star.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry(null), + Entries(null, {}), + reportInGroup = {}) + + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry(null), + Entries({}, null), + report = {}, + reportInGroup = {}) + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + star = star.toContain.inOrder.only.grouped.within.inAnyOrder( + Entry(null), + Entries(null, {}), + report = {}, + reportInGroup = {}) } } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt index 4dc5cd3f15..a39353686f 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt @@ -1,6 +1,8 @@ package ch.tutteli.atrium.api.fluent.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.utils.Group import ch.tutteli.atrium.specs.notImplemented import ch.tutteli.atrium.specs.withNullableSuffix @@ -14,14 +16,32 @@ class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec : "[Atrium][Builder] " ) { companion object : IterableToContainSpecBase() { - val functionDescription = "$toContain.$inOrder.$only.$grouped.$within.$withinInAnyOrder" + val functionDescription = "$toContain.$inOrder.$only.$grouped.$within.$withinInAnyOrder" private fun toContainInOrderOnlyGroupedInAnyOrderValues( expect: Expect>, a1: Group, a2: Group, - aX: Array> - ): Expect> = expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX) + aX: Array>, + report: InOrderOnlyReportingOptions.() -> Unit, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit + ): Expect> = + if (report === emptyInOrderOnlyReportOptions && reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX) + } else if (reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX, report = report) + } else if (report == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX, reportInGroup = reportInGroup) + } else { + expect.toContain.inOrder.only.grouped.within.inAnyOrder( + a1, + a2, + *aX, + report = report, + reportInGroup = reportInGroup + ) + } + private fun groupFactory(groups: Array): Group = when (groups.size) { @@ -36,8 +56,25 @@ class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec : expect: Expect>, a1: Group, a2: Group, - aX: Array> - ): Expect> = expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX) + aX: Array>, + report: InOrderOnlyReportingOptions.() -> Unit, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit + ): Expect> = + if (report === emptyInOrderOnlyReportOptions && reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX) + } else if (reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX, report = report) + } else if (report == emptyInAnyOrderOnlyReportOptions) { + expect.toContain.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX, reportInGroup = reportInGroup) + } else { + expect.toContain.inOrder.only.grouped.within.inAnyOrder( + a1, + a2, + *aX, + report = report, + reportInGroup = reportInGroup + ) + } private fun nullableGroupFactory(groups: Array): Group = when (groups.size) { @@ -66,10 +103,50 @@ class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec : subList = subList.toContain.inOrder.only.grouped.within.inAnyOrder(Value(1), Values(1, 2), report = {}) star = star.toContain.inOrder.only.grouped.within.inAnyOrder(Value(1), Values(1, 2), report = {}) + list = list.toContain.inOrder.only.grouped.within.inAnyOrder(Value(1), Values(1, 2), reportInGroup = {}) + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder(Value(1), Values(1, 2), reportInGroup = {}) + subList = subList.toContain.inOrder.only.grouped.within.inAnyOrder(Value(1), Values(1, 2), reportInGroup = {}) + star = star.toContain.inOrder.only.grouped.within.inAnyOrder(Value(1), Values(1, 2), reportInGroup = {}) + + list = list.toContain.inOrder.only.grouped.within.inAnyOrder( + Value(1), + Values(1, 2), + report = {}, + reportInGroup = {}) + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder( + Value(1), + Values(1, 2), + report = {}, + reportInGroup = {}) + subList = subList.toContain.inOrder.only.grouped.within.inAnyOrder( + Value(1), + Values(1, 2), + report = {}, + reportInGroup = {}) + star = star.toContain.inOrder.only.grouped.within.inAnyOrder( + Value(1), + Values(1, 2), + report = {}, + reportInGroup = {}) + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder(Value(null), Values(1, null)) star = star.toContain.inOrder.only.grouped.within.inAnyOrder(Value(null), Values(null, 2)) nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder(Value(null), Values(1, null), report = {}) star = star.toContain.inOrder.only.grouped.within.inAnyOrder(Value(null), Values(null, 2), report = {}) + + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder(Value(null), Values(1, null), reportInGroup = {}) + star = star.toContain.inOrder.only.grouped.within.inAnyOrder(Value(null), Values(null, 2), reportInGroup = {}) + + nList = nList.toContain.inOrder.only.grouped.within.inAnyOrder( + Value(null), + Values(1, null), + report = {}, + reportInGroup = {}) + star = star.toContain.inOrder.only.grouped.within.inAnyOrder( + Value(null), + Values(null, 2), + report = {}, + reportInGroup = {}) } } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyValuesExpectationsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyValuesExpectationsSpec.kt index 1b1b52c1a6..86b3093c4b 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyValuesExpectationsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainInOrderOnlyValuesExpectationsSpec.kt @@ -78,13 +78,18 @@ class IterableToContainInOrderOnlyValuesExpectationsSpec : Spek({ subList = subList.toContain.inOrder.only.values(1, 2.2, report = {}) star = star.toContain.inOrder.only.values(1, 1.2, "asdf", report = {}) + nList = nList.toContain.inOrder.only.values(null, 1.2) + star = star.toContain.inOrder.only.values(null, 1.2, "asdf") + + nList = nList.toContain.inOrder.only.values(null, 1.2, report = {}) + star = star.toContain.inOrder.only.values(null, 1.2, "asdf", report = {}) list = list.toContainExactly(1) nList = nList.toContainExactly(1, 1.2) subList = subList.toContainExactly(1) star = star.toContainExactly(1, "a", null) - list = list.toContainExactly(1, report = { showOnlyFailingIfMoreElementsThan(1) }) + list = list.toContainExactly(1, report = { showOnlyFailingIfMoreExpectedElementsThan(1) }) nList = nList.toContainExactly(1, 1.2, report = { showOnlyFailing() }) subList = subList.toContainExactly(1, 2.2, report = { showAlwaysSummary() }) // TODO would wish this does not work, maybe @OnlyInputTypes would help? diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainSpecBase.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainSpecBase.kt index c2adfa6b7c..e331e72da5 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainSpecBase.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/IterableToContainSpecBase.kt @@ -5,8 +5,9 @@ import ch.tutteli.atrium.logic.utils.Group import ch.tutteli.atrium.logic.creating.iterable.contains.IterableLikeContains import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.* import ch.tutteli.atrium.logic.creating.iterable.contains.steps.AtLeastCheckerStep +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions -import kotlin.reflect.KFunction5 +import kotlin.reflect.KFunction6 import kotlin.reflect.KProperty abstract class IterableToContainSpecBase { @@ -32,8 +33,8 @@ abstract class IterableToContainSpecBase { protected val only = IterableLikeContains.EntryPointStep, InAnyOrderSearchBehaviour>::only.name protected val grouped = IterableLikeContains.EntryPointStep, InOrderOnlySearchBehaviour>::grouped.name protected val within = IterableLikeContains.EntryPointStep, InOrderOnlyGroupedSearchBehaviour>::within.name - private val withinInAnyOrderFun: KFunction5, InOrderOnlyGroupedWithinSearchBehaviour>, Group, Group, Array>, InOrderOnlyReportingOptions.() -> Unit, Expect>> = - IterableLikeContains.EntryPointStep, InOrderOnlyGroupedWithinSearchBehaviour, >::inAnyOrder + private val withinInAnyOrderFun: KFunction6, InOrderOnlyGroupedWithinSearchBehaviour>, Group, Group, Array>, InOrderOnlyReportingOptions.() -> Unit, InAnyOrderOnlyReportingOptions.() -> Unit, Expect>> = + IterableLikeContains.EntryPointStep, InOrderOnlyGroupedWithinSearchBehaviour>::inAnyOrder protected val withinInAnyOrder = withinInAnyOrderFun.name //@formatter:on } diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/samples/IterableExpectationSamples.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/samples/IterableExpectationSamples.kt index 523ab49ec8..29f81c7b32 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/samples/IterableExpectationSamples.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/samples/IterableExpectationSamples.kt @@ -94,7 +94,7 @@ class IterableExpectationSamples { // optional report = { // allows configuring reporting, e.g. showOnlyFailing() // would not show the successful `B` - showOnlyFailingIfMoreElementsThan(10) + showOnlyFailingIfMoreExpectedElementsThan(10) } ) } @@ -142,7 +142,7 @@ class IterableExpectationSamples { // optional report = { // allows configuring reporting, e.g. showOnlyFailing() // would not show the successful `toBeLessThan(11)` - showOnlyFailingIfMoreElementsThan(10) + showOnlyFailingIfMoreExpectedElementsThan(10) } ) } @@ -166,7 +166,7 @@ class IterableExpectationSamples { // optional report = { // allows configuring reporting, e.g. showOnlyFailing() // would not show the successful first and second `1, 2` - showOnlyFailingIfMoreElementsThan(10) + showOnlyFailingIfMoreExpectedElementsThan(10) } ) } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/creating/iterable/WithInAnyOrderOnlyReportingOptions.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/creating/iterable/WithInAnyOrderOnlyReportingOptions.kt new file mode 100644 index 0000000000..2c1b7ac2bf --- /dev/null +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/creating/iterable/WithInAnyOrderOnlyReportingOptions.kt @@ -0,0 +1,10 @@ +package ch.tutteli.atrium.api.infix.en_GB.creating.iterable + +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions + +/** + * Parameter object to wrap a given [T] next to specifying [InAnyOrderOnlyReportingOptions]. + * + * @since 0.18.0 + */ +data class WithInAnyOrderOnlyReportingOptions(val options: InAnyOrderOnlyReportingOptions.() -> Unit, val t: T) diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/creating/iterable/WithInOrderOnlyReportingOptions.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/creating/iterable/WithInOrderOnlyReportingOptions.kt index 069c4aa39c..47ad11455f 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/creating/iterable/WithInOrderOnlyReportingOptions.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/creating/iterable/WithInOrderOnlyReportingOptions.kt @@ -7,4 +7,4 @@ import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderO * * @since 0.18.0 */ -data class WithInOrderOnlyReportingOptions(val report: InOrderOnlyReportingOptions.() -> Unit, val t: T) +data class WithInOrderOnlyReportingOptions(val options: InOrderOnlyReportingOptions.() -> Unit, val t: T) diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/helperFunctions.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/helperFunctions.kt index e6eb2b37d2..d9ed69a1dd 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/helperFunctions.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/helperFunctions.kt @@ -1,11 +1,13 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.api.infix.en_GB.creating.* +import ch.tutteli.atrium.api.infix.en_GB.creating.iterable.WithInAnyOrderOnlyReportingOptions import ch.tutteli.atrium.api.infix.en_GB.creating.iterable.WithInOrderOnlyReportingOptions import ch.tutteli.atrium.api.infix.en_GB.creating.map.KeyValues import ch.tutteli.atrium.api.infix.en_GB.creating.map.KeyWithValueCreator import ch.tutteli.atrium.assertions.Assertion import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.atrium.logic.creating.typeutils.MapLike @@ -20,10 +22,10 @@ fun all(t: T, vararg ts: T): All = All(t, ts) /** * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping an [IterableLike] - * based on the given [iterableLike] and the given [report]-configuration-lambda. + * based on the given [iterableLike] and the given [reportOptionsInOrderOnly]-configuration-lambda. * * @param iterableLike The [IterableLike] whose elements this function is referring to. - * @param report The lambda configuring the [InOrderOnlyReportingOptions]. + * @param reportOptionsInOrderOnly The lambda configuring the [InOrderOnlyReportingOptions]. * * @sample ch.tutteli.atrium.api.infix.en_GB.samples.IterableExpectationSamples.toContainExactlyElementsOf * @@ -31,8 +33,22 @@ fun all(t: T, vararg ts: T): All = All(t, ts) */ fun elementsOf( iterableLike: T, - report: InOrderOnlyReportingOptions.() -> Unit -): WithInOrderOnlyReportingOptions = WithInOrderOnlyReportingOptions(report, iterableLike) + reportOptionsInOrderOnly: InOrderOnlyReportingOptions.() -> Unit +): WithInOrderOnlyReportingOptions = WithInOrderOnlyReportingOptions(reportOptionsInOrderOnly, iterableLike) + +/** + * Helper function to create a [WithInAnyOrderOnlyReportingOptions] wrapping an [IterableLike] + * based on the given [iterableLike] and the given [reportOptionsInAnyOrderOnly]-configuration-lambda. + * + * @param iterableLike The [IterableLike] whose elements this function is referring to. + * @param reportOptionsInAnyOrderOnly The lambda configuring the [InAnyOrderOnlyReportingOptions]. + * + * @since 0.18.0 + */ +fun elementsOf( + iterableLike: T, + reportOptionsInAnyOrderOnly: InAnyOrderOnlyReportingOptions.() -> Unit +): WithInAnyOrderOnlyReportingOptions = WithInAnyOrderOnlyReportingOptions(reportOptionsInAnyOrderOnly, iterableLike) /** * Helper function to create an [Entry] based on the given [assertionCreatorOrNull]. @@ -60,8 +76,8 @@ fun entries( /** * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping an [Entries] based on the given - * [assertionCreatorOrNull] and [otherAssertionCreatorsOrNulls] as well as the given [report]-configuration-lambda - * -- allows expressing `{ }, vararg { }, report = { ... }`. + * [assertionCreatorOrNull] and [otherAssertionCreatorsOrNulls] as well as the given + * [reportOptionsInOrderOnly]-configuration-lambda -- allows expressing `{ }, vararg { }, reportOptionsInOrderOnly = { ... }`. * * In case `null` is used for an identification lambda then it is expected that the corresponding entry * is `null` as well. @@ -70,7 +86,7 @@ fun entries( * to be identified if it holds all [Assertion]s the lambda creates. * In case it is defined as `null`, then an entry is identified if it is `null` as well. * @param otherAssertionCreatorsOrNulls A variable amount of additional identification lambdas or `null`s. - * @param report The lambda configuring the [InOrderOnlyReportingOptions]. + * @param reportOptionsInOrderOnly The lambda configuring the [InOrderOnlyReportingOptions]. * * @sample ch.tutteli.atrium.api.infix.en_GB.samples.IterableExpectationSamples.toContainExactlyAssertions * @@ -79,23 +95,46 @@ fun entries( fun entries( assertionCreatorOrNull: (Expect.() -> Unit)?, vararg otherAssertionCreatorsOrNulls: (Expect.() -> Unit)?, - report: InOrderOnlyReportingOptions.() -> Unit + reportOptionsInOrderOnly: InOrderOnlyReportingOptions.() -> Unit ): WithInOrderOnlyReportingOptions> = - WithInOrderOnlyReportingOptions(report, Entries(assertionCreatorOrNull, otherAssertionCreatorsOrNulls)) + WithInOrderOnlyReportingOptions(reportOptionsInOrderOnly, Entries(assertionCreatorOrNull, otherAssertionCreatorsOrNulls)) + +/** + * Helper function to create a [WithInAnyOrderOnlyReportingOptions] wrapping an [Entries] based on the given + * [assertionCreatorOrNull] and [otherAssertionCreatorsOrNulls] as well as the given + * [reportOptionsInAnyOrderOnly]-configuration-lambda -- allows expressing `{ }, vararg { }, reportOptionsInAnyOrderOnly = { ... }`. + * + * In case `null` is used for an identification lambda then it is expected that the corresponding entry + * is `null` as well. + * + * @param assertionCreatorOrNull The identification lambda identifying the entry where an entry is considered + * to be identified if it holds all [Assertion]s the lambda creates. + * In case it is defined as `null`, then an entry is identified if it is `null` as well. + * @param otherAssertionCreatorsOrNulls A variable amount of additional identification lambdas or `null`s. + * @param reportOptionsInAnyOrderOnly The lambda configuring the [InOrderOnlyReportingOptions]. + * + * @since 0.18.0 + */ +fun entries( + assertionCreatorOrNull: (Expect.() -> Unit)?, + vararg otherAssertionCreatorsOrNulls: (Expect.() -> Unit)?, + reportOptionsInAnyOrderOnly: InAnyOrderOnlyReportingOptions.() -> Unit +): WithInAnyOrderOnlyReportingOptions> = + WithInAnyOrderOnlyReportingOptions(reportOptionsInAnyOrderOnly, Entries(assertionCreatorOrNull, otherAssertionCreatorsOrNulls)) /** * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping an [MapLike] - * based on the given [mapLike] and the given [report]-configuration-lambda. + * based on the given [mapLike] and the given [reportOptionsInOrderOnly]-configuration-lambda. * * @param mapLike The [MapLike] whose elements this function is referring to. - * @param report The lambda configuring the [InOrderOnlyReportingOptions]. + * @param reportOptionsInOrderOnly The lambda configuring the [InOrderOnlyReportingOptions]. * * @since 0.18.0 */ fun entriesOf( mapLike: T, - report: InOrderOnlyReportingOptions.() -> Unit -): WithInOrderOnlyReportingOptions = WithInOrderOnlyReportingOptions(report, mapLike) + reportOptionsInOrderOnly: InOrderOnlyReportingOptions.() -> Unit +): WithInOrderOnlyReportingOptions = WithInOrderOnlyReportingOptions(reportOptionsInOrderOnly, mapLike) /** * Helper function to create a [KeyValues] based on the given [keyValue] and [otherKeyValues] @@ -113,15 +152,19 @@ fun keyValues( /** * Helper function to create a [KeyValues] based on the given [keyValue] and [otherKeyValues] * -- allows expressing `Pair.() -> Unit)?>, vararg Pair.() -> Unit)?>`. + * + * @param reportOptionsInOrderOnly The lambda configuring the [InOrderOnlyReportingOptions] -- it is optional where + * the default [InOrderOnlyReportingOptions] apply if not specified. + * since 0.18.0 */ // TODO 1.0.0: consider to rename to entries once updated to Kotlin 1.4 maybe the type inference is better and there // is no longer a clash with Iterable entries fun keyValues( keyValue: KeyWithValueCreator, vararg otherKeyValues: KeyWithValueCreator, - report: InOrderOnlyReportingOptions.() -> Unit + reportOptionsInOrderOnly: InOrderOnlyReportingOptions.() -> Unit ): WithInOrderOnlyReportingOptions> = - WithInOrderOnlyReportingOptions(report, KeyValues(keyValue, otherKeyValues)) + WithInOrderOnlyReportingOptions(reportOptionsInOrderOnly, KeyValues(keyValue, otherKeyValues)) /** * Helper function to create a [KeyWithValueCreator] based on the given [key] and [valueAssertionCreatorOrNull] @@ -152,8 +195,8 @@ fun pairs(pair: Pair, vararg otherPairs: Pair): Pairs = fun pairs( pair: Pair, vararg otherPairs: Pair, - report: InOrderOnlyReportingOptions.() -> Unit -): WithInOrderOnlyReportingOptions> = WithInOrderOnlyReportingOptions(report, Pairs(pair, otherPairs)) + reportOptionsInOrderOnly: InOrderOnlyReportingOptions.() -> Unit +): WithInOrderOnlyReportingOptions> = WithInOrderOnlyReportingOptions(reportOptionsInOrderOnly, Pairs(pair, otherPairs)) /** * Helper function to create a [PresentWithCreator] based on the given [assertionCreator]. @@ -198,16 +241,34 @@ fun values(value: T, vararg otherValues: T): Values = Values(value, other /** * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping a [Values] based on the given - * [value] and [otherValues] as well as the given [report]-configuration-lambda -- allows expressing - * `T, vararg T, report = { ... }`. + * [value] and [otherValues] as well as the given [reportOptionsInOrderOnly]-configuration-lambda -- allows expressing + * `T, vararg T, reportOptionsInOrderOnly = { ... }`. * * @param value The first expected value. * @param otherValues The other expected values in the given order. - * @param report The lambda configuring the [InOrderOnlyReportingOptions]. + * @param reportOptionsInOrderOnly The lambda configuring the [InOrderOnlyReportingOptions]. + * + * @since 0.18.0 + */ +fun values( + value: T, + vararg otherValues: T, + reportOptionsInOrderOnly: InOrderOnlyReportingOptions.() -> Unit +): WithInOrderOnlyReportingOptions> = WithInOrderOnlyReportingOptions(reportOptionsInOrderOnly, Values(value, otherValues)) + +/** + * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping a [Values] based on the given + * [value] and [otherValues] as well as the given [reportOptionsInAnyOrderOnly]-configuration-lambda -- allows expressing + * `T, vararg T, reportOptionsInAnyOrderOnly = { ... }`. + * + * @param value The first expected value. + * @param otherValues The other expected values in the given order. + * @param reportOptionsInAnyOrderOnly The lambda configuring the [InOrderOnlyReportingOptions]. + * * @since 0.18.0 */ fun values( value: T, vararg otherValues: T, - report: InOrderOnlyReportingOptions.() -> Unit -): WithInOrderOnlyReportingOptions> = WithInOrderOnlyReportingOptions(report, Values(value, otherValues)) + reportOptionsInAnyOrderOnly: InAnyOrderOnlyReportingOptions.() -> Unit +): WithInAnyOrderOnlyReportingOptions> = WithInAnyOrderOnlyReportingOptions(reportOptionsInAnyOrderOnly, Values(value, otherValues)) diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableExpectations.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableExpectations.kt index ce03810e01..369a26f387 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableExpectations.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableExpectations.kt @@ -164,10 +164,10 @@ infix fun > Expect.toContainExactly(values: Values): Ex * Expects that the subject of `this` expectation (an [Iterable]) contains only * the expected [values] in the defined order. * - * It is a shortcut for `toContain o inGiven order and only the values(..., report = {... })` + * It is a shortcut for `toContain o inGiven order and only the values(..., reportOptionsInOrderOnly = {... })` * * @param values The values which are expected to be contained within the [IterableLike] plus a lambda configuring - * the [InOrderOnlyReportingOptions] -- use the function `values(t, ..., report = { ... })` + * the [InOrderOnlyReportingOptions] -- use the function `values(t, ..., reportOptionsInOrderOnly = { ... })` * to create a [WithInOrderOnlyReportingOptions] with a wrapped [Values]. * * @return an [Expect] for the subject of `this` expectation. @@ -231,10 +231,10 @@ infix fun > Expect.toContainExactly(entries: Entrie * [entries].t.[otherAssertionCreatorsOrNulls][Entries.otherAssertionCreatorsOrNulls] (if given) * whereas the entries have to appear in the defined order. * - * It is a shortcut for `toContain o inGiven order and only the entries(..., report = { ... })` + * It is a shortcut for `toContain o inGiven order and only the entries(..., reportOptionsInOrderOnly = { ... })` * * @param entries The entries which are expected to be contained within the [Iterable] plus a lambda configuring - * the [InOrderOnlyReportingOptions] -- use the function `entries(t, ..., report = { ... })` + * the [InOrderOnlyReportingOptions] -- use the function `entries(t, ..., reportOptionsInOrderOnly = { ... })` * to create a [WithInOrderOnlyReportingOptions] with a wrapped [Entries]. * * @return an [Expect] for the subject of `this` expectation. @@ -278,11 +278,11 @@ inline infix fun > Expect.toContainExactlyElements * [entries].t.[otherAssertionCreatorsOrNulls][Entries.otherAssertionCreatorsOrNulls] (if given) * whereas the entries have to appear in the defined order. * - * It is a shortcut for `toContain o inGiven order and only the elementsOf(..., report = { ... })` + * It is a shortcut for `toContain o inGiven order and only the elementsOf(..., reportOptionsInOrderOnly = { ... })` * * @param elementsOf The [IterableLike] whose elements are expected to be contained within * this [IterableLike] plus a lambda configuring the [InOrderOnlyReportingOptions] -- use the function - * `elementsOf(iterableLike, report = { ... })` + * `elementsOf(iterableLike, reportOptionsInOrderOnly = { ... })` * to create a [WithInOrderOnlyReportingOptions] with a wrapped [IterableLike]. * * @return an [Expect] for the subject of `this` expectation. diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInAnyOrderOnlyCreators.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInAnyOrderOnlyCreators.kt index 7ef4c08f74..7d4a1df94d 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInAnyOrderOnlyCreators.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInAnyOrderOnlyCreators.kt @@ -2,6 +2,8 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.api.infix.en_GB.creating.Entries import ch.tutteli.atrium.api.infix.en_GB.creating.Values +import ch.tutteli.atrium.api.infix.en_GB.creating.iterable.WithInAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.api.infix.en_GB.creating.iterable.WithInOrderOnlyReportingOptions import ch.tutteli.atrium.creating.Expect import ch.tutteli.atrium.logic._logic import ch.tutteli.atrium.logic._logicAppend @@ -10,9 +12,12 @@ import ch.tutteli.atrium.logic.creating.iterable.contains.creators.entriesInAnyO import ch.tutteli.atrium.logic.creating.iterable.contains.creators.values import ch.tutteli.atrium.logic.creating.iterable.contains.creators.valuesInAnyOrderOnly import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.atrium.logic.creating.typeutils.IterableLikeToIterableTransformer import ch.tutteli.atrium.logic.utils.toVarArg +import kotlin.jvm.JvmName /** * Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike]) @@ -38,7 +43,23 @@ infix fun EntryPointStep EntryPointStep.the(values: Values): Expect = - _logicAppend { valuesInAnyOrderOnly(values.toList()) } + the(WithInAnyOrderOnlyReportingOptions({}, values)) + +/** + * Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike]) + * needs to contain only the expected [values] where it does not matter in which order. + * + * @param values The values which are expected to be contained within the [IterableLike] plus a lambda configuring + * the [InAnyOrderOnlyReportingOptions] -- use the function `values(t, ..., reportOptionsInAnyOrderOnly = { ... })` + * to create a [WithInAnyOrderOnlyReportingOptions] with a wrapped [Values]. + * + * @return an [Expect] for the subject of `this` expectation. + * + * @since 0.18.0 + */ +@JvmName("theValuesWithReportingOptions") +infix fun EntryPointStep.the(values: WithInAnyOrderOnlyReportingOptions>): Expect = + _logicAppend { valuesInAnyOrderOnly(values.t.toList(), values.options) } /** * Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike]) @@ -76,10 +97,36 @@ infix fun EntryPointStep EntryPointStep.the( entries: Entries -): Expect = _logicAppend { entriesInAnyOrderOnly(entries.toList()) } +): Expect = the(WithInAnyOrderOnlyReportingOptions({}, entries)) + +/** + * Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike]) + * needs to contain only the given [entries] where it does not matter in which order they appear -- an entry + * is contained if it either holds all assertions + * [entries].[assertionCreatorOrNull][Entries.assertionCreatorOrNull] creates or it needs to be `null` in case + * [entries].[assertionCreatorOrNull][Entries.assertionCreatorOrNull] is defined as `null` + * + * Notice, that a first-wins strategy applies which means your assertion creator lambdas -- which kind of serve as + * identification lambdas -- should be ordered in such a way that the most specific identification lambda appears + * first, not that a less specific lambda wins. For instance, given a `setOf(1, 2)` you should not search for + * `entries({ isGreaterThan(0) }, { toEqual(1) })` but for `entries({ toEqual(1) }, { isGreaterThan(0) })` + * otherwise `isGreaterThan(0)` matches `1` before `toEqual(1)` would match it. As a consequence `toEqual(1)` could + * only match the entry which is left -- in this case `2` -- and of course this would fail. + * + * @param entries The entries which are expected to be contained within the [IterableLike] plus a lambda configuring + * the [InAnyOrderOnlyReportingOptions] -- use the function `entries(t, ..., reportOptionsInAnyOrderOnly = { ... })` + * to create a [WithInAnyOrderOnlyReportingOptions] with a wrapped [Entries]. + * + * @return an [Expect] for the subject of `this` expectation. + * + * @since 0.18.0 + */ +@JvmName("theEntriesWithReportingOptions") +infix fun EntryPointStep.the( + entries: WithInAnyOrderOnlyReportingOptions> +): Expect = _logicAppend { entriesInAnyOrderOnly(entries.t.toList(), entries.options) } /** * Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike]) @@ -103,3 +150,32 @@ infix fun EntryPointStep EntryPointStep.elementsOf( expectedIterableLike: IterableLike ): Expect = _logic.toVarArg(expectedIterableLike).let { (first, rest) -> this the values(first, *rest) } + +/** + * Finishes the specification of the sophisticated `contains` assertion where the subject (an [IterableLike]) + * needs to contain only and all elements of the given [IterableLike] in the specified order. + * + * Delegates to [values]. + * + * Notice that a runtime check applies which assures that only [Iterable], [Sequence] or one of the [Array] types + * are passed (this can be changed via [IterableLikeToIterableTransformer]). + * This function expects [IterableLike] (which is a typealias for [Any]) to avoid cluttering the API. + + * @param elementsOf The [IterableLike] whose elements are expected to be contained within + * this [IterableLike] plus a lambda configuring the [InOrderOnlyReportingOptions] -- use the function + * `elementsOf(iterableLike, report = { ... })` + * to create a [WithInOrderOnlyReportingOptions] with a wrapped [IterableLike]. + * + * @return an [Expect] for the subject of `this` expectation. + * @throws IllegalArgumentException in case the wrapped [IterableLike] is not + * an [Iterable], [Sequence] or one of the [Array] types + * or the wrapped [IterableLike] does not have elements (is empty). + * + * @since 0.18.0 + */ +@JvmName("theElementsOfsWithReportingOptions") +inline infix fun EntryPointStep.the( + elementsOf: WithInAnyOrderOnlyReportingOptions +): Expect = _logic.toVarArg(elementsOf.t).let { (first, rest) -> + this the values(first, *rest, reportOptionsInAnyOrderOnly = elementsOf.options) +} diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInOrderOnlyCreators.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInOrderOnlyCreators.kt index eda11d0d02..8b767e869f 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInOrderOnlyCreators.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInOrderOnlyCreators.kt @@ -50,18 +50,18 @@ infix fun EntryPointStep * needs to contain only the expected [values] in the specified order. * * @param values The values which are expected to be contained within the [IterableLike] plus a lambda configuring - * the [InOrderOnlyReportingOptions] -- use the function `values(t, ..., report = { ... })` + * the [InOrderOnlyReportingOptions] -- use the function `values(t, ..., reportOptionsInOrderOnly = { ... })` * to create a [WithInOrderOnlyReportingOptions] with a wrapped [Values]. * * @return an [Expect] for the subject of `this` expectation. * * @since 0.18.0 */ -@JvmName("theValuesWithReportingOption") +@JvmName("theValuesWithReportingOptions") infix fun EntryPointStep.the( values: WithInOrderOnlyReportingOptions> ): Expect = _logicAppend { - valuesInOrderOnly(values.t.toList(), values.report) + valuesInOrderOnly(values.t.toList(), values.options) } /** @@ -110,20 +110,20 @@ infix fun EntryPointStep EntryPointStep.the( entries: WithInOrderOnlyReportingOptions> ): Expect = _logicAppend { entriesInOrderOnly( entries.t.toList(), - entries.report + entries.options ) } @@ -173,9 +173,9 @@ inline infix fun EntryPointStep EntryPointStep.the( elementsOf: WithInOrderOnlyReportingOptions ): Expect = _logic.toVarArg(elementsOf.t).let { (first, rest) -> - this the values(first, *rest, report = elementsOf.report) + this the values(first, *rest, reportOptionsInOrderOnly = elementsOf.options) } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInOrderOnlyGroupedCreators.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInOrderOnlyGroupedCreators.kt index c629ba60af..584a16e268 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInOrderOnlyGroupedCreators.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/iterableLikeToContainInOrderOnlyGroupedCreators.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.api.infix.en_GB.creating.iterable.Order +import ch.tutteli.atrium.api.infix.en_GB.creating.iterable.WithInAnyOrderOnlyReportingOptions import ch.tutteli.atrium.api.infix.en_GB.creating.iterable.WithInOrderOnlyReportingOptions import ch.tutteli.atrium.creating.Expect import ch.tutteli.atrium.logic._logicAppend @@ -8,6 +9,7 @@ import ch.tutteli.atrium.logic.creating.iterable.contains.IterableLikeContains.E 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.searchbehaviours.InOrderOnlyGroupedWithinSearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.atrium.logic.utils.Group @@ -29,7 +31,10 @@ import kotlin.jvm.JvmName infix fun EntryPointStep.inAny( order: Order> -): Expect = inAny(WithInOrderOnlyReportingOptions({}, order)) +): Expect = inAny(withoutReportingOptions(order)) + +private fun withoutReportingOptions(order: Order>) = + WithInOrderOnlyReportingOptions({}, WithInAnyOrderOnlyReportingOptions({}, order)) /** * Finishes the specification of the sophisticated `contains` assertion where the expected [Order.firstGroup] as well as @@ -37,20 +42,28 @@ infix fun EntryPointStep EntryPointStep.inAny( - order: WithInOrderOnlyReportingOptions>> + order: WithInOrderOnlyReportingOptions>>> ): Expect = _logicAppend { - valuesInOrderOnlyGrouped(order.t.toList(), order.report) + valuesInOrderOnlyGrouped(order.t.t.toList(), order.options, order.t.options) } /** @@ -78,7 +91,7 @@ infix fun EntryPointStep EntryPointStep.inAny( order: Order<(Expect.() -> Unit)?, Group<(Expect.() -> Unit)?>> -): Expect = inAny(WithInOrderOnlyReportingOptions({}, order)) +): Expect = inAny(withoutReportingOptions(order)) /** * Finishes the specification of the sophisticated `contains` assertion where the expected [Order.firstGroup] as well as @@ -89,6 +102,16 @@ infix fun EntryPointStep EntryPointStep EntryPointStep EntryPointStep.inAny( - order: WithInOrderOnlyReportingOptions.() -> Unit)?, Group<(Expect.() -> Unit)?>>> + order: WithInOrderOnlyReportingOptions.() -> Unit)?, Group<(Expect.() -> Unit)?>>>> ): Expect = _logicAppend { - entriesInOrderOnlyGrouped(order.t.toList(), order.report) + entriesInOrderOnlyGrouped(order.t.t.toList(), order.options, order.t.options) } /** @@ -121,8 +145,10 @@ fun order( ): Order> = Order(firstGroup, secondGroup, otherExpectedGroups) /** - * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping an [Order] based on the given - * [firstGroup], [secondGroup] and [otherExpectedGroups] as well as the given [report]-configuration-lambda + * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping a [WithInAnyOrderOnlyReportingOptions] + * which wraps in turn an [Order] based on the given + * [firstGroup], [secondGroup] and [otherExpectedGroups] as well as the given [report]-configuration-lambda for + * the [WithInOrderOnlyReportingOptions]. * * @since 0.18.0 */ @@ -131,5 +157,43 @@ fun order( secondGroup: Group, vararg otherExpectedGroups: Group, report: InOrderOnlyReportingOptions.() -> Unit -): WithInOrderOnlyReportingOptions>> = - WithInOrderOnlyReportingOptions(report, Order(firstGroup, secondGroup, otherExpectedGroups)) +): WithInOrderOnlyReportingOptions>>> = + order(firstGroup, secondGroup, *otherExpectedGroups, report = report, reportInGroup = { }) + +/** + * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping a [WithInAnyOrderOnlyReportingOptions] + * which wraps in turn an [Order] based on the given + * [firstGroup], [secondGroup] and [otherExpectedGroups] as well as the given [reportInGroup]-configuration-lambda for + * the [WithInAnyOrderOnlyReportingOptions]. + * + * @since 0.18.0 + */ +@JvmName("orderWithReportInGroup") +fun order( + firstGroup: Group, + secondGroup: Group, + vararg otherExpectedGroups: Group, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit +): WithInOrderOnlyReportingOptions>>> = + order(firstGroup, secondGroup, *otherExpectedGroups, report = {}, reportInGroup = reportInGroup) + +/** + * Helper function to create a [WithInOrderOnlyReportingOptions] wrapping a [WithInAnyOrderOnlyReportingOptions] + * which wraps in turn an [Order] based on the given + * [firstGroup], [secondGroup] and [otherExpectedGroups] as well as the given [report]-configuration-lambda for + * the [WithInOrderOnlyReportingOptions] and the [reportInGroup]-configuration-lambda for + * the [WithInAnyOrderOnlyReportingOptions]. + * + * @since 0.18.0 + */ +fun order( + firstGroup: Group, + secondGroup: Group, + vararg otherExpectedGroups: Group, + report: InOrderOnlyReportingOptions.() -> Unit, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit +): WithInOrderOnlyReportingOptions>>> = + WithInOrderOnlyReportingOptions( + report, + WithInAnyOrderOnlyReportingOptions(reportInGroup, Order(firstGroup, secondGroup, otherExpectedGroups)) + ) diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/mapLikeToContainInOrderOnlyCreators.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/mapLikeToContainInOrderOnlyCreators.kt index 0b679705e6..d6c632f556 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/mapLikeToContainInOrderOnlyCreators.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/mapLikeToContainInOrderOnlyCreators.kt @@ -1,7 +1,6 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.api.infix.en_GB.creating.Pairs -import ch.tutteli.atrium.api.infix.en_GB.creating.Values import ch.tutteli.atrium.api.infix.en_GB.creating.iterable.WithInOrderOnlyReportingOptions import ch.tutteli.atrium.api.infix.en_GB.creating.map.KeyValues import ch.tutteli.atrium.api.infix.en_GB.creating.map.KeyWithValueCreator @@ -54,7 +53,7 @@ infix fun EntryPointStep EntryPointStep EntryPointStep.the( pairs: WithInOrderOnlyReportingOptions> ): Expect = _logicAppend { - keyValuePairsInOrderOnly(pairs.t.toList(), pairs.report) + keyValuePairsInOrderOnly(pairs.t.toList(), pairs.options) } @@ -119,7 +118,7 @@ inline infix fun EntryPointStep EntryPointStep EntryPointStep EntryPointStep.entriesOf( entriesOf: WithInOrderOnlyReportingOptions ): Expect = _logic.toVarArgPairs(entriesOf.t).let { (first, rest) -> - this the pairs(first, *rest, report = entriesOf.report) + this the pairs(first, *rest, reportOptionsInOrderOnly = entriesOf.options) } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1ElementsOfExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1ElementsOfExpectationsSpec.kt index 12b13d9d73..72f764e7d5 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1ElementsOfExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1ElementsOfExpectationsSpec.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.notImplemented import org.spekframework.spek2.Spek import kotlin.reflect.KFunction2 @@ -74,6 +75,30 @@ class IterableToContainInAnyOrderAtLeast1ElementsOfExpectationsSpec : Spek({ a: Double?, aX: Array ): Expect> = expect toContainElementsOf sequenceOf(a, *aX).asIterable() + } + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order atLeast 1 elementsOf listOf(1) + nList = nList toContain o inAny order atLeast 1 elementsOf listOf(1) + subList = subList toContain o inAny order atLeast 1 elementsOf listOf(1) + star = star toContain o inAny order atLeast 1 elementsOf listOf(1) + + list = list toContainElementsOf listOf(1) + nList = nList toContainElementsOf listOf(1) + subList = subList toContainElementsOf listOf(1) + star = star toContainElementsOf listOf(1) + + list = list toContainElementsOf listOf(1, 1.2) + nList = nList toContainElementsOf listOf(1, 1.2) + subList = subList toContainElementsOf listOf(1, 2.2) + subList = subList toContainElementsOf listOf(1) + star = star toContainElementsOf listOf(1, 1.2, "asdf") } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec.kt index b12d9aaac2..76d79670fd 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.notImplemented import org.spekframework.spek2.Spek import kotlin.reflect.KFunction2 @@ -70,4 +71,46 @@ class IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec : Spek({ if (aX.isEmpty()) expect toContain a else expect toContain entries(a, *aX) } + + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order atLeast 1 entry {} + nList = nList toContain o inAny order atLeast 1 entry {} + subList = subList toContain o inAny order atLeast 1 entry {} + star = star toContain o inAny order atLeast 1 entry {} + + nList = nList toContain o inAny order atLeast 1 entry null + star = star toContain o inAny order atLeast 1 entry null + + list = list toContain o inAny order atLeast 1 the entries({}, {}) + nList = nList toContain o inAny order atLeast 1 the entries({}, {}) + subList = subList toContain o inAny order atLeast 1 the entries({}, {}) + star = star toContain o inAny order atLeast 1 the entries({}, {}) + + nList = nList toContain o inAny order atLeast 1 the entries(null, {}, null) + star = star toContain o inAny order atLeast 1 the entries(null, {}, null) + + list = list toContain {} + nList = nList toContain {} + subList = subList toContain {} + star = star toContain {} + + //TODO should work without cast, remove as soon as KT-6591 is fixed - (with Kotlin 1.4) + nList = nList toContain null as Number? + star = star toContain null as Number? + + list = list toContain entries({}, {}) + nList = nList toContain entries({}, {}) + subList = subList toContain entries({}, {}) + star = star toContain entries({}, {}) + + nList = nList toContain entries(null, {}, null) + star = star toContain entries(null, {}, null) + } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1ValuesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1ValuesExpectationsSpec.kt index 8aa9117586..21e46931ee 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1ValuesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtLeast1ValuesExpectationsSpec.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.notImplemented import org.spekframework.spek2.Spek import kotlin.reflect.KFunction2 @@ -70,6 +71,36 @@ class IterableToContainInAnyOrderAtLeast1ValuesExpectationsSpec : Spek({ ): Expect> = if (aX.isEmpty()) expect toContain a else expect toContain values(a, *aX) + } + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order atLeast 1 value 1 + nList = nList toContain o inAny order atLeast 1 value 1 + subList = subList toContain o inAny order atLeast 1 value 1 + star = star toContain o inAny order atLeast 1 value 1 + + //TODO type parameter should not be necessary, check with Kotlin 1.4 + list = list toContain o inAny order atLeast 1 the values(1, 1.2) + nList = nList toContain o inAny order atLeast 1 the values(1, 1.2) + subList = subList toContain o inAny order atLeast 1 the values(1, 2.2) + star = star toContain o inAny order atLeast 1 the values(1, 1.2, "asdf") + + list = list toContain 1 + nList = nList toContain 1 + subList = subList toContain 1 + star = star toContain 1 + + list = list toContain values(1, 1.2) + nList = nList toContain values(1, 1.2) + subList = subList toContain values(1, 2.2) + // TODO would wish this does not work, maybe @OnlyInputTypes would help? + subList = subList toContain values("asdf") + star = star toContain values(1, 1.2, "asdf") } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtMostValuesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtMostValuesExpectationsSpec.kt index 020fbab010..3b477ce7fb 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtMostValuesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderAtMostValuesExpectationsSpec.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.notImplemented class IterableToContainInAnyOrderAtMostValuesExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableToContainInAnyOrderAtMostValuesExpectationsSpec( @@ -29,4 +30,23 @@ class IterableToContainInAnyOrderAtMostValuesExpectationsSpec : private fun getErrorMsgExactly(times: Int) = "use `$exactly $times` instead of `$atMost $times`; `$atMost $times` defines implicitly `$atLeast $times` as well" } + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order atMost 2 value(1) + nList = nList toContain o inAny order atMost 2 value(1) + subList = subList toContain o inAny order atMost 2 value(1) + star = star toContain o inAny order atMost 2 value(1) + + //TODO type parameter should not be necessary, check with Kotlin 1.4 + list = list toContain o inAny order atMost 2 the values(1, 1.2) + nList = nList toContain o inAny order atMost 2 the values(1, 1.2) + subList = subList toContain o inAny order atMost 2 the values(1, 2.2) + star = star toContain o inAny order atMost 2 the values(1, 1.2, "asdf") + } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderExactlyValuesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderExactlyValuesExpectationsSpec.kt index 24286169da..688302a059 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderExactlyValuesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderExactlyValuesExpectationsSpec.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.notImplemented class IterableToContainInAnyOrderExactlyValuesExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableToContainInAnyOrderExactlyValuesExpectationsSpec( @@ -26,6 +27,25 @@ class IterableToContainInAnyOrderExactlyValuesExpectationsSpec : private fun getNotToContainPair() = notToContain to Companion::getErrorMsgNotToContain private fun getErrorMsgNotToContain(times: Int) = "use `$notToContain` instead of `$exactly $times`" + } + + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order exactly 2 value 1 + nList = nList toContain o inAny order exactly 2 value 1 + subList = subList toContain o inAny order exactly 2 value 1 + star = star toContain o inAny order exactly 2 value 1 + //TODO type parameter should not be necessary, check with Kotlin 1.4 + list = list toContain o inAny order exactly 2 the values(1, 1.2) + nList = nList toContain o inAny order exactly 2 the values(1, 1.2) + subList = subList toContain o inAny order exactly 2 the values(1, 2.2) + star = star toContain o inAny order exactly 2 the values(1, 1.2, "asdf") } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderNotOrAtMostValuesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderNotOrAtMostValuesExpectationsSpec.kt index 6247884902..0f8719e99a 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderNotOrAtMostValuesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderNotOrAtMostValuesExpectationsSpec.kt @@ -1,6 +1,7 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.specs.notImplemented class IterableToContainInAnyOrderNotOrAtMostValuesExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableToContainInAnyOrderNotOrAtMostValuesExpectationsSpec( @@ -26,6 +27,24 @@ class IterableToContainInAnyOrderNotOrAtMostValuesExpectationsSpec : private fun getNotToContainPair() = notToContain to Companion::getErrorMsgNotToContain private fun getErrorMsgNotToContain(times: Int) = "use `$notToContain` instead of `$notOrAtMost $times`" + } + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order notOrAtMost 1 value 1 + nList = nList toContain o inAny order notOrAtMost 1 value 1 + subList = subList toContain o inAny order notOrAtMost 1 value 1 + star = star toContain o inAny order notOrAtMost 1 value 1 + + //TODO type parameter should not be necessary, check with Kotlin 1.4 + list = list toContain o inAny order notOrAtMost 1 the values(1, 1.2) + nList = nList toContain o inAny order notOrAtMost 1 the values(1, 1.2) + subList = subList toContain o inAny order notOrAtMost 1 the values(1, 2.2) + star = star toContain o inAny order notOrAtMost 1 the values(1, 1.2, "asdf") } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec.kt index fd73d30791..5153335f29 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec.kt @@ -1,6 +1,9 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.specs.integration.IterableToContainSpecBase.Companion.emptyInAnyOrderOnlyReportOptions +import ch.tutteli.atrium.specs.notImplemented import org.spekframework.spek2.Spek class IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec : Spek({ @@ -26,8 +29,17 @@ class IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec : Spek({ private fun getToContainValues( expect: Expect>, a: Double, - aX: Array - ): Expect> = expect toContain o inAny order but only elementsOf listOf(a, *aX) + aX: Array, + report: InAnyOrderOnlyReportingOptions.() -> Unit + ): Expect> = + if (report == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inAny order but only elementsOf listOf(a, *aX) + } else { + expect toContain o inAny order but only the elementsOf( + listOf(a, *aX), + reportOptionsInAnyOrderOnly = report + ) + } fun getToContainNullablePair() = "$toContain $filler $inAnyOrder $butOnly $inAnyOrderOnlyElementsOf" to Companion::getToContainNullableValues @@ -35,7 +47,42 @@ class IterableToContainInAnyOrderOnlyElementsOfExpectationsSpec : Spek({ private fun getToContainNullableValues( expect: Expect>, a: Double?, - aX: Array - ): Expect> = expect toContain o inAny order but only elementsOf sequenceOf(a, *aX) + aX: Array, + report: InAnyOrderOnlyReportingOptions.() -> Unit + ): Expect> = + if (report == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inAny order but only elementsOf listOf(a, *aX) + } else { + expect toContain o inAny order but only the elementsOf( + listOf(a, *aX), + reportOptionsInAnyOrderOnly = report + ) + } + } + + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order but only elementsOf listOf() + nList = nList toContain o inAny order but only elementsOf listOf() + subList = subList toContain o inAny order but only elementsOf listOf() + star = star toContain o inAny order but only elementsOf listOf() + + list = list toContain o inAny order but only the elementsOf(listOf(), reportOptionsInAnyOrderOnly = {}) + nList = nList toContain o inAny order but only the elementsOf(listOf(), reportOptionsInAnyOrderOnly = {}) + subList = + subList toContain o inAny order but only the elementsOf(listOf(), reportOptionsInAnyOrderOnly = {}) + star = star toContain o inAny order but only the elementsOf(listOf(), reportOptionsInAnyOrderOnly = {}) + + nList = nList toContain o inAny order but only elementsOf listOf() + star = star toContain o inAny order but only elementsOf listOf() + + nList = nList toContain o inAny order but only the elementsOf(listOf(), reportOptionsInAnyOrderOnly = {}) + star = star toContain o inAny order but only the elementsOf(listOf(), reportOptionsInAnyOrderOnly = {}) } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt index 8a4555b1fe..82b0d6a215 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt @@ -1,6 +1,9 @@ package ch.tutteli.atrium.api.infix.en_GB + import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.specs.notImplemented class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableToContainInAnyOrderOnlyEntriesExpectationsSpec( @@ -15,10 +18,13 @@ class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec : private fun toContainInAnyOrderOnlyEntries( expect: Expect>, a: Expect.() -> Unit, - aX: Array.() -> Unit> + aX: Array.() -> Unit>, + report: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - if (aX.isEmpty()) expect toContain o inAny order but only entry a - else expect toContain o inAny order but only the entries(a, *aX) + if (report === emptyInAnyOrderOnlyReportOptions) { + if (aX.isEmpty()) expect toContain o inAny order but only entry a + else expect toContain o inAny order but only the entries(a, *aX) + } else expect toContain o inAny order but only the entries(a, *aX, reportOptionsInAnyOrderOnly = report) fun getContainsNullablePair() = @@ -27,10 +33,44 @@ class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec : private fun toContainInAnyOrderOnlyNullableEntries( expect: Expect>, a: (Expect.() -> Unit)?, - aX: Array.() -> Unit)?> + aX: Array.() -> Unit)?>, + report: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - if (aX.isEmpty()) expect toContain o inAny order but only entry a - else expect toContain o inAny order but only the entries(a, *aX) + if (report === emptyInAnyOrderOnlyReportOptions) { + if (aX.isEmpty()) expect toContain o inAny order but only entry a + else expect toContain o inAny order but only the entries(a, *aX) + } else expect toContain o inAny order but only the entries(a, *aX, reportOptionsInAnyOrderOnly = report) + } + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order but only entry {} + nList = nList toContain o inAny order but only entry {} + subList = subList toContain o inAny order but only entry {} + star = star toContain o inAny order but only entry {} + + nList = nList toContain o inAny order but only entry (null) + star = star toContain o inAny order but only entry (null) + + list = list toContain o inAny order but only the entries({}, {}) + nList = nList toContain o inAny order but only the entries({}, {}) + subList = subList toContain o inAny order but only the entries({}, {}) + star = star toContain o inAny order but only the entries({}, {}) + + list = list toContain o inAny order but only the entries({}, {}, reportOptionsInAnyOrderOnly = {}) + nList = nList toContain o inAny order but only the entries({}, {}, reportOptionsInAnyOrderOnly = {}) + subList = subList toContain o inAny order but only the entries({}, {}, reportOptionsInAnyOrderOnly = {}) + star = star toContain o inAny order but only the entries({}, {}, reportOptionsInAnyOrderOnly = {}) + + nList = nList toContain o inAny order but only the entries(null, {}, null) + star = star toContain o inAny order but only the entries(null, {}, null) + nList = nList toContain o inAny order but only the entries(null, {}, null, reportOptionsInAnyOrderOnly = {}) + star = star toContain o inAny order but only the entries(null, {}, null, reportOptionsInAnyOrderOnly = {}) } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt index 3207ce4401..237d8b40ee 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt @@ -1,6 +1,8 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.specs.notImplemented class IterableToContainInAnyOrderOnlyValuesExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableToContainInAnyOrderOnlyValuesExpectationsSpec( @@ -15,10 +17,13 @@ class IterableToContainInAnyOrderOnlyValuesExpectationsSpec : private fun toContainInAnyOrderOnlyValues( expect: Expect>, a: Double, - aX: Array + aX: Array, + report: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - if (aX.isEmpty()) expect toContain o inAny order but only value a - else expect toContain o inAny order but only the values(a, *aX) + if (report === emptyInAnyOrderOnlyReportOptions) { + if (aX.isEmpty()) expect toContain o inAny order but only value a + else expect toContain o inAny order but only the values(a, *aX) + } else expect toContain o inAny order but only the values(a, *aX, reportOptionsInAnyOrderOnly = report) fun getContainsNullablePair() = @@ -27,10 +32,43 @@ class IterableToContainInAnyOrderOnlyValuesExpectationsSpec : private fun toContainInAnyOrderOnlyNullableValues( expect: Expect>, a: Double?, - aX: Array + aX: Array, + report: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - if (aX.isEmpty()) expect toContain o inAny order but only value a - else expect toContain o inAny order but only the values(a, *aX) + if (report === emptyInAnyOrderOnlyReportOptions) { + if (aX.isEmpty()) expect toContain o inAny order but only value a + else expect toContain o inAny order but only the values(a, *aX) + } else expect toContain o inAny order but only the values(a, *aX, reportOptionsInAnyOrderOnly = report) + } + + + @Suppress("unused", "UNUSED_VALUE") + private fun ambiguityTest() { + var list: Expect> = notImplemented() + var nList: Expect> = notImplemented() + var subList: Expect> = notImplemented() + var star: Expect> = notImplemented() + + list = list toContain o inAny order but only value(1) + nList = nList toContain o inAny order but only value(1) + subList = subList toContain o inAny order but only value(1) + star = star toContain o inAny order but only value(1) + + //TODO type parameter should not be necessary, check with Kotlin 1.4 + list = list toContain o inAny order but only the values(1, 1.2) + nList = nList toContain o inAny order but only the values(1, 1.2) + subList = subList toContain o inAny order but only the values(1, 2.2) + star = star toContain o inAny order but only the values(1, 1.2, "asdf") + + list = list toContain o inAny order but only the values(1, 1.2, reportOptionsInAnyOrderOnly = {}) + nList = nList toContain o inAny order but only the values(1, 1.2, reportOptionsInAnyOrderOnly = {}) + subList = subList toContain o inAny order but only the values(1, 2.2, reportOptionsInAnyOrderOnly = {}) + star = star toContain o inAny order but only the values(1, 1.2, "asdf", reportOptionsInAnyOrderOnly = {}) + + nList = nList toContain o inAny order but only the values(null, 1.2) + star = star toContain o inAny order but only the values(null, 1.2, "asdf") + nList = nList toContain o inAny order but only the values(null, 1.2, reportOptionsInAnyOrderOnly = {}) + star = star toContain o inAny order but only the values(null, 1.2, "asdf", reportOptionsInAnyOrderOnly = {}) } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyElementsOfExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyElementsOfExpectationsSpec.kt index 2a3e0e18b2..4b4a7972ba 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyElementsOfExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyElementsOfExpectationsSpec.kt @@ -51,7 +51,7 @@ class IterableToContainInOrderOnlyElementsOfExpectationsSpec : Spek({ report: InOrderOnlyReportingOptions.() -> Unit ): Expect> = if (report === emptyInOrderOnlyReportOptions) expect toContain o inGiven order and only elementsOf listOf(a, *aX) - else expect toContain o inGiven order and only the elementsOf(listOf(a, *aX), report = report) + else expect toContain o inGiven order and only the elementsOf(listOf(a, *aX), reportOptionsInOrderOnly = report) fun getToContainNullablePair() = "$toContain $filler $inOrder $andOnly $inOrderElementsOf" to Companion::toContainInOrderOnlyNullableValues @@ -63,7 +63,7 @@ class IterableToContainInOrderOnlyElementsOfExpectationsSpec : Spek({ report: InOrderOnlyReportingOptions.() -> Unit ): Expect> = if (report === emptyInOrderOnlyReportOptions) expect toContain o inGiven order and only elementsOf sequenceOf(a, *aX) - else expect toContain o inGiven order and only the elementsOf(listOf(a, *aX), report = report) + else expect toContain o inGiven order and only the elementsOf(listOf(a, *aX), reportOptionsInOrderOnly = report) private val toContainExactlyElementsOfShortcutFun: KFunction2>, Iterable, Expect>> = Expect>::toContainExactlyElementsOf @@ -109,10 +109,10 @@ class IterableToContainInOrderOnlyElementsOfExpectationsSpec : Spek({ subList = subList toContain o inGiven order and only elementsOf(listOf()) star = star toContain o inGiven order and only elementsOf(listOf()) - list = list toContain o inGiven order and only the elementsOf(listOf(), report = { showAlwaysSummary() }) - nList = nList toContain o inGiven order and only the elementsOf(listOf(), report = { showOnlyFailing()}) - subList = subList toContain o inGiven order and only the elementsOf(listOf(), report = {}) - star = star toContain o inGiven order and only the elementsOf(listOf(), report = {}) + list = list toContain o inGiven order and only the elementsOf(listOf(), reportOptionsInOrderOnly = { showAlwaysSummary() }) + nList = nList toContain o inGiven order and only the elementsOf(listOf(), reportOptionsInOrderOnly = { showOnlyFailing()}) + subList = subList toContain o inGiven order and only the elementsOf(listOf(), reportOptionsInOrderOnly = {}) + star = star toContain o inGiven order and only the elementsOf(listOf(), reportOptionsInOrderOnly = {}) list = list.toContainExactlyElementsOf(listOf(1)) nList = nList.toContainExactlyElementsOf(listOf(1)) diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt index 6dc22d7338..56d7ecc52a 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt @@ -39,7 +39,7 @@ class IterableToContainInOrderOnlyEntriesExpectationsSpec : Spek({ if (report === emptyInOrderOnlyReportOptions) { if (aX.isEmpty()) expect toContain o inGiven order and only entry a else expect toContain o inGiven order and only the entries(a, *aX) - } else expect toContain o inGiven order and only the entries(a, *aX, report = report) + } else expect toContain o inGiven order and only the entries(a, *aX, reportOptionsInOrderOnly = report) fun getToContainNullablePair() = "$toContain $filler $inOrder $andOnly $inOrderOnlyEntries" to Companion::toContainInOrderOnlyNullableEntriesPair @@ -53,7 +53,7 @@ class IterableToContainInOrderOnlyEntriesExpectationsSpec : Spek({ if (report === emptyInOrderOnlyReportOptions) { if (aX.isEmpty()) expect toContain o inGiven order and only entry a else expect toContain o inGiven order and only the entries(a, *aX) - } else expect toContain o inGiven order and only the entries(a, *aX, report = report) + } else expect toContain o inGiven order and only the entries(a, *aX, reportOptionsInOrderOnly = report) private val toContainShortcutFun: KFunction2>, Expect.() -> Unit, Expect>> = Expect>::toContainExactly @@ -69,7 +69,7 @@ class IterableToContainInOrderOnlyEntriesExpectationsSpec : Spek({ if (report === emptyInOrderOnlyReportOptions) { if (aX.isEmpty()) expect toContainExactly { a() } else expect toContainExactly entries(a, *aX) - } else expect toContainExactly entries(a, *aX, report = report) + } else expect toContainExactly entries(a, *aX, reportOptionsInOrderOnly = report) private val toContainNullableShortcutFun: KFunction2>, (Expect.() -> Unit)?, Expect>> = Expect>::toContainExactly @@ -91,6 +91,6 @@ class IterableToContainInOrderOnlyEntriesExpectationsSpec : Spek({ } else { expect toContainExactly entries(a, *aX) } - } else expect toContainExactly entries(a, *aX, report = report) + } else expect toContainExactly entries(a, *aX, reportOptionsInOrderOnly = report) } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt index a3f5c7f865..715e44e58c 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt @@ -1,6 +1,8 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.utils.Group import ch.tutteli.atrium.specs.notImplemented @@ -18,9 +20,28 @@ class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec : expect: Expect>, a1: Group<(Expect.() -> Unit)?>, a2: Group<(Expect.() -> Unit)?>, - aX: Array.() -> Unit)?>> + aX: Array.() -> Unit)?>>, + report: InOrderOnlyReportingOptions.() -> Unit, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - expect toContain o inGiven order and only grouped entries within group inAny order(a1, a2, *aX) + if (report === emptyInOrderOnlyReportOptions && reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX + ) + } else if (reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, report = report + ) + } else if (report == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, reportInGroup = reportInGroup + ) + } else { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, report = report, reportInGroup = reportInGroup + ) + } + private fun groupFactory(groups: Array.() -> Unit)?>) = when (groups.size) { @@ -86,6 +107,60 @@ class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec : report = {} ) + list = list toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry {}, + entries({}, {}), + reportInGroup = {} + ) + nList = nList toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry {}, + entries({}, {}), + reportInGroup = {} + ) + subList = subList toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry {}, + entries({}, {}), + reportInGroup = {} + ) + star = star toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry {}, + entries({}, {}), + reportInGroup = {} + ) + + list = list toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry {}, + entries({}, {}), + report = {}, + reportInGroup = {} + ) + nList = nList toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry {}, + entries({}, {}), + report = {}, + reportInGroup = {} + ) + subList = subList toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry {}, + entries({}, {}), + report = {}, + reportInGroup = {} + ) + star = star toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry {}, + entries({}, {}), + report = {}, + reportInGroup = {} + ) + nList = nList toContain o inGiven order and only grouped entries within group inAny order( //TODO check if is still necessary with kotlin 1.4, if so, report a bug entry(null), @@ -109,5 +184,33 @@ class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec : entries(null, {}), report = {} ) + + nList = nList toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry(null), + entries({}, null), + reportInGroup = {} + ) + star = star toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry(null), + entries(null, {}), + reportInGroup = {} + ) + + nList = nList toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry(null), + entries({}, null), + report = {}, + reportInGroup = {} + ) + star = star toContain o inGiven order and only grouped entries within group inAny order( + //TODO check if is still necessary with kotlin 1.4, if so, report a bug + entry(null), + entries(null, {}), + report = {}, + reportInGroup = {} + ) } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt index 36dc78d656..5cdd276af7 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt @@ -1,6 +1,8 @@ package ch.tutteli.atrium.api.infix.en_GB import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.utils.Group import ch.tutteli.atrium.specs.notImplemented @@ -14,15 +16,31 @@ class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec : ) { companion object : IterableToContainSpecBase() { fun getContainsPair() = - "$toContain $filler $inOrder $andOnly $grouped $within $withinInAnyOrder" to Companion::toContainInOrderOnlyGroupedInAnyOrdervalues + "$toContain $filler $inOrder $andOnly $grouped $within $withinInAnyOrder" to Companion::toContainInOrderOnlyGroupedInAnyOrderValues - private fun toContainInOrderOnlyGroupedInAnyOrdervalues( + private fun toContainInOrderOnlyGroupedInAnyOrderValues( expect: Expect>, a1: Group, a2: Group, - aX: Array> + aX: Array>, + report: InOrderOnlyReportingOptions.() -> Unit, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - expect toContain o inGiven order and only grouped entries within group inAny order(a1, a2, *aX) + if (report == emptyInOrderOnlyReportOptions && reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order(a1, a2, *aX) + } else if (reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, report = report + ) + } else if (report == emptyInOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, reportInGroup = reportInGroup + ) + } else { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, report = report, reportInGroup = reportInGroup + ) + } private fun groupFactory(groups: Array): Group = when (groups.size) { @@ -33,17 +51,32 @@ class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec : else -> values(groups[0], *groups.drop(1).toTypedArray()) } - fun getContainsNullablePair() = - "$toContain $filler $inOrder $andOnly $grouped $within $withinInAnyOrder" to Companion::toContainInOrderOnlyGroupedInAnyOrderNullablevalues + "$toContain $filler $inOrder $andOnly $grouped $within $withinInAnyOrder" to Companion::toContainInOrderOnlyGroupedInAnyOrderNullableValues - private fun toContainInOrderOnlyGroupedInAnyOrderNullablevalues( + private fun toContainInOrderOnlyGroupedInAnyOrderNullableValues( expect: Expect>, a1: Group, a2: Group, - aX: Array> + aX: Array>, + report: InOrderOnlyReportingOptions.() -> Unit, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit ): Expect> = - expect toContain o inGiven order and only grouped entries within group inAny order(a1, a2, *aX) + if (report == emptyInOrderOnlyReportOptions && reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order(a1, a2, *aX) + } else if (reportInGroup == emptyInAnyOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, report = report + ) + } else if (report == emptyInOrderOnlyReportOptions) { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, reportInGroup = reportInGroup + ) + } else { + expect toContain o inGiven order and only grouped entries within group inAny order( + a1, a2, *aX, report = report, reportInGroup = reportInGroup + ) + } private fun nullableGroupFactory(groups: Array): Group = when (groups.size) { @@ -104,6 +137,52 @@ class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec : report = {} ) + list = list toContain o inGiven order and only grouped entries within group inAny order( + value(1), + values(1, 2), + reportInGroup = {} + ) + nList = nList toContain o inGiven order and only grouped entries within group inAny order( + value(1), + values(1, 2), + reportInGroup = {} + ) + subList = subList toContain o inGiven order and only grouped entries within group inAny order( + value(1), + values(1, 2), + reportInGroup = {} + ) + star = star toContain o inGiven order and only grouped entries within group inAny order( + value(1), + values(1, 2), + reportInGroup = {} + ) + + list = list toContain o inGiven order and only grouped entries within group inAny order( + value(1), + values(1, 2), + report = {}, + reportInGroup = {} + ) + nList = nList toContain o inGiven order and only grouped entries within group inAny order( + value(1), + values(1, 2), + report = {}, + reportInGroup = {} + ) + subList = subList toContain o inGiven order and only grouped entries within group inAny order( + value(1), + values(1, 2), + report = {}, + reportInGroup = {} + ) + star = star toContain o inGiven order and only grouped entries within group inAny order( + value(1), + values(1, 2), + report = {}, + reportInGroup = {} + ) + nList = nList toContain o inGiven order and only grouped entries within group inAny order( value(null), values(1, null), @@ -125,5 +204,29 @@ class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec : values(null, 2), report = {} ) + + nList = nList toContain o inGiven order and only grouped entries within group inAny order( + value(null), + values(1, null), + reportInGroup = {} + ) + star = star toContain o inGiven order and only grouped entries within group inAny order( + value(null), + values(null, 2), + reportInGroup = {} + ) + + nList = nList toContain o inGiven order and only grouped entries within group inAny order( + value(null), + values(1, null), + report = {}, + reportInGroup = {} + ) + star = star toContain o inGiven order and only grouped entries within group inAny order( + value(null), + values(null, 2), + report = {}, + reportInGroup = {} + ) } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyValuesExpectationsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyValuesExpectationsSpec.kt index 2bcb402d97..9b6b8ff3e1 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyValuesExpectationsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/IterableToContainInOrderOnlyValuesExpectationsSpec.kt @@ -38,7 +38,7 @@ class IterableToContainInOrderOnlyValuesExpectationsSpec : Spek({ if (report === emptyInOrderOnlyReportOptions) { if (aX.isEmpty()) expect toContain o inGiven order and only value a else expect toContain o inGiven order and only the values(a, *aX) - } else expect toContain o inGiven order and only the values(a, *aX, report = report) + } else expect toContain o inGiven order and only the values(a, *aX, reportOptionsInOrderOnly = report) fun getToContainNullablePair() = "$toContain $filler $inOrder $andOnly $inOrderOnlyValues" to Companion::toContainInOrderOnlyNullableValues @@ -52,7 +52,7 @@ class IterableToContainInOrderOnlyValuesExpectationsSpec : Spek({ if (report === emptyInOrderOnlyReportOptions) { if (aX.isEmpty()) expect toContain o inGiven order and only value a else expect toContain o inGiven order and only the values(a, *aX) - } else expect toContain o inGiven order and only the values(a, *aX, report = report) + } else expect toContain o inGiven order and only the values(a, *aX, reportOptionsInOrderOnly = report) private val toContainShortcutFun: KFunction2>, Double, Expect>> = Expect>::toContainExactly @@ -68,7 +68,7 @@ class IterableToContainInOrderOnlyValuesExpectationsSpec : Spek({ if (report === emptyInOrderOnlyReportOptions) { if (aX.isEmpty()) expect toContainExactly a else expect toContainExactly values(a, *aX) - } else expect toContainExactly values(a, *aX, report = report) + } else expect toContainExactly values(a, *aX, reportOptionsInOrderOnly = report) private val toContainNullableShortcutFun: KFunction2>, Double?, Expect>> = Expect>::toContainExactly @@ -85,7 +85,7 @@ class IterableToContainInOrderOnlyValuesExpectationsSpec : Spek({ if (report === emptyInOrderOnlyReportOptions) { if (aX.isEmpty()) expect toContainExactly a else expect toContainExactly values(a, *aX) - } else expect toContainExactly values(a, *aX, report = report) + } else expect toContainExactly values(a, *aX, reportOptionsInOrderOnly = report) } @Suppress("unused", "UNUSED_VALUE") @@ -106,10 +106,10 @@ class IterableToContainInOrderOnlyValuesExpectationsSpec : Spek({ subList = subList toContain o inGiven order and only the values(1, 2.2) star = star toContain o inGiven order and only the values(1, 1.2, "asdf") - list = list toContain o inGiven order and only the values(1, 1.2, report = {}) - nList = nList toContain o inGiven order and only the values(1, 1.2, report = {}) - subList = subList toContain o inGiven order and only the values(1, 2.2, report = {}) - star = star toContain o inGiven order and only the values(1, 1.2, "asdf", report = {}) + list = list toContain o inGiven order and only the values(1, 1.2, reportOptionsInOrderOnly = {}) + nList = nList toContain o inGiven order and only the values(1, 1.2, reportOptionsInOrderOnly = {}) + subList = subList toContain o inGiven order and only the values(1, 2.2, reportOptionsInOrderOnly = {}) + star = star toContain o inGiven order and only the values(1, 1.2, "asdf", reportOptionsInOrderOnly = {}) list = list toContainExactly 1 nList = nList toContainExactly values(1, 1.2) @@ -119,12 +119,14 @@ class IterableToContainInOrderOnlyValuesExpectationsSpec : Spek({ //TODO we should actually setup proper tests for those cases as we only see it compiles (has no ambiguity) // but don't know if it has chosen the correct overload in the end // (because we sometimes have Any as param and passing a ParamObject to such a function is not a compile error) - list = list toContainExactly values(1, 1.2, report = { showOnlyFailingIfMoreElementsThan(1) }) - nList = nList toContainExactly values(1, 1.2, report = { showOnlyFailing() }) - subList = subList toContainExactly values(1, 2.2, report = { showAlwaysSummary() }) + list = list toContainExactly values(1, 1.2, reportOptionsInOrderOnly = { + showOnlyFailingIfMoreExpectedElementsThan(1) + }) + nList = nList toContainExactly values(1, 1.2, reportOptionsInOrderOnly = { showOnlyFailing() }) + subList = subList toContainExactly values(1, 2.2, reportOptionsInOrderOnly = { showAlwaysSummary() }) // TODO would wish this does not work, maybe @OnlyInputTypes would help? - subList = subList toContainExactly values("asdf", report = {}) - star = star toContainExactly values(1, 1.2, "asdf", report = {}) + subList = subList toContainExactly values("asdf", reportOptionsInOrderOnly = {}) + star = star toContainExactly values(1, 1.2, "asdf", reportOptionsInOrderOnly = {}) } } diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/samples/IterableExpectationSamples.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/samples/IterableExpectationSamples.kt index bbdf638935..9643f241af 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/samples/IterableExpectationSamples.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/samples/IterableExpectationSamples.kt @@ -96,9 +96,9 @@ class IterableExpectationSamples { "C", "B", // optional - report = { // allows configuring reporting, e.g. + reportOptionsInOrderOnly = { // allows configuring reporting, e.g. showOnlyFailing() // would not show the successful `B` - showOnlyFailingIfMoreElementsThan(10) + showOnlyFailingIfMoreExpectedElementsThan(10) } ) } @@ -152,11 +152,11 @@ class IterableExpectationSamples { fails { expect(listOf(3, 5)) toContainExactly entries( { toEqual(1) }, // fails - { toBeLessThan(11) }, // succeeds, + { toBeLessThan(11) }, // succeeds // optional - report = { // allows configuring reporting, e.g. + reportOptionsInOrderOnly = { // allows configuring reporting, e.g. showOnlyFailing() // would not show the successful `toBeLessThan(11)` - showOnlyFailingIfMoreElementsThan(10) + showOnlyFailingIfMoreExpectedElementsThan(10) } ) } @@ -178,9 +178,9 @@ class IterableExpectationSamples { // alternative form where you can specify a lambda configuring the InOrderOnlyReportingOptions. expect(listOf(1, 2, 2, 4)) toContainExactly elementsOf( listOf(1, 2, 4), - report = { // allows configuring reporting, e.g. + reportOptionsInOrderOnly = { // allows configuring reporting, e.g. showOnlyFailing() // would not show the successful first and second `1, 2` - showOnlyFailingIfMoreElementsThan(10) + showOnlyFailingIfMoreExpectedElementsThan(10) } ) } diff --git a/build.gradle b/build.gradle index 739d5c15f1..008fa0971b 100644 --- a/build.gradle +++ b/build.gradle @@ -381,13 +381,17 @@ def createJsTestTask(String... subprojectNames) { } } -createJsTestTask( - 'core-js', - 'api-fluent-en_GB-js', - 'api-infix-en_GB-js', - 'fluent-en_GB-js', - 'infix-en_GB-js' -) +//TODO 0.19.0 enable JS-tests again once we use the new MPP plugins because then they should only re-run if something +// changed, in contrast to now where they re-run all the time +if (Boolean.parseBoolean(System.getenv('CI'))) { + createJsTestTask( + 'core-js', + 'api-fluent-en_GB-js', + 'api-infix-en_GB-js', + 'fluent-en_GB-js', + 'infix-en_GB-js' + ) +} def useJupiter(String... projectNames) { configure(projectNamesToProject(projectNames)) { diff --git a/logic/atrium-logic-common/src/generated/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/iterableLikeContains.kt b/logic/atrium-logic-common/src/generated/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/iterableLikeContains.kt index 7a0db9adad..95a83b2463 100644 --- a/logic/atrium-logic-common/src/generated/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/iterableLikeContains.kt +++ b/logic/atrium-logic-common/src/generated/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/iterableLikeContains.kt @@ -16,14 +16,17 @@ import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderO import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlyGroupedSearchBehaviour import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlySearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.atrium.core.ExperimentalNewExpectTypes import ch.tutteli.atrium.logic.creating.iterable.contains.creators.impl.DefaultIterableLikeContainsAssertions -fun IterableLikeContains.EntryPointStepLogic.valuesInAnyOrderOnly(expected: List): Assertion = impl.valuesInAnyOrderOnly(this, expected) +fun IterableLikeContains.EntryPointStepLogic.valuesInAnyOrderOnly(expected: List, reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit): Assertion = + impl.valuesInAnyOrderOnly(this, expected, reportingOptions) -fun IterableLikeContains.EntryPointStepLogic.entriesInAnyOrderOnly(assertionCreators: List<(Expect.() -> Unit)?>): Assertion = impl.entriesInAnyOrderOnly(this, assertionCreators) +fun IterableLikeContains.EntryPointStepLogic.entriesInAnyOrderOnly(assertionCreators: List<(Expect.() -> Unit)?>, reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit): Assertion = + impl.entriesInAnyOrderOnly(this, assertionCreators, reportingOptions) fun IterableLikeContains.EntryPointStepLogic.valuesInOrderOnly(expected: List, reportingOptions: InOrderOnlyReportingOptions.() -> Unit): Assertion = @@ -33,11 +36,11 @@ fun IterableLikeContains.EntryPointStepLogic IterableLikeContains.EntryPointStepLogic.valuesInOrderOnlyGrouped(groups: List>, reportingOptions: InOrderOnlyReportingOptions.() -> Unit): Assertion = - impl.valuesInOrderOnlyGrouped(this, groups, reportingOptions) +fun IterableLikeContains.EntryPointStepLogic.valuesInOrderOnlyGrouped(groups: List>, inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit): Assertion = + impl.valuesInOrderOnlyGrouped(this, groups, inOrderOnlyReportingOptions, inAnyOrderOnlyReportingOptions) -fun IterableLikeContains.EntryPointStepLogic.entriesInOrderOnlyGrouped(groups: List.() -> Unit)?>>, reportingOptions: InOrderOnlyReportingOptions.() -> Unit): Assertion = - impl.entriesInOrderOnlyGrouped(this, groups, reportingOptions) +fun IterableLikeContains.EntryPointStepLogic.entriesInOrderOnlyGrouped(groups: List.() -> Unit)?>>, inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit): Assertion = + impl.entriesInOrderOnlyGrouped(this, groups, inOrderOnlyReportingOptions, inAnyOrderOnlyReportingOptions) @Suppress("DEPRECATION" /* OptIn is only available since 1.3.70 which we cannot use if we want to support 1.2 */) @UseExperimental(ExperimentalNewExpectTypes::class) diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/IterableLikeContainsAssertions.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/IterableLikeContainsAssertions.kt index 8d46dc78fa..8ec9675a24 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/IterableLikeContainsAssertions.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/IterableLikeContainsAssertions.kt @@ -9,6 +9,7 @@ import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderO import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlyGroupedSearchBehaviour import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlySearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike /** @@ -19,12 +20,14 @@ interface IterableLikeContainsAssertions { fun valuesInAnyOrderOnly( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, - expected: List + expected: List, + reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit ): Assertion fun entriesInAnyOrderOnly( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, - assertionCreators: List<(Expect.() -> Unit)?> + assertionCreators: List<(Expect.() -> Unit)?>, + reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit ): Assertion @@ -44,12 +47,14 @@ interface IterableLikeContainsAssertions { fun valuesInOrderOnlyGrouped( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, groups: List>, - reportingOptions: InOrderOnlyReportingOptions.() -> Unit + inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, + inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit ): Assertion fun entriesInOrderOnlyGrouped( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, groups: List.() -> Unit)?>>, - reportingOptions: InOrderOnlyReportingOptions.() -> Unit + inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, + inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit ): Assertion } diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/DefaultIterableLikeContainsAssertions.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/DefaultIterableLikeContainsAssertions.kt index dfa5cb2980..d9d3931086 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/DefaultIterableLikeContainsAssertions.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/DefaultIterableLikeContainsAssertions.kt @@ -9,21 +9,24 @@ import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderO import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlyGroupedSearchBehaviour import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlySearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike class DefaultIterableLikeContainsAssertions : IterableLikeContainsAssertions { override fun valuesInAnyOrderOnly( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, - expected: List + expected: List, + reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit ): Assertion = createAssertionGroupWithoutCheckerInAnyOrder( - entryPointStepLogic, expected, ::InAnyOrderOnlyValuesAssertionCreator + entryPointStepLogic, expected, reportingOptions, ::InAnyOrderOnlyValuesAssertionCreator ) override fun entriesInAnyOrderOnly( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, - assertionCreators: List<(Expect.() -> Unit)?> + assertionCreators: List<(Expect.() -> Unit)?>, + reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit ): Assertion = createAssertionGroupWithoutCheckerInAnyOrder( - entryPointStepLogic, assertionCreators, ::InAnyOrderOnlyEntriesAssertionCreator + entryPointStepLogic, assertionCreators, reportingOptions, ::InAnyOrderOnlyEntriesAssertionCreator ) @@ -47,19 +50,40 @@ class DefaultIterableLikeContainsAssertions : IterableLikeContainsAssertions { override fun valuesInOrderOnlyGrouped( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, groups: List>, - reportingOptions: InOrderOnlyReportingOptions.() -> Unit - ): Assertion = createAssertionGroupWithoutCheckerInOrder( - entryPointStepLogic, groups, reportingOptions, ::InOrderOnlyGroupedValuesAssertionCreator + inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, + inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit + ): Assertion = createAssertionGroupWithoutCheckerInOrderGrouped( + entryPointStepLogic, + groups, + inOrderOnlyReportingOptions, + inAnyOrderOnlyReportingOptions, + ::InOrderOnlyGroupedValuesAssertionCreator ) override fun entriesInOrderOnlyGrouped( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, groups: List.() -> Unit)?>>, - reportingOptions: InOrderOnlyReportingOptions.() -> Unit - ): Assertion = createAssertionGroupWithoutCheckerInOrder( - entryPointStepLogic, groups, reportingOptions, ::InOrderOnlyGroupedEntriesAssertionCreator + inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, + inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit + ): Assertion = createAssertionGroupWithoutCheckerInOrderGrouped( + entryPointStepLogic, + groups, + inOrderOnlyReportingOptions, + inAnyOrderOnlyReportingOptions, + ::InOrderOnlyGroupedEntriesAssertionCreator ) + + private fun createAssertionGroupWithoutCheckerInAnyOrder( + entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, + expected: List, + reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit, + factory: ((T) -> Iterable, S, InAnyOrderOnlyReportingOptions.() -> Unit) -> IterableLikeContains.Creator + ): AssertionGroup { + val creator = factory(entryPointStepLogic.converter, entryPointStepLogic.searchBehaviour, reportingOptions) + return creator.createAssertionGroup(entryPointStepLogic.container, expected) + } + private fun createAssertionGroupWithoutCheckerInOrder( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, expected: List, @@ -70,12 +94,19 @@ class DefaultIterableLikeContainsAssertions : IterableLikeContainsAssertions { return creator.createAssertionGroup(entryPointStepLogic.container, expected) } - private fun createAssertionGroupWithoutCheckerInAnyOrder( + private fun createAssertionGroupWithoutCheckerInOrderGrouped( entryPointStepLogic: IterableLikeContains.EntryPointStepLogic, expected: List, - factory: ((T) -> Iterable, S) -> IterableLikeContains.Creator + inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, + inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit, + factory: ((T) -> Iterable, S, InOrderOnlyReportingOptions.() -> Unit, InAnyOrderOnlyReportingOptions.() -> Unit) -> IterableLikeContains.Creator ): AssertionGroup { - val creator = factory(entryPointStepLogic.converter, entryPointStepLogic.searchBehaviour) + val creator = factory( + entryPointStepLogic.converter, + entryPointStepLogic.searchBehaviour, + inOrderOnlyReportingOptions, + inAnyOrderOnlyReportingOptions + ) return creator.createAssertionGroup(entryPointStepLogic.container, expected) } } diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyAssertionCreator.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyAssertionCreator.kt index 7f16b5bed5..a8683054dd 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyAssertionCreator.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyAssertionCreator.kt @@ -10,6 +10,8 @@ import ch.tutteli.atrium.logic.* import ch.tutteli.atrium.logic.assertions.impl.LazyThreadUnsafeAssertionGroup import ch.tutteli.atrium.logic.creating.iterable.contains.IterableLikeContains import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.impl.InAnyOrderOnlyReportingOptionsImpl import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.atrium.reporting.translating.Translatable import ch.tutteli.atrium.translations.DescriptionIterableLikeExpectation @@ -33,7 +35,8 @@ import ch.tutteli.atrium.translations.DescriptionIterableLikeExpectation.* */ abstract class InAnyOrderOnlyAssertionCreator( private val converter: (T) -> Iterable, - private val searchBehaviour: InAnyOrderOnlySearchBehaviour + private val searchBehaviour: InAnyOrderOnlySearchBehaviour, + private val reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit ) : IterableLikeContains.Creator { final override fun createAssertionGroup( @@ -41,47 +44,52 @@ abstract class InAnyOrderOnlyAssertionCreator( searchCriteria: List ): AssertionGroup { return LazyThreadUnsafeAssertionGroup { - val list = container.maybeSubject.fold({ mutableListOf() }) { converter(it).toMutableList() } + val listFromWhichMatchesWillBeRemoved = container.maybeSubject.fold({ mutableListOf() }) { converter(it).toMutableList() } + val initialSize = listFromWhichMatchesWillBeRemoved.size val assertions = mutableListOf() - val sizeAssertion = container.collectBasedOnSubject(Some(list)) { + //TODO 0.19.0 could be moved out to a function, is also used in InOrderOnlyBaseAssertionCreator + val sizeAssertion = container.collectBasedOnSubject(Some(listFromWhichMatchesWillBeRemoved)) { _logic .size { it } .collectAndLogicAppend { toBe(searchCriteria.size) } } - val mismatches = createAssertionsForAllSearchCriteria(container, searchCriteria, list, assertions) - if (mismatches == 0 && list.isNotEmpty()) { + val mismatches = createAssertionsForAllSearchCriteria(container, searchCriteria, listFromWhichMatchesWillBeRemoved, assertions) + if (mismatches == 0 && listFromWhichMatchesWillBeRemoved.isNotEmpty()) { assertions.add(LazyThreadUnsafeAssertionGroup { createExplanatoryGroupForMismatchesEtc( - list, + listFromWhichMatchesWillBeRemoved, WARNING_ADDITIONAL_ELEMENTS ) }) } val description = searchBehaviour.decorateDescription(TO_CONTAIN) - val summary = assertionBuilder.summary - .withDescription(description) - .withAssertions(assertions) - .build() + //TODO 0.19.0 could be moved out to a function, is also used in InOrderOnlyBaseAssertionCreator + val options = InAnyOrderOnlyReportingOptionsImpl().apply(reportingOptions) + val assertionGroup = (if (searchCriteria.size <= options.maxNumberOfExpectedElementsForSummary) { + assertionBuilder.summary.withDescription(description) + } else { + assertionBuilder.list.withDescriptionAndEmptyRepresentation(description) + }).withAssertions(assertions).build() + + if (mismatches != 0 && listFromWhichMatchesWillBeRemoved.isNotEmpty()) { + val warningDescription = + if(listFromWhichMatchesWillBeRemoved.size == mismatches || initialSize < mismatches) WARNING_MISMATCHES + else WARNING_MISMATCHES_ADDITIONAL_ELEMENTS - if (mismatches != 0 && list.isNotEmpty()) { - val warningDescription = when (list.size) { - mismatches -> WARNING_MISMATCHES - else -> WARNING_MISMATCHES_ADDITIONAL_ELEMENTS - } assertionBuilder.invisibleGroup .withAssertions( sizeAssertion, - summary, - createExplanatoryGroupForMismatchesEtc(list, warningDescription) + assertionGroup, + createExplanatoryGroupForMismatchesEtc(listFromWhichMatchesWillBeRemoved, warningDescription) ) .build() } else { assertionBuilder.invisibleGroup .withAssertions( sizeAssertion, - summary + assertionGroup ) .build() } diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyEntriesAssertionCreator.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyEntriesAssertionCreator.kt index 7c4100c7fa..f5730152b8 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyEntriesAssertionCreator.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyEntriesAssertionCreator.kt @@ -7,6 +7,7 @@ import ch.tutteli.atrium.assertions.builders.fixedClaimGroup import ch.tutteli.atrium.creating.AssertionContainer import ch.tutteli.atrium.creating.Expect import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.atrium.logic.impl.allCreatedAssertionsHold import ch.tutteli.atrium.logic.impl.createExplanatoryAssertionGroup @@ -29,8 +30,9 @@ import ch.tutteli.atrium.translations.DescriptionIterableLikeExpectation.AN_ELEM */ class InAnyOrderOnlyEntriesAssertionCreator( converter: (T) -> Iterable, - searchBehaviour: InAnyOrderOnlySearchBehaviour -) : InAnyOrderOnlyAssertionCreator.() -> Unit)?>(converter, searchBehaviour) { + searchBehaviour: InAnyOrderOnlySearchBehaviour, + reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit +) : InAnyOrderOnlyAssertionCreator.() -> Unit)?>(converter, searchBehaviour, reportingOptions) { override fun createAssertionForSearchCriterionAndRemoveMatchFromList( container: AssertionContainer<*>, diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyValuesAssertionCreator.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyValuesAssertionCreator.kt index f47410bd18..7bf0932297 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyValuesAssertionCreator.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InAnyOrderOnlyValuesAssertionCreator.kt @@ -5,6 +5,7 @@ import ch.tutteli.atrium.assertions.AssertionGroup import ch.tutteli.atrium.assertions.builders.assertionBuilder import ch.tutteli.atrium.creating.AssertionContainer import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.atrium.reporting.translating.Translatable import ch.tutteli.atrium.translations.DescriptionIterableLikeExpectation.AN_ELEMENT_WHICH_EQUALS @@ -23,8 +24,9 @@ import ch.tutteli.atrium.translations.DescriptionIterableLikeExpectation.AN_ELEM */ class InAnyOrderOnlyValuesAssertionCreator( converter: (T) -> Iterable, - searchBehaviour: InAnyOrderOnlySearchBehaviour -) : InAnyOrderOnlyAssertionCreator(converter, searchBehaviour) { + searchBehaviour: InAnyOrderOnlySearchBehaviour, + reportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit +) : InAnyOrderOnlyAssertionCreator(converter, searchBehaviour, reportingOptions) { override fun createAssertionForSearchCriterionAndRemoveMatchFromList( container: AssertionContainer<*>, diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyBaseAssertionCreator.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyBaseAssertionCreator.kt index d64f31c629..e4aafa83f3 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyBaseAssertionCreator.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyBaseAssertionCreator.kt @@ -33,7 +33,7 @@ abstract class InOrderOnlyBaseAssertionCreator( return LazyThreadUnsafeAssertionGroup { // TODO 0.19.0 more efficient and pragmatic than turnSubjectToList, use at other places too val maybeList = container.maybeSubject.map { - //TODO move into when with 1.0.0, update to Kotlin 1.4 respectively + //TODO move into when with 1.0.0, update to Kotlin >= 1.4 respectively val iterable = converter(it) when (iterable) { is List -> iterable @@ -63,7 +63,7 @@ abstract class InOrderOnlyBaseAssertionCreator( val description = searchBehaviour.decorateDescription(DescriptionIterableLikeExpectation.TO_CONTAIN) val options = InOrderOnlyReportingOptionsImpl().apply(reportingOptions) - val assertionGroup = (if (list.size <= options.numberOfElementsInSummary) { + val assertionGroup = (if (searchCriteria.size <= options.maxNumberOfExpectedElementsForSummary) { assertionBuilder.summary.withDescription(description) } else { assertionBuilder.list.withDescriptionAndEmptyRepresentation(description) diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyGroupedEntriesAssertionCreator.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyGroupedEntriesAssertionCreator.kt index a71b3bb761..6e1d46477e 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyGroupedEntriesAssertionCreator.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyGroupedEntriesAssertionCreator.kt @@ -5,23 +5,28 @@ import ch.tutteli.atrium.logic._logic import ch.tutteli.atrium.logic._logicAppend import ch.tutteli.atrium.logic.builderContainsInIterableLike import ch.tutteli.atrium.logic.creating.iterable.contains.creators.entriesInAnyOrderOnly -import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlyGroupedSearchBehaviour import ch.tutteli.atrium.logic.creating.iterable.contains.steps.butOnly import ch.tutteli.atrium.logic.creating.iterable.contains.steps.inAnyOrder +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.kbox.identity class InOrderOnlyGroupedEntriesAssertionCreator( converter: (T) -> Iterable, searchBehaviour: InOrderOnlyGroupedSearchBehaviour, - reportingOptions: InOrderOnlyReportingOptions.() -> Unit -) : InOrderOnlyGroupedAssertionCreator.() -> Unit)?>(converter, searchBehaviour, reportingOptions), - InOrderOnlyMatcher.() -> Unit)?> by InOrderOnlyEntriesMatcher() { + inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, + private val inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit +) : InOrderOnlyGroupedAssertionCreator.() -> Unit)?>( + converter, + searchBehaviour, + inOrderOnlyReportingOptions +), InOrderOnlyMatcher.() -> Unit)?> by InOrderOnlyEntriesMatcher() { override fun Expect>.addSublistAssertion(groupOfSearchCriteria: List<(Expect.() -> Unit)?>) { _logic.builderContainsInIterableLike(::identity)._logic.inAnyOrder._logic.butOnly._logicAppend { - entriesInAnyOrderOnly(groupOfSearchCriteria) + entriesInAnyOrderOnly(groupOfSearchCriteria, inAnyOrderOnlyReportingOptions) } } } diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyGroupedValuesAssertionCreator.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyGroupedValuesAssertionCreator.kt index 2648021984..4ec55779f1 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyGroupedValuesAssertionCreator.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterable/contains/creators/impl/InOrderOnlyGroupedValuesAssertionCreator.kt @@ -9,19 +9,21 @@ import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderO import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InOrderOnlyGroupedSearchBehaviour import ch.tutteli.atrium.logic.creating.iterable.contains.steps.butOnly import ch.tutteli.atrium.logic.creating.iterable.contains.steps.inAnyOrder +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.typeutils.IterableLike import ch.tutteli.kbox.identity class InOrderOnlyGroupedValuesAssertionCreator( converter: (T) -> Iterable, searchBehaviour: InOrderOnlyGroupedSearchBehaviour, - reportingOptions: InOrderOnlyReportingOptions.() -> Unit -) : InOrderOnlyGroupedAssertionCreator(converter, searchBehaviour, reportingOptions), + inOrderOnlyReportingOptions: InOrderOnlyReportingOptions.() -> Unit, + private val inAnyOrderOnlyReportingOptions: InAnyOrderOnlyReportingOptions.() -> Unit +) : InOrderOnlyGroupedAssertionCreator(converter, searchBehaviour, inOrderOnlyReportingOptions), InOrderOnlyMatcher by InOrderOnlyValueMatcher() { override fun Expect>.addSublistAssertion(groupOfSearchCriteria: List) { _logic.builderContainsInIterableLike(::identity)._logic.inAnyOrder._logic.butOnly._logicAppend { - valuesInAnyOrderOnly(groupOfSearchCriteria) + valuesInAnyOrderOnly(groupOfSearchCriteria, inAnyOrderOnlyReportingOptions) } } } diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/InAnyOrderOnlyReportingOptions.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/InAnyOrderOnlyReportingOptions.kt new file mode 100644 index 0000000000..f4e36aec0c --- /dev/null +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/InAnyOrderOnlyReportingOptions.kt @@ -0,0 +1,8 @@ +package ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting + +/** + * Reporting options for `toContain.inAnyOrder.only` expectation functions. + * + * @since 0.18.0 + */ +interface InAnyOrderOnlyReportingOptions : OnlyReportingOptions diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/InOrderOnlyReportingOptions.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/InOrderOnlyReportingOptions.kt index a04748b26b..ccd3a50045 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/InOrderOnlyReportingOptions.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/InOrderOnlyReportingOptions.kt @@ -2,32 +2,37 @@ package ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting import ch.tutteli.atrium.logic.creating.typeutils.IterableLike -interface InOrderOnlyReportingOptions { - +/** + * Reporting options for `toContain.inOrder.only` expectation functions. + * + * @since 0.17.0 + */ +interface InOrderOnlyReportingOptions : OnlyReportingOptions{ /** - * Always shows only failing expectations, same as [InOrderOnlyReportingOptions.showOnlyFailingIfMoreElementsThan]`(0)` - */ - fun showOnlyFailing() = showOnlyFailingIfMoreElementsThan(0) - - /** - * Always shows a summary where both failing and successful expectations are shown, same as - * [InOrderOnlyReportingOptions.showOnlyFailingIfMoreElementsThan]`(Int.MAX_VALUE)`. - */ - fun showAlwaysSummary() = showOnlyFailingIfMoreElementsThan(Int.MAX_VALUE) - - /** - * Show only failing expectations, i.e. elements which do not match, instead of a summary which - * lists also successful expectations/elements. + * Show only failing expectations, i.e. elements which do not match, instead of a summary (which + * lists also successful expectations/elements) if there are more than [number] elements. * - * Default shows up to 10 elements in a summary ans only failing afterwards, + * Default shows up to 10 elements in a summary and only failing afterwards, * i.e. default is [showOnlyFailingIfMoreElementsThan]`(10)` + * + * @since 0.17.0 */ + @Deprecated( + "Use showOnlyFailingIfMoreExpectedElementsThan instead; will be removed with 0.19.0", + ReplaceWith("this.showOnlyFailingIfMoreExpectedElementsThan(number)") + ) fun showOnlyFailingIfMoreElementsThan(number: Int) /** * Indicates until how many elements the summary view shall be used. If there are more elements in the * [IterableLike], then only failing expectations shall be shown. + * + * @since 0.17.0 */ + @Deprecated( + "Use maxNumberOfExpectedElementsForSummary; will be removed with 0.19.0", + ReplaceWith("this.maxNumberOfExpectedElementsForSummary") + ) val numberOfElementsInSummary: Int } diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/OnlyReportingOptions.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/OnlyReportingOptions.kt new file mode 100644 index 0000000000..ce12bf68eb --- /dev/null +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/OnlyReportingOptions.kt @@ -0,0 +1,44 @@ +package ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting + +/** + * Base interface for OnlyReportingOptions + * @since 0.18.0 + */ +interface OnlyReportingOptions { + + /** + * Always shows only failing expectations, same as [OnlyReportingOptions.showOnlyFailingIfMoreExpectedElementsThan]`(0)` + * + * @since 0.17.0 + */ + fun showOnlyFailing() = showOnlyFailingIfMoreExpectedElementsThan(0) + + /** + * Always shows a summary where both failing and successful expectations are shown, same as + * [OnlyReportingOptions.showOnlyFailingIfMoreExpectedElementsThan]`(Int.MAX_VALUE)`. + * + * @since 0.17.0 + */ + fun showAlwaysSummary() = showOnlyFailingIfMoreExpectedElementsThan(Int.MAX_VALUE) + + /** + * Show only failing expectations, i.e. elements which do not match, instead of a summary (which + * lists also successful expectations/elements) if there are more than [number] expected elements. + * + * Default shows up to 10 elements in a summary and only failing afterwards, + * i.e. default is [showOnlyFailingIfMoreExpectedElementsThan]`(10)` + * + * @since 0.17.0 + */ + fun showOnlyFailingIfMoreExpectedElementsThan(number: Int) + + /** + * Indicates until how many expected elements the summary view shall be used. If there are more expected elements, + * then only failing expectations shall be shown. + * + * @since 0.18.0 + */ + val maxNumberOfExpectedElementsForSummary: Int +} + + diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/BaseOnlyReportingOptionsImpl.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/BaseOnlyReportingOptionsImpl.kt new file mode 100644 index 0000000000..ebf55801ba --- /dev/null +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/BaseOnlyReportingOptionsImpl.kt @@ -0,0 +1,13 @@ +package ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.impl + +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.OnlyReportingOptions + +internal abstract class BaseOnlyReportingOptionsImpl : OnlyReportingOptions { + private var _maxNumberOfExpectedElementsInSummary = 10 + override val maxNumberOfExpectedElementsForSummary: Int get() = _maxNumberOfExpectedElementsInSummary + + override fun showOnlyFailingIfMoreExpectedElementsThan(number: Int) { + // could check for negative numbers, but it does not really matter that much, it still means always + _maxNumberOfExpectedElementsInSummary = number + } +} diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/InAnyOrderOnlyReportingOptionsImpl.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/InAnyOrderOnlyReportingOptionsImpl.kt new file mode 100644 index 0000000000..33b3d30364 --- /dev/null +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/InAnyOrderOnlyReportingOptionsImpl.kt @@ -0,0 +1,6 @@ +package ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.impl + +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions + +internal class InAnyOrderOnlyReportingOptionsImpl : BaseOnlyReportingOptionsImpl(), InAnyOrderOnlyReportingOptions + diff --git a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/InOrderOnlyReportingOptionsImpl.kt b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/InOrderOnlyReportingOptionsImpl.kt index 423a6f5df7..636a0ae953 100644 --- a/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/InOrderOnlyReportingOptionsImpl.kt +++ b/logic/atrium-logic-common/src/main/kotlin/ch/tutteli/atrium/logic/creating/iterablelike/contains/reporting/impl/InOrderOnlyReportingOptionsImpl.kt @@ -2,12 +2,10 @@ package ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.impl import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions -internal class InOrderOnlyReportingOptionsImpl : InOrderOnlyReportingOptions { - private var _numberOfElementsInSummary = 10 - override val numberOfElementsInSummary: Int get() = _numberOfElementsInSummary - - override fun showOnlyFailingIfMoreElementsThan(number: Int) { - // could check for negative numbers but it does not really matter that much, it still means always - _numberOfElementsInSummary = number - } +internal class InOrderOnlyReportingOptionsImpl : BaseOnlyReportingOptionsImpl(), InOrderOnlyReportingOptions{ + //TODO 0.19.0 remove + @Suppress("OverridingDeprecatedMember") + override val numberOfElementsInSummary: Int get() = maxNumberOfExpectedElementsForSummary + @Suppress("OverridingDeprecatedMember") + override fun showOnlyFailingIfMoreElementsThan(number: Int) = showOnlyFailingIfMoreExpectedElementsThan(number) } diff --git a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt index a49bf52080..e14112b08f 100644 --- a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt +++ b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInAnyOrderOnlyEntriesExpectationsSpec.kt @@ -3,43 +3,39 @@ package ch.tutteli.atrium.specs.integration import ch.tutteli.atrium.api.fluent.en_GB.* import ch.tutteli.atrium.api.verbs.internal.expect import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.utils.expectLambda import ch.tutteli.atrium.specs.* abstract class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec( - toContainInAnyOrderOnlyEntries: Fun2, Expect.() -> Unit, Array.() -> Unit>>, - toContainInAnyOrderOnlyNullableEntries: Fun2, (Expect.() -> Unit)?, Array.() -> Unit)?>>, + toContainInAnyOrderOnlyEntries: Fun3, Expect.() -> Unit, Array.() -> Unit>, InAnyOrderOnlyReportingOptions.() -> Unit>, + toContainInAnyOrderOnlyNullableEntries: Fun3, (Expect.() -> Unit)?, Array.() -> Unit)?>, InAnyOrderOnlyReportingOptions.() -> Unit>, describePrefix: String = "[Atrium] " ) : IterableToContainEntriesSpecBase({ include(object : SubjectLessSpec>( describePrefix, - toContainInAnyOrderOnlyEntries.forSubjectLess({ toEqual(2.5) }, arrayOf()) + toContainInAnyOrderOnlyEntries.forSubjectLess({ toEqual(2.5) }, arrayOf(), emptyInAnyOrderOnlyReportOptions) ) {}) include(object : SubjectLessSpec>( describePrefix, - toContainInAnyOrderOnlyNullableEntries.forSubjectLess(null, arrayOf()) + toContainInAnyOrderOnlyNullableEntries.forSubjectLess(null, arrayOf(), emptyInAnyOrderOnlyReportOptions) ) {}) include(object : AssertionCreatorSpec>( describePrefix, listOf(1.2, 2.0), *toContainInAnyOrderOnlyEntries.forAssertionCreatorSpec( "$toEqualDescr: 1.2", "$toEqualDescr: 2.0", - { toEqual(1.2) }, arrayOf(expectLambda { toEqual(2.0) }) + { toEqual(1.2) }, arrayOf(expectLambda { toEqual(2.0) }), emptyInAnyOrderOnlyReportOptions ) ) {}) include(object : AssertionCreatorSpec>( "$describePrefix[nullable] ", listOf(1.2, 2.0), *toContainInAnyOrderOnlyNullableEntries.forAssertionCreatorSpec( "$toEqualDescr: 1.2", "$toEqualDescr: 2.0", - { toEqual(1.2) }, arrayOf(expectLambda { toEqual(2.0) }) + { toEqual(1.2) }, arrayOf(expectLambda { toEqual(2.0) }), emptyInAnyOrderOnlyReportOptions ) ) {}) - fun Expect>.toContainInAnyOrderOnlyNullableEntriesFun( - t: (Expect.() -> Unit)?, - vararg tX: (Expect.() -> Unit)? - ) = toContainInAnyOrderOnlyNullableEntries(this, t, tX) - //@formatter:off val anEntryAfterSuccess = "$anElementWhichNeedsDescr: $separator$indentRootBulletPoint$indentSuccessfulBulletPoint$indentListBulletPoint$explanatoryBulletPoint" @@ -53,8 +49,9 @@ abstract class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec( ) { toContainEntriesFunArr -> fun Expect>.toContainEntriesFun( t: Expect.() -> Unit, - vararg tX: Expect.() -> Unit - ) = toContainEntriesFunArr(t, tX) + vararg tX: Expect.() -> Unit, + report: InAnyOrderOnlyReportingOptions.() -> Unit = {} + ) = toContainEntriesFunArr(t, tX, report) context("empty collection") { it("$toBeLessThanFun(1.0) throws AssertionError") { @@ -261,32 +258,167 @@ abstract class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec( } } } + + context("report options") { + context("iterable ${oneToFour().toList()}") { + it("shows only failing with report option `showOnlyFailing`") { + expect { + expect(oneToFour()).toContainEntriesFun({ toEqual(2.0) }, report = { showOnlyFailing() }) + }.toThrow { + message { + toContainSize(5, 1) + toContain.exactly(1).values( + "$rootBulletPoint$toContainInAnyOrderOnly:", + "$warningBulletPoint$additionalElements:", + "${listBulletPoint}1.0", + "${listBulletPoint}3.0" + ) + toContain.exactly(2).value("${listBulletPoint}4.0") + notToContain("$toEqualDescr: 2.0") + + } + } + } + it("shows only failing with report option `showOnlyFailingIfMoreExpectedElementsThan(3)` because there are 5") { + expect { + expect(oneToFour()).toContainEntriesFun( + { toEqual(1.0) }, + { toEqual(2.0) }, + { toEqual(3.0) }, + { toEqual(4.0) }, + { toEqual(4.0) }, + { toEqual(5.0) }, + report = { showOnlyFailingIfMoreExpectedElementsThan(3) }) + }.toThrow { + message { + toContainSize(5, 6) + toContain.exactly(1).values("$listBulletPoint$anEntryAfterSuccess$toEqualDescr: 5.0") + notToContain( + "$toEqualDescr: 1.0", + "$toEqualDescr: 2.0", + "$toEqualDescr: 3.0", + "$toEqualDescr: 4.0" + ) + notToContain(additionalElements, mismatches, mismatchesAdditionalElements) + } + } + } + + } + + context("iterable $oneToEleven") { + it("shows only failing per default as there are more than 10 expected elements") { + expect { + expect(oneToEleven).toContainEntriesFun( + { toEqual(1.0) }, + { toEqual(2.0) }, + { toEqual(3.0) }, + { toEqual(4.0) }, + { toEqual(-1.0) }, + { toEqual(6.0) }, + { toEqual(7.0) }, + { toEqual(-2.0) }, + { toEqual(9.0) }, + { toEqual(10.0) }, + { toEqual(11.0) } + ) + }.toThrow { + message { + toContain.exactly(1).values( + "$listBulletPoint$anEntryAfterSuccess$toEqualDescr: -1.0", + "$listBulletPoint$anEntryAfterSuccess$toEqualDescr: -2.0", + "$warningBulletPoint$mismatches:", + "${listBulletPoint}5.0", + "${listBulletPoint}8.0" + ) + notToContain( + "$toEqualDescr: 1.0", + "$toEqualDescr: 2.0", + "$toEqualDescr: 3.0", + "$toEqualDescr: 4.0", + "$toEqualDescr: 6.0", + "$toEqualDescr: 7.0", + "$toEqualDescr: 9.0", + "$toEqualDescr: 10.0", + "$toEqualDescr: 11.0", + + additionalElements, mismatchesAdditionalElements + ) + } + } + } + it("shows all with report option `showAlwaysSummary`") { + expect { + expect(oneToEleven).toContainEntriesFun( + { toEqual(1.0) }, + { toEqual(2.0) }, + { toEqual(3.0) }, + { toEqual(4.0) }, + { toEqual(-1.0) }, + { toEqual(6.0) }, + { toEqual(7.0) }, + { toEqual(-2.0) }, + { toEqual(9.0) }, + { toEqual(10.0) }, + { toEqual(11.0) }, + report = { showAlwaysSummary() } + ) + }.toThrow { + message { + toContain.exactly(1).values( + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 1.0", + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 2.0", + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 3.0", + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 4.0", + "$failingBulletPoint$anEntryAfterFailing$toEqualDescr: -1.0", + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 6.0", + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 7.0", + "$failingBulletPoint$anEntryAfterFailing$toEqualDescr: -2.0", + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 9.0", + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 10.0", + "$successfulBulletPoint$anEntryAfterSuccess$toEqualDescr: 11.0", + "$warningBulletPoint$mismatches:", + "${listBulletPoint}5.0", + "${listBulletPoint}8.0" + ) + notToContain(additionalElements, mismatchesAdditionalElements) + } + } + } + } + } } nullableCases(describePrefix) { + fun Expect>.toContainFun( + t: (Expect.() -> Unit)?, + vararg tX: (Expect.() -> Unit)?, + report: InAnyOrderOnlyReportingOptions.() -> Unit = {} + ) = toContainInAnyOrderOnlyNullableEntries(this, t, tX, report) + describeFun(toContainInAnyOrderOnlyNullableEntries) { val null1null3 = { sequenceOf(null, 1.0, null, 3.0).constrainOnce().asIterable() } context("iterable ${null1null3().toList()}") { context("happy cases (do not throw)") { it("null, $toEqualFun(1.0), null, $toEqualFun(3.0)") { - expect(null1null3()).toContainInAnyOrderOnlyNullableEntriesFun( + expect(null1null3()).toContainFun( null, { toEqual(1.0) }, null, { toEqual(3.0) } ) } it("$toEqualFun(1.0), null, null, $toEqualFun(3.0)") { - expect(null1null3()).toContainInAnyOrderOnlyNullableEntriesFun( + expect(null1null3()).toContainFun( { toEqual(1.0) }, null, null, { toEqual(3.0) } ) } it("$toEqualFun(1.0), null, $toEqualFun(3.0), null") { - expect(null1null3()).toContainInAnyOrderOnlyNullableEntriesFun( + expect(null1null3()).toContainFun( { toEqual(1.0) }, null, { toEqual(3.0) }, null ) } it("$toEqualFun(1.0), $toEqualFun(3.0), null, null") { - expect(null1null3()).toContainInAnyOrderOnlyNullableEntriesFun( + expect(null1null3()).toContainFun( { toEqual(1.0) }, { toEqual(3.0) }, null, null ) } @@ -295,7 +427,7 @@ abstract class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec( context("failing cases") { it("null, $toEqualFun(1.0), $toEqualFun(3.0) -- second null was missing") { expect { - expect(null1null3()).toContainInAnyOrderOnlyNullableEntriesFun( + expect(null1null3()).toContainFun( null, { toEqual(1.0) }, { toEqual(3.0) } ) }.toThrow { @@ -315,7 +447,7 @@ abstract class IterableToContainInAnyOrderOnlyEntriesExpectationsSpec( it("first wins: $toBeLessThanFun(4.0), null, null, $toEqualDescr(1.0)") { expect { - expect(null1null3()).toContainInAnyOrderOnlyNullableEntriesFun( + expect(null1null3()).toContainFun( { toBeLessThan(4.0) }, null, null, diff --git a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt index 6b33964ff8..b6b3e30f53 100644 --- a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt +++ b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInAnyOrderOnlyValuesExpectationsSpec.kt @@ -3,35 +3,36 @@ package ch.tutteli.atrium.specs.integration import ch.tutteli.atrium.api.fluent.en_GB.* import ch.tutteli.atrium.api.verbs.internal.expect import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.specs.* abstract class IterableToContainInAnyOrderOnlyValuesExpectationsSpec( - toContainInAnyOrderOnlyValues: Fun2, Double, Array>, - toContainInAnyOrderOnlyNullableValues: Fun2, Double?, Array>, + toContainInAnyOrderOnlyValues: Fun3, Double, Array, InAnyOrderOnlyReportingOptions.() -> Unit>, + toContainInAnyOrderOnlyNullableValues: Fun3, Double?, Array, InAnyOrderOnlyReportingOptions.() -> Unit>, describePrefix: String = "[Atrium] " ) : IterableToContainSpecBase({ include(object : SubjectLessSpec>( describePrefix, - toContainInAnyOrderOnlyValues.forSubjectLess(2.5, arrayOf()) + toContainInAnyOrderOnlyValues.forSubjectLess(2.5, arrayOf(), emptyInAnyOrderOnlyReportOptions) ) {}) include(object : SubjectLessSpec>( describePrefix, - toContainInAnyOrderOnlyNullableValues.forSubjectLess(2.5, arrayOf()) + toContainInAnyOrderOnlyNullableValues.forSubjectLess(2.5, arrayOf(), emptyInAnyOrderOnlyReportOptions) ) {}) - fun Expect>.toContainInAnyOrderNullableValuesFun(t: Double?, vararg tX: Double?) = - toContainInAnyOrderOnlyNullableValues(this, t, tX) - nonNullableCases( describePrefix, toContainInAnyOrderOnlyValues, toContainInAnyOrderOnlyNullableValues ) { toContainValuesFunArr -> - fun Expect>.toContainFun(t: Double, vararg tX: Double) = - toContainValuesFunArr(t, tX.toTypedArray()) + fun Expect>.toContainFun( + t: Double, + vararg tX: Double, + report: InAnyOrderOnlyReportingOptions.() -> Unit = {} + ) = toContainValuesFunArr(t, tX.toTypedArray(), report) context("empty collection") { it("1.0 throws AssertionError") { @@ -188,10 +189,148 @@ abstract class IterableToContainInAnyOrderOnlyValuesExpectationsSpec( } } } + + context("report options") { + context("iterable ${oneToFour().toList()}") { + it("shows only failing with report option `showOnlyFailing`") { + expect { + expect(oneToFour()).toContainFun(2.0, report = { showOnlyFailing() }) + }.toThrow { + message { + toContainSize(5, 1) + toContain.exactly(1).values( + "$rootBulletPoint$toContainInAnyOrderOnly:", + "$warningBulletPoint$additionalElements:", + "${listBulletPoint}1.0", + "${listBulletPoint}3.0" + ) + toContain.exactly(2).value("${listBulletPoint}4.0") + notToContain("$anElementWhichEquals: 2.0") + + } + } + } + it("shows only failing with report option `showOnlyFailingIfMoreExpectedElementsThan(3)` because there are 5") { + expect { + expect(oneToFour()).toContainFun( + 1.0, + 2.0, + 3.0, + 4.0, + 4.0, + 5.0, + report = { showOnlyFailingIfMoreExpectedElementsThan(3) }) + }.toThrow { + message { + toContainSize(5, 6) + toContain.exactly(1).values("$listBulletPoint$anElementWhichEquals: 5.0") + notToContain( + "$anElementWhichEquals: 1.0", + "$anElementWhichEquals: 2.0", + "$anElementWhichEquals: 3.0", + "$anElementWhichEquals: 4.0" + ) + notToContain(additionalElements, mismatches, mismatchesAdditionalElements) + } + } + } + + } + + context("iterable $oneToEleven") { + it("shows only failing per default as there are more than 10 expected elements") { + expect { + expect(oneToEleven).toContainFun( + 1.0, + 2.0, + 3.0, + 4.0, + -1.0, + 6.0, + 7.0, + -2.0, + 9.0, + 10.0, + 11.0 + ) + }.toThrow { + message { + toContain.exactly(1).values( + "$listBulletPoint$anElementWhichEquals: -1.0", + "$listBulletPoint$anElementWhichEquals: -2.0", + "$warningBulletPoint$mismatches:", + "${listBulletPoint}5.0", + "${listBulletPoint}8.0" + ) + notToContain( + "$anElementWhichEquals: 1.0", + "$anElementWhichEquals: 2.0", + "$anElementWhichEquals: 3.0", + "$anElementWhichEquals: 4.0", + "$anElementWhichEquals: 6.0", + "$anElementWhichEquals: 7.0", + "$anElementWhichEquals: 9.0", + "$anElementWhichEquals: 10.0", + "$anElementWhichEquals: 11.0", + + additionalElements, mismatchesAdditionalElements + ) + } + } + } + it("shows all with report option `showAlwaysSummary`") { + expect { + expect(oneToEleven).toContainFun( + 1.0, + 2.0, + 3.0, + 4.0, + -1.0, + 6.0, + 7.0, + -2.0, + 9.0, + 10.0, + 11.0, + report = { showAlwaysSummary() } + ) + }.toThrow { + message { + toContain.exactly(1).values( + "$successfulBulletPoint$anElementWhichEquals: 1.0", + "$successfulBulletPoint$anElementWhichEquals: 2.0", + "$successfulBulletPoint$anElementWhichEquals: 3.0", + "$successfulBulletPoint$anElementWhichEquals: 4.0", + "$failingBulletPoint$anElementWhichEquals: -1.0", + "$successfulBulletPoint$anElementWhichEquals: 6.0", + "$successfulBulletPoint$anElementWhichEquals: 7.0", + "$failingBulletPoint$anElementWhichEquals: -2.0", + "$successfulBulletPoint$anElementWhichEquals: 9.0", + "$successfulBulletPoint$anElementWhichEquals: 10.0", + "$successfulBulletPoint$anElementWhichEquals: 11.0", + "$warningBulletPoint$mismatches:", + "${listBulletPoint}5.0", + "${listBulletPoint}8.0" + ) + notToContain(additionalElements, mismatchesAdditionalElements) + } + } + } + } + } } nullableCases(describePrefix) { + + + fun Expect>.toContainFun( + t: Double?, + vararg tX: Double?, + report: InAnyOrderOnlyReportingOptions.() -> Unit = {} + ) = toContainInAnyOrderOnlyNullableValues(this, t, tX, report) + + describeFun(toContainInAnyOrderOnlyValues) { val null1null3 = { sequenceOf(null, 1.0, null, 3.0).constrainOnce().asIterable() } @@ -199,23 +338,23 @@ abstract class IterableToContainInAnyOrderOnlyValuesExpectationsSpec( context("iterable ${null1null3().toList()}") { context("happy cases (do not throw)") { it("null, 1.0, null, 3.0") { - expect(null1null3()).toContainInAnyOrderNullableValuesFun(null, 1.0, null, 3.0) + expect(null1null3()).toContainFun(null, 1.0, null, 3.0) } it("1.0, null, null, 3.0") { - expect(null1null3()).toContainInAnyOrderNullableValuesFun(1.0, null, null, 3.0) + expect(null1null3()).toContainFun(1.0, null, null, 3.0) } it("1.0, null, 3.0, null") { - expect(null1null3()).toContainInAnyOrderNullableValuesFun(1.0, null, 3.0, null) + expect(null1null3()).toContainFun(1.0, null, 3.0, null) } it("1.0, 3.0, null, null") { - expect(null1null3()).toContainInAnyOrderNullableValuesFun(1.0, 3.0, null, null) + expect(null1null3()).toContainFun(1.0, 3.0, null, null) } } context("failing cases") { it("null, 1.0, 3.0 -- null was missing") { expect { - expect(null1null3()).toContainInAnyOrderNullableValuesFun(null, 1.0, 3.0) + expect(null1null3()).toContainFun(null, 1.0, 3.0) }.toThrow { message { toContain.exactly(1).values( diff --git a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt index 98c4261b7b..49b210e5ab 100644 --- a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt +++ b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyEntriesExpectationsSpec.kt @@ -37,12 +37,6 @@ abstract class IterableToContainInOrderOnlyEntriesExpectationsSpec( ) ) {}) - fun Expect>.toContainInOrderOnlyNullableEntriesFun( - t: (Expect.() -> Unit)?, - vararg tX: (Expect.() -> Unit)?, - report : InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions - ) = toContainInOrderOnlyNullableEntries(this, t, tX, report) - fun Expect.elementSuccess(index: Int, actual: Any, expected: String): Expect { return this.toContain.exactly(1).regex( "\\Q$successfulBulletPoint$featureArrow${elementWithIndex(index)}: $actual\\E.*$separator" + @@ -54,16 +48,21 @@ abstract class IterableToContainInOrderOnlyEntriesExpectationsSpec( index: Int, actual: Any, expected: String, - explaining: Boolean = false + explaining: Boolean = false, + withBulletPoint: Boolean = true ): Expect { return this.toContain.exactly(1).regex( - "\\Q$failingBulletPoint$featureArrow${elementWithIndex(index)}: $actual\\E.*$separator" + + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${elementWithIndex(index)}: $actual\\E.*$separator" + "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow${if (explaining) "$indentFeatureBulletPoint$explanatoryBulletPoint" else featureBulletPoint}$expected" ) } - fun Expect.elementNonExisting(index: Int, expected: String): Expect = - elementFailing(index, sizeExceeded, expected, explaining = true) + fun Expect.elementNonExisting( + index: Int, + expected: String, + withBulletPoint: Boolean = true + ): Expect = + elementFailing(index, sizeExceeded, expected, explaining = true, withBulletPoint = withBulletPoint) nonNullableCases( describePrefix, @@ -74,7 +73,7 @@ abstract class IterableToContainInOrderOnlyEntriesExpectationsSpec( fun Expect>.toContainEntriesFun( t: Expect.() -> Unit, vararg tX: Expect.() -> Unit, - report : InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions + report: InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions ) = toContainEntriesFunArr(t, tX, report) context("empty collection") { @@ -233,10 +232,130 @@ abstract class IterableToContainInOrderOnlyEntriesExpectationsSpec( } } } + + context("report options") { + context("iterable ${oneToFour().toList()}") { + it("shows only failing with report option `showOnlyFailing`") { + expect { + expect(oneToFour()).toContainEntriesFun( + { toEqual(1.0) }, + { toEqual(2.0) }, + { toEqual(3.0) }, + { toEqual(4.0) }, + { toEqual(4.0) }, + { toEqual(5.0) }, + report = { showOnlyFailing() }) + }.toThrow { + message { + notToContainElement(0, 1.0) + notToContainElement(1, 2.0) + notToContainElement(2, 3.0) + notToContainElement(3, 4.0) + notToContainElement(4, 4.0) + elementNonExisting(5, "$toEqualDescr: 5.0", withBulletPoint = false) + } + } + } + it("shows only failing with report option `showOnlyFailingIfMoreExpectedElementsThan(3)` because there are 5") { + expect { + expect(oneToFour()).toContainEntriesFun( + { toEqual(1.0) }, + { toEqual(2.0) }, + { toEqual(3.0) }, + { toEqual(4.0) }, + { toEqual(4.0) }, + { toEqual(5.0) }, + report = { showOnlyFailingIfMoreExpectedElementsThan(3) }) + }.toThrow { + message { + notToContainElement(0, 1.0) + notToContainElement(1, 2.0) + notToContainElement(2, 3.0) + notToContainElement(3, 4.0) + notToContainElement(4, 4.0) + elementNonExisting(5, "$toEqualDescr: 5.0", withBulletPoint = false) + } + } + } + + } + + context("iterable $oneToEleven") { + it("shows only failing per default as there are more than 10 expected elements") { + expect { + expect(oneToEleven).toContainEntriesFun( + { toEqual(1.0) }, + { toEqual(2.0) }, + { toEqual(3.0) }, + { toEqual(4.0) }, + { toEqual(-1.0) }, + { toEqual(6.0) }, + { toEqual(7.0) }, + { toEqual(-2.0) }, + { toEqual(9.0) }, + { toEqual(10.0) }, + { toEqual(11.0) } + ) + }.toThrow { + message { + notToContainElement(0, 1.0) + notToContainElement(1, 2.0) + notToContainElement(2, 3.0) + notToContainElement(3, 4.0) + elementFailing(4, 5.0, "$toEqualDescr: -1.0", withBulletPoint = false) + notToContainElement(5, 6.0) + notToContainElement(6, 7.0) + elementFailing(7, 8.0, "$toEqualDescr: -2.0", withBulletPoint = false) + notToContainElement(8, 9.0) + notToContainElement(9, 10.0) + notToContainElement(10, 11.0) + } + } + } + it("shows all with report option `showAlwaysSummary`") { + expect { + expect(oneToEleven).toContainEntriesFun( + { toEqual(1.0) }, + { toEqual(2.0) }, + { toEqual(3.0) }, + { toEqual(4.0) }, + { toEqual(-1.0) }, + { toEqual(6.0) }, + { toEqual(7.0) }, + { toEqual(-2.0) }, + { toEqual(9.0) }, + { toEqual(10.0) }, + { toEqual(11.0) }, + report = { showAlwaysSummary() } + ) + }.toThrow { + message { + elementSuccess(0, 1.0, "$toEqualDescr: 1.0") + elementSuccess(1, 2.0, "$toEqualDescr: 2.0") + elementSuccess(2, 3.0, "$toEqualDescr: 3.0") + elementSuccess(3, 4.0, "$toEqualDescr: 4.0") + elementFailing(4, 5.0, "$toEqualDescr: -1.0", withBulletPoint = false) + elementSuccess(5, 6.0, "$toEqualDescr: 6.0") + elementSuccess(6, 7.0, "$toEqualDescr: 7.0") + elementFailing(7, 8.0, "$toEqualDescr: -2.0", withBulletPoint = false) + elementSuccess(8, 9.0, "$toEqualDescr: 9.0") + elementSuccess(9, 10.0, "$toEqualDescr: 10.0") + elementSuccess(10, 11.0, "$toEqualDescr: 11.0") + } + } + } + } + } } nullableCases(describePrefix) { + fun Expect>.toContainInOrderOnlyNullableEntriesFun( + t: (Expect.() -> Unit)?, + vararg tX: (Expect.() -> Unit)?, + report: InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions + ) = toContainInOrderOnlyNullableEntries(this, t, tX, report) + describeFun(toContainInOrderOnlyNullableEntries) { val null1null3 = { sequenceOf(null, 1.0, null, 3.0).constrainOnce().asIterable() } diff --git a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt index 428670b47a..70387edd17 100644 --- a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt +++ b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec.kt @@ -2,15 +2,25 @@ package ch.tutteli.atrium.specs.integration import ch.tutteli.atrium.api.fluent.en_GB.* import ch.tutteli.atrium.api.verbs.internal.expect +import ch.tutteli.atrium.core.polyfills.format import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.utils.Group import ch.tutteli.atrium.specs.* import ch.tutteli.atrium.translations.DescriptionCollectionExpectation +import ch.tutteli.atrium.translations.DescriptionIterableLikeExpectation import org.spekframework.spek2.style.specification.Suite -//TODO 0.18.0 include InOrderReportOptions abstract class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec( - toContainInOrderOnlyGroupedEntries: Fun3, Group<(Expect.() -> Unit)?>, Group<(Expect.() -> Unit)?>, Array.() -> Unit)?>>>, + toContainInOrderOnlyGroupedEntries: Fun5< + Iterable, + Group<(Expect.() -> Unit)?>, + Group<(Expect.() -> Unit)?>, + Array.() -> Unit)?>>, + InOrderOnlyReportingOptions.() -> Unit, + InAnyOrderOnlyReportingOptions.() -> Unit + >, groupFactory: (Array.() -> Unit)?>) -> Group<(Expect.() -> Unit)?>, describePrefix: String = "[Atrium] " ) : IterableToContainEntriesSpecBase({ @@ -22,23 +32,25 @@ abstract class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec( toContainInOrderOnlyGroupedEntries.forSubjectLess( context({ toEqual(2.5) }), context({ toEqual(4.1) }), - arrayOf() + arrayOf(), + emptyInOrderOnlyReportOptions, + emptyInAnyOrderOnlyReportOptions ) ) {}) //@formatter:off include(object : AssertionCreatorSpec>( describePrefix, listOf(1.2, 2.0, 3.0), assertionCreatorSpecTriple(toContainInOrderOnlyGroupedEntries.name + " [first empty]", "$toEqualDescr: 1.2", - { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { toEqual(2.0) }, arrayOf( Entry { toEqual(3.0) })) }, - { toContainInOrderOnlyGroupedEntries(this, Entry { }, Entry { toEqual(2.0) }, arrayOf( Entry { toEqual(3.0) })) } + { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { toEqual(2.0) }, arrayOf( Entry { toEqual(3.0) }), emptyInOrderOnlyReportOptions, emptyInAnyOrderOnlyReportOptions) }, + { toContainInOrderOnlyGroupedEntries(this, Entry { }, Entry { toEqual(2.0) }, arrayOf( Entry { toEqual(3.0) }), emptyInOrderOnlyReportOptions, emptyInAnyOrderOnlyReportOptions) } ), assertionCreatorSpecTriple(toContainInOrderOnlyGroupedEntries.name + " [second empty]", "$toEqualDescr: 2.0", - { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { toEqual(2.0) }, arrayOf( Entry { toEqual(3.0) })) }, - { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { }, arrayOf( Entry { toEqual(3.0) })) } + { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { toEqual(2.0) }, arrayOf( Entry { toEqual(3.0) }), emptyInOrderOnlyReportOptions, emptyInAnyOrderOnlyReportOptions) }, + { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { }, arrayOf( Entry { toEqual(3.0) }), emptyInOrderOnlyReportOptions, emptyInAnyOrderOnlyReportOptions) } ), assertionCreatorSpecTriple(toContainInOrderOnlyGroupedEntries.name + " [third empty]", "$toEqualDescr: 3.0", - { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { toEqual(2.0) }, arrayOf( Entry { })) }, - { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { toEqual(2.0) }, arrayOf( Entry { })) } + { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { toEqual(2.0) }, arrayOf( Entry { }), emptyInOrderOnlyReportOptions, emptyInAnyOrderOnlyReportOptions) }, + { toContainInOrderOnlyGroupedEntries(this, Entry { toEqual(1.2) }, Entry { toEqual(2.0) }, arrayOf( Entry { }), emptyInOrderOnlyReportOptions, emptyInAnyOrderOnlyReportOptions) } ) ) {}) //@formatter:on @@ -49,8 +61,10 @@ abstract class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec( fun Expect>.toContainInOrderOnlyGroupedEntriesFun( t1: Group<(Expect.() -> Unit)?>, t2: Group<(Expect.() -> Unit)?>, - vararg tX: Group<(Expect.() -> Unit)?> - ) = toContainInOrderOnlyGroupedEntries(this, t1, t2, tX) + vararg tX: Group<(Expect.() -> Unit)?>, + report: InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit = emptyInAnyOrderOnlyReportOptions + ) = toContainInOrderOnlyGroupedEntries(this, t1, t2, tX, report, reportInGroup) fun element(prefix: String, bulletPoint: String, indentRootBulletPoint: String, expected: Array) = expected.joinToString(".*$separator") { @@ -58,24 +72,35 @@ abstract class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec( "$prefix$indentRootBulletPoint$indentListBulletPoint$explanatoryBulletPoint$it" } - fun size(prefix: String, bulletPoint: String, actual: Int, expected: Int) = - "$prefix\\Q$bulletPoint\\E${featureArrow}${DescriptionCollectionExpectation.SIZE.getDefault()}: $actual[^:]+: $expected" + fun size(prefix: String, bulletPoint: String, actual: Int?, expected: Int) = + "$prefix\\Q$bulletPoint\\E${featureArrow}${DescriptionCollectionExpectation.SIZE.getDefault()}:${actual?.let { " $it" } ?: ""}[^:]+: $expected" fun sizeCheck(actual: Int, expected: Int) = size( - "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow", featureBulletPoint, actual, expected) + "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow", featureBulletPoint, actual, expected + ) val afterFail = "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow$indentFeatureBulletPoint" - fun failAfterFail(vararg expected: String) = - element(afterFail, failingBulletPoint, indentFailingBulletPoint, expected) + fun failAfterFail(vararg expected: String, withBulletPoint: Boolean = true) = + element(afterFail, if (withBulletPoint) failingBulletPoint else listBulletPoint, indentFailingBulletPoint, expected) fun successAfterFail(vararg expected: String) = element(afterFail, successfulBulletPoint, indentSuccessfulBulletPoint, expected) + + fun Expect.notToContainIndex(from: Int, to: Int) = + notToContain.regex("\\Q${DescriptionIterableLikeExpectation.INDEX.getDefault().format("$from..$to")}") + val additionalElementsFail = "$indentRootBulletPoint$indentFailingBulletPoint" fun additionalElementsWarning(msg: String, values: Array, act: (T) -> String) = "$additionalElementsFail\\Q$warningBulletPoint$msg\\E: $separator" + - values.joinToString(".*$separator") { "$additionalElementsFail$indentWarningBulletPoint$listBulletPoint${act(it)}" } + values.joinToString(".*$separator") { + "$additionalElementsFail$indentWarningBulletPoint$listBulletPoint${ + act( + it + ) + }" + } fun warning(msg: String, values: Array, act: (T) -> String) = "$afterFail\\Q$warningBulletPoint$msg\\E: $separator" + @@ -90,6 +115,8 @@ abstract class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec( val afterSuccess = "$indentRootBulletPoint$indentSuccessfulBulletPoint$indentFeatureArrow$indentFeatureBulletPoint" fun successAfterSuccess(vararg expected: String) = element(afterSuccess, successfulBulletPoint, indentSuccessfulBulletPoint, expected) + fun failAfterSuccess(vararg expected: String) = element(afterSuccess, failingBulletPoint, indentFailingBulletPoint, expected) + fun Expect.indexSuccess(index: Int, actual: Any, expected: String): Expect { return this.toContain.exactly(1).regex( @@ -114,36 +141,60 @@ abstract class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec( ) } - fun Expect.indexFail(index: Int, actual: Any, expected: String): Expect { + fun Expect.indexFail( + index: Int, + actual: Any, + expected: String, + withBulletPoint: Boolean = true + ): Expect { return this.toContain.exactly(1).regex( - "\\Q$failingBulletPoint$featureArrow${index(index)}: $actual\\E.*$separator" + + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${index(index)}: $actual\\E.*$separator" + "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow$featureBulletPoint$expected" ) } - fun Expect.indexNonExisting(index: Int, expected: String): Expect { + fun Expect.indexFail( + fromIndex: Int, + toIndex: Int, + actual: List, + sizeCheck: String?, + vararg expected: String, + withBulletPoint: Boolean = true + ): Expect { return this.toContain.exactly(1).regex( - "\\Q$failingBulletPoint$featureArrow${index(index)}: $sizeExceeded\\E.*$separator" + + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${ + index(fromIndex, toIndex) + }: $actual\\E.*$separator" + + (sizeCheck?.let { "$sizeCheck.*$separator" } ?: "") + + "$indentRootBulletPoint${if (withBulletPoint) indentFailingBulletPoint else indentListBulletPoint}$indentFeatureArrow$featureBulletPoint$toContainInAnyOrderOnly: $separator" + + expected.joinToString(".*$separator") + ) + } + + fun Expect.indexNonExisting(index: Int, expected: String, withBulletPoint: Boolean = true): Expect { + return this.toContain.exactly(1).regex( + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${IterableToContainSpecBase.index(index)}: $sizeExceeded\\E.*$separator" + "$afterFail$explanatoryBulletPoint$expected" ) } - sizeExceeded - fun Expect.indexFail( - fromIndex: Int, - toIndex: Int, - actual: List, + fun Expect.indexNonExisting( + fromIndex: Int, toIndex: Int, sizeCheck: String, - vararg expected: String + vararg expected: String, + withBulletPoint: Boolean = true ): Expect { return this.toContain.exactly(1).regex( - "\\Q$failingBulletPoint$featureArrow${index(fromIndex, toIndex)}: $actual\\E.*$separator" + - "$sizeCheck.*$separator" + - "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow$featureBulletPoint$toContainInAnyOrderOnly: $separator" + - expected.joinToString(".*$separator") + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${ + index(fromIndex, toIndex) + }: $sizeExceeded\\E.*$separator" + + "$afterFail$sizeCheck.*$separator" + + "$indentRootBulletPoint${if (withBulletPoint) indentFailingBulletPoint else indentListBulletPoint}$indentFeatureArrow$indentFeatureBulletPoint$explanatoryBulletPoint$toContainInAnyOrderOnly: $separator" + + expected.joinToString(".*$separator") { ".*$anElementWhichNeedsDescr:.*$separator.*$it" } ) } + describeFun(toContainInOrderOnlyGroupedEntries) { context("describe non-nullable cases") { @@ -321,7 +372,11 @@ abstract class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec( indexSuccess( 1, 3, listOf(2.0, 3.0, 4.0), sizeCheck(3, 3), - successAfterSuccess("$toEqualDescr: 4.0", "$toEqualDescr: 2.0", "$toEqualDescr: 3.0") + successAfterSuccess( + "$toEqualDescr: 4.0", + "$toEqualDescr: 2.0", + "$toEqualDescr: 3.0" + ) ) toContainRegex(additional(4 to 4.0)) } @@ -397,8 +452,349 @@ abstract class IterableToContainInOrderOnlyGroupedEntriesExpectationsSpec( } } } + + context("report options") { + context("iterable ${oneToFour().toList()}") { + it("shows only failing indices with report option `showOnlyFailing` but still default behaviour per group (i.e. only failing if more than 10") { + expect { + expect(oneToFour() as Iterable).toContainInOrderOnlyGroupedEntriesFun( + context({ toEqual(1.0) }), + context({ toEqual(2.0) }, { toEqual(4.0) }), + context( + { toEqual(1.0) }, + { toEqual(2.0) }, + { toEqual(3.0) }, + { toEqual(4.0) }, + { toEqual(5.0) }, + { toEqual(6.0) }, + { toEqual(7.0) }, + { toEqual(8.0) }, + { toEqual(9.0) }, + { toEqual(10.0) }, + { toEqual(11.0) } + ), + report = { showOnlyFailing() } + ) + }.toThrow { + message { + toContainSize(5, 14) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + notToContainIndex(0, 0) + indexFail( + 1, 2, listOf(2.0, 3.0), + null, + successAfterSuccess("$toEqualDescr: 2.0"), + failAfterSuccess("$toEqualDescr: 4.0"), + withBulletPoint = false + ) + indexFail( + 3, + 13, + listOf(4.0, 4.0), + sizeCheck(2, 11), + failAfterFail("$toEqualDescr: 1.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 2.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 3.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 5.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 6.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 7.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 8.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 9.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 10.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 11.0", withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(4.0) + } + } + } + + it("shows only failing indices with report option `showOnlyFailing` and only failing elements with reportInGroup option `showOnlyFailing` ") { + expect { + expect(oneToFour() as Iterable).toContainInOrderOnlyGroupedEntriesFun( + context({ toEqual(1.0) }, { toEqual(2.0) }, { toEqual(3.0) }), + context({ toEqual(4.0) }, { toEqual(4.0) }, { toEqual(5.0) }), + report = { showOnlyFailing() }, + reportInGroup = { showOnlyFailing() } + ) + }.toThrow { + message { + toContainSize(5, 6) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + notToContainIndex(1, 2) + indexFail( + 3, 5, listOf(4.0, 4.0), + sizeCheck(2, 3), + failAfterFail("$toEqualDescr: 5.0", withBulletPoint = false), + withBulletPoint = false + ) + notToContain("$anElementWhichEquals: 4.0") + } + } + } + + it("shows only failing indices with report option `showOnlyFailingIfMoreExpectedElementsThan(3)` because there are 5 but still all elements in group") { + expect { + expect(oneToFour() as Iterable).toContainInOrderOnlyGroupedEntriesFun( + context({ toEqual(1.0) }, { toEqual(2.0) }, { toEqual(3.0) }), + context({ toEqual(4.0) }, { toEqual(4.0) }, { toEqual(5.0) }), + report = { showOnlyFailingIfMoreExpectedElementsThan(3) } + ) + }.toThrow { + message { + toContainSize(5, 6) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + notToContainIndex(1, 2) + indexFail( + 3, 5, listOf(4.0, 4.0), + sizeCheck(2, 3), + successAfterSuccess("$toEqualDescr: 4.0", "$toEqualDescr: 4.0"), + failAfterFail("$toEqualDescr: 5.0"), + withBulletPoint = false + ) + } + } + } + } + + context("iterable $oneToEleven") { + it("shows only failing indices per default as there are more than 10 expected groups, yet still summary in group") { + expect { + expect(oneToEleven as Iterable).toContainInOrderOnlyGroupedEntriesFun( + context({ toEqual(1.0) }, { toEqual(1.0) }), + context({ toEqual(2.0) }), + context({ toEqual(3.0) }, { toEqual(-3.0) }), + context({ toEqual(1.0) }, { toEqual(4.0) }), + context({ toEqual(8.0) }), + context({ toEqual(10.0) }, { toEqual(9.0) }), + context({ toEqual(-1.0) }, { toEqual(-2.0) }, { toEqual(9.0) }), + context({ toEqual(7.0) }, { toEqual(8.0) }), + context({ toEqual(9.0) }, { toEqual(-8.0) }), + context({ toEqual(10.0) }, { toEqual(11.0) }), + context({ toEqual(12.0) }) + ) + }.toThrow { + + message { + toContainSize(11, 20) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + indexFail( + 0, 1, listOf(1.0, 2.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + successAfterFail("$toEqualDescr: 1.0"), + failAfterSuccess("$toEqualDescr: 1.0"), + withBulletPoint = false + ) + mismatchesAfterFail(2.0) + indexFail(2, 3.0, "$toEqualDescr: 2.0", withBulletPoint = false) + indexFail( + 3, 4, listOf(4.0, 5.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterSuccess("$toEqualDescr: 3.0"), + failAfterFail("$toEqualDescr: -3.0"), + withBulletPoint = false + ) + mismatchesAfterFail(4.0, 5.0) + indexFail( + 5, 6, listOf(6.0, 7.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterSuccess("$toEqualDescr: 1.0"), + failAfterFail("$toEqualDescr: 4.0"), + withBulletPoint = false + ) + mismatchesAfterFail(6.0, 7.0) + notToContainIndex(7, 7) + notToContainIndex(8, 9) + indexFail( + 10, 12, listOf(11.0), + sizeCheck(1, 3), + failAfterSuccess("$toEqualDescr: -1.0"), + failAfterFail("$toEqualDescr: -2.0"), + failAfterFail("$toEqualDescr: 9.0"), + withBulletPoint = false + ) + mismatchesAfterFail(11.0) + indexNonExisting( + 13, 14, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 7.0", "$toEqualDescr: 8.0", + withBulletPoint = false + ) + indexNonExisting( + 15, 16, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 9.0", "$toEqualDescr: -8.0", + withBulletPoint = false + ) + indexNonExisting( + 17, 18, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 10.0", "$toEqualDescr: 11.0", + withBulletPoint = false + ) + indexNonExisting(19, "$toEqualDescr: 12.0", withBulletPoint = false) + } + } + } + it("shows all indices with report option `showAlwaysSummary`") { + expect { + expect(oneToEleven as Iterable).toContainInOrderOnlyGroupedEntriesFun( + context({ toEqual(1.0) }, { toEqual(1.0) }), + context({ toEqual(2.0) }), + context({ toEqual(3.0) }, { toEqual(-3.0) }), + context({ toEqual(1.0) }, { toEqual(4.0) }), + context({ toEqual(8.0) }), + context({ toEqual(10.0) }, { toEqual(9.0) }), + context({ toEqual(-1.0) }, { toEqual(-2.0) }, { toEqual(9.0) }), + context({ toEqual(7.0) }, { toEqual(8.0) }), + context({ toEqual(9.0) }, { toEqual(-8.0) }), + context({ toEqual(10.0) }, { toEqual(11.0) }), + context({ toEqual(12.0) }), + report = { showAlwaysSummary() } + ) + }.toThrow { + message { + toContainSize(11, 20) + indexFail( + 0, 1, listOf(1.0, 2.0), + sizeCheck(2, 2), + successAfterFail("$toEqualDescr: 1.0"), + failAfterSuccess("$toEqualDescr: 1.0") + ) + mismatchesAfterFail(2.0) + indexFail(2, 3.0, "$toEqualDescr: 2.0") + indexFail( + 3, 4, listOf(4.0, 5.0), + sizeCheck(2, 2), + failAfterSuccess("$toEqualDescr: 3.0"), + failAfterFail("$toEqualDescr: -3.0") + ) + mismatchesAfterFail(4.0, 5.0) + indexFail( + 5, 6, listOf(6.0, 7.0), + sizeCheck(2, 2), + failAfterSuccess("$toEqualDescr: 1.0"), + failAfterFail("$toEqualDescr: 4.0") + ) + mismatchesAfterFail(6.0, 7.0) + indexSuccess(7, 8.0, "$toEqualDescr: 8.0") + indexSuccess( + 8, 9, listOf(9.0, 10.0), + //TODO 0.20.0: https://github.com/robstoll/atrium/issues/724 should not be shown, is enough to show the indices + sizeCheck(2, 2), + successAfterSuccess("$toEqualDescr: 10.0"), + successAfterSuccess("$toEqualDescr: 9.0") + ) + indexFail( + 10, 12, listOf(11.0), + sizeCheck(1, 3), + failAfterFail("$toEqualDescr: -1.0"), + failAfterFail("$toEqualDescr: -2.0"), + failAfterFail("$toEqualDescr: 9.0") + ) + mismatchesAfterFail(11.0) + indexNonExisting( + 13, 14, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 7.0", "$toEqualDescr: 8.0" + ) + indexNonExisting( + 15, 16, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 9.0", "$toEqualDescr: -8.0" + ) + indexNonExisting( + 17, 18, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 10.0", "$toEqualDescr: 11.0" + ) + indexNonExisting(19, "$toEqualDescr: 12.0") + } + } + } + + it("shows only failing indices per default and only failing in group with reportInGroup `showOnlyFailing`") { + expect { + expect(oneToEleven as Iterable).toContainInOrderOnlyGroupedEntriesFun( + context({ toEqual(1.0) }, { toEqual(1.0) }), + context({ toEqual(2.0) }), + context({ toEqual(3.0) }, { toEqual(-3.0) }), + context({ toEqual(1.0) }, { toEqual(4.0) }), + context({ toEqual(8.0) }), + context({ toEqual(10.0) }, { toEqual(9.0) }), + context({ toEqual(-1.0) }, { toEqual(-2.0) }, { toEqual(9.0) }), + context({ toEqual(7.0) }, { toEqual(8.0) }), + context({ toEqual(9.0) }, { toEqual(-8.0) }), + context({ toEqual(10.0) }, { toEqual(11.0) }), + context({ toEqual(12.0) }), + reportInGroup = { showOnlyFailing() } + ) + }.toThrow { + message { + toContainSize(11, 20) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + indexFail( + 0, 1, listOf(1.0, 2.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterFail("$toEqualDescr: 1.0", withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(2.0) + indexFail(2, 3.0, "$toEqualDescr: 2.0", withBulletPoint = false) + indexFail( + 3, 4, listOf(4.0, 5.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterFail("$toEqualDescr: 3.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: -3.0", withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(4.0, 5.0) + indexFail( + 5, 6, listOf(6.0, 7.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterFail("$toEqualDescr: 1.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 4.0", withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(6.0, 7.0) + notToContainIndex(7, 7) + notToContainIndex(8, 9) + indexFail( + 10, 12, listOf(11.0), + sizeCheck(1, 3), + failAfterFail("$toEqualDescr: -1.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: -2.0", withBulletPoint = false), + failAfterFail("$toEqualDescr: 9.0", withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(11.0) + indexNonExisting( + 13, 14, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 7.0", "$toEqualDescr: 8.0", + withBulletPoint = false + ) + indexNonExisting( + 15, 16, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 9.0", "$toEqualDescr: -8.0", + withBulletPoint = false + ) + indexNonExisting( + 17, 18, + size("", explanatoryBulletPoint, null, 2), + "$toEqualDescr: 10.0", "$toEqualDescr: 11.0", + withBulletPoint = false + ) + indexNonExisting(19, "$toEqualDescr: 12.0", withBulletPoint = false) + } + } + } + } + } } } + nullableCases(describePrefix) { describeFun(toContainInOrderOnlyGroupedEntries) { val null1null3 = { sequenceOf(null, 1.0, null, 3.0).constrainOnce().asIterable() } diff --git a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt index ef5efb74ef..5111cd03eb 100644 --- a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt +++ b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyGroupedValuesExpectationsSpec.kt @@ -2,16 +2,33 @@ package ch.tutteli.atrium.specs.integration import ch.tutteli.atrium.api.fluent.en_GB.* import ch.tutteli.atrium.api.verbs.internal.expect +import ch.tutteli.atrium.core.polyfills.format import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.logic.utils.Group import ch.tutteli.atrium.specs.* import ch.tutteli.atrium.translations.DescriptionCollectionExpectation +import ch.tutteli.atrium.translations.DescriptionIterableLikeExpectation //TODO 0.18.0 include InOrderReportOptions abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( - toContainInOrderOnlyGroupedValues: Fun3, Group, Group, Array>>, + toContainInOrderOnlyGroupedValues: Fun5< + Iterable, Group, + Group, + Array>, + InOrderOnlyReportingOptions.() -> Unit, + InAnyOrderOnlyReportingOptions.() -> Unit + >, groupFactory: (Array) -> Group, - toContainInOrderOnlyGroupedNullableValues: Fun3, Group, Group, Array>>, + toContainInOrderOnlyGroupedNullableValues: Fun5< + Iterable, + Group, + Group, + Array>, + InOrderOnlyReportingOptions.() -> Unit, + InAnyOrderOnlyReportingOptions.() -> Unit + >, nullableGroupFactory: (Array) -> Group, describePrefix: String = "[Atrium] " ) : IterableToContainSpecBase({ @@ -21,38 +38,49 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( include(object : SubjectLessSpec>( describePrefix, - toContainInOrderOnlyGroupedValues.forSubjectLess(context(2.5), context(4.1), arrayOf()) + toContainInOrderOnlyGroupedValues.forSubjectLess( + context(2.5), + context(4.1), + arrayOf(), + emptyInOrderOnlyReportOptions, + emptyInAnyOrderOnlyReportOptions + ) ) {}) include(object : SubjectLessSpec>( describePrefix, - toContainInOrderOnlyGroupedNullableValues.forSubjectLess(nullableGroup(2.5), nullableGroup(4.1), arrayOf()) + toContainInOrderOnlyGroupedNullableValues.forSubjectLess( + nullableGroup(2.5), + nullableGroup(4.1), + arrayOf(), + emptyInOrderOnlyReportOptions, + emptyInAnyOrderOnlyReportOptions + ) ) {}) - fun Expect>.toContainInOrderOnlyGroupedNullableValuesFun( - t1: Group, - t2: Group, - vararg tX: Group - ) = toContainInOrderOnlyGroupedNullableValues(this, t1, t2, tX) - - val toBeWithFeature = "$indentFeatureArrow$featureBulletPoint$toEqualDescr" - val toBeAfterSuccess = "$indentRootBulletPoint$indentSuccessfulBulletPoint$toBeWithFeature" - val toBeAfterFailing = "$indentRootBulletPoint$indentFailingBulletPoint$toBeWithFeature" + val toEqualWithFeature = "$indentFeatureArrow$featureBulletPoint$toEqualDescr" + val toEqualAfterSuccess = "$indentRootBulletPoint$indentSuccessfulBulletPoint$toEqualWithFeature" + val toEqualAfterFailing = "$indentRootBulletPoint$indentFailingBulletPoint$toEqualWithFeature" fun element(prefix: String, bulletPoint: String, expected: Array) = expected.joinToString(".*$separator") { "$prefix\\Q$bulletPoint$anElementWhichEquals: $it\\E" } - fun size(prefix: String, bulletPoint: String, actual: Int, expected: Int) = - "$prefix\\Q$bulletPoint\\E${featureArrow}${DescriptionCollectionExpectation.SIZE.getDefault()}: $actual[^:]+: $expected" + fun size(prefix: String, bulletPoint: String, actual: Int?, expected: Int) = + "$prefix\\Q$bulletPoint\\E${featureArrow}${DescriptionCollectionExpectation.SIZE.getDefault()}:${actual?.let { " $it" } ?: ""}[^:]+: $expected" val afterFail = "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow$indentFeatureBulletPoint" val additionalElementsFail = "$indentRootBulletPoint$indentFailingBulletPoint" - fun failAfterFail(vararg expected: Double?) = element(afterFail, failingBulletPoint, expected) + fun failAfterFail(vararg expected: Double?, withBulletPoint: Boolean = true) = + element(afterFail, if (withBulletPoint) failingBulletPoint else listBulletPoint, expected) fun successAfterFail(vararg expected: Double?) = element(afterFail, successfulBulletPoint, expected) - fun sizeCheck(actual: Int, expected: Int) = size( - "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow", featureBulletPoint, actual, expected) + fun sizeCheck(actual: Int?, expected: Int, bulletPoint: String = featureBulletPoint) = size( + "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow", bulletPoint, actual, expected + ) + + fun Expect.notToContainIndex(from: Int, to: Int) = + notToContain.regex("\\Q${DescriptionIterableLikeExpectation.INDEX.getDefault().format("$from..$to")}") fun mismatchesWarning(msg: String, values: Array, act: (T) -> String) = "$afterFail\\Q$warningBulletPoint$msg\\E: $separator" + @@ -60,9 +88,12 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( fun additionalElementsWarning(msg: String, values: Array, act: (T) -> String) = "$additionalElementsFail\\Q$warningBulletPoint$msg\\E: $separator" + - values.joinToString(".*$separator") { "$additionalElementsFail$indentWarningBulletPoint$listBulletPoint${act(it)}" } + values.joinToString(".*$separator") { + "$additionalElementsFail$indentWarningBulletPoint$listBulletPoint${act(it)}" + } - fun mismatchesAfterFail(vararg mismatched: Double) = mismatchesWarning(mismatches, mismatched.toTypedArray()) { "$it" } + fun mismatchesAfterFail(vararg mismatched: Double) = + mismatchesWarning(mismatches, mismatched.toTypedArray()) { "$it" } fun additional(vararg entryWithValue: Pair) = additionalElementsWarning(additionalElements, entryWithValue) { "${elementWithIndex(it.first)}: ${it.second}" } @@ -70,12 +101,13 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( val afterSuccess = "$indentRootBulletPoint$indentSuccessfulBulletPoint$indentFeatureArrow$indentFeatureBulletPoint" fun successAfterSuccess(vararg expected: Double?) = element(afterSuccess, successfulBulletPoint, expected) + fun failAfterSuccess(vararg expected: Double?) = element(afterSuccess, failingBulletPoint, expected) fun Expect.indexSuccess(index: Int, expected: Double): Expect { return this.toContain.exactly(1).regex( "\\Q$successfulBulletPoint$featureArrow${index(index)}: $expected\\E.*$separator" + - "$toBeAfterSuccess: $expected" + "$toEqualAfterSuccess: $expected" ) } @@ -95,10 +127,15 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( ) } - fun Expect.indexFail(index: Int, actual: Any, expected: Double): Expect { + fun Expect.indexFail( + index: Int, + actual: Any, + expected: Double, + withBulletPoint: Boolean = true + ): Expect { return this.toContain.exactly(1).regex( - "\\Q$failingBulletPoint$featureArrow${index(index)}: $actual\\E.*$separator" + - "$toBeAfterFailing: $expected" + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${index(index)}: $actual\\E.*$separator" + + "$toEqualAfterFailing: $expected" ) } @@ -106,24 +143,43 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( fromIndex: Int, toIndex: Int, actual: List, - sizeCheck: String, - vararg expected: String + sizeCheck: String?, + vararg expected: String, + withBulletPoint: Boolean = true ): Expect { return this.toContain.exactly(1).regex( - "\\Q$failingBulletPoint$featureArrow${index(fromIndex, toIndex)}: $actual\\E.*$separator" + - "$sizeCheck.*$separator" + - "$indentRootBulletPoint$indentFailingBulletPoint$indentFeatureArrow$featureBulletPoint$toContainInAnyOrderOnly: $separator" + + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${ + index(fromIndex, toIndex) + }: $actual\\E.*$separator" + + (sizeCheck?.let { "$sizeCheck.*$separator" } ?: "") + + "$indentRootBulletPoint${if (withBulletPoint) indentFailingBulletPoint else indentListBulletPoint}$indentFeatureArrow$featureBulletPoint$toContainInAnyOrderOnly: $separator" + expected.joinToString(".*$separator") ) } - fun Expect.indexNonExisting(index: Int, expected: Double): Expect { + fun Expect.indexNonExisting(index: Int, expected: Double, withBulletPoint: Boolean = true): Expect { return this.toContain.exactly(1).regex( - "\\Q$failingBulletPoint$featureArrow${index(index)}: $sizeExceeded\\E.*$separator" + + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${index(index)}: $sizeExceeded\\E.*$separator" + "$afterFail$explanatoryBulletPoint$toEqualDescr: $expected" ) } + fun Expect.indexNonExisting( + fromIndex: Int, toIndex: Int, + sizeCheck: String, + vararg expected: Double, + withBulletPoint: Boolean = true + ): Expect { + return this.toContain.exactly(1).regex( + "\\Q${if (withBulletPoint) failingBulletPoint else ""}$featureArrow${ + index(fromIndex, toIndex) + }: $sizeExceeded\\E.*$separator" + + "$afterFail$sizeCheck.*$separator" + + "$indentRootBulletPoint${if (withBulletPoint) indentFailingBulletPoint else indentListBulletPoint}$indentFeatureArrow$indentFeatureBulletPoint$explanatoryBulletPoint$toContainInAnyOrderOnly: $separator" + + expected.joinToString(".*$separator") { ".*$anElementWhichEquals: $it" } + ) + } + nonNullableCases( describePrefix, @@ -131,8 +187,13 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( toContainInOrderOnlyGroupedNullableValues ) { toContainFunArr -> - fun Expect>.toContainFun(t1: Group, t2: Group, vararg tX: Group) = - toContainFunArr(t1, t2, tX) + fun Expect>.toContainFun( + t1: Group, + t2: Group, + vararg tX: Group, + report: InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit = emptyInAnyOrderOnlyReportOptions + ) = toContainFunArr(t1, t2, tX, report, reportInGroup) context("throws an $illegalArgumentException") { it("if an empty group is given as first parameter") { @@ -163,11 +224,11 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( expect(fluentEmpty()).toContainFun(context(1.0), context(1.2)) }.toThrow { message { + toContainSize(0, 2) toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") indexNonExisting(0, 1.0) indexNonExisting(1, 1.2) notToContain(additionalElements) - toContainSize(0, 2) } } } @@ -285,7 +346,333 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( failAfterFail(5.0), successAfterFail(4.0) ) - sizeCheck(5, 6) + sizeCheck(5, 7) // TODO change back to 5,6 + } + } + } + } + } + + context("report options") { + context("iterable ${oneToFour().toList()}") { + it("shows only failing indices with report option `showOnlyFailing` but still default behaviour per group (i.e. only failing if more than 10") { + expect { + expect(oneToFour()).toContainFun( + context(1.0), + context(2.0, 4.0), + context(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0), + report = { showOnlyFailing() }) + }.toThrow { + message { + toContainSize(5, 14) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + notToContainIndex(0, 0) + indexFail( + 1, 2, listOf(2.0, 3.0), + null, + successAfterSuccess(2.0), + failAfterSuccess(4.0), + withBulletPoint = false + ) + indexFail( + 3, + 13, + listOf(4.0, 4.0), + sizeCheck(2, 11), + failAfterFail(1.0, withBulletPoint = false), + failAfterFail(2.0, withBulletPoint = false), + failAfterFail(3.0, withBulletPoint = false), + failAfterFail(5.0, withBulletPoint = false), + failAfterFail(6.0, withBulletPoint = false), + failAfterFail(7.0, withBulletPoint = false), + failAfterFail(8.0, withBulletPoint = false), + failAfterFail(9.0, withBulletPoint = false), + failAfterFail(10.0, withBulletPoint = false), + failAfterFail(11.0, withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(4.0) + } + } + } + + it("shows only failing indices with report option `showOnlyFailing` and only failing elements with reportInGroup option `showOnlyFailing` ") { + expect { + expect(oneToFour()).toContainFun( + context(1.0, 2.0, 3.0), + context(4.0, 4.0, 5.0), + report = { showOnlyFailing() }, + reportInGroup = { showOnlyFailing() } + ) + }.toThrow { + message { + toContainSize(5, 6) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + notToContainIndex(1, 2) + indexFail( + 3, 5, listOf(4.0, 4.0), + sizeCheck(2, 3), + failAfterFail(5.0, withBulletPoint = false), + withBulletPoint = false + ) + notToContain("$anElementWhichEquals: 4.0") + } + } + } + + it("shows only failing indices with report option `showOnlyFailingIfMoreExpectedElementsThan(3)` because there are 5 but still all elements in group") { + expect { + expect(oneToFour()).toContainFun( + context(1.0, 2.0, 3.0), + context(4.0, 4.0, 5.0), + report = { showOnlyFailingIfMoreExpectedElementsThan(3) }) + }.toThrow { + message { + toContainSize(5, 6) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + notToContainIndex(1, 2) + indexFail( + 3, 5, listOf(4.0, 4.0), + sizeCheck(2, 3), + successAfterSuccess(4.0, 4.0), + failAfterFail(5.0), + withBulletPoint = false + ) + } + } + } + } + + context("iterable $oneToEleven") { + it("shows only failing indices per default as there are more than 10 expected groups, yet still summary in group") { + expect { + expect(oneToEleven).toContainFun( + context(1.0, 1.0), + context(2.0), + context(3.0, -3.0), + context(1.0, 4.0), + context(8.0), + context(10.0, 9.0), + context(-1.0, -2.0, 9.0), + context(7.0, 8.0), + context(9.0, -8.0), + context(10.0, 11.0), + context(12.0) + ) + }.toThrow { + + message { + toContainSize(11, 20) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + indexFail( + 0, 1, listOf(1.0, 2.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + successAfterFail(1.0), + failAfterSuccess(1.0), + withBulletPoint = false + ) + mismatchesAfterFail(2.0) + indexFail(2, 3.0, 2.0, withBulletPoint = false) + indexFail( + 3, 4, listOf(4.0, 5.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterSuccess(3.0), + failAfterFail(-3.0), + withBulletPoint = false + ) + mismatchesAfterFail(4.0, 5.0) + indexFail( + 5, 6, listOf(6.0, 7.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterSuccess(1.0), + failAfterFail(4.0), + withBulletPoint = false + ) + mismatchesAfterFail(6.0, 7.0) + notToContainIndex(7, 7) + notToContainIndex(8, 9) + indexFail( + 10, 12, listOf(11.0), + sizeCheck(1, 3), + failAfterSuccess(-1.0), + failAfterFail(-2.0), + failAfterFail(9.0), + withBulletPoint = false + ) + mismatchesAfterFail(11.0) + indexNonExisting( + 13, 14, + size("", explanatoryBulletPoint, null, 2), + 7.0, 8.0, + withBulletPoint = false + ) + indexNonExisting( + 15, 16, + size("", explanatoryBulletPoint, null, 2), + 9.0, -8.0, + withBulletPoint = false + ) + indexNonExisting( + 17, 18, + size("", explanatoryBulletPoint, null, 2), + 10.0, 11.0, + withBulletPoint = false + ) + indexNonExisting(19, 12.0, withBulletPoint = false) + } + } + } + it("shows all indices with report option `showAlwaysSummary`") { + expect { + expect(oneToEleven).toContainFun( + context(1.0, 1.0), + context(2.0), + context(3.0, -3.0), + context(1.0, 4.0), + context(8.0), + context(10.0, 9.0), + context(-1.0, -2.0, 9.0), + context(7.0, 8.0), + context(9.0, -8.0), + context(10.0, 11.0), + context(12.0), + report = { showAlwaysSummary() } + ) + }.toThrow { + message { + toContainSize(11, 20) + indexFail( + 0, 1, listOf(1.0, 2.0), + sizeCheck(2, 2), + successAfterFail(1.0), + failAfterSuccess(1.0) + ) + mismatchesAfterFail(2.0) + indexFail(2, 3.0, 2.0) + indexFail( + 3, 4, listOf(4.0, 5.0), + sizeCheck(2, 2), + failAfterSuccess(3.0), + failAfterFail(-3.0) + ) + mismatchesAfterFail(4.0, 5.0) + indexFail( + 5, 6, listOf(6.0, 7.0), + sizeCheck(2, 2), + failAfterSuccess(1.0), + failAfterFail(4.0) + ) + mismatchesAfterFail(6.0, 7.0) + indexSuccess(7, 8.0) + indexSuccess( + 8, 9, listOf(9.0, 10.0), + //TODO 0.20.0: https://github.com/robstoll/atrium/issues/724 should not be shown, is enough to show the indices + sizeCheck(2, 2), + successAfterSuccess(10.0), + successAfterSuccess(9.0) + ) + indexFail( + 10, 12, listOf(11.0), + sizeCheck(1, 3), + failAfterFail(-1.0), + failAfterFail(-2.0), + failAfterFail(9.0) + ) + mismatchesAfterFail(11.0) + indexNonExisting( + 13, 14, + size("", explanatoryBulletPoint, null, 2), + 7.0, 8.0 + ) + indexNonExisting( + 15, 16, + size("", explanatoryBulletPoint, null, 2), + 9.0, -8.0 + ) + indexNonExisting( + 17, 18, + size("", explanatoryBulletPoint, null, 2), + 10.0, 11.0 + ) + indexNonExisting(19, 12.0) + } + } + } + + it("shows only failing indices per default and only failing in group with reportInGroup `showOnlyFailing`") { + expect { + expect(oneToEleven).toContainFun( + context(1.0, 1.0), + context(2.0), + context(3.0, -3.0), + context(1.0, 4.0), + context(8.0), + context(10.0, 9.0), + context(-1.0, -2.0, 9.0), + context(7.0, 8.0), + context(9.0, -8.0), + context(10.0, 11.0), + context(12.0), + reportInGroup = { showOnlyFailing() } + ) + }.toThrow { + message { + toContainSize(11, 20) + toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnlyGrouped:") + indexFail( + 0, 1, listOf(1.0, 2.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterFail(1.0, withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(2.0) + indexFail(2, 3.0, 2.0, withBulletPoint = false) + indexFail( + 3, 4, listOf(4.0, 5.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterFail(3.0, withBulletPoint = false), + failAfterFail(-3.0, withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(4.0, 5.0) + indexFail( + 5, 6, listOf(6.0, 7.0), + null, //i.e no size check is shown as 2=2 and summary is only for inReportGroup + failAfterFail(1.0, withBulletPoint = false), + failAfterFail(4.0, withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(6.0, 7.0) + notToContainIndex(7, 7) + notToContainIndex(8, 9) + indexFail( + 10, 12, listOf(11.0), + sizeCheck(1, 3), + failAfterFail(-1.0, withBulletPoint = false), + failAfterFail(-2.0, withBulletPoint = false), + failAfterFail(9.0, withBulletPoint = false), + withBulletPoint = false + ) + mismatchesAfterFail(11.0) + indexNonExisting( + 13, 14, + size("", explanatoryBulletPoint, null, 2), + 7.0, 8.0, + withBulletPoint = false + ) + indexNonExisting( + 15, 16, + size("", explanatoryBulletPoint, null, 2), + 9.0, -8.0, + withBulletPoint = false + ) + indexNonExisting( + 17, 18, + size("", explanatoryBulletPoint, null, 2), + 10.0, 11.0, + withBulletPoint = false + ) + indexNonExisting(19, 12.0, withBulletPoint = false) } } } @@ -295,6 +682,14 @@ abstract class IterableToContainInOrderOnlyGroupedValuesExpectationsSpec( nullableCases(describePrefix) { + fun Expect>.toContainInOrderOnlyGroupedNullableValuesFun( + t1: Group, + t2: Group, + vararg tX: Group, + report: InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions, + reportInGroup: InAnyOrderOnlyReportingOptions.() -> Unit = emptyInAnyOrderOnlyReportOptions + ) = toContainInOrderOnlyGroupedNullableValues(this, t1, t2, tX, report, reportInGroup) + describeFun(toContainInOrderOnlyGroupedNullableValues) { val null1null3 = { sequenceOf(null, 1.0, null, 3.0).constrainOnce().asIterable() } diff --git a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyValuesExpectationsSpec.kt b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyValuesExpectationsSpec.kt index 07952a99c5..1939c799b3 100644 --- a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyValuesExpectationsSpec.kt +++ b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainInOrderOnlyValuesExpectationsSpec.kt @@ -22,13 +22,6 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( toContainInOrderOnlyNullableValues.forSubjectLess(2.5, arrayOf(), emptyInOrderOnlyReportOptions) ) {}) - fun Expect>.toContainInOrderOnlyNullableValuesFun( - t: Double?, - vararg tX: Double?, - report: InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions - ) = - toContainInOrderOnlyNullableValues(this, t, tX, report) - val toBeWithFeature = "$indentFeatureArrow$featureBulletPoint$toEqualDescr" val toBeAfterSuccess = "$indentRootBulletPoint$indentSuccessfulBulletPoint$toBeWithFeature" val toBeAfterFailing = "$indentRootBulletPoint$indentFailingBulletPoint$toBeWithFeature" @@ -42,10 +35,6 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( fun Expect.elementSuccess(index: Int, expected: Double) = elementSuccess(index, expected.toString()) - fun Expect.notToContainElement(index: Int, expected: Double): Expect { - return notToContain.regex("\\Q$featureArrow${elementWithIndex(index)}: ${expected}\\E.*$separator") - } - fun Expect.elementFailing( index: Int, actual: Any, @@ -58,7 +47,6 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( ) } - fun Expect.elementNonExisting( index: Int, expected: Double, @@ -81,8 +69,7 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( t: Double, vararg tX: Double, report: InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions - ) = - toContainValuesFunArr(t, tX.toTypedArray(), report) + ) = toContainValuesFunArr(t, tX.toTypedArray(), report) context("empty collection") { it("1.0 throws AssertionError") { @@ -209,12 +196,17 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( } } } + } + } + context("report options") { + context("iterable ${oneToFour().toList()}") { it("shows only failing with report option `showOnlyFailing`") { expect { expect(oneToFour()).toContainFun(1.0, 2.0, 3.0, 4.0, 4.0, 5.0, report = { showOnlyFailing() }) }.toThrow { message { + toContainSize(5, 6) notToContainElement(0, 1.0) notToContainElement(1, 2.0) notToContainElement(2, 3.0) @@ -225,7 +217,7 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( } } } - it("shows only failing with report option `showOnlyFailingIfMoreElementsThan(3)` because there are 5") { + it("shows only failing with report option `showOnlyFailingIfMoreExpectedElementsThan(5)` because there are 6") { expect { expect(oneToFour()).toContainFun( 1.0, @@ -234,9 +226,10 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( 4.0, 4.0, 5.0, - report = { showOnlyFailingIfMoreElementsThan(3) }) + report = { showOnlyFailingIfMoreExpectedElementsThan(5) }) }.toThrow { message { + toContainSize(5, 6) notToContainElement(0, 1.0) notToContainElement(1, 2.0) notToContainElement(2, 3.0) @@ -246,70 +239,62 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( } } } - } - } - val oneToEleven = (1..11).map { it.toDouble() }.asIterable() - context("iterable $oneToEleven") { - it("shows only failing per default as there are more than 10 elements") { - expect { - expect(oneToEleven).toContainFun( - 1.0, - 2.0, - 3.0, - 4.0, - -1.0, - 6.0, - 7.0, - -2.0, - 9.0, - 10.0, - 11.0 - ) - }.toThrow { - message { - notToContainElement(0, 1.0) - notToContainElement(1, 2.0) - notToContainElement(2, 3.0) - notToContainElement(3, 4.0) - elementFailing(4, 5.0, -1.0, withBulletPoint = false) - notToContainElement(5, 6.0) - notToContainElement(6, 7.0) - elementFailing(7, 8.0, -2.0, withBulletPoint = false) - notToContainElement(8, 9.0) - notToContainElement(9, 10.0) - notToContainElement(10, 11.0) + it("shows summary with report option `showOnlyFailingIfMoreExpectedElementsThan(2)` because there are 2") { + expect { + expect(oneToFour()).toContainFun( + 1.0, + 2.0, + report = { showOnlyFailingIfMoreExpectedElementsThan(2) } + ) + }.toThrow { + message { + toContainSize(5, 2) + elementSuccess(0, 1.0) + elementSuccess(1, 2.0) + toContain( + "$warningBulletPoint$additionalElements:", + "$listBulletPoint${elementWithIndex(2)}: 3.0", + "$listBulletPoint${elementWithIndex(3)}: 4.0", + "$listBulletPoint${elementWithIndex(4)}: 4.0" + ) + + } } } - } - it("shows all with report option `showsAlwaysSummary`") { - expect { - expect(oneToEleven).toContainFun( - 1.0, - 2.0, - 3.0, - 4.0, - -1.0, - 6.0, - 7.0, - -2.0, - 9.0, - 10.0, - 11.0, - report = { showAlwaysSummary() } - ) - }.toThrow { - message { - elementSuccess(0, 1.0) - elementSuccess(1, 2.0) - elementSuccess(2, 3.0) - elementSuccess(3, 4.0) - elementFailing(4, 5.0, -1.0, withBulletPoint = false) - elementSuccess(5, 6.0) - elementSuccess(6, 7.0) - elementFailing(7, 8.0, -2.0, withBulletPoint = false) - elementSuccess(8, 9.0) - elementSuccess(9, 10.0) - elementSuccess(10, 11.0) + + it("shows summary without report option if there are 10 expected elements because default for showOnlyFailingIfMoreExpectedElementsThan is 10") { + expect { + expect(oneToFour()).toContainFun(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) + }.toThrow { + message { + elementSuccess(0, 1.0) + elementSuccess(1, 2.0) + elementSuccess(2, 3.0) + elementSuccess(3, 4.0) + elementFailing(4, 4.0, 5.0) + elementNonExisting(5, 6.0) + elementNonExisting(6, 7.0) + elementNonExisting(7, 8.0) + elementNonExisting(8, 9.0) + elementNonExisting(9, 10.0) + toContainSize(5, 10) + } + } + } + it("shows only failing without report option if there are 11 expected elements because default for showOnlyFailingIfMoreExpectedElementsThan is 10") { + expect { + expect(oneToFour()).toContainFun(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0) + }.toThrow { + message { + toContainSize(5, 11) + elementFailing(4, 4.0, 5.0, withBulletPoint = false) + elementNonExisting(5, 6.0, withBulletPoint = false) + elementNonExisting(6, 7.0, withBulletPoint = false) + elementNonExisting(7, 8.0, withBulletPoint = false) + elementNonExisting(8, 9.0, withBulletPoint = false) + elementNonExisting(9, 10.0, withBulletPoint = false) + elementNonExisting(10, 11.0, withBulletPoint = false) + } } } } @@ -318,20 +303,26 @@ abstract class IterableToContainInOrderOnlyValuesExpectationsSpec( nullableCases(describePrefix) { + fun Expect>.toContainFun( + t: Double?, + vararg tX: Double?, + report: InOrderOnlyReportingOptions.() -> Unit = emptyInOrderOnlyReportOptions + ) = toContainInOrderOnlyNullableValues(this, t, tX, report) + describeFun(toContainInOrderOnlyNullableValues) { val null1null3 = { sequenceOf(null, 1.0, null, 3.0).constrainOnce().asIterable() } context("iterable ${null1null3().toList()}") { context("happy cases (do not throw)") { it("null, 1.0, null, 3.0") { - expect(null1null3()).toContainInOrderOnlyNullableValuesFun(null, 1.0, null, 3.0) + expect(null1null3()).toContainFun(null, 1.0, null, 3.0) } } context("failing cases") { it("null, 1.0, 3.0 -- null was missing") { expect { - expect(null1null3()).toContainInOrderOnlyNullableValuesFun(null, 1.0, 3.0) + expect(null1null3()).toContainFun(null, 1.0, 3.0) }.toThrow { message { toContain.exactly(1).value("$rootBulletPoint$toContainInOrderOnly:") diff --git a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainSpecBase.kt b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainSpecBase.kt index 78300bbd22..62851f7316 100644 --- a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainSpecBase.kt +++ b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/integration/IterableToContainSpecBase.kt @@ -1,10 +1,12 @@ package ch.tutteli.atrium.specs.integration import ch.tutteli.atrium.api.fluent.en_GB.exactly +import ch.tutteli.atrium.api.fluent.en_GB.notToContain import ch.tutteli.atrium.api.fluent.en_GB.regex import ch.tutteli.atrium.api.fluent.en_GB.toContain import ch.tutteli.atrium.core.polyfills.format import ch.tutteli.atrium.creating.Expect +import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InAnyOrderOnlyReportingOptions import ch.tutteli.atrium.logic.creating.iterablelike.contains.reporting.InOrderOnlyReportingOptions import ch.tutteli.atrium.specs.* import ch.tutteli.atrium.translations.DescriptionBasic @@ -19,6 +21,7 @@ abstract class IterableToContainSpecBase(spec: Root.() -> Unit) : Spek(spec) { companion object { val oneToFour = { sequenceOf(1.0, 2.0, 3.0, 4.0, 4.0).constrainOnce().asIterable() } + val oneToEleven = (1..11).map { it.toDouble() }.asIterable() val oneToSeven = { sequenceOf(1.0, 2.0, 4.0, 4.0, 5.0, 3.0, 5.0, 6.0, 4.0, 7.0).constrainOnce().asIterable() } val oneToSevenNullable = { sequenceOf(1.0, null, 4.0, 4.0, 5.0, null, 5.0, 6.0, 4.0, 7.0).constrainOnce().asIterable() } @@ -59,10 +62,14 @@ abstract class IterableToContainSpecBase(spec: Root.() -> Unit) : Spek(spec) { val separator = lineSeparator val emptyInOrderOnlyReportOptions : InOrderOnlyReportingOptions.() -> Unit = {} + val emptyInAnyOrderOnlyReportOptions : InAnyOrderOnlyReportingOptions.() -> Unit = {} fun Expect.toContainSize(actual: Int, expected: Int) = toContain.exactly(1).regex("${DescriptionCollectionExpectation.SIZE.getDefault()}: $actual[^:]+: $expected") + fun Expect.notToContainElement(index: Int, expected: Double): Expect = + notToContain.regex("\\Q${elementWithIndex(index)}: ${expected}\\E.*$separator") + fun Suite.describeFun(spec: SpecPair<*>, body: Suite.() -> Unit) = describeFun(spec.name, body) private fun Suite.describeFun(funName: String, body: Suite.() -> Unit) = context("fun `$funName`", body = body) diff --git a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/testUtils.kt b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/testUtils.kt index b6434debd4..a72d589739 100644 --- a/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/testUtils.kt +++ b/misc/specs/atrium-specs-common/src/main/kotlin/ch/tutteli/atrium/specs/testUtils.kt @@ -23,12 +23,14 @@ typealias Feature1 = SpecPair.(A1) -> Expect> typealias Feature2 = SpecPair.(A1, A2) -> Expect> typealias Feature3 = SpecPair.(A1, A2, A3) -> Expect> typealias Feature4 = SpecPair.(A1, A2, A3, A4) -> Expect> +typealias Feature5 = SpecPair.(A1, A2, A3, A4, A5) -> Expect> typealias Fun0 = Feature0 typealias Fun1 = Feature1 typealias Fun2 = Feature2 typealias Fun3 = Feature3 typealias Fun4 = Feature4 +typealias Fun5 = Feature5 inline operator fun Feature0.invoke(expect: Expect): Expect = this.second(expect) inline operator fun Feature1.invoke(expect: Expect, a1: A1): Expect = this.second(expect, a1) @@ -43,23 +45,32 @@ inline operator fun Feature4.invoke expect: Expect, a1: A1, a2: A2, a3: A3, a4: A4 ): Expect = this.second(expect, a1, a2, a3, a4) +inline operator fun Feature5.invoke( + expect: Expect, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5 +): Expect = this.second(expect, a1, a2, a3, a4, a5) + inline fun Feature0.forSubjectLess(): Pair.() -> Unit> = - this.name to expectLambda { this@forSubjectLess(this) } + this.name to expectLambda { this@forSubjectLess.invoke(this) } inline fun Feature1.forSubjectLess(a1: A1): Pair.() -> Unit> = - this.name to expectLambda { this@forSubjectLess(this, a1) } + this.name to expectLambda { this@forSubjectLess.invoke(this, a1) } inline fun Feature2.forSubjectLess(a1: A1, a2: A2): Pair.() -> Unit> = - this.name to expectLambda { this@forSubjectLess(this, a1, a2) } + this.name to expectLambda { this@forSubjectLess.invoke(this, a1, a2) } inline fun Feature3.forSubjectLess( a1: A1, a2: A2, a3: A3 -): Pair.() -> Unit> = this.name to expectLambda { this@forSubjectLess(this, a1, a2, a3) } +): Pair.() -> Unit> = this.name to expectLambda { this@forSubjectLess.invoke(this, a1, a2, a3) } inline fun Feature4.forSubjectLess( a1: A1, a2: A2, a3: A3, a4: A4 -): Pair.() -> Unit> = this.name to expectLambda { this@forSubjectLess(this, a1, a2, a3, a4) } +): Pair.() -> Unit> = this.name to expectLambda { this@forSubjectLess.invoke(this, a1, a2, a3, a4) } + +inline fun Feature5.forSubjectLess( + a1: A1, a2: A2, a3: A3, a4: A4, a5: A5 +): Pair.() -> Unit> = + this.name to expectLambda { this@forSubjectLess.invoke(this, a1, a2, a3, a4, a5) } inline fun Fun1.() -> Unit>.forAssertionCreatorSpec( @@ -256,6 +267,7 @@ inline fun fun1(f: KFunction2, A1, Expect>): Fun1 = inline fun fun2(f: KFunction3, A1, A2, Expect>): Fun2 = f.name to f inline fun fun3(f: KFunction4, A1, A2, A3, Expect>): Fun3 = f.name to f inline fun fun4(f: KFunction5, A1, A2, A3, A4, Expect>): Fun4 = f.name to f +inline fun fun5(f: KFunction6, A1, A2, A3, A4, A5, Expect>): Fun5 = f.name to f //@formatter:on fun notImplemented(): T = throw NotImplementedError() diff --git a/misc/tools/readme-examples/src/main/kotlin/readme/examples/MostExamplesSpec.kt b/misc/tools/readme-examples/src/main/kotlin/readme/examples/MostExamplesSpec.kt index f62e150464..40fd60b799 100644 --- a/misc/tools/readme-examples/src/main/kotlin/readme/examples/MostExamplesSpec.kt +++ b/misc/tools/readme-examples/src/main/kotlin/readme/examples/MostExamplesSpec.kt @@ -156,7 +156,7 @@ class MostExamplesSpec : Spek({ { toBeLessThan(3) }, { toBeLessThan(2) }, { toBeGreaterThan(1) }, - report = { showOnlyFailingIfMoreElementsThan(3) } + report = { showOnlyFailingIfMoreExpectedElementsThan(2) } ) } test("ex-collection-builder-2") { diff --git a/misc/verbs-internal/atrium-verbs-internal-common/src/main/kotlin/ch.tutteli.atrium.api.verbs.internal/atriumVerbs.kt b/misc/verbs-internal/atrium-verbs-internal-common/src/main/kotlin/ch.tutteli.atrium.api.verbs.internal/atriumVerbs.kt index 713f1b676a..4a53e29637 100644 --- a/misc/verbs-internal/atrium-verbs-internal-common/src/main/kotlin/ch.tutteli.atrium.api.verbs.internal/atriumVerbs.kt +++ b/misc/verbs-internal/atrium-verbs-internal-common/src/main/kotlin/ch.tutteli.atrium.api.verbs.internal/atriumVerbs.kt @@ -49,5 +49,5 @@ fun expect(subject: T, assertionCreator: Expect.() -> Unit): Expect = * Might be removed at any time without previous notice or the behaviour could change etc. */ enum class AssertionVerb(override val value: String) : StringBasedTranslatable { - EXPECT("expected subject"); + EXPECT("I expected subject"); } diff --git a/settings.gradle.kts b/settings.gradle.kts index 6d48a3c606..bcc064b0ca 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -85,7 +85,10 @@ fun Settings_gradle.includeBundleAndApisWithExtensionsAndSmokeTest(vararg apiNam fun Settings_gradle.includeKotlinJvmJs(subPath: String, module: String) { include(subPath, "$module-common") - include(subPath, "$module-js") + // js starts to be annoying on local development. Let's carry this only out on CI + if (System.getenv("CI") == "true") { + include(subPath, "$module-js") + } include(subPath, "$module-jvm") }