More consise reporting for contains.atLeast(1) (#934)

This commit is contained in:
Edward Hou
2021-06-10 22:53:05 -07:00
committed by GitHub
parent 9d97be5f3e
commit dac885bc6e
21 changed files with 148 additions and 83 deletions

View File

@@ -999,8 +999,7 @@ expect(listOf(1, 2, 2, 4)).toContain(2, 3)
expected that subject: [1, 2, 2, 4] (java.util.Arrays.ArrayList <1234789>)
contains, in any order:
⚬ an element which equals: 3 (kotlin.Int <1234789>)
⚬ ▶number of such entries: 0
is at least: 1
» but no such element was found
```
</ex-collection-short-1>
@@ -1039,13 +1038,11 @@ expected that subject: [1, 2, 2, 4] (java.util.Arrays.ArrayList <1234789>
contains, in any order:
⚬ an element which:
» is less than: 0 (kotlin.Int <1234789>)
⚬ ▶number of such entries: 0
is at least: 1
» but no such element was found
⚬ an element which:
» is greater than: 2 (kotlin.Int <1234789>)
» is less than: 4 (kotlin.Int <1234789>)
⚬ ▶number of such entries: 0
is at least: 1
» but no such element was found
```
</ex-collection-short-2>
@@ -1085,8 +1082,7 @@ expected that subject: [1, 2, 3, 4] (java.util.Arrays.ArrayList <1234789>
contains, in any order:
⚬ an element which:
» is less than: 0 (kotlin.Int <1234789>)
⚬ ▶number of such entries: 0
is at least: 1
» but no such element was found
```
</ex-collection-any>
<hr/>
@@ -1739,8 +1735,7 @@ expected that subject: "calling myNullableFun with ..." <1234789>
myNullableFun(-2147483648): null
» contains:
⚬ value: "min" <1234789>
⚬ ▶number of matches:
is at least: 1
» but no match was found
myNullableFun(2147483647): "2147483647" <1234789>
equals: "max" <1234789>
```
@@ -1888,8 +1883,7 @@ expected that subject: () -> kotlin.Nothing (readme.examples.MostExamples
is instance of type: String (kotlin.String) -- Class: java.lang.String
contains:
⚬ value: "no no no" <1234789>
⚬ ▶number of matches:
is at least: 1
» but no match was found
Properties of the unexpected IllegalArgumentException
» message: "no no no..." <1234789>
» stacktrace:

View File

@@ -2,11 +2,14 @@ package ch.tutteli.atrium.logic.creating.basic.contains.creators.impl
import ch.tutteli.atrium.assertions.AssertionGroup
import ch.tutteli.atrium.assertions.builders.assertionBuilder
import ch.tutteli.atrium.assertions.builders.withExplanatoryAssertion
import ch.tutteli.atrium.creating.AssertionContainer
import ch.tutteli.atrium.logic.creating.basic.contains.Contains
import ch.tutteli.atrium.logic.assertions.impl.LazyThreadUnsafeAssertionGroup
import ch.tutteli.atrium.logic.creating.basic.contains.checkers.AtLeastChecker
import ch.tutteli.atrium.reporting.Text
import ch.tutteli.atrium.reporting.translating.Translatable
import ch.tutteli.atrium.reporting.translating.TranslatableWithArgs
/**
* Represents the base class for [Contains.Creator]s, providing a template to fulfill its job.
@@ -31,6 +34,17 @@ abstract class ContainsAssertionCreator<T : Any, TT : Any, in SC, C : Contains.C
*/
protected abstract val descriptionContains: Translatable
/**
* Provides the translation for when an item is not found in a `contains.atLeast(1)` check.
*/
protected abstract val descriptionNotFound: Translatable
/**
* Provides the translation for `and N such elements were found` when an item is not found in a
* `contains.atLeast(1)` check.
*/
protected abstract val descriptionNumberOfElementsFound: Translatable
final override fun createAssertionGroup(
container: AssertionContainer<T>,
searchCriteria: List<SC>
@@ -83,9 +97,27 @@ abstract class ContainsAssertionCreator<T : Any, TT : Any, in SC, C : Contains.C
private fun featureFactory(count: Int, numberOfOccurrences: Translatable): AssertionGroup {
val assertions = checkers.map { it.createAssertion(count) }
return assertionBuilder.feature
val checker = checkers.firstOrNull()
return if (checkers.size == 1 && checker is AtLeastChecker && checker.times == 1) {
if (checker.createAssertion(count).holds()) {
assertionBuilder.explanatoryGroup
.withDefaultType
.withExplanatoryAssertion(
TranslatableWithArgs(descriptionNumberOfElementsFound, count.toString())
)
.build()
} else {
assertionBuilder.explanatoryGroup
.withDefaultType
.withExplanatoryAssertion(descriptionNotFound)
.failing
.build()
}
} else {
assertionBuilder.feature
.withDescriptionAndRepresentation(numberOfOccurrences, Text(count.toString()))
.withAssertions(assertions)
.build()
}
}
}

View File

@@ -3,8 +3,12 @@ package ch.tutteli.atrium.logic.creating.basic.contains.creators.impl
import ch.tutteli.atrium.assertions.Assertion
import ch.tutteli.atrium.assertions.AssertionGroup
import ch.tutteli.atrium.assertions.builders.assertionBuilder
import ch.tutteli.atrium.assertions.builders.invisibleGroup
import ch.tutteli.atrium.core.trueProvider
import ch.tutteli.atrium.creating.AssertionContainer
import ch.tutteli.atrium.logic.creating.basic.contains.Contains
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.NotSearchBehaviour
import ch.tutteli.atrium.logic.impl.createExplanatoryGroupForMismatches
import ch.tutteli.atrium.reporting.translating.Translatable
/**
@@ -36,12 +40,24 @@ abstract class ContainsObjectsAssertionCreator<T : Any, TT : Any, in SC, S : Con
searchCriterion: SC,
featureFactory: (Int, Translatable) -> AssertionGroup
): AssertionGroup {
val assertions = mutableListOf<Assertion>()
if (searchBehaviour is NotSearchBehaviour) {
val mismatches = mismatchesForNotSearchBehaviour(multiConsumableContainer, searchCriterion)
if (mismatches.isNotEmpty()) assertions.add(createExplanatoryGroupForMismatches(mismatches))
} else {
val count = search(multiConsumableContainer, searchCriterion)
val featureAssertion = featureFactory(count, descriptionNumberOfOccurrences)
assertions.add(featureAssertion)
}
return assertionBuilder.list
return if (assertions.isEmpty()) {
assertionBuilder.invisibleGroup
.withAssertion(
assertionBuilder.createDescriptive(groupDescription, searchCriterion, trueProvider)
).build()
} else assertionBuilder.list
.withDescriptionAndRepresentation(groupDescription, searchCriterion)
.withAssertion(featureAssertion)
.withAssertions(assertions)
.build()
}
@@ -67,4 +83,19 @@ abstract class ContainsObjectsAssertionCreator<T : Any, TT : Any, in SC, S : Con
* @return The number of times the [searchCriterion] matched in the subject of this expectation.
*/
protected abstract fun search(multiConsumableContainer: AssertionContainer<TT>, searchCriterion: SC): Int
/**
* Finds the mismatched indices and values when the [searchBehaviour] is `NotSearchBehaviour` in the subject of the
* given [multiConsumableContainer] and creates a list of assertions about the mismatched indexed values
*
* @param multiConsumableContainer The provider of the subject of this expectation in which we shall look for something
* not matching the given [searchCriterion].
* @param searchCriterion The search criterion used to determine whether something matches or not.
*
* @return A list of [Assertion]s that describe the indexed values that did not match the [searchCriterion]
*/
protected open fun mismatchesForNotSearchBehaviour(
multiConsumableContainer: AssertionContainer<TT>,
searchCriterion: SC
): List<Assertion> = emptyList()
}

View File

@@ -37,6 +37,8 @@ class CharSequenceContainsAssertionCreator<T : CharSequence, in SC : Any, S : Se
override val descriptionContains: Translatable = DescriptionCharSequenceAssertion.CONTAINS
override val descriptionNumberOfOccurrences: Translatable = DescriptionCharSequenceAssertion.NUMBER_OF_OCCURRENCES
override val descriptionNotFound: Translatable = DescriptionCharSequenceAssertion.NOT_FOUND
override val descriptionNumberOfElementsFound: Translatable = DescriptionCharSequenceAssertion.NUMBER_OF_MATCHES_FOUND
override fun makeSubjectMultipleTimesConsumable(container: AssertionContainer<T>): AssertionContainer<String> =
container.changeSubject.unreported { it.toString() }.toAssertionContainer()

View File

@@ -53,6 +53,8 @@ class InAnyOrderEntriesAssertionCreator<E : Any, T : IterableLike>(
IterableLikeContains.Creator<T, (Expect<E>.() -> Unit)?> {
override val descriptionContains: Translatable = DescriptionIterableAssertion.CONTAINS
override val descriptionNotFound: Translatable = DescriptionIterableAssertion.ELEMENT_NOT_FOUND
override val descriptionNumberOfElementsFound: Translatable = DescriptionIterableAssertion.NUMBER_OF_ELEMENTS_FOUND
override fun makeSubjectMultipleTimesConsumable(container: AssertionContainer<T>): AssertionContainer<List<E?>> =
turnSubjectToList(container, converter)

View File

@@ -43,6 +43,8 @@ class InAnyOrderValuesAssertionCreator<SC, T : IterableLike>(
override val descriptionContains: Translatable = DescriptionIterableAssertion.CONTAINS
override val descriptionNumberOfOccurrences: Translatable = DescriptionIterableAssertion.NUMBER_OF_OCCURRENCES
override val groupDescription: Translatable = DescriptionIterableAssertion.AN_ELEMENT_WHICH_EQUALS
override val descriptionNotFound: Translatable = DescriptionIterableAssertion.ELEMENT_NOT_FOUND
override val descriptionNumberOfElementsFound: Translatable = DescriptionIterableAssertion.NUMBER_OF_ELEMENTS_FOUND
override fun makeSubjectMultipleTimesConsumable(container: AssertionContainer<T>): AssertionContainer<List<SC>> =
turnSubjectToList(container, converter)
@@ -50,23 +52,16 @@ class InAnyOrderValuesAssertionCreator<SC, T : IterableLike>(
override fun search(multiConsumableContainer: AssertionContainer<List<SC>>, searchCriterion: SC): Int =
multiConsumableContainer.maybeSubject.fold({ -1 }) { subject -> subject.filter { it == searchCriterion }.size }
override fun searchAndCreateAssertion(
/**
* Override in any subclass that wants to report mismatched elements individually when the [searchBehaviour]
* is [NotSearchBehaviour]
*/
override fun mismatchesForNotSearchBehaviour(
multiConsumableContainer: AssertionContainer<List<SC>>,
searchCriterion: SC,
featureFactory: (Int, Translatable) -> AssertionGroup
): AssertionGroup {
return if (searchBehaviour is NotSearchBehaviour) {
searchCriterion: SC
): List<Assertion> {
val list = multiConsumableContainer.maybeSubject.getOrElse { emptyList() }
val mismatches = createIndexAssertions(list) { (_, element) -> element == searchCriterion }
val assertions = mutableListOf<Assertion>()
if (mismatches.isNotEmpty()) assertions.add(createExplanatoryGroupForMismatches(mismatches))
assertionBuilder.list
.withDescriptionAndRepresentation(groupDescription, searchCriterion)
.withAssertions(assertions)
.build()
} else {
super.searchAndCreateAssertion(multiConsumableContainer, searchCriterion, featureFactory)
}
return createIndexAssertions(list) { (_, element) -> element == searchCriterion }
}
/**

View File

@@ -142,7 +142,7 @@ abstract class CharSequenceToContainAtLeastExpectationsSpec(
it("${toContainAtLeastPair.first("'h'", "once")} throws AssertionError") {
expect {
fluentHelloWorld.toContainAtLeastFun(1, 'h')
}.toThrow<AssertionError> { messageToContain("$atLeast: 1", "$valueWithIndent: 'h'") }
}.toThrow<AssertionError> { messageToContain(noMatchFoundDescr, "$valueWithIndent: 'h'") }
}
it("${toContainAtLeastIgnoringCasePair.first("'h'", "once")} does not throw") {
fluentHelloWorld.toContainAtLeastIgnoringCaseFun(1, 'h')
@@ -151,7 +151,7 @@ abstract class CharSequenceToContainAtLeastExpectationsSpec(
it("${toContainAtLeastPair.first("'H', 'E'", "once")} throws AssertionError") {
expect {
fluentHelloWorld.toContainAtLeastFun(1, 'H', 'E')
}.toThrow<AssertionError> { messageToContain(atLeast, 'E') }
}.toThrow<AssertionError> { messageToContain(noMatchFoundDescr, 'E') }
}
it("${toContainAtLeastIgnoringCasePair.first("'H', 'E'", "once")} does not throw") {
fluentHelloWorld.toContainAtLeastIgnoringCaseFun(1, 'H', 'E')
@@ -162,7 +162,7 @@ abstract class CharSequenceToContainAtLeastExpectationsSpec(
fluentHelloWorld.toContainAtLeastFun(1, 'E', 'H')
}.toThrow<AssertionError> {
message {
toContain("$atLeast: 1", "$valueWithIndent: 'E'")
toContain(noMatchFoundDescr, "$valueWithIndent: 'E'")
notToContain("$valueWithIndent: 'H'")
}
}
@@ -181,7 +181,7 @@ abstract class CharSequenceToContainAtLeastExpectationsSpec(
fluentHelloWorld.toContainAtLeastFun(1, 'H', 'E', 'w', 'r')
}.toThrow<AssertionError> {
message {
toContain("$atLeast: 1", "$valueWithIndent: 'E'", "$valueWithIndent: 'w'")
toContain(noMatchFoundDescr, "$valueWithIndent: 'E'", "$valueWithIndent: 'w'")
notToContain("$valueWithIndent: 'H'", "$valueWithIndent: 'r'")
}
}

View File

@@ -42,8 +42,7 @@ abstract class CharSequenceToContainNotToContainExpectationsSpec(
messageToContain(
"$rootBulletPoint$toContainDescr: $separator" +
"$valueWithIndent: \"Hello\"",
"$numberOfOccurrences: 0",
"$atLeast: 1"
noMatchFoundDescr
)
}
}
@@ -103,9 +102,8 @@ abstract class CharSequenceToContainNotToContainExpectationsSpec(
fluent.toContainFun("hello", "robert")
}.toThrow<AssertionError> {
message {
this.toContain.exactly(2).values(
"$numberOfOccurrences: 0",
"$atLeast: 1"
this.toContain.exactly(2).value(
noMatchFoundDescr
)
this.toContain.exactly(1).values(
"$rootBulletPoint$toContainDescr: $separator",

View File

@@ -134,8 +134,7 @@ abstract class CharSequenceToContainRegexExpectationsSpec(
toContain(
"$rootBulletPoint$toContainDescr: $separator" +
"$regexWithIndent: ${roberto.toLowerCase()}",
"$numberOfOccurrences: 0",
"$atLeast: 1"
noMatchFoundDescr
)
}
}

View File

@@ -20,6 +20,7 @@ abstract class CharSequenceToContainSpecBase(spec: Root.() -> Unit) : Spek(spec)
val numberOfOccurrences = DescriptionCharSequenceAssertion.NUMBER_OF_OCCURRENCES.getDefault()
val value = DescriptionCharSequenceAssertion.VALUE.getDefault()
val stringMatchingRegex = DescriptionCharSequenceAssertion.STRING_MATCHING_REGEX.getDefault()
val noMatchFoundDescr = DescriptionCharSequenceAssertion.NOT_FOUND.getDefault()
val atLeast = DescriptionCharSequenceAssertion.AT_LEAST.getDefault()
val atMost = DescriptionCharSequenceAssertion.AT_MOST.getDefault()

View File

@@ -27,6 +27,7 @@ abstract class IterableToContainEntriesSpecBase(
val indexDescr = String.format(DescriptionIterableAssertion.INDEX.getDefault(), index)
return "$indexDescr: ${value.toString()}"
}
val noSuchEntryDescr = DescriptionIterableAssertion.ELEMENT_NOT_FOUND.getDefault()
fun index(index: Int) = String.format(DescriptionIterableAssertion.INDEX.getDefault(), index)

View File

@@ -62,8 +62,7 @@ abstract class IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec(
"$rootBulletPoint$toContainInAnyOrder: $separator",
"$anElementWhich: $separator",
"$toBeLessThanDescr: 1.0",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
}
}
@@ -75,8 +74,7 @@ abstract class IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec(
message {
toContain.exactly(2).values(
"$anElementWhich: $separator",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
toContain.exactly(1).values(
"$rootBulletPoint$toContainInAnyOrder: $separator",
@@ -100,8 +98,7 @@ abstract class IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec(
"$anElementWhich: $separator",
"$toBeGreaterThanDescr: 1.0",
"$toBeLessThanDescr: 2.0",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
}
}
@@ -161,8 +158,7 @@ abstract class IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec(
"$rootBulletPoint$toContainInAnyOrder: $separator",
"$anElementWhich: $separator",
"$toBeDescr: 2.0",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
}
}
@@ -177,8 +173,7 @@ abstract class IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec(
message {
toContain.exactly(2).values(
"$anElementWhich: $separator",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
toContain.exactly(1).values(
"$rootBulletPoint$toContainInAnyOrder: $separator",
@@ -200,8 +195,7 @@ abstract class IterableToContainInAnyOrderAtLeast1EntriesExpectationsSpec(
"$rootBulletPoint$toContainInAnyOrder: $separator",
"$anElementWhich: $separator",
"$isDescr: null",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
}
}

View File

@@ -41,8 +41,7 @@ abstract class IterableToContainInAnyOrderAtLeast1ValuesExpectationsSpec(
messageToContain(
"$rootBulletPoint$toContainInAnyOrder: $separator",
"$anElementWhichIs: 1.0",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchValueDescr
)
}
}
@@ -73,8 +72,7 @@ abstract class IterableToContainInAnyOrderAtLeast1ValuesExpectationsSpec(
messageToContain(
"$rootBulletPoint$toContainInAnyOrder: $separator",
"$anElementWhichIs: 9.5",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchValueDescr
)
}
}
@@ -84,8 +82,7 @@ abstract class IterableToContainInAnyOrderAtLeast1ValuesExpectationsSpec(
}.toThrow<AssertionError> {
message {
toContain.exactly(2).values(
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchValueDescr
)
toContain.exactly(1).values(
"$rootBulletPoint$toContainInAnyOrder: $separator",

View File

@@ -90,14 +90,14 @@ abstract class IterableToContainInAnyOrderAtLeastValuesExpectationsSpec(
it("${toContainAtLeastPair.first("1.1", "once")} throws AssertionError") {
expect {
expect(oneToSeven()).toContainAtLeastFun(1, 1.1)
}.toThrow<AssertionError> { messageToContain("$atLeastDescr: 1", "$anElementWhichIs: 1.1") }
}.toThrow<AssertionError> { messageToContain(noSuchValueDescr, "$anElementWhichIs: 1.1") }
}
it("${toContainAtLeastPair.first("1.0, 2.3", "once")} throws AssertionError mentioning only 2.3") {
expect {
expect(oneToSeven()).toContainAtLeastFun(1, 1.0, 2.3)
}.toThrow<AssertionError> {
message {
toContain("$atLeastDescr: 1", "$anElementWhichIs: 2.3")
toContain(noSuchValueDescr, "$anElementWhichIs: 2.3")
notToContain("$anElementWhichIs: 1.0")
}
}
@@ -107,7 +107,7 @@ abstract class IterableToContainInAnyOrderAtLeastValuesExpectationsSpec(
expect(oneToSeven()).toContainAtLeastFun(1, 2.3, 1.0)
}.toThrow<AssertionError> {
message {
toContain("$atLeastDescr: 1", "$anElementWhichIs: 2.3")
toContain(noSuchValueDescr, "$anElementWhichIs: 2.3")
notToContain("$anElementWhichIs: 1.0")
}
}
@@ -118,8 +118,7 @@ abstract class IterableToContainInAnyOrderAtLeastValuesExpectationsSpec(
}.toThrow<AssertionError> {
message {
toContain.exactly(2).values(
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchValueDescr
)
toContain.exactly(1).values(
"$rootBulletPoint$toContainInAnyOrder: $separator",

View File

@@ -47,6 +47,7 @@ abstract class IterableToContainSpecBase(spec: Root.() -> Unit) : Spek(spec) {
val hasDescriptionBasic = DescriptionBasic.HAS.getDefault()
val nextElement = DescriptionIterableAssertion.NEXT_ELEMENT.getDefault()
val notToContainDescr = DescriptionIterableAssertion.CONTAINS_NOT.getDefault()
val noSuchValueDescr = DescriptionIterableAssertion.ELEMENT_NOT_FOUND.getDefault()
val sizeDescr = DescriptionCollectionAssertion.SIZE.getDefault()
val atLeastDescr = DescriptionIterableAssertion.AT_LEAST.getDefault()

View File

@@ -46,8 +46,7 @@ abstract class IterableToHaveElementsAndAnyExpectationsSpec(
"$rootBulletPoint$toContainInAnyOrder: $separator",
"$anElementWhich: $separator",
"$toBeLessThanDescr: 1.0",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
}
@@ -65,8 +64,7 @@ abstract class IterableToHaveElementsAndAnyExpectationsSpec(
"$anElementWhich: $separator",
"$isGreaterThanDescr: 1.0",
"$toBeLessThanDescr: 2.0",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
}
}
@@ -105,8 +103,7 @@ abstract class IterableToHaveElementsAndAnyExpectationsSpec(
"$rootBulletPoint$toContainInAnyOrder: $separator",
"$anElementWhich: $separator",
"$toBeDescr: 2.0",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
}
}
@@ -124,8 +121,7 @@ abstract class IterableToHaveElementsAndAnyExpectationsSpec(
"$rootBulletPoint$toContainInAnyOrder: $separator",
"$anElementWhich: $separator",
"$isDescr: null",
"$numberOfOccurrences: 0",
"$atLeastDescr: 1"
noSuchEntryDescr
)
}
}

View File

@@ -35,7 +35,12 @@ buildscript {
"IterableContains.*Spec.*points to containsNot",
// we improved reporting for notToContain with 0.17.0
"IterableContainsNot(Entries|Values)AssertionsSpec.*`containsNot( nullable)?`.*throws AssertionError",
"IterableNoneAssertionsSpec.*`(none|containsNot)( nullable)?`.*throws AssertionError"
"IterableNoneAssertionsSpec.*`(none|containsNot)( nullable)?`.*throws AssertionError",
// changed reporting for contains.atLeast(1) with 0.17.0
or(
"(CharSequence|Iterable)Contains.*Spec",
"IterableAnyAssertionsSpec"
) + ".*`.*(any|contains).*`.*(throws.*AssertionError|failing cases)"
) + ".*)",
// we don't use asci bullet points in reporting since 0.17.0
// but have own tests to assure that changing bullet points work
@@ -98,7 +103,12 @@ buildscript {
"IterableContains.*Spec.*points to containsNot",
// we improved reporting for notToContain with 0.17.0
"IterableContainsNot(Entries|Values)AssertionsSpec.*`containsNot.*`.*throws AssertionError",
"IterableNoneAssertionsSpec.*`(none|containsNot).*`.*throws AssertionError"
"IterableNoneAssertionsSpec.*`(none|containsNot).*`.*throws AssertionError",
// changed reporting for contains.atLeast(1) with 0.17.0
or(
"(CharSequence|Iterable)Contains.*Spec",
"IterableAnyAssertionsSpec"
) + ".*`.*(any|contains).*`.*(throws.*AssertionError|failing cases)"
) + ".*)",
// we don't use asci bullet points in reporting since 0.17.0
// but have own tests to assure that changing bullet points work
@@ -162,7 +172,12 @@ buildscript {
"IterableExpectationsSpec.*`(containsNoDuplicates|contains noDuplicates)`",
// we improved reporting for notToContain with 0.17.0
"IterableContainsNot(Entries|Values)ExpectationsSpec.*`containsNot.*`.*throws AssertionError",
"IterableNoneExpectationsSpec.*`(none|containsNot).*`.*throws AssertionError"
"IterableNoneExpectationsSpec.*`(none|containsNot).*`.*throws AssertionError",
// changed reporting for contains.atLeast(1) with 0.17.0
or(
"(CharSequence|Iterable)Contains.*Spec",
"IterableAnyExpectationsSpec"
) + ".*`.*(any|contains).*`.*(throws.*AssertionError|failing cases)"
) + ".*)").let { commonPatterns ->
Pair(
// bc

View File

@@ -19,6 +19,8 @@ enum class DescriptionCharSequenceAssertion(override val value: String) : String
IGNORING_CASE("%s, Gross-/Kleinschreibung ignorierend"),
MATCHES("stimmt vollständig überein mit"),
MISMATCHES("stimmt nicht vollständig überein mit"),
NOT_FOUND("aber es wurde kein Treffer gefunden"),
NUMBER_OF_MATCHES_FOUND("und %s Treffer wurden gefunden"),
NUMBER_OF_OCCURRENCES("Anzahl Treffer"),
STARTS_WITH("beginnt mit"),
STARTS_NOT_WITH("beginnt nicht mit"),

View File

@@ -46,7 +46,9 @@ enum class DescriptionIterableAssertion(override val value: String) : StringBase
NEXT_ELEMENT("ein nächstes Element"),
NO_ELEMENTS("❗❗ kann nicht eruiert werden, leeres Iterable"),
DUPLICATE_ELEMENTS("doppelte Elemente"),
DUPLICATED_BY("(dupliziert von Index: %s")
DUPLICATED_BY("(dupliziert von Index: %s"),
ELEMENT_NOT_FOUND("aber es konnte kein solches Element gefunden werden"),
NUMBER_OF_ELEMENTS_FOUND("und % Elemente wurden gefunden")
}
internal const val COULD_NOT_EVALUATE_DEFINED_ASSERTIONS =

View File

@@ -19,6 +19,8 @@ enum class DescriptionCharSequenceAssertion(override val value: String) : String
IGNORING_CASE("%s, ignoring case"),
MATCHES("matches entirely"),
MISMATCHES("does not match entirely"),
NOT_FOUND("but no match was found"),
NUMBER_OF_MATCHES_FOUND("and %s matches were found"),
NUMBER_OF_OCCURRENCES("number of matches"),
STARTS_WITH("starts with"),
STARTS_NOT_WITH("does not start with"),

View File

@@ -46,7 +46,9 @@ enum class DescriptionIterableAssertion(override val value: String) : StringBase
NEXT_ELEMENT("a next element"),
NO_ELEMENTS("❗❗ cannot be determined, empty Iterable"),
DUPLICATE_ELEMENTS("duplicate elements"),
DUPLICATED_BY("duplicated by index: %s")
DUPLICATED_BY("duplicated by index: %s"),
ELEMENT_NOT_FOUND("but no such element was found"),
NUMBER_OF_ELEMENTS_FOUND("and %s such elements were found")
}
internal const val COULD_NOT_EVALUATE_DEFINED_ASSERTIONS = "Could not evaluate the defined assertion(s)"