Skip to content

Commit

Permalink
Fix expecting items after earlier items
Browse files Browse the repository at this point in the history
  • Loading branch information
DSteve595 committed Aug 12, 2024
1 parent 272e5bd commit 96e8f4b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 14 deletions.
30 changes: 18 additions & 12 deletions strikt-core/src/main/kotlin/strikt/assertions/Iterable.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package strikt.assertions

import strikt.api.Assertion
import strikt.api.Assertion.Builder
import strikt.internal.iterable.ElementWithOrderingConstraints
import strikt.internal.iterable.OrderingConstraint
Expand Down Expand Up @@ -654,20 +653,27 @@ fun <T: Iterable<E>, E> Builder<T>.containsWithOrderingConstraints(
allSections.flatMap { it.elementsWithConstraints.map { it.element } }
) {
var elementsConsumed = 0
fun consumeElementsAndAssertSection(section: SectionAssertionSpec<E>): Assertion.Builder<out Iterable<E>> {
fun consumeElementsAndAssertSection(section: SectionAssertionSpec<E>): Builder<out Iterable<E>> {
val sectionElementCount: Int
val assertion = when (val endDefinedBy = section.endDefinedBy) {
SectionAssertionSpec.EndDefinition.DeclaredElementCount -> {
// Define the section by the number of elements declared with `expect`
sectionElementCount = section.elementsWithConstraints.size
get("section %s") { drop(elementsConsumed).take(sectionElementCount) }
.assert("has %s elements", sectionElementCount) {
if (it.size == sectionElementCount) {
pass()
} else {
fail(it.size, "only %s elements left in list")
SectionAssertionSpec.EndDefinition.Undefined -> {
if (section === allSections.last()) {
// Define the section by taking everything
val remainingElements = subject.drop(elementsConsumed)
sectionElementCount = remainingElements.size
get("section %s") { remainingElements }
} else {
// Define the section by the number of elements declared with `expect`
sectionElementCount = section.elementsWithConstraints.size
get("section %s") { drop(elementsConsumed).take(sectionElementCount) }
.assert("has %s elements", sectionElementCount) {
if (it.size == sectionElementCount) {
pass()
} else {
fail(it.size, "only %s elements left in list")
}
}
}
}
}
is SectionAssertionSpec.EndDefinition.DeclaredElement -> {
// Define the section by taking everything until the end element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ internal class OrderingConstraintsAssertScopeImpl<E>: OrderingConstraintsAssertS

override fun expectNoFurtherElements() {
expectsNoFurtherElements = true
currentBuildingSection.expectsNoOtherElements = true
}

override fun startNewSection() = endSectionIfInProgress()
Expand Down Expand Up @@ -91,11 +92,11 @@ internal data class ElementWithOrderingConstraints<E>(val element: E, val constr

internal class SectionAssertionSpec<E> {
val elementsWithConstraints = mutableListOf<ElementWithOrderingConstraints<E>>()
var endDefinedBy: EndDefinition<E> = EndDefinition.DeclaredElementCount
var endDefinedBy: EndDefinition<E> = EndDefinition.Undefined
var expectsNoOtherElements = false

sealed class EndDefinition<out E> {
data object DeclaredElementCount : EndDefinition<Nothing>()
data object Undefined : EndDefinition<Nothing>()
data class DeclaredElement<E>(val element: E) : EndDefinition<E>()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,14 @@ class IterableOrderingConstraintsAssertions {
}
}

@Test
fun passesWithElementBeforeExpectedElement() {
expectThat(listOf("a", "b"))
.containsWithOrderingConstraints {
expect("b")
}
}

@Test
fun failsWithDuplicateElement() {
assertThrows<AssertionError> {
Expand Down

0 comments on commit 96e8f4b

Please sign in to comment.