Merge pull request #952 from robstoll/notToContainDuplicates

rename notToContainDuplicates to toHaveElementsAndNoDuplicates
This commit is contained in:
Robert Stoll
2021-07-10 15:19:02 +02:00
committed by GitHub
9 changed files with 113 additions and 117 deletions

View File

@@ -372,8 +372,8 @@ fun <E, T : Iterable<E>> Expect<T>.hasNotNext(): Expect<T> =
* @since 0.14.0
*/
@Deprecated(
"Use notToContainDuplicates; will be removed with 1.0.0 at the latest",
ReplaceWith("this.notToContainDuplicates<E, T>()")
"Use toHaveElementsAndNoDuplicates; will be removed with 1.0.0 at the latest",
ReplaceWith("this.toHaveElementsAndNoDuplicates<E, T>()")
)
fun <E, T : Iterable<E>> Expect<T>.containsNoDuplicates(): Expect<T> =
_logicAppend { containsNoDuplicates(::identity) }

View File

@@ -234,6 +234,31 @@ inline fun <reified E, T : Iterable<E>> Expect<T>.toContainElementsOf(
fun <E, T : Iterable<E>> Expect<T>.notToContain(expected: E, vararg otherExpected: E): Expect<T> =
notToContain.values(expected, *otherExpected)
/**
* Expects that the subject of `this` expectation (an [Iterable]) has a next element ([Iterator.hasNext] returns true).
*
* @return an [Expect] for the subject of `this` expectation.
*
* @sample ch.tutteli.atrium.api.fluent.en_GB.samples.IterableExpectationSamples.toHaveElements
*
* @since 0.17.0
*/
fun <E, T : Iterable<E>> Expect<T>.toHaveElements(): Expect<T> =
_logicAppend { hasNext(::identity) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) does not have a next element
* ([Iterator.hasNext] returns false).
*
* @return an [Expect] for the subject of `this` expectation.
*
* @sample ch.tutteli.atrium.api.fluent.en_GB.samples.IterableExpectationSamples.notToHaveElements
*
* @since 0.17.0
*/
fun <E, T : Iterable<E>> Expect<T>.notToHaveElements(): Expect<T> =
_logicAppend { hasNotNext(::identity) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) has next element(s) and
* - that any of them holds the expectations the [assertionCreatorOrNull] creates or
@@ -282,38 +307,14 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.toHaveElementsAndAll(assertionCreatorO
/**
* Expects that the subject of `this` expectation (an [Iterable]) has a next element ([Iterator.hasNext] returns true).
* Expects that the subject of `this` expectation (an [Iterable]) has next element(s) and
* that it does not have duplicate elements.
*
* @return an [Expect] for the subject of `this` expectation.
*
* @sample ch.tutteli.atrium.api.fluent.en_GB.samples.IterableExpectationSamples.toHaveElements
* @sample ch.tutteli.atrium.api.fluent.en_GB.samples.IterableExpectationSamples.toHaveElementsAndNoDuplicates
*
* @since 0.17.0
*/
fun <E, T : Iterable<E>> Expect<T>.toHaveElements(): Expect<T> =
_logicAppend { hasNext(::identity) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) does not have a next element
* ([Iterator.hasNext] returns false).
*
* @return an [Expect] for the subject of `this` expectation.
*
* @sample ch.tutteli.atrium.api.fluent.en_GB.samples.IterableExpectationSamples.notToHaveElements
*
* @since 0.17.0
*/
fun <E, T : Iterable<E>> Expect<T>.notToHaveElements(): Expect<T> =
_logicAppend { hasNotNext(::identity) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) does not have duplicate elements.
*
* @return an [Expect] for the subject of `this` expectation.
*
* @sample ch.tutteli.atrium.api.fluent.en_GB.samples.IterableExpectationSamples.notToContainDuplicates
*
* @since 0.17.0
*/
fun <E, T : Iterable<E>> Expect<T>.notToContainDuplicates(): Expect<T> =
fun <E, T : Iterable<E>> Expect<T>.toHaveElementsAndNoDuplicates(): Expect<T> =
_logicAppend { containsNoDuplicates(::identity) }

View File

@@ -10,7 +10,7 @@ object IterableExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableEx
fun1<Iterable<Int>, Expect<Int>.() -> Unit>(Expect<Iterable<Int>>::min),
feature0<Iterable<Int>, Int>(Expect<Iterable<Int>>::max),
fun1<Iterable<Int>, Expect<Int>.() -> Unit>(Expect<Iterable<Int>>::max),
fun0(Expect<Iterable<Int>>::notToContainDuplicates)
fun0(Expect<Iterable<Int>>::toHaveElementsAndNoDuplicates)
) {
@Suppress("unused", "UNUSED_VALUE")
@@ -21,15 +21,15 @@ object IterableExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableEx
a1 = a1.toHaveElements()
a1 = a1.notToHaveElements()
a1 = a1.notToContainDuplicates()
a1 = a1.toHaveElementsAndNoDuplicates()
a1b = a1b.toHaveElements()
a1b = a1b.notToHaveElements()
a1b = a1b.notToContainDuplicates()
a1b = a1b.toHaveElementsAndNoDuplicates()
star = star.toHaveElements()
star = star.notToHaveElements()
star = star.notToContainDuplicates()
star = star.toHaveElementsAndNoDuplicates()
//nullable not supported by min/max or rather T : Comparable<T> does not exist for T? (one cannot implement an interface for the nullable type)
//same for Iterable<*>

View File

@@ -162,6 +162,25 @@ class IterableExpectationSamples {
}
}
@Test
fun toHaveElements() {
expect(listOf("A", 1, 3f)).toHaveElements()
fails {
expect(emptyList<Int>()).toHaveElements()
}
}
@Test
fun notToHaveElements() {
expect(setOf<String>()).notToHaveElements()
fails {
expect(listOf("A", "B")).notToHaveElements()
}
}
@Test
fun toHaveElementsAndAny() {
expect(listOf(1, 2, 2, 4)).toHaveElementsAndAny {
@@ -212,30 +231,13 @@ class IterableExpectationSamples {
}
}
@Test
fun toHaveElements() {
expect(listOf("A", 1, 3f)).toHaveElements()
fails {
expect(emptyList<Int>()).toHaveElements()
}
}
@Test
fun notToHaveElements() {
expect(setOf<String>()).notToHaveElements()
fun toHaveElementsAndNoDuplicates() {
expect(listOf("A", "B")).toHaveElementsAndNoDuplicates()
fails {
expect(listOf("A", "B")).notToHaveElements()
}
}
@Test
fun notToContainDuplicates() {
expect(listOf("A", "B")).notToContainDuplicates()
fails {
expect(listOf("A", "B", "C", "A")).notToContainDuplicates()
expect(listOf("A", "B", "C", "A")).toHaveElementsAndNoDuplicates()
}
}
}

View File

@@ -419,8 +419,8 @@ infix fun <E, T : Iterable<E>> Expect<T>.hasNot(@Suppress("UNUSED_PARAMETER") ne
* @since 0.14.0
*/
@Deprecated(
"Use notToContainDuplicates; will be removed with 1.0.0 at the latest",
ReplaceWith("this.notToContain<E, T>(duplicates)", "ch.tutteli.atrium.api.infix.en_GB.duplicates")
"Use toHaveElementsAnd noDuplicates; will be removed with 1.0.0 at the latest",
ReplaceWith("this.toHaveElementsAnd<E, T>(noDuplicates)")
)
@Suppress("DEPRECATION")
infix fun <E, T : Iterable<E>> Expect<T>.contains(@Suppress("UNUSED_PARAMETER") noDuplicates: noDuplicates): Expect<T> =

View File

@@ -259,6 +259,26 @@ infix fun <E, T : Iterable<E>> Expect<T>.notToContain(expected: E): Expect<T> =
infix fun <E, T : Iterable<E>> Expect<T>.notToContain(values: Values<E>): Expect<T> =
it notToContain o the values
/**
* Expects that the subject of `this` expectation (an [Iterable]) has at least one element.
*
* @return an [Expect] for the subject of `this` expectation.
*
* @since 0.17.0
*/
infix fun <E, T : Iterable<E>> Expect<T>.toHave(@Suppress("UNUSED_PARAMETER") elements: elements): Expect<T> =
_logicAppend { hasNext(::identity) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) does not have next element.
*
* @return an [Expect] for the subject of `this` expectation.
*
* @since 0.17.0
*/
infix fun <E, T : Iterable<E>> Expect<T>.notToHave(@Suppress("UNUSED_PARAMETER") elements: elements): Expect<T> =
_logicAppend { hasNotNext(::identity) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) contains an entry holding
@@ -302,26 +322,6 @@ infix fun <E : Any, T : Iterable<E?>> Expect<T>.toHaveElementsAndAll(assertionCr
_logicAppend { all(::identity, assertionCreatorOrNull) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) has at least one element.
*
* @return an [Expect] for the subject of `this` expectation.
*
* @since 0.17.0
*/
infix fun <E, T : Iterable<E>> Expect<T>.toHave(@Suppress("UNUSED_PARAMETER") elements: elements): Expect<T> =
_logicAppend { hasNext(::identity) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) does not have next element.
*
* @return an [Expect] for the subject of `this` expectation.
*
* @since 0.17.0
*/
infix fun <E, T : Iterable<E>> Expect<T>.notToHave(@Suppress("UNUSED_PARAMETER") elements: elements): Expect<T> =
_logicAppend { hasNotNext(::identity) }
/**
* Expects that the subject of `this` expectation (an [Iterable]) does not have duplicate elements.
*
@@ -329,6 +329,6 @@ infix fun <E, T : Iterable<E>> Expect<T>.notToHave(@Suppress("UNUSED_PARAMETER")
*
* @since 0.17.0
*/
infix fun <E, T : Iterable<E>> Expect<T>.notToContain(@Suppress("UNUSED_PARAMETER") duplicates: duplicates): Expect<T> =
infix fun <E, T : Iterable<E>> Expect<T>.toHaveElementsAnd(@Suppress("UNUSED_PARAMETER") noDuplicates: noDuplicates): Expect<T> =
_logicAppend { containsNoDuplicates(::identity) }

View File

@@ -168,17 +168,8 @@ object executable : Keyword
*
* @since 0.14.0
*/
@Deprecated("Will be removed with 1.0.0 at the latest without replacement")
object noDuplicates : Keyword
/**
* A helper construct to allow expressing expectations about duplicates as in `expect(iterable) notToContain duplicates`.
* It can be used for a parameterless function so that it has one parameter and thus can be used as infix function.
*
* @since 0.17.0
*/
object duplicates : Keyword
/**
* A helper construct to allow expressing expectations about elements as in `expect(iterable) toHave elements`.
* It can be used for a parameterless function so that it has one parameter and thus can be used as infix function.

View File

@@ -6,22 +6,22 @@ import kotlin.reflect.KFunction2
class IterableExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableExpectationsSpec(
getToHaveElementsPair(),
getNotToHaveElementstPair(),
getNotToHaveElementsPair(),
minFeaturePair(),
fun1<Iterable<Int>, Expect<Int>.() -> Unit>(Expect<Iterable<Int>>::min),
maxFeaturePair(),
fun1<Iterable<Int>, Expect<Int>.() -> Unit>(Expect<Iterable<Int>>::max),
getToContainNoDuplicatesPair()
getToHaveElementsAndNoDuplicatesPair()
) {
companion object {
private val toHave: KFunction2<Expect<Iterable<Int>>, elements, Expect<Iterable<Int>>> = Expect<Iterable<Int>>::toHave
private fun getToHaveElementsPair() = "${toHave.name} ${next::class.simpleName}" to Companion::toHaveElements
private fun getToHaveElementsPair() = "${toHave.name} ${elements::class.simpleName}" to Companion::toHaveElements
private fun toHaveElements(expect: Expect<Iterable<Int>>) = expect toHave elements
private val notToHave: KFunction2<Expect<Iterable<Int>>, elements, Expect<Iterable<Int>>> =
Expect<Iterable<Int>>::notToHave
private fun getNotToHaveElementstPair() = "${notToHave.name} ${next::class.simpleName}" to Companion::notToHaveElements
private fun getNotToHaveElementsPair() = "${notToHave.name} ${elements::class.simpleName}" to Companion::notToHaveElements
private fun notToHaveElements(expect: Expect<Iterable<Int>>) = expect notToHave elements
private fun minFeaturePair() = feature1<Iterable<Int>, o, Int>(Expect<Iterable<Int>>::min).name to ::minFeature
@@ -30,13 +30,13 @@ class IterableExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableExp
private fun maxFeaturePair() = feature1<Iterable<Int>, o, Int>(Expect<Iterable<Int>>::min).name to ::maxFeature
private fun maxFeature(expect: Expect<Iterable<Int>>) = expect max o
private val notToContainDuplicates: KFunction2<Expect<Iterable<Int>>, duplicates, Expect<Iterable<Int>>> =
Expect<Iterable<Int>>::notToContain
private val toHaveElementsAnd: KFunction2<Expect<Iterable<Int>>, noDuplicates, Expect<Iterable<Int>>> =
Expect<Iterable<Int>>::toHaveElementsAnd
private fun getToContainNoDuplicatesPair() =
"${notToContainDuplicates.name} ${duplicates::class.simpleName}" to Companion::toContainNoDuplicates
private fun getToHaveElementsAndNoDuplicatesPair() =
"${toHaveElementsAnd.name} ${noDuplicates::class.simpleName}" to Companion::toHaveElementsAndNoDuplicates
private fun toContainNoDuplicates(expect: Expect<Iterable<Int>>) = expect notToContain duplicates
private fun toHaveElementsAndNoDuplicates(expect: Expect<Iterable<Int>>) = expect toHaveElementsAnd noDuplicates
}
@@ -48,15 +48,15 @@ class IterableExpectationsSpec : ch.tutteli.atrium.specs.integration.IterableExp
a1 = a1 toHave elements
a1 = a1 notToHave elements
a1 = a1 notToContain duplicates
a1 = a1 toHaveElementsAnd noDuplicates
a1b = a1b toHave elements
a1b = a1b notToHave elements
a1b = a1b notToContain duplicates
a1b = a1b toHaveElementsAnd noDuplicates
star = star toHave elements
star = star notToHave elements
star = star notToContain duplicates
star = star toHaveElementsAnd noDuplicates
//nullable not supported by min/max or rather T : Comparable<T> does not exist for T? (one cannot implement an interface for the nullable type)
//same for Iterable<*>

View File

@@ -11,23 +11,25 @@ import org.spekframework.spek2.Spek
import org.spekframework.spek2.style.specification.Suite
abstract class IterableExpectationsSpec(
toHaveANextElement: Fun0<Iterable<Int>>,
notToHaveANextElement: Fun0<Iterable<Int>>,
toHaveElements: Fun0<Iterable<Int>>,
notToHaveElements: Fun0<Iterable<Int>>,
minFeature: Feature0<Iterable<Int>, Int>,
min: Fun1<Iterable<Int>, Expect<Int>.() -> Unit>,
maxFeature: Feature0<Iterable<Int>, Int>,
max: Fun1<Iterable<Int>, Expect<Int>.() -> Unit>,
notToContainDuplicates: Fun0<Iterable<Int>>,
toHaveElementsAndNoDuplicates: Fun0<Iterable<Int>>,
describePrefix: String = "[Atrium] "
) : Spek({
include(object : SubjectLessSpec<Iterable<Int>>(
describePrefix,
toHaveANextElement.forSubjectLess(),
toHaveElements.forSubjectLess(),
notToHaveElements.forSubjectLess(),
minFeature.forSubjectLess(),
min.forSubjectLess { toBeGreaterThan(-100) },
maxFeature.forSubjectLess(),
max.forSubjectLess { toEqual(1) }
max.forSubjectLess { toEqual(1) },
toHaveElementsAndNoDuplicates.forSubjectLess()
) {})
include(object : AssertionCreatorSpec<Iterable<Int>>(
@@ -46,30 +48,30 @@ abstract class IterableExpectationsSpec(
val hasANextElement = "$hasDescr: $nextElementDescr"
describeFun(toHaveANextElement) {
val toHaveANextElementFun = toHaveANextElement.lambda
describeFun(toHaveElements) {
val toHaveElementsFun = toHaveElements.lambda
it("does not throw if an iterable has next") {
expect(listOf(1, 2) as Iterable<Int>).toHaveANextElementFun()
expect(listOf(1, 2) as Iterable<Int>).toHaveElementsFun()
}
it("throws an AssertionError if an iterable does not have next") {
expect {
expect(listOf<Int>() as Iterable<Int>).toHaveANextElementFun()
expect(listOf<Int>() as Iterable<Int>).toHaveElementsFun()
}.toThrow<AssertionError> { messageToContain(hasANextElement) }
}
}
describeFun(notToHaveANextElement) {
val notToHaveANextElementFun = notToHaveANextElement.lambda
describeFun(notToHaveElements) {
val notToHaveElementsFun = notToHaveElements.lambda
it("does not throw if an iterable has not next") {
expect(listOf<Int>() as Iterable<Int>).notToHaveANextElementFun()
expect(listOf<Int>() as Iterable<Int>).notToHaveElementsFun()
}
it("throws an AssertionError if an iterable has next element") {
expect {
expect(listOf(1, 2) as Iterable<Int>).notToHaveANextElementFun()
expect(listOf(1, 2) as Iterable<Int>).notToHaveElementsFun()
}.toThrow<AssertionError> { messageToContain("$hasNotDescr: $nextElementDescr") }
}
}
@@ -131,17 +133,17 @@ abstract class IterableExpectationsSpec(
}
}
describeFun(notToContainDuplicates) {
val notToContainDuplicatesFun = notToContainDuplicates.lambda
describeFun(toHaveElementsAndNoDuplicates) {
val toHaveElementsAndNoDuplicatesFun = toHaveElementsAndNoDuplicates.lambda
describe("empty collection") {
it("throws AssertionError as there needs to be at least one element") {
expect {
expect(listOf<Int>() as Iterable<Int>).notToContainDuplicatesFun()
expect(listOf<Int>() as Iterable<Int>).toHaveElementsAndNoDuplicatesFun()
}.toThrow<AssertionError> {
message {
toContain(
"$hasANextElement",
hasANextElement,
"$hasNotDescr: $duplicateElements"
)
}
@@ -151,7 +153,7 @@ abstract class IterableExpectationsSpec(
describe("list without duplicates") {
it("happy case") {
expect(listOf(1, 2) as Iterable<Int>).notToContainDuplicatesFun()
expect(listOf(1, 2) as Iterable<Int>).toHaveElementsAndNoDuplicatesFun()
}
}
@@ -164,7 +166,7 @@ abstract class IterableExpectationsSpec(
val input = listOf(1, 2, 1, 2, 3, 4, 4, 4).asIterable()
expect {
expect(input).notToContainDuplicatesFun()
expect(input).toHaveElementsAndNoDuplicatesFun()
}.toThrow<AssertionError> {
message {
toContain("$hasNotDescr: $duplicateElements")