Skip to content

Commit f47dc23

Browse files
authored
Merge pull request #63 from farajist/31-add-assertions-for-NonEmptyList<A>-type
feat(31): add assertion for NonEmptyList<A> type
2 parents db8d0b9 + b0e4219 commit f47dc23

17 files changed

+650
-1
lines changed

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,19 @@ The available assertions are:
8989
| `raises` | Verifies that the function in the Raise context fails with the given error. |
9090
| `fails` | Verifies that the function in the Raise context fails, no matter the type of the logical error. |
9191
| `result` | Verifies that the actual function in the `Raise` context succeeds and returns an `Object` assertion that allows chaining (object) assertions on the returned value. |
92-
| `error` | Verifies that the actual function in the Raise context fails and returns an Object assertion that allows chaining (object) assertions on the raised error. |
92+
| `error` | Verifies that the actual function in the Raise context fails and returns an Object assertion that allows chaining (object) assertions on the raised error. |
93+
94+
### `NonEmptyList<A>`
95+
96+
Use the `in.rcard.assertj.arrowcore.NonEmptyListAssert` class as an entry point to assert `NonEmptyList<A>` instances.
97+
98+
| Assertions | Description |
99+
|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
100+
| `shouldContain` | Verifies that the actual `NonEmptyList` contains the expected element. |
101+
| `shouldContainAll` | Verifies that the actual `NonEmptyList` contains all the expected elements. |
102+
| `shouldContainNoNulls` | Verifies that the actual `NonEmptyList` does not contain null. |
103+
| `shouldContainOnlyNulls` | Verifies that the actual `NonEmptyList` contains only null. |
104+
| `shouldContainNull` | Verifies that the actual `NonEmptyList` contains null. |
105+
| `shouldHaveDuplicates` | Verifies that the actual `NonEmptyList` contains at least one duplicate. |
106+
| `shouldBeSingleElement` | Verifies that the actual `NonEmptyList` has a single element which is expected element. |
107+
| `shouldBeSorted` | Verifies that the actual `NonEmptyList` is sorted. |
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package `in`.rcard.assertj.arrowcore
2+
3+
import arrow.core.NonEmptyList
4+
import `in`.rcard.assertj.arrowcore.errors.NonEmptyListShouldNotContain.Companion.shouldNotContain
5+
import `in`.rcard.assertj.arrowcore.errors.NonEmptyListShouldContain.Companion.shouldContain
6+
import `in`.rcard.assertj.arrowcore.errors.NonEmptyListShouldContainOnly.Companion.shouldContainOnly
7+
import `in`.rcard.assertj.arrowcore.errors.NonEmptyListShouldBeSingleElement.Companion.shouldBeSingleElement
8+
import `in`.rcard.assertj.arrowcore.errors.NonEmptyListShouldHaveDuplicates.Companion.shouldHaveDuplicates
9+
import `in`.rcard.assertj.arrowcore.errors.NonEmptyListShouldBeSorted.Companion.shouldBeSorted
10+
import org.assertj.core.api.AbstractAssert
11+
import org.assertj.core.api.AssertFactory
12+
import org.assertj.core.api.FactoryBasedNavigableListAssert
13+
import org.assertj.core.internal.StandardComparisonStrategy
14+
15+
16+
/**
17+
* Assertions for [NonEmptyList].
18+
*
19+
* @param SELF the "self" type of this assertion class.
20+
* @param ELEMENT type of the element contained in the [NonEmptyList].
21+
* @param ELEMENT_ASSERT type used for assertion of element contained in the [NonEmptyList].
22+
* @author Hamza Faraji
23+
*
24+
* @since 1.2.0
25+
*/
26+
open class AbstractNonEmptyListAssert<
27+
SELF : AbstractNonEmptyListAssert<SELF, ELEMENT, ELEMENT_ASSERT>,
28+
ELEMENT : Any?,
29+
ELEMENT_ASSERT : AbstractAssert<ELEMENT_ASSERT, ELEMENT>
30+
> internal constructor(
31+
list: NonEmptyList<ELEMENT?>?,
32+
assertFactory: AssertFactory<ELEMENT, ELEMENT_ASSERT>?,
33+
) : FactoryBasedNavigableListAssert<SELF, NonEmptyList<ELEMENT?>, ELEMENT, ELEMENT_ASSERT>(
34+
list,
35+
AbstractNonEmptyListAssert::class.java,
36+
assertFactory
37+
) {
38+
private val comparisonStrategy: StandardComparisonStrategy = StandardComparisonStrategy.instance()
39+
40+
/**
41+
* Verifies that the actual [NonEmptyList] contains the expected element
42+
*
43+
* @return the assertion object
44+
*/
45+
fun shouldContain(expectedValue: ELEMENT): SELF {
46+
isNotNull
47+
assertContains(expectedValue)
48+
return myself
49+
}
50+
51+
/**
52+
* Verifies that the actual [NonEmptyList] contains all the expected elements
53+
*
54+
* @return the assertion object
55+
*/
56+
fun shouldContainAll(vararg elements: ELEMENT): SELF {
57+
isNotNull
58+
if (!actual.containsAll(elements.toList())) {
59+
throwAssertionError(shouldContain(actual, elements))
60+
}
61+
return myself
62+
}
63+
64+
/**
65+
* Verifies that the actual [NonEmptyList] contains null
66+
*
67+
* @return the assertion object
68+
*/
69+
fun shouldContainNull(): SELF {
70+
isNotNull
71+
assertContains(null)
72+
return myself
73+
}
74+
75+
/**
76+
* Verifies that the actual [NonEmptyList] does not contain null
77+
*
78+
* @return the assertion object
79+
*/
80+
fun shouldContainNoNulls(): SELF {
81+
isNotNull
82+
if (actual.contains(null)) {
83+
throwAssertionError(shouldNotContain(actual, null))
84+
}
85+
return myself
86+
}
87+
88+
/**
89+
* Verifies that the actual [NonEmptyList] contains only null
90+
*
91+
* @return the assertion object
92+
*/
93+
fun shouldContainOnlyNulls(): SELF {
94+
isNotNull
95+
if (!actual.none { it != null }) {
96+
throwAssertionError(shouldContainOnly(actual, null))
97+
}
98+
return myself
99+
}
100+
101+
/**
102+
* Verifies that the actual [NonEmptyList] contains at least one duplicate
103+
*
104+
* @return the assertion object
105+
*/
106+
fun shouldHaveDuplicates(): SELF {
107+
isNotNull
108+
if (actual.distinct().size == actual.size) {
109+
throwAssertionError(shouldHaveDuplicates(actual))
110+
}
111+
return myself
112+
}
113+
114+
/**
115+
* Verifies that the actual [NonEmptyList] has a single element which is expected element
116+
*
117+
* @return the assertion object
118+
*/
119+
fun shouldBeSingleElement(expectedValue: ELEMENT): SELF {
120+
isNotNull
121+
if (actual.size != 1 || !comparisonStrategy.areEqual(actual.first(), expectedValue)) {
122+
throwAssertionError(shouldBeSingleElement(actual, expectedValue))
123+
}
124+
return myself
125+
}
126+
127+
/**
128+
* Verifies that the actual [NonEmptyList] is sorted
129+
*
130+
* @return the assertion object
131+
*/
132+
fun shouldBeSorted(): SELF {
133+
isNotNull
134+
if (actual.sortedWith { first, second ->
135+
when {
136+
comparisonStrategy.areEqual(first, second) -> 0
137+
comparisonStrategy.isLessThanOrEqualTo(first, second) -> -1
138+
else -> 1
139+
}
140+
} != actual) {
141+
throwAssertionError(shouldBeSorted(actual))
142+
}
143+
144+
return myself
145+
}
146+
147+
private fun assertContains(expectedValue: ELEMENT?) {
148+
isNotNull
149+
if (!actual.contains(expectedValue)) {
150+
throwAssertionError(shouldContain(actual, expectedValue))
151+
}
152+
}
153+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package `in`.rcard.assertj.arrowcore
2+
3+
import arrow.core.NonEmptyList
4+
import org.assertj.core.api.AssertFactory
5+
import org.assertj.core.api.ObjectAssert
6+
7+
/**
8+
* Assertions for [NonEmptyList].
9+
*
10+
* @param ELEMENT type of the element contained in the [NonEmptyList].
11+
* @author Hamza Faraji
12+
*
13+
* @since 1.2.0
14+
*/
15+
class NonEmptyListAssert<ELEMENT : Any?> private constructor(nel: NonEmptyList<ELEMENT>?) :
16+
AbstractNonEmptyListAssert<NonEmptyListAssert<ELEMENT>, ELEMENT, ObjectAssert<ELEMENT>>(
17+
nel,
18+
AssertFactory { actual: ELEMENT -> ObjectAssert(actual) }
19+
) {
20+
companion object {
21+
fun <VALUE : Any?> assertThat(list: NonEmptyList<VALUE>?): NonEmptyListAssert<VALUE> =
22+
NonEmptyListAssert(list)
23+
}
24+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package `in`.rcard.assertj.arrowcore.errors
2+
3+
import arrow.core.NonEmptyList
4+
import org.assertj.core.error.BasicErrorMessageFactory
5+
6+
/**
7+
* Build error message when a [NonEmptyList] does not have a single element equal a specific value.
8+
*
9+
* @author Hamza Faraji
10+
* @since 1.2.0
11+
*/
12+
class NonEmptyListShouldBeSingleElement private constructor(message: String, actual: NonEmptyList<Any?>, expected: Any?) :
13+
BasicErrorMessageFactory(message, actual, expected) {
14+
companion object {
15+
private const val EXPECTING_TO_HAVE_SINGLE_ELEMENT_EQUAL =
16+
"%nExpecting:%n <%s>%nto have single element:%n <%s>%nbut did not."
17+
18+
internal fun <ELEMENT : Any> shouldBeSingleElement(
19+
actual: NonEmptyList<ELEMENT?>,
20+
expected: ELEMENT?
21+
): NonEmptyListShouldBeSingleElement = NonEmptyListShouldBeSingleElement(
22+
EXPECTING_TO_HAVE_SINGLE_ELEMENT_EQUAL,
23+
actual,
24+
expected
25+
)
26+
}
27+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package `in`.rcard.assertj.arrowcore.errors
2+
3+
import arrow.core.NonEmptyList
4+
import org.assertj.core.error.BasicErrorMessageFactory
5+
6+
/**
7+
* Build error message when a [NonEmptyList] is not sorted.
8+
*
9+
* @author Hamza Faraji
10+
* @since 1.2.0
11+
*/
12+
class NonEmptyListShouldBeSorted private constructor(message: String, actual: NonEmptyList<Any?>) :
13+
BasicErrorMessageFactory(message, actual) {
14+
companion object {
15+
private const val EXPECTING_TO_BE_SORTED =
16+
"%nExpecting:%n <%s>%nto be sorted, but it is not."
17+
18+
internal fun <ELEMENT : Any> shouldBeSorted(
19+
actual: NonEmptyList<ELEMENT?>
20+
): NonEmptyListShouldBeSorted = NonEmptyListShouldBeSorted(
21+
EXPECTING_TO_BE_SORTED,
22+
actual
23+
)
24+
}
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package `in`.rcard.assertj.arrowcore.errors
2+
3+
import arrow.core.NonEmptyList
4+
import org.assertj.core.error.BasicErrorMessageFactory
5+
6+
/**
7+
* Build error message when a [NonEmptyList] does not contain a specific value.
8+
*
9+
* @author Hamza Faraji
10+
* @since 1.2.0
11+
*/
12+
internal class NonEmptyListShouldContain private constructor(message: String, actual: NonEmptyList<Any?>, expected: Any?) :
13+
BasicErrorMessageFactory(message, actual, expected) {
14+
companion object {
15+
private const val EXPECTING_TO_CONTAIN =
16+
"%nExpecting:%n <%s>%nto contain:%n <%s>%nbut did not."
17+
18+
internal fun <ELEMENT : Any> shouldContain(
19+
actual: NonEmptyList<ELEMENT?>,
20+
vararg expected: ELEMENT?
21+
): NonEmptyListShouldContain = NonEmptyListShouldContain(
22+
EXPECTING_TO_CONTAIN,
23+
actual,
24+
expected
25+
)
26+
}
27+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package `in`.rcard.assertj.arrowcore.errors
2+
3+
import arrow.core.NonEmptyList
4+
import org.assertj.core.error.BasicErrorMessageFactory
5+
6+
/**
7+
* Build error message when a [NonEmptyList] does not contain only a specific value.
8+
*
9+
* @author Hamza Faraji
10+
* @since 1.2.0
11+
*/
12+
class NonEmptyListShouldContainOnly private constructor(message: String, actual: NonEmptyList<Any?>, expected: Any?) :
13+
BasicErrorMessageFactory(message, actual, expected) {
14+
15+
companion object {
16+
private const val EXPECTING_TO_CONTAIN_ONLY =
17+
"%nExpecting:%n <%s>%nto contain only:%n <%s>%nbut did not."
18+
19+
internal fun <ELEMENT : Any> shouldContainOnly(
20+
actual: NonEmptyList<ELEMENT?>,
21+
expected: ELEMENT?
22+
): NonEmptyListShouldContainOnly = NonEmptyListShouldContainOnly(
23+
EXPECTING_TO_CONTAIN_ONLY,
24+
actual,
25+
expected
26+
)
27+
}
28+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package `in`.rcard.assertj.arrowcore.errors
2+
3+
import arrow.core.NonEmptyList
4+
import org.assertj.core.error.BasicErrorMessageFactory
5+
6+
/**
7+
* Build error message when a [NonEmptyList] has no duplicates.
8+
*
9+
* @author Hamza Faraji
10+
* @since 1.2.0
11+
*/
12+
class NonEmptyListShouldHaveDuplicates private constructor(message: String, actual: NonEmptyList<Any?>) :
13+
BasicErrorMessageFactory(message, actual) {
14+
companion object {
15+
private const val EXPECTING_TO_CONTAIN_DUPLICATES =
16+
"%nExpecting:%n <%s>%nto contain duplicates but did not."
17+
18+
internal fun <ELEMENT : Any> shouldHaveDuplicates(
19+
actual: NonEmptyList<ELEMENT?>
20+
): NonEmptyListShouldHaveDuplicates = NonEmptyListShouldHaveDuplicates(
21+
EXPECTING_TO_CONTAIN_DUPLICATES,
22+
actual
23+
)
24+
}
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package `in`.rcard.assertj.arrowcore.errors
2+
3+
import arrow.core.NonEmptyList
4+
import org.assertj.core.error.BasicErrorMessageFactory
5+
6+
/**
7+
* Build error message when a [NonEmptyList] contains a specific value.
8+
*
9+
* @author Hamza Faraji
10+
* @since 1.2.0
11+
*/
12+
class NonEmptyListShouldNotContain(message: String, actual: NonEmptyList<Any?>, expected: Any?) :
13+
BasicErrorMessageFactory(message, actual, expected) {
14+
companion object {
15+
private const val EXPECTING_NOT_TO_CONTAIN =
16+
"%nExpecting:%n <%s>%nnot to contain any:%n <%s>%nbut it did."
17+
18+
internal fun <ELEMENT : Any?> shouldNotContain(
19+
actual: NonEmptyList<ELEMENT>,
20+
expected: ELEMENT
21+
): NonEmptyListShouldNotContain = NonEmptyListShouldNotContain(
22+
EXPECTING_NOT_TO_CONTAIN,
23+
actual,
24+
expected
25+
)
26+
}
27+
}

0 commit comments

Comments
 (0)