Add tests for Any.isNoneOf and Any.isNotIn assertions

and update error message, reflect IterableLike
This commit is contained in:
Anes Abismail
2020-07-29 22:28:29 +01:00
committed by Robert Stoll
parent 3a3f0468e0
commit bdd894b892
8 changed files with 178 additions and 23 deletions

View File

@@ -177,7 +177,7 @@ infix fun <T> Expect<T>.and(assertionCreator: Expect<T>.() -> Unit): Expect<T> =
*
* @since 0.13.0
*/
inline fun <reified T> Expect<T>.isNoneOf(expected: T, vararg otherValues: T): Expect<T> =
fun <T> Expect<T>.isNoneOf(expected: T, vararg otherValues: T): Expect<T> =
_logicAppend { isNotIn(expected glue otherValues) }
/**
@@ -194,7 +194,7 @@ inline fun <reified T> Expect<T>.isNoneOf(expected: T, vararg otherValues: T): E
*/
inline fun <reified T> Expect<T>.isNotIn(expected: IterableLike): Expect<T> {
val iterable = iterableLikeToIterable<T>(expected)
require(iterable.iterator().hasNext()) { "Iterable without elements are not allowed for this function." }
require(iterable.iterator().hasNext()) { "IterableLike without elements are not allowed for this function." }
return _logicAppend { isNotIn(iterable.toList()) }
}

View File

