Skip to content

Commit 320728f

Browse files
committed
Added the containsOnRight assertion
1 parent f18acf5 commit 320728f

File tree

6 files changed

+122
-17
lines changed

6 files changed

+122
-17
lines changed

src/main/kotlin/in/rcard/assertj/arrowcore/AbstractEitherAssert.kt

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,32 @@ package `in`.rcard.assertj.arrowcore
33
import arrow.core.Either
44
import `in`.rcard.assertj.arrowcore.errors.EitherShouldBeLeft.Companion.shouldBeLeft
55
import `in`.rcard.assertj.arrowcore.errors.EitherShouldBeRight.Companion.shouldBeRight
6+
import `in`.rcard.assertj.arrowcore.errors.EitherShouldContain.Companion.shouldContainOnRight
67
import org.assertj.core.api.AbstractObjectAssert
8+
import org.assertj.core.internal.ComparisonStrategy
9+
import org.assertj.core.internal.StandardComparisonStrategy
710

811
/**
912
* Assertions for [Either].
1013
*
11-
* @param <SELF> the "self" type of this assertion class.
12-
* @param <LEFT> type of the left value contained in the [Either].
13-
* @param <RIGHT> type of the right value contained in the [Either].
14+
* @param SELF the "self" type of this assertion class.
15+
* @param LEFT type of the left value contained in the [Either].
16+
* @param RIGHT type of the right value contained in the [Either].
1417
* @author Riccardo Cardin
1518
*/
16-
abstract class AbstractEitherAssert<SELF : AbstractEitherAssert<SELF, LEFT, RIGHT>, LEFT, RIGHT>(either: Either<LEFT, RIGHT>?) :
19+
abstract class AbstractEitherAssert<SELF : AbstractEitherAssert<SELF, LEFT, RIGHT>, LEFT : Any, RIGHT : Any>(either: Either<LEFT, RIGHT>?) :
1720
AbstractObjectAssert<SELF, Either<LEFT, RIGHT>>(either, AbstractEitherAssert::class.java) {
1821

22+
private val comparisonStrategy: ComparisonStrategy = StandardComparisonStrategy.instance()
23+
1924
/**
2025
* Verifies that the actual [Either] is right.
2126
*
2227
* @return this assertion object.
2328
*/
2429
fun isRight(): SELF {
2530
isNotNull
26-
if (!actual.isRight()) {
27-
throwAssertionError(shouldBeRight(actual))
28-
}
31+
assertIsRight()
2932
return myself
3033
}
3134

@@ -35,10 +38,31 @@ abstract class AbstractEitherAssert<SELF : AbstractEitherAssert<SELF, LEFT, RIGH
3538
* @return this assertion object.
3639
*/
3740
fun isLeft(): SELF {
41+
assertIsLeft()
42+
return myself
43+
}
44+
45+
private fun assertIsLeft() {
3846
isNotNull
3947
if (!actual.isLeft()) {
4048
throwAssertionError(shouldBeLeft(actual))
4149
}
50+
}
51+
52+
fun containsOnRight(expectedValue: RIGHT): SELF {
53+
assertIsRight()
54+
actual.onRight { right ->
55+
if (!comparisonStrategy.areEqual(right, expectedValue)) throwAssertionError(
56+
shouldContainOnRight(actual, expectedValue)
57+
)
58+
}
4259
return myself
4360
}
61+
62+
private fun assertIsRight() {
63+
isNotNull
64+
if (!actual.isRight()) {
65+
throwAssertionError(shouldBeRight(actual))
66+
}
67+
}
4468
}

