mirror of
https://github.com/jlengrand/atrium.git
synced 2026-03-10 08:01:19 +00:00
Make notToContain less verbose and show mismatched indices (#931)
This commit is contained in:
@@ -42,12 +42,21 @@ abstract class ContainsAssertionCreator<T : Any, TT : Any, in SC, C : Contains.C
|
||||
}
|
||||
}
|
||||
val description = searchBehaviour.decorateDescription(descriptionContains)
|
||||
return assertionBuilder.list
|
||||
val inAnyOrderAssertion = assertionBuilder.list
|
||||
.withDescriptionAndEmptyRepresentation(description)
|
||||
.withAssertions(assertions)
|
||||
.build()
|
||||
return decorateInAnyOrderAssertion(inAnyOrderAssertion, multiConsumableContainer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Override in a subclass if you want to decorate the assertion.
|
||||
*/
|
||||
protected open fun decorateInAnyOrderAssertion(
|
||||
inAnyOrderAssertion: AssertionGroup,
|
||||
multiConsumableContainer: AssertionContainer<TT>
|
||||
): AssertionGroup = inAnyOrderAssertion
|
||||
|
||||
/**
|
||||
* Make the underlying subject multiple times consumable.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@ 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.AssertionGroupType
|
||||
import ch.tutteli.atrium.assertions.builders.assertionBuilder
|
||||
import ch.tutteli.atrium.creating.AssertionContainer
|
||||
import ch.tutteli.atrium.logic.creating.basic.contains.Contains
|
||||
@@ -32,7 +31,7 @@ abstract class ContainsObjectsAssertionCreator<T : Any, TT : Any, in SC, S : Con
|
||||
checkers: List<C>
|
||||
) : ContainsAssertionCreator<T, TT, SC, C>(searchBehaviour, checkers) {
|
||||
|
||||
final override fun searchAndCreateAssertion(
|
||||
override fun searchAndCreateAssertion(
|
||||
multiConsumableContainer: AssertionContainer<TT>,
|
||||
searchCriterion: SC,
|
||||
featureFactory: (Int, Translatable) -> AssertionGroup
|
||||
@@ -40,9 +39,9 @@ abstract class ContainsObjectsAssertionCreator<T : Any, TT : Any, in SC, S : Con
|
||||
val count = search(multiConsumableContainer, searchCriterion)
|
||||
val featureAssertion = featureFactory(count, descriptionNumberOfOccurrences)
|
||||
|
||||
return assertionBuilder.customType(getAssertionGroupType())
|
||||
return assertionBuilder.list
|
||||
.withDescriptionAndRepresentation(groupDescription, searchCriterion)
|
||||
.withAssertions(decorateAssertion(multiConsumableContainer, featureAssertion))
|
||||
.withAssertion(featureAssertion)
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -56,11 +55,6 @@ abstract class ContainsObjectsAssertionCreator<T : Any, TT : Any, in SC, S : Con
|
||||
*/
|
||||
protected abstract val groupDescription: Translatable
|
||||
|
||||
/**
|
||||
* Provides the [AssertionGroupType] for the resulting [AssertionGroup].
|
||||
*/
|
||||
protected abstract fun getAssertionGroupType(): AssertionGroupType
|
||||
|
||||
|
||||
/**
|
||||
* Searches for something matching the given [searchCriterion] in the subject of the given
|
||||
@@ -73,9 +67,4 @@ 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
|
||||
|
||||
/**
|
||||
* Either return the given [featureAssertion] as [List] or add further assertions.
|
||||
*/
|
||||
abstract fun decorateAssertion(container: AssertionContainer<TT>, featureAssertion: Assertion): List<Assertion>
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package ch.tutteli.atrium.logic.creating.charsequence.contains.creators.impl
|
||||
|
||||
import ch.tutteli.atrium.assertions.Assertion
|
||||
import ch.tutteli.atrium.assertions.AssertionGroup
|
||||
import ch.tutteli.atrium.assertions.AssertionGroupType
|
||||
import ch.tutteli.atrium.assertions.DefaultListAssertionGroupType
|
||||
import ch.tutteli.atrium.creating.AssertionContainer
|
||||
import ch.tutteli.atrium.logic.changeSubject
|
||||
import ch.tutteli.atrium.logic.creating.charsequence.contains.CharSequenceContains.*
|
||||
@@ -40,8 +38,6 @@ class CharSequenceContainsAssertionCreator<T : CharSequence, in SC : Any, S : Se
|
||||
override val descriptionContains: Translatable = DescriptionCharSequenceAssertion.CONTAINS
|
||||
override val descriptionNumberOfOccurrences: Translatable = DescriptionCharSequenceAssertion.NUMBER_OF_OCCURRENCES
|
||||
|
||||
override fun getAssertionGroupType(): AssertionGroupType = DefaultListAssertionGroupType
|
||||
|
||||
override fun makeSubjectMultipleTimesConsumable(container: AssertionContainer<T>): AssertionContainer<String> =
|
||||
container.changeSubject.unreported { it.toString() }.toAssertionContainer()
|
||||
|
||||
@@ -49,9 +45,4 @@ class CharSequenceContainsAssertionCreator<T : CharSequence, in SC : Any, S : Se
|
||||
// if the maybeSubject is None it means we are in an explanation like context in which
|
||||
// it should not matter what this number is. Moreover, we check in the atMostChecker that times is >= 0
|
||||
multiConsumableContainer.maybeSubject.fold({ -1 }) { searcher.search(it, searchCriterion) }
|
||||
|
||||
override fun decorateAssertion(
|
||||
container: AssertionContainer<String>,
|
||||
featureAssertion: Assertion
|
||||
): List<Assertion> = listOf(featureAssertion)
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@ package ch.tutteli.atrium.logic.creating.iterable.contains.creators.impl
|
||||
|
||||
import ch.tutteli.atrium.assertions.Assertion
|
||||
import ch.tutteli.atrium.assertions.AssertionGroup
|
||||
import ch.tutteli.atrium.assertions.DefaultListAssertionGroupType
|
||||
import ch.tutteli.atrium.assertions.DefaultSummaryAssertionGroupType
|
||||
import ch.tutteli.atrium.assertions.builders.assertionBuilder
|
||||
import ch.tutteli.atrium.assertions.builders.invisibleGroup
|
||||
import ch.tutteli.atrium.core.None
|
||||
import ch.tutteli.atrium.core.getOrElse
|
||||
import ch.tutteli.atrium.creating.AssertionContainer
|
||||
@@ -17,12 +16,15 @@ import ch.tutteli.atrium.logic.creating.iterable.contains.IterableLikeContains
|
||||
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderSearchBehaviour
|
||||
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.NotSearchBehaviour
|
||||
import ch.tutteli.atrium.logic.creating.typeutils.IterableLike
|
||||
import ch.tutteli.atrium.logic.hasNext
|
||||
import ch.tutteli.atrium.logic.impl.allCreatedAssertionsHold
|
||||
import ch.tutteli.atrium.logic.impl.createExplanatoryAssertionGroup
|
||||
import ch.tutteli.atrium.logic.impl.createHasElementAssertion
|
||||
import ch.tutteli.atrium.logic.impl.createExplanatoryGroupForMismatches
|
||||
import ch.tutteli.atrium.logic.impl.createIndexAssertions
|
||||
import ch.tutteli.atrium.reporting.translating.Translatable
|
||||
import ch.tutteli.atrium.translations.DescriptionIterableAssertion
|
||||
import ch.tutteli.atrium.translations.DescriptionIterableAssertion.AN_ELEMENT_WHICH
|
||||
import ch.tutteli.kbox.identity
|
||||
|
||||
/**
|
||||
* Represents a creator of a sophisticated `contains` assertions for [Iterable] where an expected entry can appear
|
||||
@@ -55,6 +57,26 @@ class InAnyOrderEntriesAssertionCreator<E : Any, T : IterableLike>(
|
||||
override fun makeSubjectMultipleTimesConsumable(container: AssertionContainer<T>): AssertionContainer<List<E?>> =
|
||||
turnSubjectToList(container, converter)
|
||||
|
||||
override fun decorateInAnyOrderAssertion(
|
||||
inAnyOrderAssertion: AssertionGroup,
|
||||
multiConsumableContainer: AssertionContainer<List<E?>>
|
||||
): AssertionGroup {
|
||||
val hasNext = multiConsumableContainer.hasNext(::identity)
|
||||
return if (searchBehaviour is NotSearchBehaviour && !hasNext.holds()) {
|
||||
assertionBuilder.invisibleGroup
|
||||
.withAssertions(
|
||||
hasNext,
|
||||
assertionBuilder.explanatoryGroup
|
||||
.withDefaultType
|
||||
.withAssertion(inAnyOrderAssertion)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
} else {
|
||||
inAnyOrderAssertion
|
||||
}
|
||||
}
|
||||
|
||||
override fun searchAndCreateAssertion(
|
||||
multiConsumableContainer: AssertionContainer<List<E?>>,
|
||||
searchCriterion: (Expect<E>.() -> Unit)?,
|
||||
@@ -68,15 +90,18 @@ class InAnyOrderEntriesAssertionCreator<E : Any, T : IterableLike>(
|
||||
)
|
||||
|
||||
val featureAssertion = featureFactory(count, DescriptionIterableAssertion.NUMBER_OF_OCCURRENCES)
|
||||
val assertions = mutableListOf<Assertion>(explanatoryGroup, featureAssertion)
|
||||
val groupType = if (searchBehaviour is NotSearchBehaviour) {
|
||||
assertions.add(createHasElementAssertion(list))
|
||||
addEmptyAssertionCreatorLambdaIfNecessary(multiConsumableContainer, assertions, searchCriterion, count)
|
||||
DefaultSummaryAssertionGroupType
|
||||
val assertions = mutableListOf<Assertion>(explanatoryGroup)
|
||||
if (searchBehaviour is NotSearchBehaviour) {
|
||||
createEmptyAssertionHintIfNecessary(multiConsumableContainer, searchCriterion, count)
|
||||
?.let { assertions.add(it) }
|
||||
val mismatches = createIndexAssertions(list) { (_, element) ->
|
||||
allCreatedAssertionsHold(multiConsumableContainer, element, searchCriterion)
|
||||
}
|
||||
if (mismatches.isNotEmpty()) assertions.add(createExplanatoryGroupForMismatches(mismatches))
|
||||
} else {
|
||||
DefaultListAssertionGroupType
|
||||
assertions.add(featureAssertion)
|
||||
}
|
||||
return assertionBuilder.customType(groupType)
|
||||
return assertionBuilder.list
|
||||
.withDescriptionAndEmptyRepresentation(AN_ELEMENT_WHICH)
|
||||
.withAssertions(assertions)
|
||||
.build()
|
||||
@@ -97,21 +122,21 @@ class InAnyOrderEntriesAssertionCreator<E : Any, T : IterableLike>(
|
||||
// maybe it would be enough to collect
|
||||
@Suppress("DEPRECATION" /* OptIn is only available since 1.3.70 which we cannot use if we want to support 1.2 */)
|
||||
@UseExperimental(ExperimentalComponentFactoryContainer::class)
|
||||
private fun addEmptyAssertionCreatorLambdaIfNecessary(
|
||||
private fun createEmptyAssertionHintIfNecessary(
|
||||
container: AssertionContainer<*>,
|
||||
assertions: MutableList<Assertion>,
|
||||
searchCriterion: (Expect<E>.() -> Unit)?,
|
||||
count: Int
|
||||
) {
|
||||
): Assertion? {
|
||||
if (searchCriterion != null && count == 0) {
|
||||
val collectingExpect = CollectingExpect<E>(None, container.components)
|
||||
// not using addAssertionsCreatedBy on purpose so that we don't append a failing assertion
|
||||
collectingExpect.searchCriterion()
|
||||
val collectedAssertions = collectingExpect.getAssertions()
|
||||
if (collectedAssertions.isEmpty()) {
|
||||
// no assertion created in the lambda, so lets add the failing assertion containing the hint
|
||||
assertions.add(container.collectBasedOnSubject(None, searchCriterion))
|
||||
// no assertion created in the lambda, so return the failing assertion containing the hint
|
||||
return container.collectBasedOnSubject(None, searchCriterion)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package ch.tutteli.atrium.logic.creating.iterable.contains.creators.impl
|
||||
|
||||
import ch.tutteli.atrium.assertions.*
|
||||
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.getOrElse
|
||||
import ch.tutteli.atrium.creating.AssertionContainer
|
||||
import ch.tutteli.atrium.logic.creating.basic.contains.creators.impl.ContainsObjectsAssertionCreator
|
||||
@@ -8,9 +11,12 @@ import ch.tutteli.atrium.logic.creating.iterable.contains.IterableLikeContains
|
||||
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.InAnyOrderSearchBehaviour
|
||||
import ch.tutteli.atrium.logic.creating.iterable.contains.searchbehaviours.NotSearchBehaviour
|
||||
import ch.tutteli.atrium.logic.creating.typeutils.IterableLike
|
||||
import ch.tutteli.atrium.logic.impl.createHasElementAssertion
|
||||
import ch.tutteli.atrium.logic.hasNext
|
||||
import ch.tutteli.atrium.logic.impl.createExplanatoryGroupForMismatches
|
||||
import ch.tutteli.atrium.logic.impl.createIndexAssertions
|
||||
import ch.tutteli.atrium.reporting.translating.Translatable
|
||||
import ch.tutteli.atrium.translations.DescriptionIterableAssertion
|
||||
import ch.tutteli.kbox.identity
|
||||
|
||||
/**
|
||||
* Represents a creator of a sophisticated `contains` assertions for [Iterable] where an expected entry can appear
|
||||
@@ -38,31 +44,49 @@ class InAnyOrderValuesAssertionCreator<SC, T : IterableLike>(
|
||||
override val descriptionNumberOfOccurrences: Translatable = DescriptionIterableAssertion.NUMBER_OF_OCCURRENCES
|
||||
override val groupDescription: Translatable = DescriptionIterableAssertion.AN_ELEMENT_WHICH_EQUALS
|
||||
|
||||
override fun getAssertionGroupType(): AssertionGroupType {
|
||||
return if (searchBehaviour is NotSearchBehaviour) {
|
||||
DefaultSummaryAssertionGroupType
|
||||
} else {
|
||||
DefaultListAssertionGroupType
|
||||
}
|
||||
}
|
||||
|
||||
override fun makeSubjectMultipleTimesConsumable(container: AssertionContainer<T>): AssertionContainer<List<SC>> =
|
||||
turnSubjectToList(container, converter)
|
||||
|
||||
override fun search(multiConsumableContainer: AssertionContainer<List<SC>>, searchCriterion: SC): Int =
|
||||
multiConsumableContainer.maybeSubject.fold({ -1 }) { subject -> subject.filter { it == searchCriterion }.size }
|
||||
|
||||
override fun decorateAssertion(
|
||||
container: AssertionContainer<List<SC>>,
|
||||
featureAssertion: Assertion
|
||||
): List<Assertion> {
|
||||
override fun searchAndCreateAssertion(
|
||||
multiConsumableContainer: AssertionContainer<List<SC>>,
|
||||
searchCriterion: SC,
|
||||
featureFactory: (Int, Translatable) -> AssertionGroup
|
||||
): AssertionGroup {
|
||||
return if (searchBehaviour is NotSearchBehaviour) {
|
||||
listOf(
|
||||
featureAssertion,
|
||||
createHasElementAssertion(container.maybeSubject.getOrElse { emptyList() })
|
||||
)
|
||||
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 {
|
||||
listOf(featureAssertion)
|
||||
super.searchAndCreateAssertion(multiConsumableContainer, searchCriterion, featureFactory)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override in a subclass if you want to decorate the assertion.
|
||||
*/
|
||||
override fun decorateInAnyOrderAssertion(
|
||||
inAnyOrderAssertion: AssertionGroup,
|
||||
multiConsumableContainer: AssertionContainer<List<SC>>
|
||||
): AssertionGroup {
|
||||
val hasNext = multiConsumableContainer.hasNext(::identity)
|
||||
return if (searchBehaviour is NotSearchBehaviour && !hasNext.holds()) {
|
||||
assertionBuilder.invisibleGroup.withAssertions(
|
||||
hasNext,
|
||||
assertionBuilder.explanatoryGroup
|
||||
.withDefaultType
|
||||
.withAssertion(inAnyOrderAssertion)
|
||||
.build()
|
||||
).build()
|
||||
} else {
|
||||
inAnyOrderAssertion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package ch.tutteli.atrium.logic.impl
|
||||
import ch.tutteli.atrium.assertions.Assertion
|
||||
import ch.tutteli.atrium.assertions.builders.*
|
||||
import ch.tutteli.atrium.core.Option
|
||||
import ch.tutteli.atrium.core.falseProvider
|
||||
import ch.tutteli.atrium.creating.AssertionContainer
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.logic.IterableLikeAssertions
|
||||
@@ -27,7 +26,6 @@ import ch.tutteli.atrium.reporting.translating.TranslatableWithArgs
|
||||
import ch.tutteli.atrium.translations.DescriptionBasic
|
||||
import ch.tutteli.atrium.translations.DescriptionIterableAssertion
|
||||
import ch.tutteli.atrium.translations.DescriptionIterableAssertion.NEXT_ELEMENT
|
||||
import ch.tutteli.kbox.WithIndex
|
||||
import ch.tutteli.kbox.mapWithIndex
|
||||
|
||||
class DefaultIterableLikeAssertions : IterableLikeAssertions {
|
||||
@@ -101,17 +99,7 @@ class DefaultIterableLikeAssertions : IterableLikeAssertions {
|
||||
val mismatches = createIndexAssertions(list) { (_, element) ->
|
||||
!allCreatedAssertionsHold(container, element, assertionCreatorOrNull)
|
||||
}
|
||||
assertions.add(
|
||||
assertionBuilder.explanatoryGroup
|
||||
.withWarningType
|
||||
.withAssertion(
|
||||
assertionBuilder.list
|
||||
.withDescriptionAndEmptyRepresentation(DescriptionIterableAssertion.WARNING_MISMATCHES)
|
||||
.withAssertions(mismatches)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
)
|
||||
assertions.add(createExplanatoryGroupForMismatches(mismatches))
|
||||
|
||||
createHasElementPlusFixedClaimGroup(
|
||||
list,
|
||||
@@ -134,22 +122,6 @@ class DefaultIterableLikeAssertions : IterableLikeAssertions {
|
||||
}
|
||||
}
|
||||
|
||||
private fun <E> createIndexAssertions(
|
||||
list: List<E>,
|
||||
predicate: (WithIndex<E>) -> Boolean
|
||||
) = list
|
||||
.asSequence()
|
||||
.mapWithIndex()
|
||||
.filter { predicate(it) }
|
||||
.map { (index, element) ->
|
||||
assertionBuilder.createDescriptive(
|
||||
TranslatableWithArgs(DescriptionIterableAssertion.INDEX, index),
|
||||
element,
|
||||
falseProvider
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
|
||||
private fun <E> createHasElementPlusFixedClaimGroup(
|
||||
list: List<E>,
|
||||
description: Translatable,
|
||||
|
||||
@@ -5,14 +5,18 @@ import ch.tutteli.atrium.assertions.AssertionGroup
|
||||
import ch.tutteli.atrium.assertions.builders.assertionBuilder
|
||||
import ch.tutteli.atrium.core.None
|
||||
import ch.tutteli.atrium.core.Some
|
||||
import ch.tutteli.atrium.core.falseProvider
|
||||
import ch.tutteli.atrium.core.trueProvider
|
||||
import ch.tutteli.atrium.creating.AssertionContainer
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.logic.collectBasedOnSubject
|
||||
import ch.tutteli.atrium.logic.creating.collectors.collectAssertions
|
||||
import ch.tutteli.atrium.reporting.Text
|
||||
import ch.tutteli.atrium.reporting.translating.TranslatableWithArgs
|
||||
import ch.tutteli.atrium.translations.DescriptionBasic
|
||||
import ch.tutteli.atrium.translations.DescriptionIterableAssertion
|
||||
import ch.tutteli.kbox.WithIndex
|
||||
import ch.tutteli.kbox.mapWithIndex
|
||||
|
||||
internal fun createHasElementAssertion(list: List<*>): Assertion {
|
||||
return assertionBuilder.feature
|
||||
@@ -53,3 +57,34 @@ internal fun <E : Any> createExplanatoryAssertionGroup(
|
||||
}
|
||||
.build()
|
||||
}
|
||||
|
||||
internal fun <E> createIndexAssertions(
|
||||
list: List<E>,
|
||||
predicate: (WithIndex<E>) -> Boolean
|
||||
) = list
|
||||
.asSequence()
|
||||
.mapWithIndex()
|
||||
.filter { predicate(it) }
|
||||
.map { (index, element) ->
|
||||
assertionBuilder.createDescriptive(
|
||||
TranslatableWithArgs(DescriptionIterableAssertion.INDEX, index),
|
||||
element,
|
||||
falseProvider
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
|
||||
internal fun createExplanatoryGroupForMismatches(
|
||||
mismatches: List<Assertion>
|
||||
) : AssertionGroup {
|
||||
return assertionBuilder.explanatoryGroup
|
||||
.withWarningType
|
||||
.withAssertion(
|
||||
assertionBuilder.list
|
||||
.withDescriptionAndEmptyRepresentation(DescriptionIterableAssertion.WARNING_MISMATCHES)
|
||||
.withAssertions(mismatches)
|
||||
.build()
|
||||
)
|
||||
.failing
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ abstract class IterableNotToContainEntriesExpectationsSpec(
|
||||
) = notToContainNullableEntries(this, a, aX)
|
||||
|
||||
val notToContainDescr = DescriptionIterableAssertion.CONTAINS_NOT.getDefault()
|
||||
val hasElement = DescriptionIterableAssertion.HAS_ELEMENT.getDefault()
|
||||
|
||||
nonNullableCases(
|
||||
describePrefix,
|
||||
@@ -67,13 +66,10 @@ abstract class IterableNotToContainEntriesExpectationsSpec(
|
||||
}.toThrow<AssertionError> {
|
||||
message {
|
||||
toContainRegex(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$toBeDescr: 4.0.*$separator" +
|
||||
"$featureSuccess$numberOfOccurrences: 0$separator" +
|
||||
"$isAfterSuccess: 0.*$separator" +
|
||||
"$featureFailing$hasElement: false$separator" +
|
||||
"$isAfterFailing: true"
|
||||
"$hasANextElement$separator" +
|
||||
"$indentRootBulletPoint\\Q$explanatoryBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$indentRootBulletPoint$indentListBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$indentListBulletPoint$afterExplanatory$toBeDescr: 4.0.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -104,10 +100,10 @@ abstract class IterableNotToContainEntriesExpectationsSpec(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$toBeLessThanDescr: 4.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 3$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(0, "1.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(1, "2.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(5, "3.0")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -121,16 +117,14 @@ abstract class IterableNotToContainEntriesExpectationsSpec(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$toBeDescr: 1.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 1$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true$separator" +
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(0, "1.0")}.*$separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$toBeDescr: 4.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 3$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(2, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(3, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(8, "4.0")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -167,10 +161,9 @@ abstract class IterableNotToContainEntriesExpectationsSpec(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$isDescr: null$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 2$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(1, "null")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(5, "null")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -185,10 +178,9 @@ abstract class IterableNotToContainEntriesExpectationsSpec(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$isDescr: null$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 2$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${index(1)}: null.*$separator" +
|
||||
"$afterMismatchedWarning${index(5)}: null.*"
|
||||
)
|
||||
this.notToContain("$notToContainDescr: 1.1")
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ 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.specs.*
|
||||
import ch.tutteli.atrium.translations.DescriptionIterableAssertion
|
||||
|
||||
abstract class IterableNotToContainValuesExpectationsSpec(
|
||||
notToContainValues: Fun2<Iterable<Double>, Double, Array<out Double>>,
|
||||
@@ -24,9 +23,6 @@ abstract class IterableNotToContainValuesExpectationsSpec(
|
||||
fun Expect<Iterable<Double?>>.notToContainNullableFun(a: Double?, vararg aX: Double?) =
|
||||
notToContainNullableValues(this, a, aX)
|
||||
|
||||
val notToContainDescr = DescriptionIterableAssertion.CONTAINS_NOT.getDefault()
|
||||
val hasElement = DescriptionIterableAssertion.HAS_ELEMENT.getDefault()
|
||||
|
||||
val anElementWhichIsWithIndent = "$indentRootBulletPoint$listBulletPoint$anElementWhichIs"
|
||||
|
||||
nonNullableCases(
|
||||
@@ -46,12 +42,9 @@ abstract class IterableNotToContainValuesExpectationsSpec(
|
||||
}.toThrow<AssertionError> {
|
||||
message {
|
||||
toContainRegex(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$anElementWhichIsWithIndent: 4.0.*$separator" +
|
||||
"$featureSuccess$numberOfOccurrences: 0$separator" +
|
||||
"$isAfterSuccess: 0.*$separator" +
|
||||
"$featureFailing$hasElement: false$separator" +
|
||||
"$isAfterFailing: true"
|
||||
"$hasANextElement$separator" +
|
||||
"$indentRootBulletPoint\\Q$explanatoryBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$indentListBulletPoint$anElementWhichIsWithIndent: 4.0.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -81,10 +74,10 @@ abstract class IterableNotToContainValuesExpectationsSpec(
|
||||
toContainRegex(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$anElementWhichIsWithIndent: 4.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 3$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(2, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(3, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(8, "4.0")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -97,15 +90,13 @@ abstract class IterableNotToContainValuesExpectationsSpec(
|
||||
toContainRegex(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$anElementWhichIsWithIndent: 1.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 1$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true$separator" +
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(0, "1.0")}.*$separator" +
|
||||
"$anElementWhichIsWithIndent: 4.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 3$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(2, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(3, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(8, "4.0")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -118,15 +109,13 @@ abstract class IterableNotToContainValuesExpectationsSpec(
|
||||
toContainRegex(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$anElementWhichIsWithIndent: 4.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 3$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true$separator" +
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(2, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(3, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(8, "4.0")}.*$separator" +
|
||||
"$anElementWhichIsWithIndent: 1.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 1$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(0, "1.0")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -152,10 +141,9 @@ abstract class IterableNotToContainValuesExpectationsSpec(
|
||||
toContainRegex(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$anElementWhichIsWithIndent: null$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 2$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(1, "null")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(5, "null")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -169,10 +157,9 @@ abstract class IterableNotToContainValuesExpectationsSpec(
|
||||
toContainRegex(
|
||||
"\\Q$rootBulletPoint\\E$notToContainDescr: $separator" +
|
||||
"$anElementWhichIsWithIndent: null$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 2$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(1, "null")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(5, "null")}.*"
|
||||
)
|
||||
notToContain("$notToContainDescr: 1.1")
|
||||
}
|
||||
|
||||
@@ -23,14 +23,18 @@ abstract class IterableToContainEntriesSpecBase(
|
||||
val anElementWhich = DescriptionIterableAssertion.AN_ELEMENT_WHICH.getDefault()
|
||||
val toBeLessThanDescr = DescriptionComparableAssertion.IS_LESS_THAN.getDefault()
|
||||
val toBeGreaterThanDescr = DescriptionComparableAssertion.IS_GREATER_THAN.getDefault()
|
||||
fun <T> mismatchedIndex(index: Int, value: T) : String {
|
||||
val indexDescr = String.format(DescriptionIterableAssertion.INDEX.getDefault(), index)
|
||||
return "$indexDescr: ${value.toString()}"
|
||||
}
|
||||
|
||||
fun index(index: Int) = String.format(DescriptionIterableAssertion.INDEX.getDefault(), index)
|
||||
|
||||
//@formatter:off
|
||||
val featureSuccess = "$indentRootBulletPoint$indentListBulletPoint\\Q$successfulBulletPoint$featureArrow\\E"
|
||||
val featureFailing = "$indentRootBulletPoint$indentListBulletPoint\\Q$failingBulletPoint$featureArrow\\E"
|
||||
val isAfterFailing = "$indentRootBulletPoint$indentListBulletPoint$indentFailingBulletPoint$indentFeatureArrow\\Q$featureBulletPoint\\E$isDescr"
|
||||
val isAfterSuccess = "$indentRootBulletPoint$indentListBulletPoint$indentSuccessfulBulletPoint$indentFeatureArrow\\Q$featureBulletPoint\\E$isDescr"
|
||||
val afterExplanatory = "$indentRootBulletPoint$indentListBulletPoint$indentSuccessfulBulletPoint\\Q$explanatoryBulletPoint\\E"
|
||||
val afterExplanatoryIndent = "$indentRootBulletPoint$indentListBulletPoint$indentSuccessfulBulletPoint"
|
||||
val afterMismatchedWarning = "$afterExplanatoryIndent$indentWarningBulletPoint\\Q$listBulletPoint\\E"
|
||||
val hasANextElement = "\\Q$rootBulletPoint\\E$hasDescriptionBasic: $nextElement"
|
||||
//@formatter:on
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ 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.specs.*
|
||||
import ch.tutteli.atrium.translations.DescriptionBasic
|
||||
import ch.tutteli.atrium.translations.DescriptionCollectionAssertion
|
||||
import ch.tutteli.atrium.translations.DescriptionIterableAssertion
|
||||
import org.spekframework.spek2.Spek
|
||||
@@ -43,6 +44,9 @@ abstract class IterableToContainSpecBase(spec: Root.() -> Unit) : Spek(spec) {
|
||||
val mismatchesAdditionalElements = DescriptionIterableAssertion.WARNING_MISMATCHES_ADDITIONAL_ELEMENTS.getDefault()
|
||||
val sizeExceeded = DescriptionIterableAssertion.SIZE_EXCEEDED.getDefault()
|
||||
val anElementWhichIs = DescriptionIterableAssertion.AN_ELEMENT_WHICH_EQUALS.getDefault()
|
||||
val hasDescriptionBasic = DescriptionBasic.HAS.getDefault()
|
||||
val nextElement = DescriptionIterableAssertion.NEXT_ELEMENT.getDefault()
|
||||
val notToContainDescr = DescriptionIterableAssertion.CONTAINS_NOT.getDefault()
|
||||
|
||||
val sizeDescr = DescriptionCollectionAssertion.SIZE.getDefault()
|
||||
val atLeastDescr = DescriptionIterableAssertion.AT_LEAST.getDefault()
|
||||
|
||||
@@ -29,7 +29,6 @@ abstract class IterableToHaveElementsAndNoneExpectationsSpec(
|
||||
) {})
|
||||
|
||||
val containsNotDescr = DescriptionIterableAssertion.CONTAINS_NOT.getDefault()
|
||||
val hasElement = DescriptionIterableAssertion.HAS_ELEMENT.getDefault()
|
||||
|
||||
nonNullableCases(
|
||||
describePrefix,
|
||||
@@ -42,7 +41,14 @@ abstract class IterableToHaveElementsAndNoneExpectationsSpec(
|
||||
expect {
|
||||
expect(fluentEmpty()).toHaveElementsAndNoneFun { toBeLessThan(1.0) }
|
||||
}.toThrow<AssertionError> {
|
||||
messageToContain("$featureArrow$hasElement: false")
|
||||
message {
|
||||
toContainRegex(
|
||||
"$hasANextElement$separator" +
|
||||
"$indentRootBulletPoint\\Q$explanatoryBulletPoint\\E$containsNotDescr: $separator" +
|
||||
"$indentRootBulletPoint$indentListBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$indentListBulletPoint$afterExplanatory$toBeLessThanDescr: 1.0.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,10 +72,10 @@ abstract class IterableToHaveElementsAndNoneExpectationsSpec(
|
||||
"\\Q$rootBulletPoint\\E$containsNotDescr: $separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$toBeDescr: 4.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 3$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(2, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(3, "4.0")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(8, "4.0")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -96,10 +102,9 @@ abstract class IterableToHaveElementsAndNoneExpectationsSpec(
|
||||
"\\Q$rootBulletPoint\\E$containsNotDescr: $separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$isDescr: null$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 2$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(1, "null")}.*$separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(5, "null")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -114,10 +119,8 @@ abstract class IterableToHaveElementsAndNoneExpectationsSpec(
|
||||
"\\Q$rootBulletPoint\\E$containsNotDescr: $separator" +
|
||||
"$indentRootBulletPoint\\Q$listBulletPoint\\E$anElementWhich: $separator" +
|
||||
"$afterExplanatory$toBeDescr: 1.0.*$separator" +
|
||||
"$featureFailing$numberOfOccurrences: 1$separator" +
|
||||
"$isAfterFailing: 0.*$separator" +
|
||||
"$featureSuccess$hasElement: true$separator" +
|
||||
"$isAfterSuccess: true"
|
||||
"$afterExplanatoryIndent\\Q$warningBulletPoint$mismatches:\\E $separator" +
|
||||
"$afterMismatchedWarning${mismatchedIndex(0, "1.0")}.*"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,10 @@ buildscript {
|
||||
"BigDecimalAssertionsSpec.*overload throws PleaseUseReplacementException",
|
||||
// we renamed containsNot to notToContain with 0.17.0
|
||||
"CharSequenceContains.*Spec.*points to containsNot",
|
||||
"IterableContains.*Spec.*points to containsNot"
|
||||
"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"
|
||||
) + ".*)",
|
||||
// we don't use asci bullet points in reporting since 0.17.0
|
||||
// but have own tests to assure that changing bullet points work
|
||||
@@ -92,7 +95,10 @@ buildscript {
|
||||
"BigDecimalAssertionsSpec.*overload throws PleaseUseReplacementException.*",
|
||||
// we renamed containsNot to notToContain with 0.17.0
|
||||
"CharSequenceContains.*Spec.*points to containsNot",
|
||||
"IterableContains.*Spec.*points to containsNot"
|
||||
"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"
|
||||
) + ".*)",
|
||||
// we don't use asci bullet points in reporting since 0.17.0
|
||||
// but have own tests to assure that changing bullet points work
|
||||
@@ -153,7 +159,10 @@ buildscript {
|
||||
"CharSequenceContains.*Spec.*points to containsNot",
|
||||
"IterableContains.*Spec.*points to containsNot",
|
||||
// we improved reporting for containsNoDuplicates
|
||||
"IterableExpectationsSpec.*`(containsNoDuplicates|contains noDuplicates)`"
|
||||
"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"
|
||||
) + ".*)").let { commonPatterns ->
|
||||
Pair(
|
||||
// bc
|
||||
|
||||
Reference in New Issue
Block a user