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