Skip to content

Commit 043eb83

Browse files
committed
Added shouldContains assertion to OptionAssert
1 parent 49e4b69 commit 043eb83

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ package `in`.rcard.assertj.arrowcore
33
import arrow.core.Option
44
import `in`.rcard.assertj.arrowcore.errors.OptionShouldBeEmpty.Companion.shouldBeEmpty
55
import `in`.rcard.assertj.arrowcore.errors.OptionShouldBePresent.Companion.shouldBePresent
6+
import `in`.rcard.assertj.arrowcore.errors.OptionShouldContain.Companion.shouldContain
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 [Option].
@@ -18,6 +21,8 @@ abstract class AbstractOptionAssert<
1821
option: Option<VALUE>?,
1922
) : AbstractObjectAssert<SELF, Option<VALUE>>(option, AbstractOptionAssert::class.java) {
2023

24+
private val comparisonStrategy: ComparisonStrategy = StandardComparisonStrategy.instance()
25+
2126
/**
2227
* Verifies that there is a value present in the actual [Option].
2328
*
@@ -39,4 +44,23 @@ abstract class AbstractOptionAssert<
3944
if (actual.isDefined()) throwAssertionError(shouldBeEmpty(actual))
4045
return myself
4146
}
47+
48+
/**
49+
* Verifies that the actual [Option] contains the given value.
50+
*
51+
* @param expectedValue the expected value inside the [Option].
52+
* @return this assertion object.
53+
*/
54+
fun contains(expectedValue: VALUE): SELF {
55+
isNotNull
56+
actual.fold(
57+
{ throwAssertionError(shouldContain(actual, expectedValue)) },
58+
{ actualValue ->
59+
if (!comparisonStrategy.areEqual(actualValue, expectedValue)) {
60+
throwAssertionError(shouldContain(actual, expectedValue))
61+
}
62+
},
63+
)
64+
return myself
65+
}
4266
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package `in`.rcard.assertj.arrowcore.errors
2+
3+
import arrow.core.Option
4+
import org.assertj.core.error.BasicErrorMessageFactory
5+
6+
/**
7+
* Build error message when an [Option] should contain a specific value.
8+
*
9+
* @author Riccardo Cardin
10+
*/
11+
internal class OptionShouldContain(message: String, vararg objs: Any) :
12+
BasicErrorMessageFactory(message, *objs) {
13+
14+
companion object {
15+
private const val EXPECTING_TO_CONTAIN =
16+
"%nExpecting:%n <%s>%nto contain:%n <%s>%nbut did not."
17+
private const val EXPECTING_TO_CONTAIN_BUT_WAS_EMPTY =
18+
"%nExpecting Option to contain:%n <%s>%nbut was empty."
19+
20+
/**
21+
* Indicates that the provided [Option] does not contain the provided argument.
22+
*
23+
* @param VALUE the type of the value contained in the [Option].
24+
* @param option the [Option] which contains a value.
25+
* @param expectedValue the value we expect to be in the provided [Option].
26+
* @return an error message factory
27+
*/
28+
internal fun <VALUE : Any> shouldContain(
29+
option: Option<VALUE>,
30+
expectedValue: VALUE,
31+
): OptionShouldContain =
32+
option.fold(
33+
{ OptionShouldContain(EXPECTING_TO_CONTAIN_BUT_WAS_EMPTY, expectedValue) },
34+
{ _ ->
35+
OptionShouldContain(
36+
EXPECTING_TO_CONTAIN,
37+
option,
38+
expectedValue,
39+
)
40+
},
41+
)
42+
}
43+
}
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.None
4+
import arrow.core.Option
5+
import arrow.core.some
6+
import `in`.rcard.assertj.arrowcore.OptionAssert.Companion.assertThat
7+
import `in`.rcard.assertj.arrowcore.errors.OptionShouldContain.Companion.shouldContain
8+
import org.assertj.core.api.Assertions
9+
import org.assertj.core.util.FailureMessages
10+
import org.junit.jupiter.api.Test
11+
12+
internal class OptionAssert_contains_Test {
13+
14+
@Test
15+
internal fun `should fail when option is null`() {
16+
Assertions.assertThatThrownBy {
17+
val nullOption: Option<String>? = null
18+
assertThat(nullOption).contains("something")
19+
}
20+
.isInstanceOf(AssertionError::class.java)
21+
.hasMessage(FailureMessages.actualIsNull())
22+
}
23+
24+
@Test
25+
internal fun `should pass if option contains expected value`() {
26+
assertThat("something".some()).contains("something")
27+
}
28+
29+
@Test
30+
internal fun `should fail if option does not contain expected value`() {
31+
val actual: Option<String> = "not-expected".some()
32+
val expectedValue = "something"
33+
Assertions.assertThatThrownBy { assertThat(actual).contains(expectedValue) }
34+
.isInstanceOf(AssertionError::class.java)
35+
.hasMessage(shouldContain(actual, expectedValue).create())
36+
}
37+
38+
@Test
39+
internal fun `should fail if option is empty`() {
40+
val expectedValue = "something"
41+
val emptyOption: Option<String> = None
42+
Assertions.assertThatThrownBy {
43+
assertThat(emptyOption).contains(expectedValue)
44+
}
45+
.isInstanceOf(AssertionError::class.java)
46+
.hasMessage(shouldContain(emptyOption, expectedValue).create())
47+
}
48+
}

0 commit comments

Comments
 (0)