Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ import org.assertj.core.internal.StandardComparisonStrategy
* @since 0.0.1
*/
abstract class AbstractEitherAssert<
SELF : AbstractEitherAssert<SELF, LEFT, RIGHT>, LEFT : Any, RIGHT : Any,
> internal constructor(
SELF : AbstractEitherAssert<SELF, LEFT, RIGHT>,
LEFT : Any,
RIGHT : Any,
> internal constructor(
either: Either<LEFT, RIGHT>?,
) : AbstractObjectAssert<SELF, Either<LEFT, RIGHT>>(either, AbstractEitherAssert::class.java) {

private val comparisonStrategy: ComparisonStrategy = StandardComparisonStrategy.instance()

/**
Expand Down
61 changes: 54 additions & 7 deletions src/main/kotlin/in/rcard/assertj/arrowcore/AbstractRaiseAssert.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package `in`.rcard.assertj.arrowcore

import arrow.core.raise.Raise
import arrow.core.raise.fold
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldFailButSucceeded.Companion.shouldFailButSucceeded
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldFailButSucceeds.Companion.shouldFailButSucceedsWith
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldFailButSucceeds.Companion.shouldFailWithButSucceedsWith
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldFailWith.Companion.shouldFailWith
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldSucceedButFailed.Companion.shouldSucceedButFailed
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldSucceedWith.Companion.shouldSucceedWith
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldSucceedWithButFailed.Companion.shouldSucceedWithButFailed
import org.assertj.core.api.AbstractAssert
import org.assertj.core.internal.ComparisonStrategy
import org.assertj.core.internal.StandardComparisonStrategy
Expand All @@ -19,10 +21,17 @@ import org.assertj.core.internal.StandardComparisonStrategy
* @since 0.2.0
*/
abstract class AbstractRaiseAssert<
SELF : AbstractRaiseAssert<SELF, ERROR, VALUE>, ERROR : Any, VALUE : Any,
> internal constructor(lambda: context(Raise<ERROR>) () -> VALUE) :
AbstractAssert<SELF, context(Raise<ERROR>) () -> VALUE>(lambda, AbstractRaiseAssert::class.java) {

SELF : AbstractRaiseAssert<SELF, ERROR, VALUE>,
ERROR : Any,
VALUE : Any,
> internal constructor(
lambda: context(Raise<ERROR>)
() -> VALUE,
) : AbstractAssert<
SELF,
context(Raise<ERROR>)
() -> VALUE,
>(lambda, AbstractRaiseAssert::class.java) {
private val comparisonStrategy: ComparisonStrategy = StandardComparisonStrategy.instance()

/**
Expand All @@ -32,7 +41,14 @@ abstract class AbstractRaiseAssert<
fun succeedsWith(expectedValue: VALUE) {
fold(
block = actual,
recover = { actualError: ERROR -> throwAssertionError(shouldSucceedButFailed(expectedValue, actualError)) },
recover = { actualError: ERROR ->
throwAssertionError(
shouldSucceedWithButFailed(
expectedValue,
actualError,
),
)
},
transform = { actualValue ->
if (!comparisonStrategy.areEqual(actualValue, expectedValue)) {
throwAssertionError(shouldSucceedWith(expectedValue, actualValue))
Expand All @@ -41,6 +57,20 @@ abstract class AbstractRaiseAssert<
)
}

/**
* Verifies that the function in the [Raise] context succeeded. No check on the value returned by the function is
* performed.
*
* @see succeedsWith
*/
fun succeeds() {
fold(
block = actual,
recover = { actualError: ERROR -> throwAssertionError(shouldSucceedButFailed(actualError)) },
transform = { _ -> },
)
}

/**
* Verifies that the function in the [Raise] context fails with the given error.
* @param expectedError the expected error raised by the function.
Expand All @@ -55,7 +85,24 @@ abstract class AbstractRaiseAssert<
},
transform = { actualValue ->
throwAssertionError(
shouldFailButSucceeded(expectedError, actualValue)
shouldFailWithButSucceedsWith(expectedError, actualValue),
)
},
)
}

/**
* Verifies that the function in the [Raise] context fails, no matter the type of the logical error.
*
* @see raises
*/
fun fails() {
fold(
block = actual,
recover = { _ -> },
transform = { actualValue ->
throwAssertionError(
shouldFailButSucceedsWith(actualValue),
)
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ import org.assertj.core.error.BasicErrorMessageFactory
*/
internal class OptionShouldBePresent private constructor() :
BasicErrorMessageFactory("%nExpecting Option to contain a value but it didn't.") {
companion object {

/**
* Indicates that a value should be present in an empty [Option].
*
* @return a error message factory.
*/
internal fun shouldBePresent(): OptionShouldBePresent = OptionShouldBePresent()
companion object {
/**
* Indicates that a value should be present in an empty [Option].
*
* @return a error message factory.
*/
internal fun shouldBePresent(): OptionShouldBePresent = OptionShouldBePresent()
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package `in`.rcard.assertj.arrowcore.errors

import org.assertj.core.error.BasicErrorMessageFactory

private const val SHOULD_FAIL_WITH_BUT_SUCCEEDS_WITH_MESSAGE: String =
"%nExpecting the lambda to fail with:%n <%s> %nbut it succeeded with:%n <%s>"

private const val SHOULD_FAIL_BUT_SUCCEEDS_WITH_MESSAGE: String =
"%nExpecting the lambda to fail<%s>, but it succeeded with:%n <%s>"

/**
* Build error message when a lambda should fail with a logic error but it succeeded with a value.
*
* @author Riccardo Cardin
* @since 0.2.0
*/
internal class RaiseShouldFailButSucceeds private constructor(
expectedError: Any,
actualSucceededValue: Any,
message: String,
) : BasicErrorMessageFactory(message, expectedError, actualSucceededValue) {
companion object {
internal fun shouldFailWithButSucceedsWith(
expectedError: Any,
actualSucceededValue: Any,
): RaiseShouldFailButSucceeds =
RaiseShouldFailButSucceeds(expectedError, actualSucceededValue, SHOULD_FAIL_WITH_BUT_SUCCEEDS_WITH_MESSAGE)

internal fun shouldFailButSucceedsWith(actualSucceededValue: Any): RaiseShouldFailButSucceeds =
RaiseShouldFailButSucceeds("", actualSucceededValue, SHOULD_FAIL_BUT_SUCCEEDS_WITH_MESSAGE)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ package `in`.rcard.assertj.arrowcore.errors
import org.assertj.core.error.BasicErrorMessageFactory

private const val SHOULD_SUCCEED_BUT_FAILED_MESSAGE: String =
"%nExpecting the lambda to succeed with:%n <%s> %nbut it failed with:%n <%s>"
"%nExpecting the lambda to succeed but it failed with:%n <%s>"

/**
* Build error message when a lambda should succeed but it fails with a logic error.
* Build error message when a lambda should succeed, but it fails with a logic error.
*
* @author Riccardo Cardin
* @since 0.2.0
* @since 1.0.0
*/
internal class RaiseShouldSucceedButFailed private constructor(expected: Any, actualRaisedError: Any) :
BasicErrorMessageFactory(SHOULD_SUCCEED_BUT_FAILED_MESSAGE, expected, actualRaisedError) {

internal class RaiseShouldSucceedButFailed private constructor(
actualRaisedError: Any,
) : BasicErrorMessageFactory(SHOULD_SUCCEED_BUT_FAILED_MESSAGE, actualRaisedError) {
companion object {
internal fun shouldSucceedButFailed(expected: Any, actualRaisedError: Any): RaiseShouldSucceedButFailed =
RaiseShouldSucceedButFailed(expected, actualRaisedError)
internal fun shouldSucceedButFailed(actualRaisedError: Any): RaiseShouldSucceedButFailed =
RaiseShouldSucceedButFailed(actualRaisedError)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package `in`.rcard.assertj.arrowcore.errors

import org.assertj.core.error.BasicErrorMessageFactory

private const val SHOULD_SUCCEED_WITH_BUT_FAILED_MESSAGE: String =
"%nExpecting the lambda to succeed with:%n <%s> %nbut it failed with:%n <%s>"

/**
* Build error message when a lambda should succeed with a value, but it fails with a logic error.
*
* @author Riccardo Cardin
* @since 0.2.0
*/
internal class RaiseShouldSucceedWithButFailed private constructor(
expected: Any,
actualRaisedError: Any,
) : BasicErrorMessageFactory(SHOULD_SUCCEED_WITH_BUT_FAILED_MESSAGE, expected, actualRaisedError) {
companion object {
internal fun shouldSucceedWithButFailed(
expected: Any,
actualRaisedError: Any,
): RaiseShouldSucceedWithButFailed = RaiseShouldSucceedWithButFailed(expected, actualRaisedError)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.assertj.core.api.BDDAssertions.then
import org.junit.jupiter.api.Test

internal class OptionAssert_assertThat_Test {

@Test
internal fun `should create an assertion instance when given object is not null`() {
// GIVEN
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package `in`.rcard.assertj.arrowcore

import `in`.rcard.assertj.arrowcore.RaiseAssert.Companion.assertThat
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldFailButSucceeds.Companion.shouldFailButSucceedsWith
import org.assertj.core.api.Assertions
import org.junit.jupiter.api.Test

@Suppress("ktlint:standard:class-naming")
internal class RaiseAssert_fails_Test {
@Test
internal fun `should pass if lambda raises a logical error`() {
assertThat { Dummy.aFunctionThatRaisesAnError() }.fails()
}

@Test
internal fun `should fail if lambda succeeds with a value instead of failing`() {
Assertions
.assertThatThrownBy {
assertThat { Dummy.aFunctionWithContext(42) }.fails()
}.isInstanceOf(AssertionError::class.java)
.hasMessage(
shouldFailButSucceedsWith(42).create(),
)
}

@Test
internal fun `should fail if lambda throws an exception`() {
Assertions
.assertThatThrownBy {
assertThat { Dummy.aFunctionThatThrowsAnException() }.fails()
}.isInstanceOf(RuntimeException::class.java)
.hasMessage("AN EXCEPTION")
}
}
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
package `in`.rcard.assertj.arrowcore

import `in`.rcard.assertj.arrowcore.RaiseAssert.Companion.assertThat
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldFailButSucceeded.Companion.shouldFailButSucceeded
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldFailButSucceeds.Companion.shouldFailWithButSucceedsWith
import `in`.rcard.assertj.arrowcore.errors.RaiseShouldFailWith.Companion.shouldFailWith
import org.assertj.core.api.Assertions
import org.junit.jupiter.api.Test

internal class RaiseAssert_raises_Test {

@Test
internal fun `should pass if lambda raises a logical error`() {
assertThat { Dummy.aFunctionThatRaisesAnError() }.raises("LOGICAL ERROR")
}

@Test
internal fun `should fail if lambda raises a logical error different from the expected`() {
Assertions.assertThatThrownBy {
assertThat { Dummy.aFunctionThatRaisesAnError() }.raises("ANOTHER LOGICAL ERROR")
}.isInstanceOf(AssertionError::class.java)
Assertions
.assertThatThrownBy {
assertThat { Dummy.aFunctionThatRaisesAnError() }.raises("ANOTHER LOGICAL ERROR")
}.isInstanceOf(AssertionError::class.java)
.hasMessage(shouldFailWith("ANOTHER LOGICAL ERROR", "LOGICAL ERROR").create())
}

@Test
internal fun `should fail if lambda succeeds with a value instead of failing`() {
Assertions.assertThatThrownBy {
assertThat { Dummy.aFunctionWithContext(42) }.raises("LOGICAL ERROR")
}.isInstanceOf(AssertionError::class.java)
Assertions
.assertThatThrownBy {
assertThat { Dummy.aFunctionWithContext(42) }.raises("LOGICAL ERROR")
}.isInstanceOf(AssertionError::class.java)
.hasMessage(
shouldFailButSucceeded("LOGICAL ERROR", 42).create(),
shouldFailWithButSucceedsWith("LOGICAL ERROR", 42).create(),
)
}

@Test
internal fun `should fail if lambda throws an exception`() {
Assertions.assertThatThrownBy {
assertThat { Dummy.aFunctionThatThrowsAnException() }.raises("LOGICAL ERROR")
}.isInstanceOf(RuntimeException::class.java)
Assertions
.assertThatThrownBy {
assertThat { Dummy.aFunctionThatThrowsAnException() }.raises("LOGICAL ERROR")
}.isInstanceOf(RuntimeException::class.java)
.hasMessage("AN EXCEPTION")
}
}
Loading