Skip to content

Commit

Permalink
Implement top level "invoking" function to chain throwable assertions
Browse files Browse the repository at this point in the history
This implements the second proposal in MarkusAmshove#111. The tests have been
adjusted to showcase the new syntax.
  • Loading branch information
rubengees committed Jan 26, 2019
1 parent 83d0abe commit c857719
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 52 deletions.
2 changes: 2 additions & 0 deletions jvm/src/main/kotlin/org/amshove/kluent/Exceptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package org.amshove.kluent
import org.junit.ComparisonFailure
import kotlin.reflect.KClass

fun invoking(function: () -> Any?): () -> Any? = function

infix fun <T : Throwable> (() -> Any?).shouldThrow(expectedException: KClass<T>): ExceptionResult<T> {
try {
this.invoke()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,57 @@ package org.amshove.kluent.tests.assertions.exceptions

import org.amshove.kluent.*
import org.junit.Test
import java.io.IOException
import kotlin.test.assertFails

class ShouldNotThrowShould {
@Test
fun passWhenTestingAFunctionThatDoesNotThrowAnException() {
val func = { Unit }
func shouldNotThrow AnyException
invoking { Unit } shouldNotThrow AnyException
}

@Test
fun failWhenTestingAFunctionThatDoesThrowAnException() {
val func = { throw IllegalArgumentException() }
assertFails { func shouldNotThrow AnyException }
assertFails {
invoking { throw IllegalArgumentException() } shouldNotThrow AnyException
}
}

@Test
fun passWhenTestingAFunctionThatDoesNotThrowTheExpectedException() {
val func = { throw IllegalArgumentException() }
func shouldNotThrow ArrayIndexOutOfBoundsException::class
invoking { throw IllegalArgumentException() } shouldNotThrow ArrayIndexOutOfBoundsException::class
}

@Test
fun passWhenTestingAFunctionThatReturnsNull() {
val func = { null }
func shouldNotThrow AnyException
invoking { null } shouldNotThrow AnyException
}

@Test
fun passWhenTestingAFunctionThatThrowsAnExceptionWithADifferentMessage() {
val func = { throw IllegalArgumentException("Actual Message") }
func shouldNotThrow IllegalAccessException::class withMessage "Expected Message"
invoking { throw IllegalArgumentException("Actual Message") } shouldNotThrow
IllegalAccessException::class withMessage "Expected Message"
}

@Test
fun failWhenTestingAFunctionThatThrowsAnExceptionWithTheSameMessage() {
val func = { throw IllegalArgumentException("Actual Message") }
assertFails { func shouldNotThrow IllegalAccessException::class withMessage "Actual Message" }
assertFails {
invoking { throw IllegalArgumentException("Actual Message") } shouldNotThrow
IllegalAccessException::class withMessage "Actual Message"
}
}

@Test
fun failWhenTestingAFunctionThatDoesThrowAnExceptionWithTheExpectedCause() {
val func = { throw Exception(RuntimeException()) }
assertFails { func shouldNotThrow Exception::class withCause RuntimeException::class }
assertFails {
invoking { throw Exception(RuntimeException()) } shouldNotThrow
Exception::class withCause RuntimeException::class
}
}

@Test
fun failWhenExpectingAnExceptionThatWasThrown() {
val func = { throw Exception() }
assertFails { func shouldNotThrow Exception::class }
assertFails {
invoking { throw Exception() } shouldNotThrow Exception::class
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,96 +8,89 @@ import kotlin.test.assertFails
class ShouldThrowShould {
@Test
fun passWhenTestingAFunctionThatThrowsTheExpectedException() {
val func = { throw IndexOutOfBoundsException() }
func shouldThrow IndexOutOfBoundsException::class
invoking { throw IndexOutOfBoundsException() } shouldThrow IndexOutOfBoundsException::class
}

@Test
fun failWhenTestingAFunctionThatDoesNotThrowTheExpectedException() {
val func = { throw IndexOutOfBoundsException() }
assertFails { func shouldThrow IllegalArgumentException::class }
assertFails {
invoking { throw IndexOutOfBoundsException() } shouldThrow IllegalArgumentException::class
}
}

@Test
fun passWhenTestingAFunctionThatTriesToGetAnOutOfIndexedItem() {
val funcWithReturn = { listOf(0).get(-1) }
funcWithReturn shouldThrow IndexOutOfBoundsException::class
invoking { listOf(0)[-1] } shouldThrow IndexOutOfBoundsException::class
}

@Test
fun passWhenTestingAFunctionWhichThrowsASubtypeOfTheExpectedException() {
val func = { throw IllegalStateException() }
func shouldThrow RuntimeException::class
invoking { throw IllegalStateException() } shouldThrow RuntimeException::class
}

@Test
fun passWhenTestingAFunctionWhichThrowsAnExceptionWithTheExpectedMessage() {
val func = { throw Exception("Hello World!") }
func shouldThrow Exception::class withMessage "Hello World!"
invoking { throw Exception("Hello World!") } shouldThrow Exception::class withMessage "Hello World!"
}

@Test
fun failWhenTestingAFunctionWhichThrowsAnExceptionWithADifferentMessage() {
val func = { throw Exception("Hello World!") }
assertFails { func shouldThrow Exception::class withMessage "Hello" }
assertFails {
invoking { throw Exception("Hello World!") } shouldThrow Exception::class withMessage "Hello"
}
}

@Test
fun passWhenTestingAFunctionWhichThrowsAnExceptionWithTheExpectedCause() {
val func = { throw Exception(RuntimeException()) }
func shouldThrow Exception::class withCause RuntimeException::class
invoking { throw Exception(RuntimeException()) } shouldThrow Exception::class withCause RuntimeException::class
}

@Test
fun failWhenTestingAFunctionWhichThrowsAnExceptionWithAnUnexpectedCause() {
val func = { throw Exception(RuntimeException()) }
assertFails { func shouldThrow Exception::class withCause IOException::class }
assertFails {
invoking { throw Exception(RuntimeException()) } shouldThrow Exception::class withCause IOException::class
}
}

@Test
fun passWhenTestingAFunctionWhichThrowsWhenAnyExceptionIsExpected() {
val func = { throw Exception() }
func shouldThrow AnyException
invoking { throw Exception() } shouldThrow AnyException
}

@Test
fun failWhenTestingAFunctionWhichDoesNotThrowButAnyExceptionIsExpected() {
val func = { Unit }
assertFails { func shouldThrow AnyException }
assertFails { invoking { Unit } shouldThrow AnyException }
}

@Test
fun passWhenTestingAFunctionWhichThrowsAnExceptionWithMessageAndCause() {
val func = { throw IllegalArgumentException("hello", IOException()) }
func shouldThrow IllegalArgumentException::class withCause IOException::class withMessage "hello"
invoking { throw IllegalArgumentException("hello", IOException()) } shouldThrow
IllegalArgumentException::class withCause IOException::class withMessage "hello"
}

@Test
fun failWhenTestingAFunctionWhichThrowsAnExceptionWithMessageAndCauseExceptingADifferentMessage() {
val func = { throw IllegalArgumentException("not hello", IOException()) }
assertFails { func shouldThrow IllegalArgumentException::class withCause IOException::class withMessage "hello" }
assertFails {
invoking { throw IllegalArgumentException("not hello", IOException()) } shouldThrow
IllegalArgumentException::class withCause IOException::class withMessage "hello"
}
}

@Test
fun returnTheExceptionWhenPassing() {
val exception = invoking { throw CustomException(10) }.shouldThrow(CustomException::class).exception

val func = { throw CustomException(10) }

val exception = func.shouldThrow(CustomException::class).exception
exception.code.shouldEqual(10)
}

@Test
fun passWhenTestingForAnExactThrownException() {

val func = { throw CustomException(12345) }
func shouldThrow CustomException(12345)
invoking { throw CustomException(12345) } shouldThrow CustomException(12345)
}

@Test
fun failWhenTestingForAnExactThrownExceptionWhenTheExceptionDiffers() {
val func = { throw CustomException(12345) }
assertFails { func shouldThrow CustomException(54321) }
fun failWhenTestisngForAnExactThrownExceptionWhenTheExceptionDiffers() {
assertFails { invoking { throw CustomException(12345) } shouldThrow CustomException(54321) }
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ class StubTests : Spek({
it("should throw an exception") {
val mock = mock(Database::class)
When calling mock.getPerson() itReturns any()
val func = { mock.getPerson() }
func shouldThrow InvalidUseOfMatchersException::class
invoking { mock.getPerson() } shouldThrow InvalidUseOfMatchersException::class
}
}

Expand Down

0 comments on commit c857719

Please sign in to comment.