1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 @file:Suppress("NOTHING_TO_INLINE")
18
19 package com.android.intentresolver
20
21 import kotlin.DeprecationLevel.ERROR
22 import kotlin.DeprecationLevel.WARNING
23 import org.mockito.ArgumentCaptor
24 import org.mockito.ArgumentMatcher
25 import org.mockito.ArgumentMatchers
26 import org.mockito.MockSettings
27 import org.mockito.Mockito
28 import org.mockito.stubbing.Answer
29 import org.mockito.stubbing.OngoingStubbing
30 import org.mockito.stubbing.Stubber
31
32 /*
33 * Kotlin versions of popular mockito methods that can return null in situations when Kotlin expects
34 * a non-null value. Kotlin will throw an IllegalStateException when this takes place ("x must not
35 * be null"). To fix this, we can use methods that modify the return type to be nullable. This
36 * causes Kotlin to skip the null checks. Cloned from
37 * frameworks/base/packages/SystemUI/tests/utils/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt
38 */
39
40 /**
41 * Returns Mockito.eq() as nullable type to avoid java.lang.IllegalStateException when null is
42 * returned.
43 *
44 * Generic T is nullable because implicitly bounded by Any?.
45 */
46 @Deprecated(
47 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
48 ReplaceWith(expression = "eq", imports = ["org.mockito.kotlin.eq"]),
49 level = ERROR
50 )
eqnull51 inline fun <T> eq(obj: T): T = Mockito.eq<T>(obj) ?: obj
52
53 /**
54 * Returns Mockito.same() as nullable type to avoid java.lang.IllegalStateException when null is
55 * returned.
56 *
57 * Generic T is nullable because implicitly bounded by Any?.
58 */
59 @Deprecated(
60 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
61 ReplaceWith(expression = "same(obj)", imports = ["org.mockito.kotlin.same"]),
62 level = ERROR
63 )
64 inline fun <T> same(obj: T): T = Mockito.same<T>(obj) ?: obj
65
66 /**
67 * Returns Mockito.any() as nullable type to avoid java.lang.IllegalStateException when null is
68 * returned.
69 *
70 * Generic T is nullable because implicitly bounded by Any?.
71 */
72 @Deprecated(
73 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
74 ReplaceWith(expression = "any(type)", imports = ["org.mockito.kotlin.any"]),
75 level = WARNING
76 )
77 inline fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
78
79 @Deprecated(
80 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
81 ReplaceWith(expression = "any()", imports = ["org.mockito.kotlin.any"]),
82 level = WARNING
83 )
84 inline fun <reified T> any(): T = any(T::class.java)
85
86 /**
87 * Returns Mockito.argThat() as nullable type to avoid java.lang.IllegalStateException when null is
88 * returned.
89 *
90 * Generic T is nullable because implicitly bounded by Any?.
91 */
92 @Deprecated(
93 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
94 ReplaceWith(expression = "argThat(matcher)", imports = ["org.mockito.kotlin.argThat"]),
95 level = WARNING
96 )
97 inline fun <T> argThat(matcher: ArgumentMatcher<T>): T = Mockito.argThat(matcher)
98
99 /**
100 * Kotlin type-inferred version of Mockito.nullable()
101 *
102 * @see org.mockito.kotlin.anyOrNull
103 */
104 @Deprecated(
105 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
106 ReplaceWith(expression = "anyOrNull()", imports = ["org.mockito.kotlin.anyOrNull"]),
107 level = ERROR
108 )
109 inline fun <reified T> nullable(): T? = Mockito.nullable(T::class.java)
110
111 /**
112 * Returns ArgumentCaptor.capture() as nullable type to avoid java.lang.IllegalStateException when
113 * null is returned.
114 *
115 * Generic T is nullable because implicitly bounded by Any?.
116 *
117 * @see org.mockito.kotlin.capture
118 */
119 @Deprecated(
120 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
121 ReplaceWith(expression = "capture(argumentCaptor)", imports = ["org.mockito.kotlin.capture"]),
122 level = ERROR
123 )
124 inline fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
125
126 /**
127 * Helper function for creating an argumentCaptor in kotlin.
128 *
129 * Generic T is nullable because implicitly bounded by Any?.
130 *
131 * @see org.mockito.kotlin.argumentCaptor
132 */
133 @Deprecated(
134 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
135 ReplaceWith(expression = "argumentCaptor()", imports = ["org.mockito.kotlin.argumentCaptor"]),
136 level = ERROR
137 )
138 inline fun <reified T : Any> argumentCaptor(): ArgumentCaptor<T> =
139 ArgumentCaptor.forClass(T::class.java)
140
141 /**
142 * Helper function for creating new mocks, without the need to pass in a [Class] instance.
143 *
144 * Generic T is nullable because implicitly bounded by Any?.
145 *
146 * Updated kotlin-mockito usage:
147 * ```
148 * val value: Widget = mock<> {
149 * on { status } doReturn "OK"
150 * on { buttonPress } doNothing
151 * on { destroy } doAnswer error("Boom!")
152 * }
153 * ```
154 *
155 * __Deprecation note__
156 *
157 * Automatic replacement is not possible due to a change in lambda receiver type to KStubbing<T>
158 *
159 * @see org.mockito.kotlin.mock
160 * @see org.mockito.kotlin.KStubbing.on
161 */
162 @Suppress("DeprecatedCallableAddReplaceWith")
163 @Deprecated("Replace with mockito-kotlin. See http://go/mockito-kotlin", level = WARNING)
164 inline fun <reified T : Any> mock(
165 mockSettings: MockSettings = Mockito.withSettings(),
166 apply: T.() -> Unit = {}
167 ): T = Mockito.mock(T::class.java, mockSettings).apply(apply)
168
169 /** Matches any array of type T. */
170 @Deprecated(
171 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
172 ReplaceWith(expression = "anyArray()", imports = ["org.mockito.kotlin.anyArray"]),
173 level = ERROR
174 )
anyArraynull175 inline fun <reified T : Any?> anyArray(): Array<T> = Mockito.any(Array<T>::class.java) ?: arrayOf()
176
177 /**
178 * Helper function for stubbing methods without the need to use backticks.
179 *
180 * Avoid. It is preferable to provide stubbing at creation time using the [mock] lambda argument.
181 *
182 * @see org.mockito.kotlin.whenever
183 */
184 @Deprecated(
185 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
186 ReplaceWith(expression = "whenever(methodCall)", imports = ["org.mockito.kotlin.whenever"]),
187 level = ERROR
188 )
189 inline fun <T> whenever(methodCall: T): OngoingStubbing<T> = Mockito.`when`(methodCall)
190
191 /**
192 * Helper function for stubbing methods without the need to use backticks.
193 *
194 * Avoid. It is preferable to provide stubbing at creation time using the [mock] lambda argument.
195 *
196 * __Deprecation note__
197 *
198 * Replace with KStubber<T>.on within [org.mockito.kotlin.mock] { stubbing }
199 *
200 * @see org.mockito.kotlin.mock
201 * @see org.mockito.kotlin.KStubbing.on
202 */
203 @Deprecated(
204 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
205 ReplaceWith(expression = "whenever(mock)", imports = ["org.mockito.kotlin.whenever"]),
206 level = ERROR
207 )
208 inline fun <T> Stubber.whenever(mock: T): T = `when`(mock)
209
210 /**
211 * A kotlin implemented wrapper of [ArgumentCaptor] which prevents the following exception when
212 * kotlin tests are mocking kotlin objects and the methods take non-null parameters:
213 *
214 * java.lang.NullPointerException: capture() must not be null
215 */
216 @Deprecated("Replace with mockito-kotlin. See http://go/mockito-kotlin", level = WARNING)
217 class KotlinArgumentCaptor<T> constructor(clazz: Class<T>) {
218 private val wrapped: ArgumentCaptor<T> = ArgumentCaptor.forClass(clazz)
219 fun capture(): T = wrapped.capture()
220 val value: T
221 get() = wrapped.value
222 val allValues: List<T>
223 get() = wrapped.allValues
224 }
225
226 /**
227 * Helper function for creating an argumentCaptor in kotlin.
228 *
229 * Generic T is nullable because implicitly bounded by Any?.
230 *
231 * @see org.mockito.kotlin.argumentCaptor
232 */
233 @Deprecated(
234 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
235 ReplaceWith(expression = "argumentCaptor()", imports = ["org.mockito.kotlin.argumentCaptor"]),
236 level = WARNING
237 )
kotlinArgumentCaptornull238 inline fun <reified T : Any> kotlinArgumentCaptor(): KotlinArgumentCaptor<T> =
239 KotlinArgumentCaptor(T::class.java)
240
241 /**
242 * Helper function for creating and using a single-use ArgumentCaptor in kotlin.
243 *
244 * val captor = argumentCaptor<Foo>() verify(...).someMethod(captor.capture()) val captured =
245 * captor.value
246 *
247 * becomes:
248 *
249 * val captured = withArgCaptor<Foo> { verify(...).someMethod(capture()) }
250 *
251 * NOTE: this uses the KotlinArgumentCaptor to avoid the NullPointerException.
252 *
253 * @see org.mockito.kotlin.verify
254 */
255 @Suppress("DeprecatedCallableAddReplaceWith")
256 @Deprecated("Replace with mockito-kotlin. See http://go/mockito-kotlin", level = WARNING)
257 inline fun <reified T : Any> withArgCaptor(block: KotlinArgumentCaptor<T>.() -> Unit): T =
258 kotlinArgumentCaptor<T>().apply { block() }.value
259
260 /**
261 * Variant of [withArgCaptor] for capturing multiple arguments.
262 *
263 * val captor = argumentCaptor<Foo>() verify(...).someMethod(captor.capture()) val captured:
264 * List<Foo> = captor.allValues
265 *
266 * becomes:
267 *
268 * val capturedList = captureMany<Foo> { verify(...).someMethod(capture()) }
269 *
270 * @see org.mockito.kotlin.verify
271 */
272 @Deprecated(
273 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
274 ReplaceWith(expression = "capture()", imports = ["org.mockito.kotlin.capture"]),
275 level = WARNING
276 )
captureManynull277 inline fun <reified T : Any> captureMany(block: KotlinArgumentCaptor<T>.() -> Unit): List<T> =
278 kotlinArgumentCaptor<T>().apply { block() }.allValues
279
280 /** @see org.mockito.kotlin.anyOrNull */
281 @Deprecated(
282 "Replace with mockito-kotlin. See http://go/mockito-kotlin",
283 ReplaceWith(expression = "anyOrNull()", imports = ["org.mockito.kotlin.anyOrNull"]),
284 level = ERROR
285 )
<lambda>null286 inline fun <reified T> anyOrNull() = ArgumentMatchers.argThat(ArgumentMatcher<T?> { true })
287
288 /**
289 * @see org.mockito.kotlin.mock
290 * @see org.mockito.kotlin.doThrow
291 */
292 @Deprecated("Replace with mockito-kotlin. See http://go/mockito-kotlin", level = ERROR)
<lambda>null293 val THROWS_EXCEPTION = Answer { error("Unstubbed behavior was accessed.") }
294