@@ -3,6 +3,7 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.feature0
import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.fun2
import ch.tutteli.atrium.specs.withFeatureSuffix
import ch.tutteli.atrium.specs.withNullableSuffix
import kotlin.reflect.KFunction2
@@ -25,6 +26,14 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
fun1(Expect<DataClass>::isNotSameAs),
fun1(Expect<Int?>::isNotSameAs).withNullableSuffix(),
fun1(Expect<DataClass?>::isNotSameAs).withNullableSuffix(),
fun2(Expect<Int>::isNoneOf),
fun2(Expect<DataClass>::isNoneOf),
fun2(Expect<Int?>::isNoneOf).withNullableSuffix(),
fun2(Expect<DataClass?>::isNoneOf).withNullableSuffix(),
fun1(Expect<Int>::isNotIn),
fun1(Expect<DataClass>::isNotIn),
fun1(Expect<Int?>::isNotIn).withNullableSuffix(),
fun1(Expect<DataClass?>::isNotIn).withNullableSuffix(),
"${Expect<Int?>::toBe.name}(null)" to Companion::toBeNull,
fun1(Expect<Int?>::toBeNullIfNullGivenElse),
@@ -39,7 +48,8 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
"notToBeNull" to Companion::notToBeNull,
getAndImmediatePair(),
getAndLazyPair()
getAndLazyPair(),
""
) {
companion object {

View File

@@ -1,11 +1,11 @@
package ch.tutteli.atrium.api.infix.en_GB
import ch.tutteli.atrium.api.infix.en_GB.creating.Values
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.builders.utils.iterableLikeToIterable
import ch.tutteli.atrium.domain.creating.typeutils.IterableLike
import ch.tutteli.atrium.logic.*
import ch.tutteli.atrium.reporting.Reporter
import ch.tutteli.kbox.glue
/**
* Expects that the subject of the assertion is (equal to) [expected].
@@ -229,15 +229,18 @@ inline val <T> Expect<T>.it: Expect<T> get() : Expect<T> = this
inline val <T> Expect<T>.its: Expect<T> get() : Expect<T> = this
/**
* Expects that the subject of the assertion is not (equal to) [expected] and [otherValues].
* Expects that the subject of the assertion is not (equal to) in [values].
*
* @param values The values which are not expected to be contained within the subject of the assertion
* -- use the function `values(t, ...)` to create a [Values].
*
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.13.0
*/
inline fun <reified T> Expect<T>.isNoneOf(expected: T, vararg otherValues: T): Expect<T> =
_logicAppend { isNotIn(expected glue otherValues) }
infix fun <T> Expect<T>.isNoneOf(values: Values<T>): Expect<T> =
_logicAppend { isNotIn(values.toList()) }
/**
* Expects that the subject of the assertion is not (equal to) any value of [expected].
@@ -251,8 +254,8 @@ inline fun <reified T> Expect<T>.isNoneOf(expected: T, vararg otherValues: T): E
*
* @since 0.13.0
*/
inline fun <reified T> Expect<T>.isNotIn(expected: IterableLike): Expect<T> {
inline infix fun <reified T> Expect<T>.isNotIn(expected: IterableLike): Expect<T> {
val iterable = iterableLikeToIterable<T>(expected)
require(iterable.iterator().hasNext()) { "Iterable without elements are not allowed for this function." }
require(iterable.iterator().hasNext()) { "IterableLike without elements are not allowed for this function." }
return _logicAppend { isNotIn(iterable.toList()) }
}

View File

@@ -2,6 +2,7 @@ package ch.tutteli.atrium.api.infix.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.fun2
import ch.tutteli.atrium.specs.notImplemented
import ch.tutteli.atrium.specs.testutils.WithAsciiReporter
import ch.tutteli.atrium.specs.withFeatureSuffix
@@ -25,6 +26,14 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
fun1(Expect<DataClass>::isNotSameAs),
fun1(Expect<Int?>::isNotSameAs).withNullableSuffix(),
fun1(Expect<DataClass?>::isNotSameAs).withNullableSuffix(),
fun2(Companion::isNoneOfInt),
fun2(Companion::isNoneOfDataClass),
fun2(Companion::isNoneOfIntNullable).withNullableSuffix(),
fun2(Companion::isNoneOfDataClassNullable).withNullableSuffix(),
fun1(Expect<Int>::isNotIn),
fun1(Expect<DataClass>::isNotIn),
fun1(Expect<Int?>::isNotIn).withNullableSuffix(),
fun1(Expect<DataClass?>::isNotIn).withNullableSuffix(),
"${Expect<Int?>::toBe.name}(null)" to Companion::toBeNull,
fun1(Expect<Int?>::toBeNullIfNullGivenElse),
@@ -39,10 +48,11 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
"notToBeNull" to Companion::notToBeNull,
getAndImmediatePair(),
getAndLazyPair()
getAndLazyPair(),
"- "
) {
companion object : WithAsciiReporter(){
companion object : WithAsciiReporter() {
private fun toBeNull(expect: Expect<Int?>) = expect toBe null
@Suppress("RemoveExplicitTypeArguments")
@@ -81,6 +91,18 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
private fun notToBeNull(expect: Expect<Int?>, assertionCreator: Expect<Int>.() -> Unit) =
expect notToBeNull assertionCreator
private fun isNoneOfInt(expect: Expect<Int>, expected: Int, otherValues: Array<out Int>): Expect<Int> =
expect isNoneOf values(expected, *otherValues)
private fun isNoneOfIntNullable(expect: Expect<Int?>, expected: Int?, otherValues: Array<out Int?>): Expect<Int?> =
expect isNoneOf values(expected, *otherValues)
private fun isNoneOfDataClass(expect: Expect<DataClass>, expected: DataClass, otherValues: Array<out DataClass>): Expect<DataClass> =
expect isNoneOf values(expected, *otherValues)
private fun isNoneOfDataClassNullable(expect: Expect<DataClass?>, expected: DataClass?, otherValues: Array<out DataClass?>): Expect<DataClass?> =
expect isNoneOf values(expected, *otherValues)
}
@Suppress("unused")
@@ -98,6 +120,8 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
a1 isNotSameAs 1.2
a1.isA<Int>()
a1.isA<Int> {}
a1 isNoneOf values(1, 2)
a1 isNotIn listOf(1, 1.2)
a1b toBe 1
a1b toBe 1.2
@@ -109,6 +133,8 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
a1b isNotSameAs 1.2
a1b.isA<Int>()
a1b.isA<Int> {}
a1b isNoneOf values(1, 2)
a1b isNotIn listOf(1, 1.2)
a1b notToBeNull o toBe 1
a1b notToBeNull {}

View File

@@ -2,6 +2,7 @@ package ch.tutteli.atrium.logic.impl
import ch.tutteli.atrium.assertions.Assertion
import ch.tutteli.atrium.assertions.builders.assertionBuilder
import ch.tutteli.atrium.core.trueProvider
import ch.tutteli.atrium.creating.AssertionContainer
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.creating.changers.ChangedSubjectPostStep
@@ -54,8 +55,13 @@ class DefaultAnyAssertions : AnyAssertions {
.downCastTo(subType)
.build()
override fun <T> isNotIn(container: AssertionContainer<T>, expected: List<T>): Assertion {
val assertions = expected.map { assertionBuilder.representationOnly.failing.withRepresentation(it).build() }
override fun <T> isNotIn(container: AssertionContainer<T>, expected: Iterable<T>): Assertion {
val assertions = expected.map { value ->
assertionBuilder.representationOnly
.withTest(container) { it != value }
.withRepresentation(value)
.build()
}
return assertionBuilder.list
.withDescriptionAndEmptyRepresentation(IS_NONE_OF)
.withAssertions(assertions)

View File

@@ -52,7 +52,7 @@ inline fun <reified T> iterableLikeToIterable(iterableLike: IterableLike): Itera
is FloatArray -> iterableLike.map { it as T }
is DoubleArray -> iterableLike.map { it as T }
is BooleanArray -> iterableLike.map { it as T }
else -> throw IllegalArgumentException("toVarArg accepts arguments of types Iterable, Sequence, Array")
else -> throw IllegalArgumentException("iterableLikeToIterable accepts arguments of types Iterable, Sequence, Array")
}
inline fun <reified T> iterableToPair(iterable: Iterable<T>): Pair<T, Array<out T>> {

View File

@@ -32,6 +32,14 @@ abstract class AnyAssertionsSpec(
isNotSameDataClass: Fun1<DataClass, DataClass>,
isNotSameNullableInt: Fun1<Int?, Int?>,
isNotSameNullableDataClass: Fun1<DataClass?, DataClass?>,
isNoneOfInt: Fun2<Int, Int, Array<out Int>>,
isNoneOfDataClass: Fun2<DataClass, DataClass, Array<out DataClass>>,
isNoneOfNullableInt: Fun2<Int?, Int?, Array<out Int?>>,
isNoneOfNullableDataClass: Fun2<DataClass?, DataClass?, Array<out DataClass?>>,
isNotInInt: Fun1<Int, Iterable<Int>>,
isNotInDataClass: Fun1<DataClass, Iterable<DataClass>>,
isNotInNullableInt: Fun1<Int?, Iterable<Int?>>,
isNotInNullableDataClass: Fun1<DataClass?, Iterable<DataClass?>>,
toBeNull: Fun0<Int?>,
toBeNullIfNullGivenElse: Fun1<Int?, (Expect<Int>.() -> Unit)?>,
@@ -49,6 +57,7 @@ abstract class AnyAssertionsSpec(
andPair: Fun0<Int>,
andLazyPair: Fun1<Int, Expect<Int>.() -> Unit>,
listBulletPoint: String,
describePrefix: String = "[Atrium] "
) : Spek({
@@ -58,6 +67,8 @@ abstract class AnyAssertionsSpec(
notToBeInt.forSubjectLess(1),
isSameInt.forSubjectLess(1),
isNotSameInt.forSubjectLess(1),
isNoneOfInt.forSubjectLess(1, emptyArray()),
isNotInInt.forSubjectLess(listOf(1)),
andPair.forSubjectLess(),
andLazyPair.forSubjectLess { toBe(1) }
) {})
@@ -68,6 +79,8 @@ abstract class AnyAssertionsSpec(
notToBeNullableInt.forSubjectLess(1),
isSameNullableInt.forSubjectLess(1),
isNotSameNullableInt.forSubjectLess(1),
isNoneOfNullableInt.forSubjectLess(1, emptyArray()),
isNotInNullableInt.forSubjectLess(listOf(1)),
toBeNull.forSubjectLess(),
isAIntFeature.forSubjectLess(),
isAInt.forSubjectLess { toBe(1) },
@@ -107,13 +120,17 @@ abstract class AnyAssertionsSpec(
toBe: Fun1<T, Int>,
notToBe: Fun1<T, Int>,
isSame: Fun1<T, Int>,
isNotSame: Fun1<T, Int>
isNotSame: Fun1<T, Int>,
isNoneOf: Fun2<T, Int, Array<Int>>,
isNotIn: Fun1<T, Iterable<Int>>
) {
context(description) {
val toBeFun = toBe.lambda
val notToBeFun = notToBe.lambda
val isSameFun = isSame.lambda
val isNotSameFun = isNotSame.lambda
val isNoneOfFun = isNoneOf.lambda
val isNotInFun = isNotIn.lambda
context("one equals the other") {
it("${toBe.name} does not throw") {
@@ -151,6 +168,36 @@ abstract class AnyAssertionsSpec(
expectSubject.isNotSameFun(2)
}
}
context("one equals only one of the others") {
it("${isNoneOf.name} throws AssertionError") {
expect {
expectSubject.isNoneOfFun(1, arrayOf(2))
}.toThrow<AssertionError> {
message {
contains(IS_NONE_OF.getDefault(), "${listBulletPoint}1")
containsNot("$listBulletPoint 2")
}
}
}
it("${isNotIn.name} throws AssertionError") {
expect {
expectSubject.isNotInFun(listOf(1, 2))
}.toThrow<AssertionError> {
message {
contains(IS_NONE_OF.getDefault(), "${listBulletPoint}1")
containsNot("$listBulletPoint 2")
}
}
}
}
context("one does not equal to any of the others") {
it("${isNoneOf.name} does not throw") {
expectSubject.isNoneOfFun(2, arrayOf(3))
}
it("${isNotIn.name} does not throw") {
expectSubject.isNotInFun(listOf(2, 3))
}
}
}
}
@@ -161,12 +208,16 @@ abstract class AnyAssertionsSpec(
notToBe: Fun1<T, DataClass>,
isSame: Fun1<T, DataClass>,
isNotSame: Fun1<T, DataClass>,
isNoneOf: Fun2<T, DataClass, Array<DataClass>>,
isNotIn: Fun1<T, Iterable<DataClass>>,
test: DataClass
) {
val toBeFun = toBe.lambda
val notToBeFun = notToBe.lambda
val isSameFun = isSame.lambda
val isNotSameFun = isNotSame.lambda
val isNoneOfFun = isNoneOf.lambda
val isNotInFun = isNotIn.lambda
context(description) {
context("same") {
@@ -186,6 +237,16 @@ abstract class AnyAssertionsSpec(
expectSubject.isNotSameFun(test)
}.toThrow<AssertionError>()
}
it("${isNoneOf.name} throws AssertionError") {
expect {
expectSubject.isNoneOfFun(test, emptyArray())
}.toThrow<AssertionError> { messageContains(IS_NONE_OF.getDefault()) }
}
it("${isNotIn.name} throws AssertionError") {
expect {
expectSubject.isNotInFun(listOf(test))
}.toThrow<AssertionError> { messageContains(IS_NONE_OF.getDefault()) }
}
}
context("not same but one equals the other") {
val other = DataClass(true)
@@ -205,6 +266,16 @@ abstract class AnyAssertionsSpec(
it("${isNotSame.name} does not throw") {
expectSubject.isNotSameFun(other)
}
it("${isNoneOf.name} throws AssertionError") {
expect {
expectSubject.isNoneOfFun(other, emptyArray())
}.toThrow<AssertionError> { messageContains(IS_NONE_OF.getDefault()) }
}
it("${isNotIn.name} throws AssertionError") {
expect {
expectSubject.isNotInFun(listOf(other))
}.toThrow<AssertionError> { messageContains(IS_NONE_OF.getDefault()) }
}
}
context("one does not equal the other") {
val other = DataClass(false)
@@ -224,6 +295,12 @@ abstract class AnyAssertionsSpec(
it("${isNotSame.name} does not throw") {
expectSubject.isNotSameFun(other)
}
it("${isNoneOf.name} does not throw") {
expectSubject.isNoneOfFun(other, emptyArray())
}
it("${isNotIn.name} does not throw") {
expectSubject.isNotInFun(listOf(other))
}
}
}
}
@@ -234,13 +311,18 @@ abstract class AnyAssertionsSpec(
notToBe: Fun1<T?, T?>,
isSame: Fun1<T?, T?>,
isNotSame: Fun1<T?, T?>,
value: T
isNoneOf: Fun2<T?, T?, Array<T?>>,
isNotIn: Fun1<T?, Iterable<T?>>,
value: T,
emptyArray: Array<T?>
) {
val toBeFun = toBe.lambda
val notToBeFun = notToBe.lambda
val isSameFun = isSame.lambda
val isNotSameFun = isNotSame.lambda
val isNoneOfFun = isNoneOf.lambda
val isNotInFun = isNotIn.lambda
val expectSubject = expect(null as T?)
context(description) {
@@ -261,6 +343,16 @@ abstract class AnyAssertionsSpec(
expectSubject.isNotSameFun(null)
}.toThrow<AssertionError> { messageContains(IS_NOT_SAME.getDefault()) }
}
it("${isNoneOf.name} throws AssertionError") {
expect {
expectSubject.isNoneOfFun(null, emptyArray)
}.toThrow<AssertionError> { messageContains(IS_NONE_OF.getDefault()) }
}
it("${isNotIn.name} throws AssertionError") {
expect {
expectSubject.isNotInFun(listOf(null))
}.toThrow<AssertionError> { messageContains(IS_NONE_OF.getDefault()) }
}
}
context("one does not equal the other") {
it("${toBe.name} throws AssertionError") {
@@ -281,19 +373,27 @@ abstract class AnyAssertionsSpec(
it("${isNotSame.name} does not throw") {
expectSubject.isNotSameFun(value)
}
it("${isNoneOf.name} does not throw") {
expectSubject.isNoneOfFun(value, emptyArray)
}
it("${isNotIn.name} does not throw") {
expectSubject.isNotInFun(listOf(value))
}
}
}
}
describeFun(toBeInt, notToBeInt, isSameInt, isNotSameInt) {
checkInt("primitive", expect(1), toBeInt, notToBeInt, isSameInt, isNotSameInt)
describeFun(toBeInt, notToBeInt, isSameInt, isNotSameInt, isNoneOfInt, isNotInInt) {
checkInt("primitive", expect(1), toBeInt, notToBeInt, isSameInt, isNotSameInt, isNoneOfInt, isNotInInt)
checkInt(
"nullable primitive",
expect(1 as Int?),
toBeNullableInt,
notToBeNullableInt,
isSameNullableInt,
isNotSameNullableInt
isNotSameNullableInt,
isNoneOfNullableInt,
isNotInNullableInt
)
val subject = DataClass(true)
@@ -304,6 +404,8 @@ abstract class AnyAssertionsSpec(
notToBeDataClass,
isSameDataClass,
isNotSameDataClass,
isNoneOfDataClass,
isNotInDataClass,
subject
)
checkDataClass(
@@ -313,6 +415,8 @@ abstract class AnyAssertionsSpec(
notToBeNullableDataClass,
isSameNullableDataClass,
isNotSameNullableDataClass,
isNoneOfNullableDataClass,
isNotInNullableDataClass,
subject
)
@@ -322,7 +426,10 @@ abstract class AnyAssertionsSpec(
notToBeNullableInt,
isSameNullableInt,
isNotSameNullableInt,
2
isNoneOfNullableInt,
isNotInNullableInt,
2,
emptyArray<Int?>()
)
checkNull(
"null as DataClass?",
@@ -330,7 +437,10 @@ abstract class AnyAssertionsSpec(
notToBeNullableDataClass,
isSameNullableDataClass,
isNotSameNullableDataClass,
subject
isNoneOfNullableDataClass,
isNotInNullableDataClass,
subject,
emptyArray<DataClass?>()
)
}
@@ -503,7 +613,7 @@ abstract class AnyAssertionsSpec(
expect(i).notToBeNullFun { isGreaterThan(2); isLessThan(0) }
}.toThrow<AssertionError> {
messageContains(IS_GREATER_THAN.getDefault())
if(hasExtraHint) messageContains(IS_LESS_THAN.getDefault())
if (hasExtraHint) messageContains(IS_LESS_THAN.getDefault())
}
}
}

View File

@@ -38,7 +38,7 @@ abstract class IterableLikeSpec<T>(
expect {
expect(subject).funIterableLike("test")
}.toThrow<IllegalArgumentException> {
messageContains("toVarArg accepts arguments of types Iterable, Sequence, Array")
messageContains("iterableLikeToIterable accepts arguments of types Iterable, Sequence, Array")
}
}
}