fail assertions if the subject is None

This commit is contained in:
Robert Stoll
2020-12-09 20:45:05 +01:00
parent 49debd68a9
commit f027ce13dd
10 changed files with 34 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
buildscript {
rootProject.version = '0.13.0-SNAPSHOT'
rootProject.version = '0.15.0-SNAPSHOT'
rootProject.group = 'ch.tutteli.atrium'
ext {
atriumKotlinDep = { name -> "ch.tutteli.atrium:atrium-$name:$rootProject.version" }

View File

@@ -1,7 +1,7 @@
package ch.tutteli.atrium.assertions.builders.common.impl
import ch.tutteli.atrium.assertions.builders.common.HoldsStep
import ch.tutteli.atrium.core.trueProvider
import ch.tutteli.atrium.core.falseProvider
import ch.tutteli.atrium.creating.SubjectProvider
internal abstract class HoldsStepImpl<R> : HoldsStep<R> {
@@ -11,7 +11,7 @@ internal abstract class HoldsStepImpl<R> : HoldsStep<R> {
override val holding: R = withTest { true }
override fun <T> withTest(subjectProvider: SubjectProvider<T>, test: (T) -> Boolean): R = withTest {
subjectProvider.maybeSubject.fold(trueProvider, test)
subjectProvider.maybeSubject.fold(falseProvider, test)
}
final override fun withTest(test: () -> Boolean): R = createNextStep(test)

View File

@@ -2,7 +2,7 @@ package ch.tutteli.atrium.assertions.builders.impl.descriptive
import ch.tutteli.atrium.assertions.DescriptiveAssertion
import ch.tutteli.atrium.assertions.builders.Descriptive
import ch.tutteli.atrium.core.trueProvider
import ch.tutteli.atrium.core.falseProvider
import ch.tutteli.atrium.creating.SubjectProvider
import ch.tutteli.atrium.reporting.Text
import ch.tutteli.atrium.reporting.translating.Translatable
@@ -25,7 +25,7 @@ internal object HoldsOptionImpl : Descriptive.HoldsOption {
subjectProvider: SubjectProvider<T>,
test: (T) -> Boolean
): Descriptive.DescriptionOption<Descriptive.FinalStep> = withTest {
subjectProvider.maybeSubject.fold(trueProvider, test)
subjectProvider.maybeSubject.fold(falseProvider, test)
}
}

View File

@@ -22,5 +22,5 @@ class DefaultAtMostChecker(
) : AtMostChecker, ContainsChecker(times, nameContainsNotFun, atMostCall) {
override fun createAssertion(foundNumberOfTimes: Int): Assertion =
createDescriptiveAssertion(AT_MOST) { foundNumberOfTimes <= times }
createDescriptiveAssertion(AT_MOST) { foundNumberOfTimes in 0..times }
}

View File

@@ -22,5 +22,5 @@ class DefaultAtMostChecker(
) : AtMostChecker, ContainsChecker(times, nameContainsNotFun, atMostCall) {
override fun createAssertion(foundNumberOfTimes: Int): Assertion =
createDescriptiveAssertion(DescriptionIterableAssertion.AT_MOST) { foundNumberOfTimes <= times }
createDescriptiveAssertion(DescriptionIterableAssertion.AT_MOST) { foundNumberOfTimes in 0..times }
}

View File

@@ -38,7 +38,10 @@ class DefaultSubjectChanger : SubjectChanger {
container.maybeSubject.fold(trueProvider, { expect.maybeSubject.isDefined() })
val descriptiveAssertion = assertionBuilder.descriptive
.withTest { shallTransform }
.withTest(expect) {
// only here if transformation could be carried out
true
}
.withDescriptionAndRepresentation(description, representation)
.build()

View File

@@ -30,7 +30,7 @@ class DefaultFun0Assertions : Fun0Assertions {
// because we want to show the planned downCast in the error message
return container.manualFeature(THROWN_EXCEPTION_WHEN_CALLED) {
catchAndAdjustThrowable(this)
.fold({ it }, { /* use null as subject in case no exception occurred*/ null })
.fold({ it }, { /* use null as subject in case no exception occurred */ null })
}.transform().let { previousExpect ->
FeatureExpect(
previousExpect,

View File

@@ -8,7 +8,6 @@ import ch.tutteli.atrium.assertions.DescriptiveAssertion
import ch.tutteli.atrium.assertions.InvisibleAssertionGroupType
import ch.tutteli.atrium.assertions.builders.assertionBuilder
import ch.tutteli.atrium.core.Option
import ch.tutteli.atrium.core.trueProvider
import ch.tutteli.atrium.creating.AssertionContainer
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.creating.ExpectInternal
@@ -35,9 +34,10 @@ fun <T> AssertionContainer<T>.createDescriptiveAssertion(
description: Translatable,
representation: Any?,
test: (T) -> Boolean
): Assertion = assertionBuilder.createDescriptive(description, representation) {
maybeSubject.fold(trueProvider) { test(it) }
}
): Assertion = assertionBuilder.descriptive
.withTest(this, test)
.withDescriptionAndRepresentation(description, representation)
.build()
/**
* Entry point to use the [SubjectChangerBuilder] based on this [AssertionContainer].

View File

@@ -40,7 +40,7 @@ fun <T, R> _changeSubject(
originalAssertionContainer.maybeSubject.fold(trueProvider, { expect.maybeSubject.isDefined() })
val descriptiveAssertion = assertionBuilder.descriptive
.withTest { shallTransform }
.withTest(expect) { true }
.withDescriptionAndRepresentation(description, representation)
.build()

View File

@@ -1,5 +1,9 @@
package ch.tutteli.atrium.specs
import ch.tutteli.atrium.api.fluent.en_GB.all
import ch.tutteli.atrium.api.fluent.en_GB.feature
import ch.tutteli.atrium.api.fluent.en_GB.toBe
import ch.tutteli.atrium.api.verbs.internal.expect
import ch.tutteli.atrium.assertions.Assertion
import ch.tutteli.atrium.assertions.AssertionGroup
import ch.tutteli.atrium.assertions.ExplanatoryAssertionGroupType
@@ -18,7 +22,7 @@ abstract class SubjectLessSpec<T>(
vararg assertionCreator: Pair<String, Expect<T>.() -> Unit>
) : Spek({
describe("${groupPrefix}assertion function can be used in an ${AssertionGroup::class.simpleName} with an ${ExplanatoryAssertionGroupType::class.simpleName} and reportBuilder without failure") {
describe("${groupPrefix}assertion function can be used in an ${AssertionGroup::class.simpleName} with an ${ExplanatoryAssertionGroupType::class.simpleName} and report without failure") {
assertionCreator.forEach { (name, createAssertion) ->
it("fun `$name`") {
val assertions = CollectingExpect<T>(None)
@@ -44,10 +48,21 @@ abstract class SubjectLessSpec<T>(
.withAssertions(assertions)
.build()
container.addAssertion(explanatoryGroup)
}
}
}
describe("${groupPrefix}assertion function does not hold if there is no subject") {
assertionCreator.forEach { (name, createAssertion) ->
it("fun `$name`") {
val assertions = CollectingExpect<T>(None)
.addAssertionsCreatedBy(createAssertion)
.getAssertions()
expect(assertions).all { feature(Assertion::holds).toBe(false) }
}
}
}
}) {
companion object {
/**