Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add assertions for sequences #159

Merged
merged 9 commits into from
Nov 17, 2019
75 changes: 72 additions & 3 deletions common/src/main/kotlin/org/amshove/kluent/Collections.kt
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,70 @@ infix fun <I : Iterable<*>> I.shouldHaveSize(expectedSize: Int) = apply {
}
}

private fun <T> areSequencesEqual(sequence1: Sequence<T>, sequence2: Sequence<T>): Boolean {
val iterator1 = sequence1.iterator()
val iterator2 = sequence2.iterator()

while (iterator1.hasNext() && iterator2.hasNext()) {
if (iterator1.next() != iterator2.next()) return false
}

return !iterator1.hasNext() && !iterator2.hasNext()
}

@Deprecated("Equality should not be tested on sequences", level = DeprecationLevel.ERROR)
infix fun <T, S : Sequence<T>> S.shouldEqual(expected: Sequence<T>): S =
fail("Equality should not be tested on sequences")

@Deprecated("Equality should not be tested on sequences", level = DeprecationLevel.ERROR)
infix fun <T, S : Sequence<T>> S.shouldNotEqual(expected: Sequence<T>): S =
fail("Equality should not be tested on sequences")

fun <S : Sequence<*>> S.shouldBeEmpty(): S = apply { assertEmpty(asIterable(), "Sequence") }
fun <S : Sequence<*>> S.shouldNotBeEmpty(): S = apply { assertNotEmpty(asIterable(), "Sequence") }

infix fun <T, S : Sequence<T>> S.shouldContain(expected: T): S = apply {
if (expected !in this)
failExpectedActual("Sequence doesn't contain \"$expected\"", "the Sequence to contain \"$expected\"", join(asIterable()))
}

infix fun <S, I : Sequence<S>> I.shouldNotContain(expected: S): I = apply {
if (expected in this)
failExpectedActual("Sequence should not contain \"$expected\"", "the Sequence to not contain \"$expected\"", join(asIterable()))
}

infix fun <T, S : Sequence<T>> S.shouldContainAll(expected: Sequence<T>): S = apply {
val set = toHashSet()
expected.forEach {
if (it !in set)
failExpectedActual("Sequence doesn't contain \"$expected\"", "the Sequence to contain \"$expected\"", join(asIterable()))
}
}

infix fun <T, S : Sequence<T>> S.shouldContainNone(expected: Sequence<T>): S = apply {
assertTrue(none { it in expected }) {
"Expected Sequence to contain none of \"${join(expected.asIterable())}\""
}
}

infix fun <T, S : Sequence<T>> S.shouldContainSome(expected: Sequence<T>): S = apply {
val expectedSet = expected.toHashSet()
assertTrue(any { it in expectedSet }) { "Expected Iterable to contain at least one of \"$expected\"" }
}

fun <S : Sequence<T>, T> S.shouldHaveSingleItem(): T {
shouldHaveSize(1)
return first()
}

infix fun <S : Sequence<*>> S.shouldHaveSize(expectedSize: Int) = apply {
val actualSize = count()
assertTrue(actualSize == expectedSize) { "Expected collection size to be $expectedSize but was $actualSize" }
}

infix fun <T, S : Sequence<T>> S.shouldContainSame(expected: Sequence<T>): S =
assertBothIterablesContainsSame(expected.toList(), this.toList())

infix fun <K, M : Map<K, *>> M.shouldEqual(expected: M): M = apply { assertMapEquals(this, expected) }

infix fun <K, M : Map<K, *>> M.shouldNotEqual(expected: M): M = apply { assertMapNotEquals(this, expected) }
Expand Down Expand Up @@ -557,10 +621,15 @@ fun <E> Iterable<E>.shouldMatchAllWith(predicate: (E) -> Boolean): Iterable<E> {
return this
}

internal fun <T> assertEmpty(iterable: Iterable<T>, collectionType: String) = assertTrue("Expected the $collectionType to be empty, but has ${iterable.count()} elements", iterable.count() == 0)
internal fun <T> assertNotEmpty(iterable: Iterable<T>, collectionType: String) = assertTrue("Expected the $collectionType to contain elements, but is empty", iterable.count() > 0)
internal fun <T> assertEmpty(iterable: Iterable<T>, collectionType: String) {
assertTrue(iterable.none()) { "Expected the $collectionType to be empty, but has ${iterable.count()} elements" }
}

internal fun <T> assertNotEmpty(iterable: Iterable<T>, collectionType: String) {
assertTrue(iterable.any()) { "Expected the $collectionType to contain elements, but is empty" }
}

