Skip to content

Commit

Permalink
Merge pull request #159 from jcornaz/feature/sequence-assertions
Browse files Browse the repository at this point in the history
Add assertions for sequences
  • Loading branch information
MarkusAmshove authored Nov 17, 2019
2 parents 11efb45 + 8f0fa49 commit 5ef432d
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 13 deletions.
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

0 comments on commit 5ef432d

Please sign in to comment.