diff options
Diffstat (limited to 'app/src/test')
-rw-r--r-- | app/src/test/kotlin/com/pitchedapps/frost/kotlin/FlyweightTest.kt | 120 | ||||
-rw-r--r-- | app/src/test/kotlin/com/pitchedapps/frost/utils/CoroutineTest.kt | 89 |
2 files changed, 0 insertions, 209 deletions
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/kotlin/FlyweightTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/kotlin/FlyweightTest.kt deleted file mode 100644 index 89289322..00000000 --- a/app/src/test/kotlin/com/pitchedapps/frost/kotlin/FlyweightTest.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2018 Allan Wang - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package com.pitchedapps.frost.kotlin - -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.runBlocking -import org.junit.Rule -import org.junit.rules.Timeout -import java.util.concurrent.atomic.AtomicInteger -import kotlin.test.BeforeTest -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue -import kotlin.test.fail - -class FlyweightTest { - - @get:Rule - val globalTimeout: Timeout = Timeout.seconds(5) - - lateinit var flyweight: Flyweight<Int, Int> - - lateinit var callCount: AtomicInteger - - private val LONG_RUNNING_KEY = -78 - - @BeforeTest - fun before() { - callCount = AtomicInteger(0) - flyweight = Flyweight(GlobalScope, 200L) { - callCount.incrementAndGet() - when (it) { - LONG_RUNNING_KEY -> Thread.sleep(100000) - else -> Thread.sleep(100) - } - it * 2 - } - } - - @Test - fun basic() { - assertEquals(2, runBlocking { flyweight.fetch(1).await() }, "Invalid result") - assertEquals(1, callCount.get(), "1 call expected") - } - - @Test - fun multipleWithOneKey() { - val results: List<Int> = runBlocking { - (0..1000).map { - flyweight.fetch(1) - }.map { it.await() } - } - assertEquals(1, callCount.get(), "1 call expected") - assertEquals(1001, results.size, "Incorrect number of results returned") - assertTrue(results.all { it == 2 }, "Result should all be 2") - } - - @Test - fun consecutiveReuse() { - runBlocking { - flyweight.fetch(1).await() - assertEquals(1, callCount.get(), "1 call expected") - flyweight.fetch(1).await() - assertEquals(1, callCount.get(), "Reuse expected") - Thread.sleep(300) - flyweight.fetch(1).await() - assertEquals(2, callCount.get(), "Refetch expected") - } - } - - @Test - fun invalidate() { - runBlocking { - flyweight.fetch(1).await() - assertEquals(1, callCount.get(), "1 call expected") - flyweight.invalidate(1) - flyweight.fetch(1).await() - assertEquals(2, callCount.get(), "New call expected") - } - } - - @Test - fun destroy() { - runBlocking { - val longRunningResult = flyweight.fetch(LONG_RUNNING_KEY) - flyweight.fetch(1).await() - flyweight.cancel() - try { - flyweight.fetch(1).await() - fail("Flyweight should not be fulfilled after it is destroyed") - } catch (ignore: CancellationException) { - } - try { - assertFalse( - longRunningResult.isActive, - "Long running result should no longer be active" - ) - longRunningResult.await() - fail("Flyweight should have cancelled previously running requests") - } catch (ignore: CancellationException) { - } - } - } -} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/CoroutineTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/CoroutineTest.kt index 43bd1563..551d0b7b 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/utils/CoroutineTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/CoroutineTest.kt @@ -16,15 +16,10 @@ */ package com.pitchedapps.frost.utils -import com.pitchedapps.frost.kotlin.Flyweight import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.async -import kotlinx.coroutines.channels.BroadcastChannel -import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow @@ -81,49 +76,6 @@ class CoroutineTest { return@withContext data } - /** - * When refreshing, we have a temporary subscriber that hooks onto a single cycle. - * The refresh channel only contains booleans, but for the sake of identification, - * each boolean will have a unique integer attached. - * - * Things to note: - * Subscription should be opened outside of async, since we don't want to miss any events. - */ - @Test - fun refreshSubscriptions() { - val refreshChannel = BroadcastChannel<Pair<Boolean, Int>>(100) - runBlocking { - // Listen to all events - val fullReceiver = refreshChannel.openSubscription() - val fullDeferred = async { listen(fullReceiver) } - - refreshChannel.send(true to 1) - refreshChannel.send(false to 2) - refreshChannel.send(true to 3) - - val partialReceiver = refreshChannel.openSubscription() - val partialDeferred = async { transition(partialReceiver) } - refreshChannel.send(false to 4) - refreshChannel.send(true to 5) - refreshChannel.send(false to 6) - refreshChannel.send(true to 7) - refreshChannel.close() - val fullStream = fullDeferred.await() - val partialStream = partialDeferred.await() - - assertEquals( - 7, - fullStream.size, - "Full stream should contain all events" - ) - assertEquals( - listOf(false to 4, true to 5, false to 6), - partialStream, - "Partial stream should include up until first true false pair" - ) - } - } - private fun <T : Any> SharedFlow<T?>.takeUntilNull(): Flow<T> = takeWhile { it != null }.filterNotNull() @@ -159,45 +111,4 @@ class CoroutineTest { assertEquals(4, count, "Not all events received") } } - - class TestException(msg: String) : RuntimeException(msg) - - @Test - fun exceptionChecks() { - val mainTag = "main-test" - val mainDispatcher = Executors.newSingleThreadExecutor { r -> - Thread(r, mainTag) - }.asCoroutineDispatcher() - val channel = Channel<Int>() - - val job = SupervisorJob() - - val flyweight = Flyweight<Int, Int>(GlobalScope, 200L) { - throw TestException("Flyweight exception") - } - - suspend fun crash(): Boolean = withContext(Dispatchers.IO) { - try { - withContext(Dispatchers.Default) { - flyweight.fetch(0).await() - } - true - } catch (e: TestException) { - false - } - } - - runBlocking(mainDispatcher + job) { - launch { - val i = channel.receive() - println("Received $i") - } - launch { - println("A") - println(crash()) - println("B") - channel.offer(1) - } - } - } } |