Skip to content
This repository has been archived by the owner on Feb 2, 2025. It is now read-only.

Commit

Permalink
Upgrading to Arrow v2 (#269)
Browse files Browse the repository at this point in the history
* migrating to Arrow v2

* re-adding composeModify laws

* upgrade yarn lock

* Removing SetterLaws

arrow-kt/arrow#2859

* Cleaning up build warnings

Example of warning:

>  > Configure project :kotest-assertions-arrow-fx-coroutines
>  w: A compileOnly dependency is used in targets: Kotlin/JS.
>  Dependencies:
>      - io.arrow-kt:arrow-fx-coroutines:2.0.0 (source sets: jsMain)
>
>  Using compileOnly dependencies in these targets is not currently supported, because compileOnly dependencies must be present during the compilation of projects that depend on this project.
>
>  To ensure consistent compilation behaviour, compileOnly dependencies should be exposed as api dependencies.
>
>  Example:
>
>      kotlin {
>          sourceSets {
>              nativeMain {
>                  dependencies {
>                      compileOnly("org.example:lib:1.2.3")
>                      // additionally add the compileOnly dependency as an api dependency:
>                      api("org.example:lib:1.2.3")
>                  }
>              }
>          }
>      }
>
>  This warning can be suppressed in gradle.properties:
>
>      kotlin.suppressGradlePluginWarnings=IncorrectCompileOnlyDependencyWarning
  • Loading branch information
Kantis authored Dec 23, 2024
1 parent 6918f2a commit 8fa66cb
Show file tree
Hide file tree
Showing 31 changed files with 776 additions and 1,259 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ project/plugins/project/
credentials.sbt
/.idea/
.DS_Store
.kotlin
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ The project is not shipping the arrow jars because this leads to dependency conf

## Changelog

### 2.0.0

* Release for Kotlin 2.1.0 and Arrow 2.0

### 1.4.0

* Release for Kotlin 1.8 and Kotest 5.7 and Arrow 1.2
Expand Down
152 changes: 26 additions & 126 deletions buildSrc/src/main/kotlin/kotest-conventions.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.gradle.kotlin.dsl.all
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.named

plugins {
`java-library`
kotlin("multiplatform")
id("ru.vyarus.animalsniffer")
}
Expand All @@ -22,144 +19,47 @@ version = Ci.version
kotlin {
explicitApi()

targets {
metadata()
metadata()

jvm {
compilations.all {
kotlinOptions.jvmTarget = "1.8"
}
}

js(IR) {
browser()
nodejs()
jvm {
compilations.all {
kotlinOptions.jvmTarget = "1.8"
}
}

linuxX64()

mingwX64()

iosArm32()
iosArm64()
iosSimulatorArm64()
iosX64()
macosArm64()
macosX64()
tvosArm64()
tvosSimulatorArm64()
tvosX64()
watchosArm32()
watchosArm64()
watchosSimulatorArm64()
watchosX64()
watchosX86()
js(IR) {
browser()
nodejs()
}

sourceSets {
val commonMain by getting
val commonTest by getting {
dependsOn(commonMain)
}
linuxX64()

val jvmMain by getting {
dependsOn(commonMain)
}
mingwX64()

iosArm64()
iosSimulatorArm64()
iosX64()
macosArm64()
macosX64()
tvosArm64()
tvosSimulatorArm64()
tvosX64()
watchosArm32()
watchosArm64()
watchosSimulatorArm64()
watchosX64()

applyDefaultHierarchyTemplate()

sourceSets {
val kotestVersion = resolveVersion("kotest")

val jvmTest by getting {
dependsOn(commonTest)
dependsOn(jvmMain)
dependencies {
implementation("io.kotest:kotest-runner-junit5:$kotestVersion")
}
}

val jsMain by getting {
dependsOn(commonMain)
}

val jsTest by getting {
dependsOn(commonTest)
dependsOn(jsMain)
}

val mingwX64Main by getting
val linuxX64Main by getting
val iosArm32Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosX64Main by getting
val macosArm64Main by getting
val macosX64Main by getting
val tvosArm64Main by getting
val tvosSimulatorArm64Main by getting
val tvosX64Main by getting
val watchosArm32Main by getting
val watchosArm64Main by getting
val watchosSimulatorArm64Main by getting
val watchosX64Main by getting
val watchosX86Main by getting

val nativeMain by creating {
dependsOn(commonMain)
mingwX64Main.dependsOn(this)
linuxX64Main.dependsOn(this)
iosArm32Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
iosX64Main.dependsOn(this)
macosArm64Main.dependsOn(this)
macosX64Main.dependsOn(this)
tvosArm64Main.dependsOn(this)
tvosSimulatorArm64Main.dependsOn(this)
tvosX64Main.dependsOn(this)
watchosArm32Main.dependsOn(this)
watchosArm64Main.dependsOn(this)
watchosSimulatorArm64Main.dependsOn(this)
watchosX64Main.dependsOn(this)
watchosX86Main.dependsOn(this)
}

val mingwX64Test by getting
val linuxX64Test by getting
val iosArm32Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosX64Test by getting
val macosArm64Test by getting
val macosX64Test by getting
val tvosArm64Test by getting
val tvosSimulatorArm64Test by getting
val tvosX64Test by getting
val watchosArm32Test by getting
val watchosArm64Test by getting
val watchosSimulatorArm64Test by getting
val watchosX64Test by getting
val watchosX86Test by getting

create("nativeTest") {
dependsOn(nativeMain)
dependsOn(commonTest)
mingwX64Test.dependsOn(this)
linuxX64Test.dependsOn(this)
iosArm32Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
iosX64Test.dependsOn(this)
macosArm64Test.dependsOn(this)
macosX64Test.dependsOn(this)
tvosArm64Test.dependsOn(this)
tvosSimulatorArm64Test.dependsOn(this)
tvosX64Test.dependsOn(this)
watchosArm32Test.dependsOn(this)
watchosArm64Test.dependsOn(this)
watchosSimulatorArm64Test.dependsOn(this)
watchosX64Test.dependsOn(this)
watchosX86Test.dependsOn(this)
}

all {
languageSettings.optIn("kotlin.RequiresOptIn")
}
Expand Down
7 changes: 4 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[versions]
arrow = "1.2.4"
kotlin = "1.8.10"
arrow = "2.0.0"
kotlin = "2.1.0"
kotest = "5.8.1"
kotlinx-coroutines = "1.6.4"
animalsniffer = "1.7.1"
animalsniffer = "1.7.2"
kotlinBinaryCompatibilityValidator = "0.14.0"

[libraries]
Expand All @@ -18,6 +18,7 @@ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-c
arrow-fx-coroutines = { module = "io.arrow-kt:arrow-fx-coroutines", version.ref = "arrow" }
arrow-core = { module = "io.arrow-kt:arrow-core", version.ref = "arrow" }
arrow-optics = { module = "io.arrow-kt:arrow-optics", version.ref = "arrow" }
arrow-functions = { module = "io.arrow-kt:arrow-functions", version.ref = "arrow" }

# Gradle plugins used in buildSrc
kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
6 changes: 6 additions & 0 deletions kotest-assertions-arrow-fx-coroutines/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ kotlin {
}
}

jsMain {
dependencies {
api(libs.arrow.fx.coroutines)
}
}

nativeMain {
dependencies {
implementation(libs.arrow.fx.coroutines)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package io.kotest.assertions.arrow.fx.coroutines

import arrow.fx.coroutines.Resource
import arrow.fx.coroutines.continuations.ResourceScope
import arrow.fx.coroutines.continuations.resource
import io.kotest.core.extensions.LazyMaterialized
import io.kotest.core.listeners.ProjectListener

Expand Down Expand Up @@ -32,7 +30,6 @@ public class ProjectResource<A> private constructor(
) : ProjectListener, LazyMaterialized<A> by default {

public constructor(resource: Resource<A>) : this(resource, ResourceLazyMaterialized(resource))
public constructor(block: suspend ResourceScope.() -> Resource<A>) : this(resource { block().bind() })

override suspend fun beforeProject() {
default.init()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package io.kotest.assertions.arrow.fx.coroutines

import arrow.core.identity
import arrow.fx.coroutines.Resource
import arrow.fx.coroutines.continuations.resource
import arrow.fx.coroutines.resourceScope

public suspend infix fun <A> Resource<A>.shouldBeResource(a: A): A =
use { it shouldBe a }
resourceScope {
bind() shouldBe a
}

public suspend infix fun <A> Resource<A>.shouldBeResource(expected: Resource<A>): A =
resource {
resourceScope {
bind() shouldBe expected.bind()
}.use(::identity)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.kotest.assertions.arrow.fx.coroutines

import arrow.fx.coroutines.ExitCase
import arrow.fx.coroutines.Resource
import arrow.fx.coroutines.*
import io.kotest.core.extensions.LazyMaterialized
import io.kotest.core.extensions.LazyMountableExtension
import io.kotest.core.listeners.AfterSpecListener
Expand Down Expand Up @@ -62,28 +61,28 @@ public fun <A> Resource<A>.extension(lifecycleMode: LifecycleMode = LifecycleMod
public class ResourceExtension<A>(
public val resource: Resource<A>, public val lifecycleMode: LifecycleMode = LifecycleMode.Spec,
) : LazyMountableExtension<A, A>, TestListener, AfterSpecListener {

private var underlying: ResourceLazyMaterialized<A>? = null

override fun mount(configure: A.() -> Unit): LazyMaterialized<A> =
ResourceLazyMaterialized(resource, configure).also {
underlying = it
}

override suspend fun beforeSpec(spec: Spec) {
super.beforeSpec(spec)
if (lifecycleMode == LifecycleMode.Spec) {
underlying?.init()
}
}

override suspend fun afterSpec(spec: Spec) {
if (lifecycleMode == LifecycleMode.Spec) {
underlying?.release()
}
underlying?.close()
}

override suspend fun beforeAny(testCase: TestCase) {
val every = lifecycleMode == LifecycleMode.EveryTest
val root = lifecycleMode == LifecycleMode.Root && testCase.isRootTest()
Expand All @@ -92,7 +91,7 @@ public class ResourceExtension<A>(
underlying?.init()
}
}

override suspend fun afterAny(testCase: TestCase, result: TestResult) {
val every = lifecycleMode == LifecycleMode.EveryTest
val root = lifecycleMode == LifecycleMode.Root && testCase.isRootTest()
Expand All @@ -107,22 +106,22 @@ internal class ResourceLazyMaterialized<A>(
private val resource: Resource<A>,
private val configure: A.() -> Unit = {},
) : LazyMaterialized<A> {

sealed interface State<out A> {
object Empty : State<Nothing>
object Closed : State<Nothing>
data object Empty : State<Nothing>
data object Closed : State<Nothing>
data class Loading<A>(
val acquiring: CompletableDeferred<A> = CompletableDeferred(),
val finalizers: CompletableDeferred<suspend (ExitCase) -> Unit> = CompletableDeferred(),
) : State<A>

data class Done<A>(val value: A, val finalizers: suspend (ExitCase) -> Unit) : State<A>
}

private val state = AtomicReference<State<A>>(State.Empty)

override suspend fun get(): A = init()

@OptIn(DelicateCoroutinesApi::class)
tailrec suspend fun init(): A = when (val current = state.value) {
is State.Done -> current.value
Expand All @@ -131,11 +130,10 @@ internal class ResourceLazyMaterialized<A>(
State.Empty -> {
val loading = State.Loading<A>()
if (state.compareAndSet(State.Empty, loading)) {
val (res, fin) = resource.allocated()
.let { (acquire, finalizer) ->
val a = acquire()
val (res, fin) = resource.allocate()
.let { (a, finalizer) ->
@Suppress("NAME_SHADOWING")
val finalizer: suspend (ExitCase) -> Unit = { finalizer(a, it) }
val finalizer: suspend (ExitCase) -> Unit = { finalizer(it) }
Pair(a, finalizer)
}
state.value = State.Done(res, fin)
Expand All @@ -145,19 +143,19 @@ internal class ResourceLazyMaterialized<A>(
} else init()
}
}

tailrec suspend fun release(): Unit = when (val current = state.value) {
State.Empty -> Unit
is State.Done -> if (state.compareAndSet(current, State.Empty)) current.finalizers(ExitCase.Completed)
else release()

is State.Loading -> if (state.compareAndSet(current, State.Empty)) current.finalizers.await()
.invoke(ExitCase.Completed)
else release()

State.Closed -> Unit
}

fun close() {
state.value = State.Closed
}
Expand Down
Loading

0 comments on commit 8fa66cb

Please sign in to comment.