internal fun <T, I : Iterable<T>> I.assertBothIterablesContainsSame(expected: Iterable<T>, actual: Iterable<T>): I {
internal fun <T, C> C.assertBothIterablesContainsSame(expected: Iterable<T>, actual: Iterable<T>): C {
assertBothCollectionsContainsSame(expected.toList(), actual.toList())
return this
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.amshove.kluent.internal

import kotlin.test.assertTrue
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import kotlin.test.fail

internal fun assertTrue(message: String, boolean: Boolean) = assertTrue(boolean, message)
internal inline fun assertTrue(boolean: Boolean, lazyMessage: () -> String) {
if (!boolean) fail(lazyMessage())
}

internal fun assertFalse(message: String, boolean: Boolean) = assertFalse(boolean, message)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class ShouldBeEmptyShould {
iterable.shouldBeEmpty()
}

@Test
fun passWhenTestingAnEmptySequence() {
val sequence = emptySequence<String>()
sequence.shouldBeEmpty()
}

@Test
fun passWhenTestingAnEmptyMap() {
val map = mapOf<Int, String>()
Expand All @@ -33,6 +39,11 @@ class ShouldBeEmptyShould {
assertFails { listOf("Hi").shouldBeEmpty() }
}

@Test
fun failWhenTestingANonEmptySequence() {
assertFails { sequenceOf("Hi").shouldBeEmpty() }
}

@Test
fun failWhenTestingANonEmptyMap() {
assertFails { mapOf(1 to "Hi").shouldBeEmpty() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ class ShouldContainAllShould {
assertFails { set shouldContainAll setOf(5, 9) }
}

@Test
fun passWhenTestingASequenceWhichContainsAllValues() {
val sequence = sequenceOf(5, 8, 12)
sequence shouldContainAll sequenceOf(12, 8)
}

@Test
fun failWhenTestingASequenceWhichDoesNotContainAllValues() {
val sequence = sequenceOf(4, 9)
assertFails { sequence shouldContainAll sequenceOf(5, 9) }
}

@Test
fun passWhenTestingAMapWhichContainsAllValues() {
val map = mapOf('a' to 1, 'b' to 2, 'c' to 3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ class ShouldContainNoneShould {
assertFails { actual shouldContainNone cities }
}

@Test
fun passWhenTestingASequenceWhichDoesNotContainAtLeastOneElement() {
val cities = sequenceOf("Israel", "Phoenix", "Egypt")
val actual = sequenceOf("Berlin", "Stuttgart")

actual shouldContainNone cities
}

@Test
fun failWhenTestingASequenceWhichContainsAtLeastOneElement() {
val cities = sequenceOf("Israel", "Phoenix", "Stuttgart", "Egypt")
val actual = sequenceOf("Berlin", "Stuttgart")

assertFails { actual shouldContainNone cities }
}

@Test
fun passWhenTestingAPrimitiveIntegerArrayWhichDoesNotContainAtLeastOneElement() {
val theArray = intArrayOf(1, 5, 7, 13)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ class ShouldContainSameShould {
assertFails { set shouldContainSame setOf(4, 6) }
}

@Test
fun passWhenTestingASequenceWhichContainsSameValues() {
val sequence = sequenceOf(5, 8, 12)
sequence shouldContainSame sequenceOf(12, 8, 5)
}

@Test
fun failWhenTestingASequenceWhichDoesNotContainSameValues() {
val sequence = sequenceOf(4, 9)
assertFails { sequence shouldContainSame sequenceOf(4, 6) }
}

@Test
fun passWhenTestingAMapWhichContainsSameValues() {
val map = mapOf('a' to 1, 'b' to 2, 'c' to 3)
Expand Down Expand Up @@ -170,4 +182,4 @@ class ShouldContainSameShould {

anArray.shouldContainSame(anIterable)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.amshove.kluent.collections

import org.amshove.kluent.shouldContain
import org.amshove.kluent.Person
import kotlin.test.assertFails
import org.amshove.kluent.shouldContain
import kotlin.test.Test
import kotlin.test.assertFails

class ShouldContainShould {
@Test
Expand All @@ -26,6 +26,14 @@ class ShouldContainShould {
list shouldContain jon
}

@Test
fun passWhenTestingASequenceWhichContainsTheValue() {
val alice = Person("Alice", "Bob")
val jon = Person("Jon", "Doe")
val sequence = sequenceOf(alice, jon)
sequence shouldContain jon
}

@Test
fun failWhenTestingAnIterableWhichDoesNotContainTheValue() {
val alice = Person("Alice", "Bob")
Expand All @@ -34,6 +42,14 @@ class ShouldContainShould {
assertFails { list shouldContain jon }
}

@Test
fun failWhenTestingASequenceWhichDoesNotContainTheValue() {
val alice = Person("Alice", "Bob")
val jon = Person("Jon", "Doe")
val sequence = sequenceOf(alice)
assertFails { sequence shouldContain jon }
}

@Test
fun passWhenTestingAMapWhichContainsAPair() {
val map = mapOf(1 to "one", 2 to "two")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,35 @@ class ShouldContainSingleItemShould {
assertEquals("Hello", item)
}

@Test
fun notThrowWhenASequenceHasOneItem() {
val sequence = sequenceOf(1)
sequence.shouldHaveSingleItem()
}

@Test
fun failWhenASequenceIsEmpty() {
val sequence = emptySequence<Int>()
assertFails {
sequence.shouldHaveSingleItem()
}
}

@Test
fun failWhenASequenceHasMoreThanOneItem() {
val sequence = sequenceOf(1, 2, 3, 4, 5)
assertFails {
sequence.shouldHaveSingleItem()
}
}

@Test
fun returnTheItemInsideTheSequence() {
val sequence = sequenceOf("Hello")
val item = sequence.shouldHaveSingleItem()
assertEquals("Hello", item)
}

@Test
fun workWithArrays() {
val arr = arrayOf("World")
Expand All @@ -47,4 +76,4 @@ class ShouldContainSingleItemShould {
val arr = shortArrayOf(5)
arr.shouldHaveSingleItem().shouldEqual(5)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ class ShouldContainSomeShould {
assertFails { actual shouldContainSome cities }
}

@Test
fun passWhenTestingASequenceWhichContainsAtLeastOneElement() {
val cities = sequenceOf("Israel", "Berlin", "Phoenix", "Egypt")
val actual = sequenceOf("Berlin", "Stuttgart")

actual shouldContainSome cities
}

@Test
fun failWhenTestingASequenceWhichDoesNotContainAtLeastOneElement() {

val cities = sequenceOf("Israel", "Phoenix", "Egypt")
val actual = sequenceOf("Berlin", "Stuttgart")

assertFails { actual shouldContainSome cities }
}


@Test
fun passWhenTestingIfAListContainsASubsetOfAnArrayWhenItDoes() {

Expand Down Expand Up @@ -151,4 +169,4 @@ class ShouldContainSomeShould {
assertFails { theArray shouldContainSome listOf(false) }
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ class ShouldHaveSizeShould {
}
}

@Test
fun passWhenTestingASequenceWithTheCorrectSize() {
val sequence = sequenceOf("First", "valueIchi", "Second", "valueNi")
sequence.shouldHaveSize(4)
}

@Test
fun failWhenTestingASequenceWithAnIncorrectSize() {
val sequence = sequenceOf("First", "valueIchi", "Second", "valueNi")
assertFails {
sequence.shouldHaveSize(2)
}
}

@Test
fun workWithArrays() {
val arr = arrayOf(1, 2, 3, 4, 5)
Expand All @@ -36,4 +50,4 @@ class ShouldHaveSizeShould {
val intArray = intArrayOf(1, 2)
intArray.shouldHaveSize(2)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class ShouldNotBeEmptyShould {
iterable.shouldNotBeEmpty()
}

@Test
fun passWhenTestingANonEmptySequence() {
val sequence = sequenceOf("Hi")
sequence.shouldNotBeEmpty()
}

@Test
fun passWhenTestingANonEmptyMap() {
val map = mapOf(1 to "Hi")
Expand All @@ -35,6 +41,12 @@ class ShouldNotBeEmptyShould {
assertFails { iterable.shouldNotBeEmpty() }
}

@Test
fun failWhenTestingAnEmptySequence() {
val sequence: Sequence<String> = emptySequence()
assertFails { sequence.shouldNotBeEmpty() }
}

@Test
fun failWhenTestingAnEmptyMap() {
val map = mapOf<Int, String>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ class ShouldNotContainShould {
assertFails { list shouldNotContain jon }
}

@Test
fun passWhenTestingASequenceWhichDoesNotContainTheValue() {
val alice = Person("Alice", "Bob")
val jon = Person("Jon", "Doe")
val sequence = sequenceOf(alice)
sequence shouldNotContain jon
}

@Test
fun failWhenTestingASequenceWhichContainsTheValue() {
val alice = Person("Alice", "Bob")
val jon = Person("Jon", "Doe")
val sequence = sequenceOf(alice, jon)
assertFails { sequence shouldNotContain jon }
}


@Test
fun passWhenTestingAMapWhichDoesNotContainAPair() {
val map = mapOf(1 to "one", 2 to "two")
Expand Down
Loading