Skip to content

Commit

Permalink
Support loading the testing JS on non-JVM platforms (#1018)
Browse files Browse the repository at this point in the history
* Support loading the testing JS on non-JVM platforms

* More public APIs for testing
  • Loading branch information
squarejesse authored May 30, 2023
1 parent 85e5063 commit 996349c
Show file tree
Hide file tree
Showing 28 changed files with 160 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,12 @@ import app.cash.zipline.loader.internal.cache.SqlDriverFactory
import java.security.SecureRandom
import okio.ByteString
import okio.ByteString.Companion.toByteString
import okio.FileSystem

// This file is necessary to get Android tests to build.
//
// Note that we don't run Android tests because we don't have the right QuickJS or SQLite to run
// them on the JVM.

actual val systemFileSystem = FileSystem.SYSTEM

internal actual fun testSqlDriverFactory(): SqlDriverFactory =
error("testSqlDriverFactory not available for Android")

Expand All @@ -43,5 +40,3 @@ private fun testSecureRandom() = SecureRandom()
}

internal actual fun canSignEcdsaP256() = true

internal actual fun getEnv(name: String): String? = System.getenv(name)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package app.cash.zipline.loader
import app.cash.zipline.loader.testing.LoaderTestFixtures
import app.cash.zipline.loader.testing.LoaderTestFixtures.Companion.alphaUrl
import app.cash.zipline.loader.testing.LoaderTestFixtures.Companion.bravoUrl
import app.cash.zipline.testing.systemFileSystem
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import app.cash.zipline.Zipline
import app.cash.zipline.loader.ManifestVerifier.Companion.NO_SIGNATURE_CHECKS
import app.cash.zipline.loader.internal.getApplicationManifestFileName
import app.cash.zipline.loader.testing.LoaderTestFixtures
import app.cash.zipline.testing.systemFileSystem
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import app.cash.zipline.loader.testing.LoaderTestFixtures.Companion.bravoUrl
import app.cash.zipline.loader.testing.LoaderTestFixtures.Companion.createJs
import app.cash.zipline.loader.testing.LoaderTestFixtures.Companion.createRelativeManifest
import app.cash.zipline.loader.testing.LoaderTestFixtures.Companion.manifestUrl
import app.cash.zipline.testing.systemFileSystem
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
package app.cash.zipline.loader.internal.cache

import app.cash.zipline.loader.randomToken
import app.cash.zipline.loader.systemFileSystem
import app.cash.zipline.loader.testSqlDriverFactory
import app.cash.zipline.loader.testing.LoaderTestFixtures
import app.cash.zipline.testing.systemFileSystem
import com.squareup.sqldelight.db.SqlDriver
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ package app.cash.zipline.loader.internal.cache
import app.cash.zipline.loader.ZiplineCache
import app.cash.zipline.loader.internal.fetcher.LoadedManifest
import app.cash.zipline.loader.randomToken
import app.cash.zipline.loader.systemFileSystem
import app.cash.zipline.loader.testSqlDriverFactory
import app.cash.zipline.loader.testing.LoaderTestFixtures
import app.cash.zipline.loader.testing.LoaderTestFixtures.Companion.createJs
import app.cash.zipline.loader.testing.LoaderTestFixtures.Companion.createRelativeManifest
import app.cash.zipline.testing.systemFileSystem
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

package app.cash.zipline.loader.internal.tink.subtle

import app.cash.zipline.loader.systemFileSystem
import app.cash.zipline.loader.ziplineRoot
import app.cash.zipline.testing.systemFileSystem
import app.cash.zipline.testing.ziplineRoot
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import okio.Path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ import kotlinx.serialization.json.JsonElement
import okio.ByteString
import okio.FileSystem
import okio.Path
import okio.Path.Companion.toPath

expect val systemFileSystem: FileSystem

internal val ziplineRoot: Path
get() = getEnv("ZIPLINE_ROOT")!!.toPath()

fun testZiplineLoader(
dispatcher: CoroutineDispatcher,
Expand Down Expand Up @@ -82,5 +76,3 @@ fun prettyPrint(jsonString: String): String {
internal fun generateKeyPairForTest(): KeyPair {
return newKeyPairFromSeed(randomByteString(Field25519.FIELD_LEN))
}

internal expect fun getEnv(name: String): String?
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ import app.cash.zipline.loader.internal.cache.SqlDriverFactory
import java.security.SecureRandom
import okio.ByteString
import okio.ByteString.Companion.toByteString
import okio.FileSystem

actual val systemFileSystem = FileSystem.SYSTEM

internal actual fun testSqlDriverFactory() = SqlDriverFactory()

Expand All @@ -37,5 +34,3 @@ private fun testSecureRandom() = SecureRandom()
}

internal actual fun canSignEcdsaP256() = true

internal actual fun getEnv(name: String): String? = System.getenv(name)
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@ package app.cash.zipline.loader

import app.cash.zipline.loader.internal.cache.SqlDriverFactory
import kotlin.random.Random
import kotlinx.cinterop.toKString
import okio.ByteString
import okio.ByteString.Companion.toByteString
import okio.FileSystem
import platform.posix.getenv

actual val systemFileSystem = FileSystem.SYSTEM

internal actual fun testSqlDriverFactory() = SqlDriverFactory()

Expand All @@ -32,5 +27,3 @@ actual fun randomByteString(size: Int): ByteString {
}

internal actual fun canSignEcdsaP256() = false

internal actual fun getEnv(name: String): String? = getenv(name)?.toKString()
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import app.cash.zipline.testing.EchoService
import app.cash.zipline.testing.LoggingEventListener
import app.cash.zipline.testing.PotatoService
import app.cash.zipline.testing.SuspendingEchoService
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.isEmpty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package app.cash.zipline
import app.cash.zipline.testing.EchoRequest
import app.cash.zipline.testing.EchoResponse
import app.cash.zipline.testing.EchoService
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.matches
import kotlin.test.assertFailsWith
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import app.cash.zipline.testing.MessageInterfaceSerializersModule
import app.cash.zipline.testing.RealMessageInterface
import app.cash.zipline.testing.RequestInterfaceService
import app.cash.zipline.testing.ResponseInterfaceService
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.isEqualTo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import app.cash.zipline.testing.EchoRequest
import app.cash.zipline.testing.EchoResponse
import app.cash.zipline.testing.EchoService
import app.cash.zipline.testing.LoggingEventListener
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.isEqualTo
import kotlinx.coroutines.runBlocking
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package app.cash.zipline
import app.cash.zipline.testing.SealedClassMessageService
import app.cash.zipline.testing.SealedMessage.BlueMessage
import app.cash.zipline.testing.SealedMessage.RedMessage
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.containsExactly
import assertk.assertions.isEqualTo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import app.cash.zipline.testing.AdaptersResponse
import app.cash.zipline.testing.AdaptersResponseSerializersModule
import app.cash.zipline.testing.AdaptersSerializersModule
import app.cash.zipline.testing.AdaptersService
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.isEqualTo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import app.cash.zipline.testing.EchoService
import app.cash.zipline.testing.ServiceAndPrefix
import app.cash.zipline.testing.ServiceMemberSerializersModule
import app.cash.zipline.testing.ServiceTransformer
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.isEqualTo
import kotlinx.coroutines.runBlocking
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package app.cash.zipline

import app.cash.zipline.testing.loadTestingJs
import kotlin.test.assertEquals
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
Expand Down
1 change: 1 addition & 0 deletions zipline/src/jniTest/kotlin/app/cash/zipline/Utf8Test.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package app.cash.zipline

import app.cash.zipline.testing.Formatter
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.contains
import kotlin.test.assertFailsWith
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package app.cash.zipline

import app.cash.zipline.testing.SchedulerService
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.isEqualTo
import kotlinx.coroutines.async
Expand Down
1 change: 1 addition & 0 deletions zipline/src/jniTest/kotlin/app/cash/zipline/ZiplineTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import app.cash.zipline.testing.EchoService
import app.cash.zipline.testing.PotatoService
import app.cash.zipline.testing.SuspendingEchoService
import app.cash.zipline.testing.SuspendingPotatoService
import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.containsExactlyInAnyOrder
import assertk.assertions.isEqualTo
Expand Down
22 changes: 0 additions & 22 deletions zipline/src/jniTest/kotlin/app/cash/zipline/testUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,6 @@
*/
package app.cash.zipline

import java.io.BufferedReader

/** Load our testing libraries into QuickJS. */
fun Zipline.loadTestingJs() {
// Load modules in topologically-sorted order. In production the zipline-manifest does this.
loadJsModuleFromResource("./kotlin-kotlin-stdlib-js-ir.js")
loadJsModuleFromResource("./88b0986a7186d029-atomicfu-js-ir.js")
loadJsModuleFromResource("./kotlinx-serialization-kotlinx-serialization-core-js-ir.js")
loadJsModuleFromResource("./kotlinx-serialization-kotlinx-serialization-json-js-ir.js")
loadJsModuleFromResource("./kotlinx.coroutines-kotlinx-coroutines-core-js-ir.js")
loadJsModuleFromResource("./zipline-root-zipline.js")
loadJsModuleFromResource("./zipline-root-testing.js")
quickJs.evaluate("globalThis['testing'] = require('./zipline-root-testing.js');")
}

private fun Zipline.loadJsModuleFromResource(fileName: String) {
val fileJs = Zipline::class.java.getResourceAsStream(fileName.removePrefix("."))!!
.bufferedReader()
.use(BufferedReader::readText)
loadJsModule(fileJs, fileName)
}

/**
* See FinalizationTester for discussion on how to best trigger GC in tests.
* https://android.googlesource.com/platform/libcore/+/master/support/src/test/java/libcore/
Expand Down
1 change: 1 addition & 0 deletions zipline/src/jvmTest/kotlin/app/cash/zipline/ConsoleTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package app.cash.zipline

import app.cash.zipline.testing.loadTestingJs
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.isEqualTo
Expand Down
11 changes: 11 additions & 0 deletions zipline/testing/api/testing.api
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ public final class app/cash/zipline/testing/InterfaceSerializersKt {
public static final fun getMessageInterfaceSerializersModule ()Lkotlinx/serialization/modules/SerializersModule;
}

public final class app/cash/zipline/testing/IoTestingCommonKt {
public static final fun getZiplineRoot ()Lokio/Path;
public static final fun getZiplineRootOrNull ()Lokio/Path;
public static final fun loadTestingJs (Lapp/cash/zipline/Zipline;)V
}

public final class app/cash/zipline/testing/IoTestingJvmKt {
public static final fun getResourcesFileSystem ()Lokio/FileSystem;
public static final fun getSystemFileSystem ()Lokio/FileSystem;
}

public final class app/cash/zipline/testing/KotlinSerializersKt {
public static final fun getKotlinBuiltInSerializersModule ()Lkotlinx/serialization/modules/SerializersModule;
}
Expand Down
6 changes: 5 additions & 1 deletion zipline/testing/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,13 @@ kotlin {
dependsOn(hostMain)
}

val nativeMain by creating {
dependsOn(hostMain)
}

targets.withType<KotlinNativeTarget> {
val main by compilations.getting
main.defaultSourceSet.dependsOn(hostMain)
main.defaultSourceSet.dependsOn(nativeMain)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2023 Cash App
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package app.cash.zipline.testing

import app.cash.zipline.Zipline
import okio.FileSystem
import okio.Path
import okio.Path.Companion.toPath
import okio.buffer
import okio.use

expect val systemFileSystem: FileSystem

expect val resourcesFileSystem: FileSystem?

val ziplineRoot: Path
get() = ziplineRootOrNull!!

val ziplineRootOrNull: Path?
get() = getEnv("ZIPLINE_ROOT")?.toPath()

internal expect fun getEnv(name: String): String?

/** Load our testing libraries into QuickJS. */
fun Zipline.loadTestingJs() {
// Load modules in topologically-sorted order. In production the zipline-manifest does this.
loadJsModuleFromResource("./kotlin-kotlin-stdlib-js-ir.js")
loadJsModuleFromResource("./88b0986a7186d029-atomicfu-js-ir.js")
loadJsModuleFromResource("./kotlinx-serialization-kotlinx-serialization-core-js-ir.js")
loadJsModuleFromResource("./kotlinx-serialization-kotlinx-serialization-json-js-ir.js")
loadJsModuleFromResource("./kotlinx.coroutines-kotlinx-coroutines-core-js-ir.js")
loadJsModuleFromResource("./zipline-root-zipline.js")
loadJsModuleFromResource("./zipline-root-testing.js")
quickJs.evaluate("globalThis['testing'] = require('./zipline-root-testing.js');")
}

private fun Zipline.loadJsModuleFromResource(fileName: String) {
val fileJs = readJsAsResourceOrFile(fileName)
loadJsModule(fileJs, fileName)
}

/** Read as a resource on Android, and as a file on the file system on other platforms. */
private fun readJsAsResourceOrFile(fileName: String): String {
val root = ziplineRootOrNull
val resources = resourcesFileSystem

val source = when {
root != null -> {
systemFileSystem.source(
root / "zipline/testing/build/compileSync/js/main/developmentLibrary/kotlin" / fileName,
)
}

resources != null -> resources.source(fileName.toPath())

else -> error("no mechanism to read $fileName")
}

return source.buffer().use {
it.readUtf8()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (C) 2023 Cash App
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package app.cash.zipline.testing

import okio.FileSystem

actual val systemFileSystem = FileSystem.SYSTEM

actual val resourcesFileSystem: FileSystem? = FileSystem.RESOURCES

internal actual fun getEnv(name: String): String? = System.getenv(name)
Loading

0 comments on commit 996349c

Please sign in to comment.