@@ -5,6 +5,7 @@ import org.mockito.Mockito.`when` as whenCalled
5
5
import org.mockito.kotlin.any as reifiedAny
6
6
import org.mockito.kotlin.anyOrNull as reifiedAnyOrNull
7
7
import org.mockito.kotlin.argThat as reifiedArgThat
8
+ import android.content.ContentValues
8
9
import android.database.Cursor
9
10
import android.database.MatrixCursor
10
11
import android.os.CancellationSignal
@@ -23,6 +24,7 @@ import org.mockito.Mockito.mock
23
24
import org.mockito.Mockito.verify
24
25
import org.mockito.Mockito.verifyNoMoreInteractions
25
26
import org.mockito.kotlin.anyArray
27
+ import org.mockito.kotlin.eq
26
28
import org.mockito.kotlin.isNull
27
29
import java.util.stream.Stream
28
30
import kotlin.streams.asStream
@@ -147,7 +149,18 @@ class MappingSupportSQLiteDatabaseTest {
147
149
verifyNoMoreInteractions(delegateMock)
148
150
}
149
151
150
- /* TODO insert, update */
152
+ /* TODO insert */
153
+
154
+ @ParameterizedTest
155
+ @MethodSource(" org.cryptomator.data.db.sqlmapping.MappingSupportSQLiteDatabaseTestKt#sourceForTestUpdate" )
156
+ fun testUpdate (contentValues : CallData <ContentValues >, whereClauses : CallData <String ?>, whereArgs : CallData <List <String >? >) {
157
+ identityMapping.update(" id_test" , 1001 , contentValues.idCall, whereClauses.idCall, whereArgs.idCall?.toTypedArray())
158
+ commentMapping.update(" comment_test" , 1002 , contentValues.commentCall, whereClauses.commentCall, whereArgs.commentCall?.toTypedArray())
159
+
160
+ verify(delegateMock).update(eq(" id_test" ), eq(1001 ), anyPseudoEquals(contentValues.idExpected, contentValuesProperties), eq(whereClauses.idExpected), eq(whereArgs.idExpected?.toTypedArray()))
161
+ verify(delegateMock).update(eq(" comment_test" ), eq(1002 ), anyPseudoEquals(contentValues.commentExpected, contentValuesProperties), eq(whereClauses.commentExpected), eq(whereArgs.commentExpected?.toTypedArray()))
162
+ verifyNoMoreInteractions(delegateMock)
163
+ }
151
164
152
165
@Test
153
166
fun testDelete () {
@@ -276,6 +289,11 @@ private class CachingSupportSQLiteProgram : SupportSQLiteProgram {
276
289
override fun close () = throw UnsupportedOperationException (" Stub!" )
277
290
}
278
291
292
+ private val contentValuesProperties
293
+ get() = setOf (
294
+ ContentValues ::valueSet
295
+ )
296
+
279
297
private val DUMMY_CURSOR : Cursor
280
298
get() = MatrixCursor (arrayOf())
281
299
@@ -286,6 +304,14 @@ private fun mockCancellationSignal(isCanceled: Boolean): CancellationSignal {
286
304
return mock
287
305
}
288
306
307
+ private fun mockContentValues (vararg elements : Pair <String , Any ?>): ContentValues {
308
+ val entries = mapOf (* elements)
309
+ val mock = mock(ContentValues ::class .java)
310
+ whenCalled(mock.valueSet()).thenReturn(entries.entries)
311
+ whenCalled(mock.toString()).thenReturn(" Mock<ContentValues>${entries} " )
312
+ return mock
313
+ }
314
+
289
315
data class CallData <T >(
290
316
val idCall : T ,
291
317
val commentCall : T ,
@@ -326,11 +352,63 @@ fun sourceForTestQueryCancelable(): Stream<Arguments> {
326
352
return queries.cartesianProduct(signals).map { it.toList() }.toArgumentsStream()
327
353
}
328
354
355
+ fun sourceForTestUpdate (): Stream <Arguments > {
356
+ val contentValues = sequenceOf(
357
+ CallData (
358
+ mockContentValues(" key1" to " value1" ),
359
+ mockContentValues(" key2" to " value2" ),
360
+ mockContentValues(" key1" to " value1" ),
361
+ mockContentValues(" key2" to " value2" )
362
+ ),
363
+ CallData (
364
+ mockContentValues(" key1" to null ),
365
+ mockContentValues(),
366
+ mockContentValues(" key1" to null ),
367
+ mockContentValues()
368
+ )
369
+ )
370
+ val whereClauses = listOf<CallData <String ?>>(
371
+ CallData (
372
+ " `col1` = ?" ,
373
+ " `col2` = ?" ,
374
+ " `col1` = ?" ,
375
+ " `col2` = ? -- Comment!"
376
+ ),
377
+ CallData (
378
+ null ,
379
+ null ,
380
+ null ,
381
+ " 1 = 1 -- Comment!"
382
+ )
383
+ )
384
+ val whereArgs = listOf<CallData <List <String >? >> ( // Use List instead of Array to make result data more readable
385
+ CallData (
386
+ listOf (),
387
+ null ,
388
+ listOf (),
389
+ null
390
+ ),
391
+ CallData (
392
+ listOf (" val1" ),
393
+ listOf (" val2" ),
394
+ listOf (" val1" ),
395
+ listOf (" val2" )
396
+ )
397
+ )
398
+
399
+ return contentValues.cartesianProduct(whereClauses).cartesianProduct(whereArgs).map { it.toList() }.toArgumentsStream()
400
+ }
401
+
329
402
@JvmName(" cartesianProductTwo" )
330
403
fun <A , B > Sequence<A>.cartesianProduct (other : Iterable <B >): Sequence <Pair <A , B >> = flatMap { a ->
331
404
other.asSequence().map { b -> a to b }
332
405
}
333
406
407
+ @JvmName(" cartesianProductThree" )
408
+ fun <A , B , C > Sequence <Pair <A , B >>.cartesianProduct (other : Iterable <C >): Sequence <Triple <A , B , C >> = flatMap { abPair ->
409
+ other.asSequence().map { c -> Triple (abPair.first, abPair.second, c) }
410
+ }
411
+
334
412
fun Sequence<List<Any?>>.toArgumentsStream (): Stream <Arguments > = map {
335
413
Arguments { it.toTypedArray() }
336
414
}.asStream()
0 commit comments