diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f1534ed..6219da7 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -86,7 +86,7 @@ jobs:
name: Release ${{ matrix.module }} to Sonatype
strategy:
matrix:
- module: [kstore, kstore-file, kstore-storage]
+ module: [kstore, kstore-file, kstore-storage, kstore-test]
if: ${{ github.event_name != 'pull_request' }}
runs-on: macos-latest
needs:
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 38fe278..a5ce611 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -12,6 +12,7 @@
+
diff --git a/README.md b/README.md
index 014b4df..e584a74 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,9 @@ kstore-file = { module = "io.github.xxfast:kstore-file", version.ref = "kstore"
# for jsBrowser and wasmJsBrowser
kstore-storage = { module = "io.github.xxfast:kstore-storage", version.ref = "kstore" }
+
+# for testing
+kstore-test = { module = "io.github.xxfast:kstore-test", version.ref = "kstore" }
```
Depending on your target platforms, you will need to add platform configurations [here](https://xxfast.github.io/KStore/installation.html)
diff --git a/docs/topics/installation.md b/docs/topics/installation.md
index d0a99a6..47a2821 100644
--- a/docs/topics/installation.md
+++ b/docs/topics/installation.md
@@ -19,6 +19,7 @@ kstore = "x.x.x"
kstore = { module = "io.github.xxfast:kstore", version.ref = "kstore" }
kstore-file = { module = "io.github.xxfast:kstore-file", version.ref = "kstore" }
kstore-storage = { module = "io.github.xxfast:kstore-storage", version.ref = "kstore" }
+kstore-test = { module = "io.github.xxfast:kstore-test", version.ref = "kstore" }
```
### Targeting Android, iOS and/or Desktop
diff --git a/kstore-test/.gitignore b/kstore-test/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/kstore-test/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/kstore-test/build.gradle.kts b/kstore-test/build.gradle.kts
new file mode 100644
index 0000000..026b8bb
--- /dev/null
+++ b/kstore-test/build.gradle.kts
@@ -0,0 +1,57 @@
+import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
+import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask
+
+plugins {
+ kotlin("multiplatform")
+ id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.15.1"
+}
+
+kotlin {
+ explicitApi()
+
+ js(IR) {
+ browser()
+ }
+
+ wasmJs {
+ binaries.executable()
+ browser()
+ }
+
+ sourceSets {
+ val commonMain by getting {
+ dependencies {
+ implementation(project(":kstore"))
+ implementation(libs.kotlinx.serialization.json)
+ }
+ }
+
+ val commonTest by getting {
+ dependencies {
+ implementation(kotlin("test"))
+ implementation(libs.kotlinx.coroutines.test)
+ }
+ }
+ }
+}
+
+//
+// TODO: https://youtrack.jetbrains.com/issue/KT-63014/Running-tests-with-wasmJs-in-1.9.20-requires-Chrome-Canary#focus=Comments-27-8321383.0-0
+// The following is required to support the wasmJs target.
+//
+// Node.js Canary is set to 21.0.0-v8-canary20231019bd785be450
+// as that is the last version to ship Windows binaries too.
+//
+
+rootProject.extensions.configure {
+ nodeVersion = "21.0.0-v8-canary20231019bd785be450"
+ nodeDownloadBaseUrl = "https://nodejs.org/download/v8-canary"
+}
+
+rootProject.tasks.withType().configureEach {
+ val flag = "--ignore-engines"
+
+ if (!args.contains(flag)) {
+ args.add(flag)
+ }
+}
diff --git a/kstore-test/src/commonMain/kotlin/io/github/xxfast/kstore/test/InMemoryCodec.kt b/kstore-test/src/commonMain/kotlin/io/github/xxfast/kstore/test/InMemoryCodec.kt
new file mode 100644
index 0000000..13e7401
--- /dev/null
+++ b/kstore-test/src/commonMain/kotlin/io/github/xxfast/kstore/test/InMemoryCodec.kt
@@ -0,0 +1,36 @@
+package io.github.xxfast.kstore.test
+
+import io.github.xxfast.kstore.Codec
+import io.github.xxfast.kstore.DefaultJson
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.StringFormat
+import kotlinx.serialization.serializer
+
+
+/**
+ * A codec that stores data in memory.
+ */
+public inline fun InMemoryCodec(
+ format: StringFormat = DefaultJson,
+): InMemoryCodec = InMemoryCodec(format, format.serializersModule.serializer())
+
+/**
+ * A codec that stores data in memory.
+ */
+public class InMemoryCodec(
+ private val format: StringFormat,
+ private val serializer: KSerializer
+) : Codec {
+
+ private var storedData: String? = null
+
+ override suspend fun encode(value: T?) {
+ storedData = value?.let { format.encodeToString(serializer, it) }
+ }
+
+ override suspend fun decode(): T? = storedData?.let {
+ format.decodeFromString(serializer, it)
+ }
+
+}
diff --git a/kstore-test/src/commonMain/kotlin/io/github/xxfast/kstore/test/KStore.kt b/kstore-test/src/commonMain/kotlin/io/github/xxfast/kstore/test/KStore.kt
new file mode 100644
index 0000000..293838b
--- /dev/null
+++ b/kstore-test/src/commonMain/kotlin/io/github/xxfast/kstore/test/KStore.kt
@@ -0,0 +1,25 @@
+package io.github.xxfast.kstore.test
+
+import io.github.xxfast.kstore.DefaultJson
+import io.github.xxfast.kstore.KStore
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.StringFormat
+
+/**
+ * Creates a store with [InMemoryCodec]
+ *
+ * @param default returns this value if the record is not found. defaults to null
+ * @param enableCache maintain a cache. If set to false, it always reads from storage
+ * @param format Serializer to use. defaults to [DefaultJson]
+ *
+ * @return store that contains a value of type [T]
+ */
+public inline fun testStoreOf(
+ default: T? = null,
+ enableCache: Boolean = true,
+ format: StringFormat = DefaultJson,
+): KStore = KStore(
+ default = default,
+ enableCache = enableCache,
+ codec = InMemoryCodec(format)
+)
diff --git a/kstore/build.gradle.kts b/kstore/build.gradle.kts
index 65001e8..3595ac9 100644
--- a/kstore/build.gradle.kts
+++ b/kstore/build.gradle.kts
@@ -170,4 +170,5 @@ rootProject.tasks.withType().configureEach {
dependencies {
kover(project(":kstore-file"))
kover(project(":kstore-storage"))
+ kover(project(":kstore-test"))
}
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 92ffe25..860e28d 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -3,3 +3,4 @@ rootProject.name = "KStore"
include(":kstore")
include(":kstore-file")
include(":kstore-storage")
+include(":kstore-test")