Apply renaming of with*FailureHint -> withHelpOn*Failure for issue #671 (#970)

This commit is contained in:
stevenlmcgraw
2021-08-30 14:30:38 -06:00
committed by GitHub
parent f074b5d925
commit 50a28dce03
8 changed files with 116 additions and 28 deletions

View File

@@ -14,9 +14,22 @@ import ch.tutteli.atrium.reporting.translating.Translatable
* Option to create a [DescriptiveAssertion] like assertion with an additional hint which might be shown if the * Option to create a [DescriptiveAssertion] like assertion with an additional hint which might be shown if the
* [Descriptive.DescriptionOption.test] fails. * [Descriptive.DescriptionOption.test] fails.
* *
* You can use [withFailureHintBasedOnSubject] or [withFailureHintBasedOnDefinedSubject] * You can use [withHelpOnFailureBasedOnSubject] or [withHelpOnFailureBasedOnDefinedSubject]
* in case your [DescriptiveAssertion] is based on the subject. * in case your [DescriptiveAssertion] is based on the subject.
*/ */
fun Descriptive.DescriptionOption<Descriptive.FinalStep>.withHelpOnFailure(
failureHintFactory: () -> Assertion
): DescriptiveAssertionWithFailureHint.ShowOption =
DescriptiveAssertionWithFailureHint.ShowOption.create(test, failureHintFactory)
/**
* Option to create a [DescriptiveAssertion] like assertion with an additional hint which might be shown if the
* [Descriptive.DescriptionOption.test] fails.
*
* You can use [withHelpOnFailureBasedOnSubject] or [withHelpOnFailureBasedOnDefinedSubject]
* in case your [DescriptiveAssertion] is based on the subject.
*/
@Deprecated("Use withHelpOnFailure; will be removed with 1.0.0")
fun Descriptive.DescriptionOption<Descriptive.FinalStep>.withFailureHint( fun Descriptive.DescriptionOption<Descriptive.FinalStep>.withFailureHint(
failureHintFactory: () -> Assertion failureHintFactory: () -> Assertion
): DescriptiveAssertionWithFailureHint.ShowOption = ): DescriptiveAssertionWithFailureHint.ShowOption =
@@ -27,20 +40,50 @@ fun Descriptive.DescriptionOption<Descriptive.FinalStep>.withFailureHint(
* which is based on the subject of the expectation and * which is based on the subject of the expectation and
* which is only shown the subject is defined. * which is only shown the subject is defined.
* *
* You can use [withFailureHintBasedOnSubject] in case you want to: * You can use [withHelpOnFailureBasedOnSubject] in case you want to:
* - provide a hint also if the subject is absent. * - provide a hint also if the subject is absent.
* - do not show the hint in certain cases even if the subject is defined * - do not show the hint in certain cases even if the subject is defined
* *
* Or use [withFailureHint] which does not expect a [subjectProvider] in case your [DescriptiveAssertion] is not based * Or use [withHelpOnFailure] which does not expect a [subjectProvider] in case your [DescriptiveAssertion] is not based
* on the subject of the expectation. * on the subject of the expectation.
*/ */
//TODO if we introduce Record or something else as replacement for Assertion then not but if we keep Assertion //TODO if we introduce Record or something else as replacement for Assertion then not but if we keep Assertion
// then move to logic and expect ProofContainer with 0.18.0 // then move to logic and expect ProofContainer with 0.18.0
fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withHelpOnFailureBasedOnDefinedSubject(
expect: Expect<T>,
failureHintFactory: (T) -> Assertion
): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> {
return withHelpOnFailureBasedOnSubject(expect) {
ifDefined(failureHintFactory)
.ifAbsent {
assertionBuilder.explanatoryGroup
.withWarningType
.withExplanatoryAssertion(Text(SHOULD_NOT_BE_SHOWN_TO_THE_USER_BUG))
.build()
}
}.showOnlyIfSubjectDefined(expect)
}
/**
* Option to create a [DescriptiveAssertion] like assertion with an additional hint
* which is based on the subject of the expectation and
* which is only shown the subject is defined.
*
* You can use [withHelpOnFailureBasedOnSubject] in case you want to:
* - provide a hint also if the subject is absent.
* - do not show the hint in certain cases even if the subject is defined
*
* Or use [withHelpOnFailure] which does not expect a [subjectProvider] in case your [DescriptiveAssertion] is not based
* on the subject of the expectation.
*/
//TODO if we introduce Record or something else as replacement for Assertion then not but if we keep Assertion
// then move to logic and expect ProofContainer with 0.18.0
@Deprecated("Use withHelpOnFailureBasedOnDefinedSubject; will be removed with 1.0.0")
fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withFailureHintBasedOnDefinedSubject( fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withFailureHintBasedOnDefinedSubject(
expect: Expect<T>, expect: Expect<T>,
failureHintFactory: (T) -> Assertion failureHintFactory: (T) -> Assertion
): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> { ): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> {
return withFailureHintBasedOnSubject(expect) { return withHelpOnFailureBasedOnSubject(expect) {
ifDefined(failureHintFactory) ifDefined(failureHintFactory)
.ifAbsent { .ifAbsent {
assertionBuilder.explanatoryGroup assertionBuilder.explanatoryGroup
@@ -56,13 +99,33 @@ fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withFailureHintBase
* (which is based on the subject of the expectation) * (which is based on the subject of the expectation)
* which might be shown if the [Descriptive.DescriptionOption.test] fails. * which might be shown if the [Descriptive.DescriptionOption.test] fails.
* *
* You can use [withFailureHint] which does not expect a [expect] in case your [DescriptiveAssertion] is not based * You can use [withHelpOnFailure] which does not expect a [expect] in case your [DescriptiveAssertion] is not based
* on the subject of the expectation. * on the subject of the expectation.
*/ */
fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withHelpOnFailureBasedOnSubject(
expect: Expect<T>,
failureHintSubStep: DescriptiveAssertionWithFailureHint.FailureHintSubjectDefinedOption<T>.() -> Pair<() -> Assertion, (T) -> Assertion>
): DescriptiveAssertionWithFailureHint.ShowOption = withHelpOnFailure {
SubjectBasedOption(
expect,
failureHintSubStep,
DescriptiveAssertionWithFailureHint.FailureHintSubjectDefinedOption.Companion::create
)
}
/**
* Option to create a [DescriptiveAssertion] like assertion with an additional hint
* (which is based on the subject of the expectation)
* which might be shown if the [Descriptive.DescriptionOption.test] fails.
*
* You can use [withHelpOnFailure] which does not expect a [expect] in case your [DescriptiveAssertion] is not based
* on the subject of the expectation.
*/
@Deprecated("Use withHelpOnFailureBasedOnSubject; will be removed with 1.0.0")
fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withFailureHintBasedOnSubject( fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withFailureHintBasedOnSubject(
expect: Expect<T>, expect: Expect<T>,
failureHintSubStep: DescriptiveAssertionWithFailureHint.FailureHintSubjectDefinedOption<T>.() -> Pair<() -> Assertion, (T) -> Assertion> failureHintSubStep: DescriptiveAssertionWithFailureHint.FailureHintSubjectDefinedOption<T>.() -> Pair<() -> Assertion, (T) -> Assertion>
): DescriptiveAssertionWithFailureHint.ShowOption = withFailureHint { ): DescriptiveAssertionWithFailureHint.ShowOption = withHelpOnFailure {
SubjectBasedOption( SubjectBasedOption(
expect, expect,
failureHintSubStep, failureHintSubStep,

View File

@@ -40,7 +40,7 @@ internal class CollectingExpectImpl<T>(
} else { } else {
allAssertions.add(assertionBuilder.descriptive allAssertions.add(assertionBuilder.descriptive
.failing .failing
.withFailureHint { .withHelpOnFailure {
assertionBuilder.explanatoryGroup assertionBuilder.explanatoryGroup
.withDefaultType .withDefaultType
.withAssertions( .withAssertions(

View File

@@ -20,17 +20,17 @@ class DescriptiveWithBasedOnSubjectSpec : Spek({
.withDescriptionAndRepresentation("what ever", 1) .withDescriptionAndRepresentation("what ever", 1)
.build() .build()
}, },
"withFailureHintBasedOnDefinedSubject" to addDescriptive { expect, builder -> "withHelpOnFailureBasedOnDefinedSubject" to addDescriptive { expect, builder ->
builder.failing builder.failing
.withFailureHintBasedOnDefinedSubject(expect) { .withHelpOnFailureBasedOnDefinedSubject(expect) {
assertionBuilder.explanatory.withExplanation("asdf").build() assertionBuilder.explanatory.withExplanation("asdf").build()
} }
.withDescriptionAndRepresentation("what ever", 1) .withDescriptionAndRepresentation("what ever", 1)
.build() .build()
}, },
"withFailureHintBasedOnSubject" to addDescriptive { expect, builder -> "withHelpOnFailureBasedOnSubject" to addDescriptive { expect, builder ->
builder.failing builder.failing
.withFailureHintBasedOnSubject(expect) { .withHelpOnFailureBasedOnSubject(expect) {
ifDefined { ifDefined {
assertionBuilder.explanatory.withExplanation("asdf").build() assertionBuilder.explanatory.withExplanation("asdf").build()
} ifAbsent { } ifAbsent {
@@ -43,7 +43,7 @@ class DescriptiveWithBasedOnSubjectSpec : Spek({
}, },
"showOnlyIf" to addDescriptive { expect, builder -> "showOnlyIf" to addDescriptive { expect, builder ->
builder.failing builder.failing
.withFailureHint { assertionBuilder.explanatory.withExplanation("any hint").build() } .withHelpOnFailure { assertionBuilder.explanatory.withExplanation("any hint").build() }
.showBasedOnSubjectOnlyIf(expect) { .showBasedOnSubjectOnlyIf(expect) {
ifDefined { ifDefined {
it < 3 it < 3
@@ -54,14 +54,14 @@ class DescriptiveWithBasedOnSubjectSpec : Spek({
}, },
"showOnlyIfSubjectDefined" to addDescriptive { expect, builder -> "showOnlyIfSubjectDefined" to addDescriptive { expect, builder ->
builder.failing builder.failing
.withFailureHint { assertionBuilder.explanatory.withExplanation("any hint").build() } .withHelpOnFailure { assertionBuilder.explanatory.withExplanation("any hint").build() }
.showOnlyIfSubjectDefined(expect) .showOnlyIfSubjectDefined(expect)
.withDescriptionAndRepresentation("what ever", 1) .withDescriptionAndRepresentation("what ever", 1)
.build() .build()
}, },
"showBasedOnDefinedSubjectOnlyIf" to addDescriptive { expect, builder -> "showBasedOnDefinedSubjectOnlyIf" to addDescriptive { expect, builder ->
builder.failing builder.failing
.withFailureHint { assertionBuilder.explanatory.withExplanation("any hint").build() } .withHelpOnFailure { assertionBuilder.explanatory.withExplanation("any hint").build() }
.showBasedOnDefinedSubjectOnlyIf(expect) { it < 3 } .showBasedOnDefinedSubjectOnlyIf(expect) { it < 3 }
.withDescriptionAndRepresentation("what ever", 1) .withDescriptionAndRepresentation("what ever", 1)
.build() .build()

View File

@@ -3,7 +3,7 @@ package ch.tutteli.atrium.logic.impl
import ch.tutteli.atrium.assertions.Assertion import ch.tutteli.atrium.assertions.Assertion
import ch.tutteli.atrium.assertions.ExplanatoryAssertion import ch.tutteli.atrium.assertions.ExplanatoryAssertion
import ch.tutteli.atrium.assertions.builders.assertionBuilder import ch.tutteli.atrium.assertions.builders.assertionBuilder
import ch.tutteli.atrium.assertions.builders.withFailureHintBasedOnDefinedSubject import ch.tutteli.atrium.assertions.builders.withHelpOnFailureBasedOnDefinedSubject
import ch.tutteli.atrium.core.polyfills.formatFloatingPointNumber import ch.tutteli.atrium.core.polyfills.formatFloatingPointNumber
import ch.tutteli.atrium.core.polyfills.fullName import ch.tutteli.atrium.core.polyfills.fullName
import ch.tutteli.atrium.creating.AssertionContainer import ch.tutteli.atrium.creating.AssertionContainer
@@ -74,7 +74,7 @@ internal fun <T : Comparable<T>> toBeWithErrorTolerance(
): Assertion = ): Assertion =
assertionBuilder.descriptive assertionBuilder.descriptive
.withTest(container.toExpect()) { absDiff(it) <= tolerance } .withTest(container.toExpect()) { absDiff(it) <= tolerance }
.withFailureHintBasedOnDefinedSubject(container.toExpect()) { subject -> .withHelpOnFailureBasedOnDefinedSubject(container.toExpect()) { subject ->
//TODO 0.18.0 that's not nice in case we use it in an Iterable contains assertion, for instance contains...entry { toBeWithErrorTolerance(x, 0.01) } //TODO 0.18.0 that's not nice in case we use it in an Iterable contains assertion, for instance contains...entry { toBeWithErrorTolerance(x, 0.01) }
//we do not want to see the failure nor the exact check in the 'an entry which...' part //we do not want to see the failure nor the exact check in the 'an entry which...' part
//same problematic applies to feature assertions within an identification lambda //same problematic applies to feature assertions within an identification lambda

View File

@@ -134,7 +134,7 @@ class DefaultIterableLikeAssertions : IterableLikeAssertions {
val (element, indices) = pair val (element, indices) = pair
assertionBuilder.descriptive assertionBuilder.descriptive
.failing .failing
.withFailureHint { .withHelpOnFailure {
assertionBuilder.explanatoryGroup assertionBuilder.explanatoryGroup
.withDefaultType .withDefaultType
.withExplanatoryAssertion( .withExplanatoryAssertion(

View File

@@ -22,21 +22,46 @@ import java.nio.file.Path
import java.nio.file.attribute.* import java.nio.file.attribute.*
import java.util.* import java.util.*
inline fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withIOExceptionFailureHint( inline fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withHelpOnIOExceptionFailure(
expect: Expect<IoResult<T>>, expect: Expect<IoResult<T>>,
crossinline f: (Path, IOException) -> Assertion? crossinline f: (Path, IOException) -> Assertion?
): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> = ): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> =
withFailureHintBasedOnDefinedSubject(expect) { result -> withHelpOnFailureBasedOnDefinedSubject(expect) { result ->
explainForResolvedLink(result.path) { realPath -> explainForResolvedLink(result.path) { realPath ->
val exception = (result as Failure).exception val exception = (result as Failure).exception
f(realPath, exception) ?: hintForIoException(realPath, exception) f(realPath, exception) ?: hintForIoException(realPath, exception)
} }
} }
@Deprecated("Use withHelpOnIOExceptionFailure; will be removed with 1.0.0")
inline fun <T> Descriptive.DescriptionOption<Descriptive.FinalStep>.withIOExceptionFailureHint(
expect: Expect<IoResult<T>>,
crossinline f: (Path, IOException) -> Assertion?
): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> =
withHelpOnFailureBasedOnDefinedSubject(expect) { result ->
explainForResolvedLink(result.path) { realPath ->
val exception = (result as Failure).exception
f(realPath, exception) ?: hintForIoException(realPath, exception)
}
}
fun Descriptive.DescriptionOption<Descriptive.FinalStep>.withHelpOnFileAttributesFailure(
expect: Expect<IoResult<BasicFileAttributes>>
): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> =
withHelpOnFailureBasedOnDefinedSubject(expect) { result ->
explainForResolvedLink(result.path) { realPath ->
when (result) {
is Success -> describeWas(result.value.fileType)
is Failure -> hintForIoException(realPath, result.exception)
}
}
}
@Deprecated("Use withHelpOnFileAttributesFailure; will be removed with 1.0.0")
fun Descriptive.DescriptionOption<Descriptive.FinalStep>.withFileAttributesFailureHint( fun Descriptive.DescriptionOption<Descriptive.FinalStep>.withFileAttributesFailureHint(
expect: Expect<IoResult<BasicFileAttributes>> expect: Expect<IoResult<BasicFileAttributes>>
): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> = ): Descriptive.DescriptionOption<DescriptiveAssertionWithFailureHint.FinalStep> =
withFailureHintBasedOnDefinedSubject(expect) { result -> withHelpOnFailureBasedOnDefinedSubject(expect) { result ->
explainForResolvedLink(result.path) { realPath -> explainForResolvedLink(result.path) { realPath ->
when (result) { when (result) {
is Success -> describeWas(result.value.fileType) is Success -> describeWas(result.value.fileType)

View File

@@ -8,7 +8,7 @@ package ch.tutteli.atrium.logic.impl
import ch.tutteli.atrium.assertions.Assertion import ch.tutteli.atrium.assertions.Assertion
import ch.tutteli.atrium.assertions.builders.assertionBuilder import ch.tutteli.atrium.assertions.builders.assertionBuilder
import ch.tutteli.atrium.assertions.builders.withExplanatoryAssertion import ch.tutteli.atrium.assertions.builders.withExplanatoryAssertion
import ch.tutteli.atrium.assertions.builders.withFailureHint import ch.tutteli.atrium.assertions.builders.withHelpOnFailure
import ch.tutteli.atrium.creating.AssertionContainer import ch.tutteli.atrium.creating.AssertionContainer
import ch.tutteli.atrium.logic.BigDecimalAssertions import ch.tutteli.atrium.logic.BigDecimalAssertions
import ch.tutteli.atrium.logic.createDescriptiveAssertion import ch.tutteli.atrium.logic.createDescriptiveAssertion
@@ -37,7 +37,7 @@ class DefaultBigDecimalAssertions : BigDecimalAssertions {
): Assertion = ): Assertion =
assertionBuilder.descriptive assertionBuilder.descriptive
.withTest(container.toExpect()) { it == expected } .withTest(container.toExpect()) { it == expected }
.withFailureHint { .withHelpOnFailure {
assertionBuilder.explanatoryGroup assertionBuilder.explanatoryGroup
.withInformationType(withIndent = true) .withInformationType(withIndent = true)
.withExplanatoryAssertion( .withExplanatoryAssertion(

View File

@@ -8,7 +8,7 @@ package ch.tutteli.atrium.logic.impl
import ch.tutteli.atrium.assertions.Assertion import ch.tutteli.atrium.assertions.Assertion
import ch.tutteli.atrium.assertions.builders.assertionBuilder import ch.tutteli.atrium.assertions.builders.assertionBuilder
import ch.tutteli.atrium.assertions.builders.invisibleGroup import ch.tutteli.atrium.assertions.builders.invisibleGroup
import ch.tutteli.atrium.assertions.builders.withFailureHintBasedOnDefinedSubject import ch.tutteli.atrium.assertions.builders.withHelpOnFailureBasedOnDefinedSubject
import ch.tutteli.atrium.core.None import ch.tutteli.atrium.core.None
import ch.tutteli.atrium.core.Some import ch.tutteli.atrium.core.Some
import ch.tutteli.atrium.creating.AssertionContainer import ch.tutteli.atrium.creating.AssertionContainer
@@ -63,7 +63,7 @@ class DefaultPathAssertions : PathAssertions {
changeSubjectToFileAttributes(container, linkOption) { fileAttributesExpect -> changeSubjectToFileAttributes(container, linkOption) { fileAttributesExpect ->
assertionBuilder.descriptive assertionBuilder.descriptive
.withTest(fileAttributesExpect) { it is Success } .withTest(fileAttributesExpect) { it is Success }
.withIOExceptionFailureHint(fileAttributesExpect) { realPath, exception -> .withHelpOnIOExceptionFailure(fileAttributesExpect) { realPath, exception ->
when (exception) { when (exception) {
// TODO remove group once https://github.com/robstoll/atrium-roadmap/issues/1 is implemented // TODO remove group once https://github.com/robstoll/atrium-roadmap/issues/1 is implemented
is NoSuchFileException -> assertionBuilder.explanatoryGroup is NoSuchFileException -> assertionBuilder.explanatoryGroup
@@ -82,7 +82,7 @@ class DefaultPathAssertions : PathAssertions {
changeSubjectToFileAttributes(container, linkOption) { fileAttributesExpect -> changeSubjectToFileAttributes(container, linkOption) { fileAttributesExpect ->
assertionBuilder.descriptive assertionBuilder.descriptive
.withTest(fileAttributesExpect) { it is Failure && it.exception is NoSuchFileException } .withTest(fileAttributesExpect) { it is Failure && it.exception is NoSuchFileException }
.withFileAttributesFailureHint(fileAttributesExpect) .withHelpOnFileAttributesFailure(fileAttributesExpect)
.withDescriptionAndRepresentation(DescriptionBasic.NOT_TO, EXIST) .withDescriptionAndRepresentation(DescriptionBasic.NOT_TO, EXIST)
.build() .build()
} }
@@ -130,7 +130,7 @@ class DefaultPathAssertions : PathAssertions {
}.let { checkAccessResultExpect -> }.let { checkAccessResultExpect ->
assertionBuilder.descriptive assertionBuilder.descriptive
.withTest(checkAccessResultExpect) { it is Success } .withTest(checkAccessResultExpect) { it is Success }
.withIOExceptionFailureHint(checkAccessResultExpect) { realPath, exception -> .withHelpOnIOExceptionFailure(checkAccessResultExpect) { realPath, exception ->
when (exception) { when (exception) {
is AccessDeniedException -> findHintForProblemWithParent(realPath) is AccessDeniedException -> findHintForProblemWithParent(realPath)
?: assertionBuilder.explanatoryGroup ?: assertionBuilder.explanatoryGroup
@@ -155,7 +155,7 @@ class DefaultPathAssertions : PathAssertions {
) = changeSubjectToFileAttributes(container, linkOption) { fileAttributesExpect -> ) = changeSubjectToFileAttributes(container, linkOption) { fileAttributesExpect ->
assertionBuilder.descriptive assertionBuilder.descriptive
.withTest(fileAttributesExpect) { it is Success && typeTest(it.value) } .withTest(fileAttributesExpect) { it is Success && typeTest(it.value) }
.withFileAttributesFailureHint(fileAttributesExpect) .withHelpOnFileAttributesFailure(fileAttributesExpect)
.withDescriptionAndRepresentation(DescriptionBasic.IS, typeName) .withDescriptionAndRepresentation(DescriptionBasic.IS, typeName)
.build() .build()
} }
@@ -204,7 +204,7 @@ class DefaultPathAssertions : PathAssertions {
}.let { expectResult -> }.let { expectResult ->
assertionBuilder.descriptive assertionBuilder.descriptive
.withTest(expectResult) { it is Success && it.value.isEmpty() } .withTest(expectResult) { it is Success && it.value.isEmpty() }
.withFailureHintBasedOnDefinedSubject(expectResult) { ioResult -> .withHelpOnFailureBasedOnDefinedSubject(expectResult) { ioResult ->
explainForResolvedLink(ioResult.path) { realPath -> explainForResolvedLink(ioResult.path) { realPath ->
when (ioResult) { when (ioResult) {
is Success -> { is Success -> {