Last active
March 10, 2021 23:38
-
-
Save keyboardr/68028799a90f8fa8b93ac564d31911c7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.keyboardr.testing | |
import com.google.common.truth.* | |
import com.google.common.truth.Truth.assertWithMessage | |
import com.google.common.truth.Truth.assert_ | |
import java.math.BigDecimal | |
import kotlin.contracts.ExperimentalContracts | |
import kotlin.contracts.InvocationKind | |
import kotlin.contracts.contract | |
open class AssertionBuilder<T : AssertionScope> | |
internal constructor(val scope: T) { | |
inline infix fun that(block: T.() -> Unit) { | |
scope.block() | |
} | |
infix fun that(actual: BigDecimal?): BigDecimalSubject = scope.startAssert().that(actual) | |
infix fun that(actual: Any?): Subject = scope.startAssert().that(actual) | |
infix fun that(actual: Class<*>?): ClassSubject = scope.startAssert().that(actual) | |
infix fun that(actual: Throwable?): ThrowableSubject = scope.startAssert().that(actual) | |
infix fun that(actual: Long?): LongSubject = scope.startAssert().that(actual) | |
infix fun that(actual: Double?): DoubleSubject = scope.startAssert().that(actual) | |
infix fun that(actual: Float?): FloatSubject = scope.startAssert().that(actual) | |
infix fun that(actual: Int?): IntegerSubject = scope.startAssert().that(actual) | |
infix fun that(actual: Boolean?): BooleanSubject = scope.startAssert().that(actual) | |
infix fun that(actual: String?): StringSubject = scope.startAssert().that(actual) | |
infix fun that(actual: Iterable<*>?): IterableSubject = scope.startAssert().that(actual) | |
infix fun <T> that(actual: Array<T>?): ObjectArraySubject<T> = scope.startAssert().that(actual) | |
infix fun that(actual: Map<*, *>?): MapSubject = scope.startAssert().that(actual) | |
} | |
object Assert : AssertionBuilder<AssertionScope>(Assertions) { | |
fun withMessage(message: String) = AssertionBuilder(MessageAssertionScope(message)) | |
fun <T : AssertionScope> withExtension(extension: T) = AssertionBuilder(extension) | |
} | |
@OptIn(ExperimentalContracts::class) | |
inline fun assertThat(block: AssertionScope.() -> Unit) { | |
contract { | |
callsInPlace(block, InvocationKind.EXACTLY_ONCE) | |
} | |
Assert that block | |
} | |
@OptIn(ExperimentalContracts::class) | |
inline fun assertWithMessage(message: String, block: AssertionScope.() -> Unit) { | |
contract { | |
callsInPlace(block, InvocationKind.EXACTLY_ONCE) | |
} | |
Assert.withMessage(message) that block | |
} | |
@Suppress("unused", "NOTHING_TO_INLINE") | |
@AssertionDsl | |
abstract class AssertionScope { | |
open fun startAssert(): StandardSubjectBuilder = assert_() | |
inline infix fun Boolean?.shouldBe(expected: Boolean?) = when (expected) { | |
null -> startAssert().that(this).isNull() | |
true -> startAssert().that(this).isTrue() | |
false -> startAssert().that(this).isFalse() | |
} | |
inline infix fun Int?.shouldEqual(expected: Int) = startAssert().that(this).isEqualTo(expected) | |
inline infix fun Long?.shouldEqual(expected: Long) = startAssert().that(this).isEqualTo(expected) | |
inline infix fun Float?.shouldEqual(expected: Float) = startAssert().that(this).isEqualTo(expected) | |
inline infix fun Any?.shouldEqual(expected: Any?) = startAssert().that(this).isEqualTo(expected) | |
inline infix fun Int?.shouldNotEqual(expected: Int) = startAssert().that(this).isNotEqualTo(expected) | |
inline infix fun Long?.shouldNotEqual(expected: Long) = startAssert().that(this).isNotEqualTo(expected) | |
inline infix fun Float?.shouldNotEqual(expected: Float) = startAssert().that(this).isNotEqualTo(expected) | |
inline infix fun Any?.shouldNotEqual(expected: Any) = startAssert().that(this).isNotEqualTo(expected) | |
inline infix fun Int?.shouldBeSameAs(expected: Int) = startAssert().that(this).isSameInstanceAs(expected) | |
inline infix fun Long?.shouldBeSameAs(expected: Long) = startAssert().that(this).isSameInstanceAs(expected) | |
inline infix fun Float?.shouldBeSameAs(expected: Float) = startAssert().that(this).isSameInstanceAs(expected) | |
inline infix fun Any?.shouldBeSameAs(expected: Any?) = startAssert().that(this).isSameInstanceAs(expected) | |
inline infix fun Int?.shouldBeAtLeast(expected: Int) = startAssert().that(this).isAtLeast(expected) | |
inline infix fun Long?.shouldBeAtLeast(expected: Long) = startAssert().that(this).isAtLeast(expected) | |
inline infix fun Float?.shouldBeAtLeast(expected: Float) = startAssert().that(this).isAtLeast(expected) | |
// foo shouldBe null | |
inline infix fun Any?.shouldBe(@Suppress("UNUSED_PARAMETER") nothing: Nothing?) = startAssert().that(this).isNull() | |
// foo shouldBe !null | |
inline infix fun Any?.shouldBe(@Suppress("UNUSED_PARAMETER") nonNull: NonNull) = startAssert().that(this).isNotNull() | |
inline fun Iterable<*>?.shouldBeEmpty() = startAssert().that(this).isEmpty() | |
inline fun Iterable<*>?.shouldNotBeEmpty() = startAssert().that(this).isNotEmpty() | |
inline fun Iterable<*>?.shouldNotContainDuplicates() = startAssert().that(this).containsNoDuplicates() | |
inline infix fun Iterable<*>?.shouldHaveSize(expectedSize: Int) = startAssert().that(this).hasSize(expectedSize) | |
inline infix fun Iterable<*>?.shouldContain(element: Any?) = startAssert().that(this).contains(element) | |
inline infix fun Iterable<*>?.shouldNotContain(element: Any?) = startAssert().that(this).doesNotContain(element) | |
inline infix fun Iterable<*>?.shouldContainOnly(element: Any?): Ordered = startAssert().that(this).containsExactly(element) | |
inline fun Iterable<*>?.shouldContainExactlyElements(vararg varargs: Any): Ordered = startAssert().that(this).containsExactly(*varargs) | |
inline infix fun Iterable<*>?.shouldContainExactly(expected: Iterable<*>): Ordered = startAssert().that(this).containsExactlyElementsIn(expected) | |
inline infix fun Iterable<*>?.shouldContainExactly(expected: Array<*>): Ordered = startAssert().that(this).containsExactlyElementsIn(expected) | |
inline operator fun Nothing?.not() = NonNull | |
object NonNull | |
} | |
object Assertions : AssertionScope() | |
class MessageAssertionScope(private val message: String) : | |
AssertionScope() { | |
override fun startAssert(): StandardSubjectBuilder = assertWithMessage(message) | |
} | |
@DslMarker | |
annotation class AssertionDsl |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment