Skip to content

Commit

Permalink
Add support for Kotlin/JS targets (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevincianfarini authored Mar 9, 2024
1 parent 0f661fc commit c4b853c
Show file tree
Hide file tree
Showing 18 changed files with 680 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: actions/setup-java@v4.0.0
with:
distribution: 'zulu'
java-version: 19
java-version: 17

- name: Build and publish artifacts
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: actions/setup-java@v4.0.0
with:
distribution: 'zulu'
java-version: 19
java-version: 17

- run: ./gradlew -p . ${{matrix.job}}

11 changes: 11 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.gradle.api.tasks.testing.logging.TestLogEvent

plugins {
alias(libs.plugins.android.library) apply false
alias(libs.plugins.dokka)
Expand Down Expand Up @@ -32,4 +34,13 @@ subprojects {
if (jvmVersion.isPresent) jvmTarget = jvmVersion.get()
}
}

tasks.withType<AbstractTestTask> {
testLogging {
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
showStandardStreams = true
showStackTraces = true
events(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)
}
}
}
9 changes: 9 additions & 0 deletions compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ kotlin {
iosSimulatorArm64()
iosX64()
jvm()
js {
nodejs {
testTask {
useMocha {
timeout = "5s"
}
}
}
}
linuxArm64()
linuxX64()
macosArm64()
Expand Down
11 changes: 10 additions & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ kotlin {
iosSimulatorArm64()
iosX64()
jvm()
js {
nodejs {
testTask {
useMocha {
timeout = "5s"
}
}
}
}
linuxArm64()
linuxX64()
macosArm64()
Expand All @@ -32,7 +41,7 @@ kotlin {
}
commonTest.dependencies {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.coroutines.test)
implementation(libs.turbine)
implementation(project(":test"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.github.kevincianfarini.monarch
import app.cash.turbine.test
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
Expand Down Expand Up @@ -80,7 +80,7 @@ class InMemoryFeatureFlagDataStoreOverrideTest {
overrideValue: Any,
delegateValue: Any,
produceFlow: InMemoryFeatureFlagDataStoreOverride.(String) -> Flow<*>
) = runBlocking {
) = runTest {
val key = "foo"
val delegate = InMemoryFeatureFlagDataStore().apply { setValue(key, delegateValue) }
val storeOverride = storeOverride(
Expand Down Expand Up @@ -110,7 +110,7 @@ class InMemoryFeatureFlagDataStoreOverrideTest {
private fun storeCacheFallsBackToDelegateFlowParameterized(
delegateValue: Any,
produceFlow: InMemoryFeatureFlagDataStoreOverride.(String) -> Flow<*>
) = runBlocking {
) = runTest {
val key = "foo"
val delegate = InMemoryFeatureFlagDataStore().apply { setValue(key, delegateValue) }
val storeOverride = storeOverride(delegate = delegate)
Expand Down Expand Up @@ -138,7 +138,7 @@ class InMemoryFeatureFlagDataStoreOverrideTest {
initialValue: Any,
setNewValue: InMemoryFeatureFlagDataStoreOverride.(String) -> Unit,
produceFlow: InMemoryFeatureFlagDataStoreOverride.(String) -> Flow<*>
) = runBlocking {
) = runTest {
val key = "foo"
val storeOverride = storeOverride(initialOverrides = mapOf(key to initialValue))
storeOverride.produceFlow(key).test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@ import kotlin.test.*

class MixinFeatureFlagManagerTest {

@Test fun `manager gets string value`() {
@Test fun manager_gets_string_value() {
val store = InMemoryFeatureFlagDataStore().apply { setValue("foo", "bar") }
assertEquals(
expected = "bar",
actual = manager(store).currentValueOf(StringFeature),
)
}

@Test fun `manager gets default string value`() = assertEquals(
@Test fun manager_gets_default_string_value() = assertEquals(
expected = "blah",
actual = manager().currentValueOf(StringFeature),
)

@Test fun `manager gets boolean value`() {
@Test fun manager_gets_boolean_value() {
val store = InMemoryFeatureFlagDataStore().apply { setValue("bool", true) }
assertTrue(manager(store).currentValueOf(BooleanFeature))
}

@Test fun `manager gets default boolean value`() = assertFalse(manager().currentValueOf(BooleanFeature))
@Test fun manager_gets_default_boolean_value() = assertFalse(manager().currentValueOf(BooleanFeature))

@Test fun `manager gets double value`() {
@Test fun manager_gets_double_value() {
val store = InMemoryFeatureFlagDataStore().apply { setValue("double", 15.7) }
assertEquals(
expected = 15.7,
Expand All @@ -33,34 +33,34 @@ class MixinFeatureFlagManagerTest {
)
}

@Test fun `manager gets default double value`() = assertEquals(
@Test fun manager_gets_default_double_value() = assertEquals(
expected = 1.5,
actual = manager().currentValueOf(DoubleFeature),
absoluteTolerance = 0.05,
)

@Test fun `manager gets long value`() {
@Test fun manager_gets_long_value() {
val store = InMemoryFeatureFlagDataStore().apply { setValue("long", 27L) }
assertEquals(
expected = 27L,
actual = manager(store).currentValueOf(LongFeature),
)
}

@Test fun `manager gets default long value`() = assertEquals(
@Test fun manager_gets_default_long_value() = assertEquals(
expected = 1027L,
actual = manager().currentValueOf(LongFeature),
)

@Test fun `manager gets mixin value`() {
@Test fun manager_gets_mixin_value() {
val store = InMemoryFeatureFlagDataStore().apply { setValue("some_int", "1") }
assertEquals(
expected = 1,
actual = manager(store, listOf(ObservableIntDecodingMixin)).currentValueOf(IntFeatureFlag),
)
}

@Test fun `manager errors with unrecognized flag type`() {
@Test fun manager_errors_with_unrecognized_flag_type() {
// the below IS NOT a `BooleanOption` and therefore will go unrecognized
val someRandomFlag = object : FeatureFlag<Boolean> {
override val key: String = "random_key"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.github.kevincianfarini.monarch

import app.cash.turbine.test
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlin.test.*

class ObservableMixinFeatureFlagManagerTest {

@Test fun `manager gets string value`() {
runBlocking {
@Test fun manager_gets_string_value() {
runTest {
val store = InMemoryFeatureFlagDataStore().apply { setValue("foo", "bar") }
manager(store).valuesOf(StringFeature).test {
assertEquals("bar", awaitItem())
Expand All @@ -16,17 +16,17 @@ class ObservableMixinFeatureFlagManagerTest {
}
}

@Test fun `manager gets default string value`() {
runBlocking {
@Test fun manager_gets_default_string_value() {
runTest {
manager().valuesOf(StringFeature).test {
assertEquals("blah", awaitItem())
cancelAndIgnoreRemainingEvents()
}
}
}

@Test fun `manager gets boolean value`() {
runBlocking {
@Test fun manager_gets_boolean_value() {
runTest {
val store = InMemoryFeatureFlagDataStore().apply { setValue("bool", true) }
manager(store).valuesOf(BooleanFeature).test {
assertTrue(awaitItem())
Expand All @@ -35,17 +35,17 @@ class ObservableMixinFeatureFlagManagerTest {
}
}

@Test fun `manager gets default boolean value`() {
runBlocking {
@Test fun manager_gets_default_boolean_value() {
runTest {
manager().valuesOf(BooleanFeature).test {
assertFalse(awaitItem())
cancelAndIgnoreRemainingEvents()
}
}
}

@Test fun `manager gets double value`() {
runBlocking {
@Test fun manager_gets_double_value() {
runTest {
val store = InMemoryFeatureFlagDataStore().apply { setValue("double", 15.7) }
manager(store).valuesOf(DoubleFeature).test {
assertEquals(expected = 15.7, actual = awaitItem(), absoluteTolerance = 0.05)
Expand All @@ -54,17 +54,17 @@ class ObservableMixinFeatureFlagManagerTest {
}
}

@Test fun `manager gets default double value`() {
runBlocking {
@Test fun manager_gets_default_double_value() {
runTest {
manager().valuesOf(DoubleFeature).test {
assertEquals(expected = 1.5, actual = awaitItem(), absoluteTolerance = 0.05)
cancelAndIgnoreRemainingEvents()
}
}
}

@Test fun `manager gets long value`() {
runBlocking {
@Test fun manager_gets_long_value() {
runTest {
val store = InMemoryFeatureFlagDataStore().apply { setValue("long", 27L) }
manager(store).valuesOf(LongFeature).test {
assertEquals(expected = 27L, actual = awaitItem())
Expand All @@ -73,17 +73,17 @@ class ObservableMixinFeatureFlagManagerTest {
}
}

@Test fun `manager gets default long value`() {
runBlocking {
@Test fun manager_gets_default_long_value() {
runTest {
manager().valuesOf(LongFeature).test {
assertEquals(expected = 1027L, actual = awaitItem())
cancelAndIgnoreRemainingEvents()
}
}
}

@Test fun `manager gets mixin value`() {
runBlocking {
@Test fun manager_gets_mixin_value() {
runTest {
val store = InMemoryFeatureFlagDataStore().apply { setValue("some_int", "1") }
manager(store, listOf(ObservableIntDecodingMixin)).valuesOf(IntFeatureFlag).test {
assertEquals(expected = 1, actual = awaitItem())
Expand All @@ -92,8 +92,8 @@ class ObservableMixinFeatureFlagManagerTest {
}
}

@Test fun `manager errors with unrecognized flag type`() {
runBlocking {
@Test fun manager_errors_with_unrecognized_flag_type() {
runTest {
// the below IS NOT a `BooleanOption` and therefore will go unrecognized
val someRandomFlag = object : FeatureFlag<Boolean> {
override val key: String = "random_key"
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ android-minSdk = "21"
compose = "1.6.0"
dokka = "1.9.10"
kotlin = "1.9.22"
kotlin-nodejs = "18.16.12-pre.634"
kotlinx-coroutines = "1.8.0"
kotlinx-serialization = "1.6.2"
launchdarkly-android = "5.0.0"
Expand All @@ -13,6 +14,7 @@ turbine = "1.0.0"

[libraries]
compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose" }
kotlin-nodejs = { module = "org.jetbrains.kotlin-wrappers:kotlin-node", version.ref = "kotlin-nodejs" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
Expand Down
23 changes: 23 additions & 0 deletions integrations/environment-variable/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,32 @@ kotlin {

explicitApi()

iosArm64()
iosSimulatorArm64()
iosX64()
jvm()
js {
nodejs {
testTask {
useMocha {
timeout = "5s"
}
}
}
}
linuxArm64()
linuxX64()
macosArm64()
macosX64()
mingwX64()
tvosArm64()
tvosSimulatorArm64()
tvosX64()
watchosArm32()
watchosArm64()
watchosDeviceArm64()
watchosSimulatorArm64()
watchosX64()

sourceSets {
commonMain.dependencies {
Expand All @@ -22,5 +42,8 @@ kotlin {
commonTest.dependencies {
implementation(libs.kotlin.test)
}
jsMain.dependencies {
implementation(libs.kotlin.nodejs)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.kevincianfarini.monarch.environment

import node.process.process

internal actual fun getSystemEnvVar(key: String): String? {
return process.env[key]
}
2 changes: 1 addition & 1 deletion integrations/launch-darkly/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ android {

kotlin {
explicitApi()
jvmToolchain(19)
jvmToolchain(17)

iosArm64()
iosSimulatorArm64()
Expand Down
Loading

0 comments on commit c4b853c

Please sign in to comment.