diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 9f01535f..212b873a 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -9,5 +9,7 @@ object Dependencies { object Kotlinx { const val coroutinesCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0-native-mt" + + const val atomicfu = "org.jetbrains.kotlinx:atomicfu:0.17.1" } } \ No newline at end of file diff --git a/kmp-nativecoroutines-core/build.gradle.kts b/kmp-nativecoroutines-core/build.gradle.kts index 93a30d57..7b498bef 100644 --- a/kmp-nativecoroutines-core/build.gradle.kts +++ b/kmp-nativecoroutines-core/build.gradle.kts @@ -35,6 +35,7 @@ kotlin { val commonTest by getting { dependencies { implementation(kotlin("test")) + implementation(Dependencies.Kotlinx.atomicfu) } } val appleMain by creating { diff --git a/kmp-nativecoroutines-core/src/appleTest/kotlin/com/rickclephas/kmp/nativecoroutines/NativeFlowTests.kt b/kmp-nativecoroutines-core/src/appleTest/kotlin/com/rickclephas/kmp/nativecoroutines/NativeFlowTests.kt index ce5dce3f..302ab64a 100644 --- a/kmp-nativecoroutines-core/src/appleTest/kotlin/com/rickclephas/kmp/nativecoroutines/NativeFlowTests.kt +++ b/kmp-nativecoroutines-core/src/appleTest/kotlin/com/rickclephas/kmp/nativecoroutines/NativeFlowTests.kt @@ -1,9 +1,9 @@ package com.rickclephas.kmp.nativecoroutines +import kotlinx.atomicfu.atomic import kotlinx.coroutines.* import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.flow -import kotlin.native.concurrent.AtomicInt import kotlin.native.concurrent.isFrozen import kotlin.test.* @@ -23,10 +23,10 @@ class NativeFlowTests { val flow = flow { } val job = Job() val nativeFlow = flow.asNativeFlow(CoroutineScope(job)) - val completionCount = AtomicInt(0) + val completionCount = atomic(0) nativeFlow({ _, _ -> }, { error, _ -> assertNull(error, "Flow should complete without an error") - completionCount.increment() + completionCount.incrementAndGet() }) job.children.forEach { it.join() } // Waits for the collection to complete assertEquals(1, completionCount.value, "Completion callback should be called once") @@ -38,12 +38,12 @@ class NativeFlowTests { val flow = flow { throw exception } val job = Job() val nativeFlow = flow.asNativeFlow(CoroutineScope(job)) - val completionCount = AtomicInt(0) + val completionCount = atomic(0) nativeFlow({ _, _ -> }, { error, _ -> assertNotNull(error, "Flow should complete with an error") val kotlinException = error.userInfo["KotlinException"] assertSame(exception, kotlinException, "Kotlin exception should be the same exception") - completionCount.increment() + completionCount.incrementAndGet() }) job.children.forEach { it.join() } // Waits for the collection to complete assertEquals(1, completionCount.value, "Completion callback should be called once") @@ -55,10 +55,10 @@ class NativeFlowTests { val flow = flow { values.forEach { emit(it) } } val job = Job() val nativeFlow = flow.asNativeFlow(CoroutineScope(job)) - val receivedValueCount = AtomicInt(0) + val receivedValueCount = atomic(0) nativeFlow({ value, _ -> assertSame(values[receivedValueCount.value], value, "Received incorrect value") - receivedValueCount.increment() + receivedValueCount.incrementAndGet() }, { _, _ -> }) job.children.forEach { it.join() } // Waits for the collection to complete assertEquals(values.size, receivedValueCount.value, "Item callback should be called for every value") @@ -69,12 +69,12 @@ class NativeFlowTests { val flow = MutableSharedFlow() val job = Job() val nativeFlow = flow.asNativeFlow(CoroutineScope(job)) - val completionCount = AtomicInt(0) + val completionCount = atomic(0) val cancel = nativeFlow({ _, _ -> }, { error, _ -> assertNotNull(error, "Flow should complete with an error") val exception = error.userInfo["KotlinException"] assertIs(exception, "Error should contain CancellationException") - completionCount.increment() + completionCount.incrementAndGet() }) delay(100) // Gives the collection some time to start cancel() diff --git a/kmp-nativecoroutines-core/src/appleTest/kotlin/com/rickclephas/kmp/nativecoroutines/NativeSuspendTests.kt b/kmp-nativecoroutines-core/src/appleTest/kotlin/com/rickclephas/kmp/nativecoroutines/NativeSuspendTests.kt index 40d14a7d..84e45d36 100644 --- a/kmp-nativecoroutines-core/src/appleTest/kotlin/com/rickclephas/kmp/nativecoroutines/NativeSuspendTests.kt +++ b/kmp-nativecoroutines-core/src/appleTest/kotlin/com/rickclephas/kmp/nativecoroutines/NativeSuspendTests.kt @@ -1,11 +1,11 @@ package com.rickclephas.kmp.nativecoroutines +import kotlinx.atomicfu.atomic import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlin.coroutines.cancellation.CancellationException -import kotlin.native.concurrent.AtomicInt import kotlin.native.concurrent.isFrozen import kotlin.test.* @@ -35,13 +35,13 @@ class NativeSuspendTests { val value = RandomValue() val job = Job() val nativeSuspend = nativeSuspend(CoroutineScope(job)) { delayAndReturn(100, value) } - val receivedResultCount = AtomicInt(0) - val receivedErrorCount = AtomicInt(0) + val receivedResultCount = atomic(0) + val receivedErrorCount = atomic(0) nativeSuspend({ receivedValue, _ -> assertSame(value, receivedValue, "Received incorrect value") - receivedResultCount.increment() + receivedResultCount.incrementAndGet() }, { _, _ -> - receivedErrorCount.increment() + receivedErrorCount.incrementAndGet() }) job.children.forEach { it.join() } // Waits for the function to complete assertEquals(1, receivedResultCount.value, "Result callback should be called once") @@ -53,15 +53,15 @@ class NativeSuspendTests { val exception = RandomException() val job = Job() val nativeSuspend = nativeSuspend(CoroutineScope(job)) { delayAndThrow(100, exception) } - val receivedResultCount = AtomicInt(0) - val receivedErrorCount = AtomicInt(0) + val receivedResultCount = atomic(0) + val receivedErrorCount = atomic(0) nativeSuspend({ _, _ -> - receivedResultCount.increment() + receivedResultCount.incrementAndGet() }, { error, _ -> assertNotNull(error, "Function should complete with an error") val kotlinException = error.userInfo["KotlinException"] assertSame(exception, kotlinException, "Kotlin exception should be the same exception") - receivedErrorCount.increment() + receivedErrorCount.incrementAndGet() }) job.children.forEach { it.join() } // Waits for the function to complete assertEquals(1, receivedErrorCount.value, "Error callback should be called once") @@ -72,15 +72,15 @@ class NativeSuspendTests { fun `ensure function is cancelled`() = runBlocking { val job = Job() val nativeSuspend = nativeSuspend(CoroutineScope(job)) { delayAndReturn(5_000, RandomValue()) } - val receivedResultCount = AtomicInt(0) - val receivedErrorCount = AtomicInt(0) + val receivedResultCount = atomic(0) + val receivedErrorCount = atomic(0) val cancel = nativeSuspend({ _, _ -> - receivedResultCount.increment() + receivedResultCount.incrementAndGet() }, { error, _ -> assertNotNull(error, "Function should complete with an error") val exception = error.userInfo["KotlinException"] assertIs(exception, "Error should contain CancellationException") - receivedErrorCount.increment() + receivedErrorCount.incrementAndGet() }) delay(100) // Gives the function some time to start cancel()