src/main/kotlin/in/rcard/assertj/arrowcore/EitherAssert.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import arrow.core.Either
55
/**
66
* Assertions for [Either].
77
*
8-
* @param <LEFT> type of the value on the left contained in the [Either].
9-
* @param <RIGHT> type of the value on the right contained in the [Either].
8+
* @param LEFT type of the value on the left contained in the [Either].
9+
* @param RIGHT type of the value on the right contained in the [Either].
1010
* @author Riccardo Cardin
1111
*/
12-
class EitherAssert<LEFT, RIGHT>(either: Either<LEFT, RIGHT>?) :
12+
class EitherAssert<LEFT : Any, RIGHT : Any>(either: Either<LEFT, RIGHT>?) :
1313
AbstractEitherAssert<EitherAssert<LEFT, RIGHT>, LEFT, RIGHT>(either) {
1414
companion object {
15-
fun <LEFT, RIGHT> assertThat(actual: Either<LEFT, RIGHT>?): EitherAssert<LEFT, RIGHT> {
15+
fun <LEFT : Any, RIGHT : Any> assertThat(actual: Either<LEFT, RIGHT>?): EitherAssert<LEFT, RIGHT> {
1616
return EitherAssert(actual)
1717
}
1818
}

src/main/kotlin/in/rcard/assertj/arrowcore/errors/EitherShouldBeLeft.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import org.assertj.core.error.BasicErrorMessageFactory
1111
class EitherShouldBeLeft(actual: Either<*, *>) :
1212
BasicErrorMessageFactory("%nExpecting an Either to be left but was <$actual>.") {
1313
companion object {
14-
fun shouldBeLeft(actual: Either<*, *>): EitherShouldBeLeft {
15-
return EitherShouldBeLeft(actual)
16-
}
14+
fun shouldBeLeft(actual: Either<*, *>): EitherShouldBeLeft = EitherShouldBeLeft(actual)
1715
}
1816
}

src/main/kotlin/in/rcard/assertj/arrowcore/errors/EitherShouldBeRight.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import org.assertj.core.error.BasicErrorMessageFactory
1111
class EitherShouldBeRight(actual: Either<*, *>) :
1212
BasicErrorMessageFactory("%nExpecting an Either to be right but was <$actual>.") {
1313
companion object {
14-
fun shouldBeRight(actual: Either<*, *>): EitherShouldBeRight {
15-
return EitherShouldBeRight(actual)
16-
}
14+
fun shouldBeRight(actual: Either<*, *>): EitherShouldBeRight = EitherShouldBeRight(actual)
1715
}
1816
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package `in`.rcard.assertj.arrowcore.errors
2+
3+
import arrow.core.Either
4+
import org.assertj.core.error.BasicErrorMessageFactory
5+
6+
/**
7+
* Build error message when an [Either] should contain a specific value.
8+
*
9+
* @author Riccardo Cardin
10+
*/
11+
class EitherShouldContain(message: String, actual: Either<Any, Any>, expected: Any) :
12+
BasicErrorMessageFactory(message, actual, expected) {
13+
14+
companion object {
15+
16+
private const val EXPECTING_TO_CONTAIN_ON_RIGHT =
17+
"%nExpecting:%n <%s>%nto contain:%n <%s> on the [RIGHT]%nbut did not."
18+
19+
/**
20+
* Indicates that the provided [Either] does not contain the provided argument as right value.
21+
*
22+
* @param actual the [Either] which contains a value.
23+
* @param expectedValue the value we expect to be in the provided [Either] on the right side.
24+
* @param LEFT the type of the value contained in the [Either] on the left side.
25+
* @param RIGHT the type of the value contained in the [Either] on the right side.
26+
* @return an error message factory
27+
*/
28+
fun <LEFT : Any, RIGHT : Any> shouldContainOnRight(
29+
actual: Either<LEFT, RIGHT>,
30+
expectedValue: RIGHT
31+
): EitherShouldContain = EitherShouldContain(
32+
EXPECTING_TO_CONTAIN_ON_RIGHT,
33+
actual,
34+
expectedValue
35+
)
36+
}
37+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package `in`.rcard.assertj.arrowcore
2+
3+
import arrow.core.Either
4+
import arrow.core.left
5+
import arrow.core.right
6+
import `in`.rcard.assertj.arrowcore.errors.EitherShouldBeRight.Companion.shouldBeRight
7+
import `in`.rcard.assertj.arrowcore.errors.EitherShouldContain.Companion.shouldContainOnRight
8+
import org.assertj.core.api.Assertions
9+
import org.assertj.core.util.FailureMessages.actualIsNull
10+
import org.junit.jupiter.api.Test
11+
12+
class EitherAssert_containsOnRight_Test {
13+
@Test
14+
fun `should fail when either is null`() {
15+
val rightValue: Either<Nothing, String>? = null
16+
Assertions.assertThatThrownBy {
17+
EitherAssert.assertThat(rightValue).containsOnRight(
18+
"something"
19+
)
20+
}
21+
.isInstanceOf(AssertionError::class.java)
22+
.hasMessage(actualIsNull())
23+
}
24+
25+
@Test
26+
fun `should pass if either contains expected value on right side`() {
27+
val rightValue = "something".right()
28+
EitherAssert.assertThat(rightValue).containsOnRight("something")
29+
}
30+
31+
@Test
32+
fun should_fail_if_either_is_left() {
33+
val actual: Either<String, String> = "nothing".left()
34+
val expectedValue = "something"
35+
Assertions.assertThatThrownBy { EitherAssert.assertThat(actual).containsOnRight(expectedValue) }
36+
.isInstanceOf(AssertionError::class.java)
37+
.hasMessage(shouldBeRight(actual).create())
38+
}
39+
40+
@Test
41+
fun `should fail if either does not contain expected value on right side`() {
42+
val actual: Either<Nothing, String> = "something".right()
43+
val expectedValue = "nothing"
44+
Assertions.assertThatThrownBy { EitherAssert.assertThat(actual).containsOnRight(expectedValue) }
45+
.isInstanceOf(AssertionError::class.java)
46+
.hasMessage(shouldContainOnRight(actual, expectedValue).create())
47+
}
48+
}

0 commit comments

Comments
 (0)