aboutsummaryrefslogtreecommitdiff
path: root/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt
diff options
context:
space:
mode:
Diffstat (limited to 'mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt')
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt212
1 files changed, 212 insertions, 0 deletions
diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt
new file mode 100644
index 0000000..253a58c
--- /dev/null
+++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt
@@ -0,0 +1,212 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2018 Niek Haarman
+ * Copyright (c) 2007 Mockito contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package org.mockito.kotlin
+
+import org.mockito.kotlin.internal.createInstance
+import org.mockito.ArgumentCaptor
+import kotlin.reflect.KClass
+
+/**
+ * Creates a [KArgumentCaptor] for given type.
+ */
+inline fun <reified T : Any> argumentCaptor(): KArgumentCaptor<T> {
+ return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)
+}
+
+/**
+ * Creates 2 [KArgumentCaptor]s for given types.
+ */
+inline fun <reified A : Any, reified B : Any> argumentCaptor(
+ a: KClass<A> = A::class,
+ b: KClass<B> = B::class
+): Pair<KArgumentCaptor<A>, KArgumentCaptor<B>> {
+ return Pair(
+ KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
+ KArgumentCaptor(ArgumentCaptor.forClass(b.java), b)
+ )
+}
+
+/**
+ * Creates 3 [KArgumentCaptor]s for given types.
+ */
+inline fun <reified A : Any, reified B : Any, reified C : Any> argumentCaptor(
+ a: KClass<A> = A::class,
+ b: KClass<B> = B::class,
+ c: KClass<C> = C::class
+): Triple<KArgumentCaptor<A>, KArgumentCaptor<B>, KArgumentCaptor<C>> {
+ return Triple(
+ KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
+ KArgumentCaptor(ArgumentCaptor.forClass(b.java), b),
+ KArgumentCaptor(ArgumentCaptor.forClass(c.java), c)
+ )
+}
+
+class ArgumentCaptorHolder4<out A, out B, out C, out D>(
+ val first: A,
+ val second: B,
+ val third: C,
+ val fourth: D
+) {
+
+ operator fun component1() = first
+ operator fun component2() = second
+ operator fun component3() = third
+ operator fun component4() = fourth
+}
+
+class ArgumentCaptorHolder5<out A, out B, out C, out D, out E>(
+ val first: A,
+ val second: B,
+ val third: C,
+ val fourth: D,
+ val fifth: E
+) {
+
+ operator fun component1() = first
+ operator fun component2() = second
+ operator fun component3() = third
+ operator fun component4() = fourth
+ operator fun component5() = fifth
+}
+
+
+/**
+ * Creates 4 [KArgumentCaptor]s for given types.
+ */
+inline fun <reified A : Any, reified B : Any, reified C : Any, reified D : Any> argumentCaptor(
+ a: KClass<A> = A::class,
+ b: KClass<B> = B::class,
+ c: KClass<C> = C::class,
+ d: KClass<D> = D::class
+): ArgumentCaptorHolder4<KArgumentCaptor<A>, KArgumentCaptor<B>, KArgumentCaptor<C>, KArgumentCaptor<D>> {
+ return ArgumentCaptorHolder4(
+ KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
+ KArgumentCaptor(ArgumentCaptor.forClass(b.java), b),
+ KArgumentCaptor(ArgumentCaptor.forClass(c.java), c),
+ KArgumentCaptor(ArgumentCaptor.forClass(d.java), d)
+ )
+}
+
+/**
+ * Creates 4 [KArgumentCaptor]s for given types.
+ */
+inline fun <reified A : Any, reified B : Any, reified C : Any, reified D : Any, reified E : Any> argumentCaptor(
+ a: KClass<A> = A::class,
+ b: KClass<B> = B::class,
+ c: KClass<C> = C::class,
+ d: KClass<D> = D::class,
+ e: KClass<E> = E::class
+): ArgumentCaptorHolder5<KArgumentCaptor<A>, KArgumentCaptor<B>, KArgumentCaptor<C>, KArgumentCaptor<D>, KArgumentCaptor<E>> {
+ return ArgumentCaptorHolder5(
+ KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
+ KArgumentCaptor(ArgumentCaptor.forClass(b.java), b),
+ KArgumentCaptor(ArgumentCaptor.forClass(c.java), c),
+ KArgumentCaptor(ArgumentCaptor.forClass(d.java), d),
+ KArgumentCaptor(ArgumentCaptor.forClass(e.java), e)
+ )
+}
+
+/**
+ * Creates a [KArgumentCaptor] for given type, taking in a lambda to allow fast verification.
+ */
+inline fun <reified T : Any> argumentCaptor(f: KArgumentCaptor<T>.() -> Unit): KArgumentCaptor<T> {
+ return argumentCaptor<T>().apply(f)
+}
+
+/**
+ * Creates a [KArgumentCaptor] for given nullable type.
+ */
+inline fun <reified T : Any> nullableArgumentCaptor(): KArgumentCaptor<T?> {
+ return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)
+}
+
+/**
+ * Creates a [KArgumentCaptor] for given nullable type, taking in a lambda to allow fast verification.
+ */
+inline fun <reified T : Any> nullableArgumentCaptor(f: KArgumentCaptor<T?>.() -> Unit): KArgumentCaptor<T?> {
+ return nullableArgumentCaptor<T>().apply(f)
+}
+
+/**
+ * Alias for [ArgumentCaptor.capture].
+ */
+inline fun <reified T : Any> capture(captor: ArgumentCaptor<T>): T {
+ return captor.capture() ?: createInstance()
+}
+
+class KArgumentCaptor<out T : Any?>(
+ private val captor: ArgumentCaptor<T>,
+ private val tClass: KClass<*>
+) {
+
+ /**
+ * The first captured value of the argument.
+ * @throws IndexOutOfBoundsException if the value is not available.
+ */
+ val firstValue: T
+ get() = captor.firstValue
+
+ /**
+ * The second captured value of the argument.
+ * @throws IndexOutOfBoundsException if the value is not available.
+ */
+ val secondValue: T
+ get() = captor.secondValue
+
+ /**
+ * The third captured value of the argument.
+ * @throws IndexOutOfBoundsException if the value is not available.
+ */
+ val thirdValue: T
+ get() = captor.thirdValue
+
+ /**
+ * The last captured value of the argument.
+ * @throws IndexOutOfBoundsException if the value is not available.
+ */
+ val lastValue: T
+ get() = captor.lastValue
+
+ val allValues: List<T>
+ get() = captor.allValues
+
+ @Suppress("UNCHECKED_CAST")
+ fun capture(): T {
+ return captor.capture() ?: createInstance(tClass) as T
+ }
+}
+
+val <T> ArgumentCaptor<T>.firstValue: T
+ get() = allValues[0]
+
+val <T> ArgumentCaptor<T>.secondValue: T
+ get() = allValues[1]
+
+val <T> ArgumentCaptor<T>.thirdValue: T
+ get() = allValues[2]
+
+val <T> ArgumentCaptor<T>.lastValue: T
+ get() = allValues.last()