Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add tests for core functionality #95

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
19 changes: 13 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ jobs:
strategy:
matrix:
config: [
{ target: "default", os: "ubuntu-latest", tasks: "test", continueOnError: false },
{ target: "osx", os: "macos-latest", tasks: "test", continueOnError: false },
{ target: "package", os: "ubuntu-latest", tasks: ":demo:composeApp:packageDistributionForCurrentOS", continueOnError: false }
{ target: "default", os: "ubuntu-latest", tasks: "test" },
{ target: "osx", os: "macos-latest", tasks: "test" },
{ target: "js-node", os: "ubuntu-latest", tasks: "jsNodeTest" },
{ target: "wasm-node", os: "ubuntu-latest", tasks: "wasmJsNodeTest" },
{ target: "package", os: "ubuntu-latest", tasks: ":demo:composeApp:packageDistributionForCurrentOS" }
]
runs-on: ${{ matrix.config.os }}
name: Test ${{ matrix.config.target }}
Expand Down Expand Up @@ -87,12 +89,17 @@ jobs:
uses: gradle/actions/wrapper-validation@v4

- name: Run ${{ matrix.config.target }} tests
continue-on-error: ${{ matrix.config.continueOnError }}
run: ./gradlew ${{ matrix.config.tasks }} --scan

test-browser:
strategy:
matrix:
config: [
{ target: "js", tasks: "jsBrowserTest" },
{ target: "wasm", tasks: "wasmJsBrowserTest" },
]
runs-on: ubuntu-latest
name: Test JS in browser
name: Test ${{ matrix.config.target }} in browser
needs: verify
steps:
- name: Checkout
Expand All @@ -114,4 +121,4 @@ jobs:
uses: browser-actions/setup-chrome@v1

- name: Run tests in browser
run: ./gradlew jsTest --scan
run: ./gradlew ${{ matrix.config.tasks }} --scan
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ fun Project.configureMultiplatform(
}
}

@OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)
internal fun KotlinMultiplatformExtension.configurePlatforms(
platforms: Set<Platform> = Platforms.All,
name: String,
) {
applyDefaultHierarchyTemplate()

@OptIn(ExperimentalKotlinGradlePluginApi::class)
compilerOptions {
freeCompilerArgs.add("-Xexpect-actual-classes")
optIn.add("dev.jordond.connectivity.InternalConnectivityApi")
Expand All @@ -70,11 +70,10 @@ internal fun KotlinMultiplatformExtension.configurePlatforms(
tvosArm64()
}

// TODO: Not currently supported by ktor-wasm02
// if (platforms.contains(Platform.Linux)) {
// linuxX64()
// linuxArm64()
// }
if (platforms.contains(Platform.Linux)) {
linuxX64()
linuxArm64()
}

if (platforms.contains(Platform.Js)) {
js {
Expand Down Expand Up @@ -118,6 +117,18 @@ internal fun KotlinMultiplatformExtension.configurePlatforms(

sourceSets.commonTest.dependencies {
implementation(kotlin("test"))
implementation(project.libs.findLibrary("kotlinx-coroutines-test").get())
implementation(project.libs.findLibrary("kotest-assertions").get())
implementation(project.libs.findLibrary("turbine").get())
}

sourceSets.androidUnitTest.dependencies {
implementation(project.libs.findLibrary("mockk-android").get())
implementation(project.libs.findLibrary("mockk-agent").get())
}

sourceSets.androidInstrumentedTest.dependencies {
implementation(project.libs.findLibrary("mockk-android").get())
implementation(project.libs.findLibrary("mockk-agent").get())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOf

// This suppress is needed because we now use a wrapper for the version code see VersionCodeProvider
@SuppressLint("NewApi")
internal class AndroidConnectivityProvider(
private val context: Context,
private val versionCodeProvider: VersionCodeProvider = VersionCodeProvider.Default,
) : ConnectivityProvider {

// The permission is in the manifest but the IDE doesn't seem to recognize it
Expand Down Expand Up @@ -49,10 +52,12 @@ internal class AndroidConnectivityProvider(
}

try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (versionCodeProvider.code >= Build.VERSION_CODES.N) {
println("Using registerDefaultNetworkCallback")
manager.registerDefaultNetworkCallback(networkCallback)
} else {
val networkRequest = NetworkRequest.Builder().build()
println("Using registerNetworkCallback")
manager.registerNetworkCallback(networkRequest, networkCallback)
}

Expand All @@ -67,7 +72,7 @@ internal class AndroidConnectivityProvider(
}

private fun ConnectivityManager.initialStatus(): Connectivity.Status {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return if (versionCodeProvider.code >= Build.VERSION_CODES.M) {
activeNetwork?.let { network ->
getNetworkCapabilities(network)?.let { capabilities ->
status(capabilities)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package dev.jordond.connectivity.internal

import android.os.Build

internal interface VersionCodeProvider {

val code: Int

companion object {
val Default = object : VersionCodeProvider {
override val code: Int = Build.VERSION.SDK_INT
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package dev.jordond.connectivity

import dev.jordond.connectivity.tools.ContextProvider
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.shouldBeInstanceOf
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.unmockkObject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.cancel
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test

@OptIn(ExperimentalCoroutinesApi::class)
class AndroidConnectivityTest {

private lateinit var testScope: TestScope
private lateinit var sutScope: TestScope
private lateinit var contextProvider: ContextProvider

@BeforeTest
fun setup() {
testScope = TestScope()
sutScope = TestScope()
contextProvider = mockk()
mockkObject(ContextProvider.Companion)
every { ContextProvider.getInstance() } returns contextProvider
every { contextProvider.context } returns mockk()
}

@AfterTest
fun cleanup() {
testScope.cancel()
sutScope.cancel()
unmockkObject(ContextProvider.Companion)
}

@Test
fun shouldCreateConnectivityWithDefaultOptions() = testScope.runTest {
val connectivity = Connectivity()

connectivity.shouldNotBeNull()
connectivity.shouldBeInstanceOf<Connectivity>()
sutScope.advanceUntilIdle()
connectivity.monitoring.value shouldBe false
}

@Test
fun shouldCreateConnectivityWithCustomOptions() = testScope.runTest {
val options = ConnectivityOptions(autoStart = true)

val connectivity = Connectivity(
options = options,
scope = sutScope,
)

connectivity.shouldNotBeNull()
connectivity.shouldBeInstanceOf<Connectivity>()
sutScope.advanceUntilIdle()
connectivity.monitoring.value shouldBe true
}

@Test
fun shouldCreateAndroidConnectivityWithDefaultOptions() = testScope.runTest {
val connectivity = AndroidConnectivity()

connectivity.shouldNotBeNull()
connectivity.shouldBeInstanceOf<Connectivity>()
sutScope.advanceUntilIdle()
connectivity.monitoring.value shouldBe false
}

@Test
fun shouldCreateAndroidConnectivityWithCustomOptions() = testScope.runTest {
val options = ConnectivityOptions(autoStart = true)

val connectivity = AndroidConnectivity(
options = options,
scope = sutScope,
)

connectivity.shouldNotBeNull()
connectivity.shouldBeInstanceOf<Connectivity>()
sutScope.advanceUntilIdle()
connectivity.monitoring.value shouldBe true
}

@Test
fun shouldUseProvidedCoroutineScope() = testScope.runTest {
val connectivity = Connectivity(scope = sutScope)

connectivity.shouldNotBeNull()
connectivity.shouldBeInstanceOf<Connectivity>()
}
}
Loading
Loading