diff --git a/core/src/main/kotlin/com/boswelja/watchconnection/core/discovery/Status.kt b/core/src/main/kotlin/com/boswelja/watchconnection/core/discovery/Status.kt index a3599f75..34792519 100644 --- a/core/src/main/kotlin/com/boswelja/watchconnection/core/discovery/Status.kt +++ b/core/src/main/kotlin/com/boswelja/watchconnection/core/discovery/Status.kt @@ -3,6 +3,7 @@ package com.boswelja.watchconnection.core.discovery enum class Status { CONNECTING, CONNECTED, + CONNECTED_NEARBY, DISCONNECTED, MISSING_APP, ERROR diff --git a/test/src/test/kotlin/com/boswelja/watchconnection/TestHelpers.kt b/test/src/test/kotlin/com/boswelja/watchconnection/TestHelpers.kt index f3a02aa6..adf8c041 100644 --- a/test/src/test/kotlin/com/boswelja/watchconnection/TestHelpers.kt +++ b/test/src/test/kotlin/com/boswelja/watchconnection/TestHelpers.kt @@ -5,7 +5,7 @@ import com.boswelja.watchconnection.core.message.Message import kotlin.random.Random fun createWatchesFor(count: Int, platformIdentifier: String): List { - return (0..count).map { + return (0 until count).map { Watch( name = "Watch $it", "platform$count", @@ -15,7 +15,7 @@ fun createWatchesFor(count: Int, platformIdentifier: String): List { } fun createCapabilities(count: Int): List { - return (0..count).map { "capability$it" } + return (0 until count).map { "capability$it" } } /** @@ -23,7 +23,7 @@ fun createCapabilities(count: Int): List { * assigned by WatchConnectionLib), and a fake [Message]. */ fun createMessagesFor(count: Int, platform: String): List> { - return (0..count).map { + return (0 until count).map { Pair( it.toString(), Message( diff --git a/test/src/test/kotlin/com/boswelja/watchconnection/wearos/WearOSDiscoveryPlatformTest.kt b/test/src/test/kotlin/com/boswelja/watchconnection/wearos/WearOSDiscoveryPlatformTest.kt index 8a3b3625..094f2843 100644 --- a/test/src/test/kotlin/com/boswelja/watchconnection/wearos/WearOSDiscoveryPlatformTest.kt +++ b/test/src/test/kotlin/com/boswelja/watchconnection/wearos/WearOSDiscoveryPlatformTest.kt @@ -1,7 +1,5 @@ package com.boswelja.watchconnection.wearos -import android.os.Build -import androidx.test.ext.junit.runners.AndroidJUnit4 import com.boswelja.watchconnection.wearos.rules.CapabilityClientTestRule import com.boswelja.watchconnection.wearos.rules.NodeClientTestRule import com.boswelja.watchconnection.wearos.rules.createNodes @@ -13,14 +11,10 @@ import kotlinx.coroutines.withTimeoutOrNull import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.annotation.Config import strikt.api.expectThat import strikt.assertions.containsExactly import strikt.assertions.isNotNull -@RunWith(AndroidJUnit4::class) -@Config(sdk = [Build.VERSION_CODES.R]) class WearOSDiscoveryPlatformTest { private val appCapability = "app-capability" diff --git a/test/src/test/kotlin/com/boswelja/watchconnection/wearos/WearOSMessagePlatformTest.kt b/test/src/test/kotlin/com/boswelja/watchconnection/wearos/WearOSMessagePlatformTest.kt index 42a993c3..8a47fca1 100644 --- a/test/src/test/kotlin/com/boswelja/watchconnection/wearos/WearOSMessagePlatformTest.kt +++ b/test/src/test/kotlin/com/boswelja/watchconnection/wearos/WearOSMessagePlatformTest.kt @@ -1,7 +1,5 @@ package com.boswelja.watchconnection.wearos -import android.os.Build -import androidx.test.ext.junit.runners.AndroidJUnit4 import com.boswelja.watchconnection.core.message.Message import com.boswelja.watchconnection.createMessagesFor import com.boswelja.watchconnection.wearos.rules.MessageClientTestRule @@ -10,20 +8,17 @@ import io.mockk.verify import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.cancel +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.annotation.Config import strikt.api.expectThat import strikt.assertions.containsExactlyInAnyOrder -@RunWith(AndroidJUnit4::class) -@Config(sdk = [Build.VERSION_CODES.R]) class WearOSMessagePlatformTest { @get:Rule @@ -81,21 +76,22 @@ class WearOSMessagePlatformTest { @ExperimentalCoroutinesApi @Test fun `incomingMessages gets all messages received by OnMessageReceivedListener`() { - val messages = createMessagesFor(10, messagePlatform.platformIdentifier) + val messageCount = 10 + val messages = createMessagesFor(messageCount, messagePlatform.platformIdentifier) val scope = CoroutineScope(Dispatchers.Default) // Start collecting messages + val job = Job() val collectedMessages = mutableListOf() - scope.launch { - messagePlatform.incomingMessages().collect { + scope.launch(job) { + messagePlatform.incomingMessages().take(messageCount).collect { collectedMessages += it + println("Got $it") } + println("Finished collection") } - // TODO This could cause flaky tests, remove it - Thread.sleep(50) - // Send the dummy messages messages.forEach { messageClientTestRule.receiveMessage( @@ -103,8 +99,8 @@ class WearOSMessagePlatformTest { ) } - // Cancel message collection - scope.cancel() + // Wait for collection to finish + job.complete() // Make sure we got all the messages expectThat(collectedMessages).containsExactlyInAnyOrder(messages.map { it.second }) diff --git a/test/src/test/kotlin/com/boswelja/watchconnection/wearos/rules/MessageClientTestRule.kt b/test/src/test/kotlin/com/boswelja/watchconnection/wearos/rules/MessageClientTestRule.kt index e73a4f29..2b02b59c 100644 --- a/test/src/test/kotlin/com/boswelja/watchconnection/wearos/rules/MessageClientTestRule.kt +++ b/test/src/test/kotlin/com/boswelja/watchconnection/wearos/rules/MessageClientTestRule.kt @@ -4,6 +4,10 @@ import com.google.android.gms.tasks.Tasks import com.google.android.gms.wearable.MessageClient import io.mockk.every import io.mockk.mockk +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import kotlinx.coroutines.withTimeoutOrNull import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement @@ -19,10 +23,19 @@ class MessageClientTestRule : TestRule { } fun receiveMessage(sourceNodeId: String, message: String, data: ByteArray? = null) { - if (messageListener == null) - throw NullPointerException("No message listener has been added") + val messageListener = runBlocking { + withTimeoutOrNull(1000L) { + withContext(Dispatchers.Default) { + while (messageListener == null) { + continue + } + } + + messageListener + } + } ?: throw NullPointerException("No message listener has been added") - messageListener!!.onMessageReceived(DummyMessageEvent(sourceNodeId, message, data)) + messageListener.onMessageReceived(DummyMessageEvent(sourceNodeId, message, data)) } inner class MessageClientTestRuleStatement(private val base: Statement?) : Statement() { diff --git a/wearos/src/main/kotlin/com/boswelja/watchconnection/wearos/WearOSDiscoveryPlatform.kt b/wearos/src/main/kotlin/com/boswelja/watchconnection/wearos/WearOSDiscoveryPlatform.kt index cd106a00..477eb2d6 100644 --- a/wearos/src/main/kotlin/com/boswelja/watchconnection/wearos/WearOSDiscoveryPlatform.kt +++ b/wearos/src/main/kotlin/com/boswelja/watchconnection/wearos/WearOSDiscoveryPlatform.kt @@ -135,8 +135,12 @@ class WearOSDiscoveryPlatform( // runBlocking should be safe here, since we're within a Flow val connectedNodes = runBlocking { nodeClient.connectedNodes.await() } // Got connected nodes, check if it contains our desired node - if (connectedNodes.any { it.id == watchId }) trySend(Status.CONNECTED) - else trySend(Status.DISCONNECTED) + val node = connectedNodes.firstOrNull { it.id == watchId } + val status = node?.let { + if (node.isNearby) Status.CONNECTED_NEARBY + else Status.CONNECTED + } ?: Status.DISCONNECTED + trySend(status) } catch (e: CancellationException) { // Failed, send error trySend(Status.ERROR)