Missed expect functions for atomics and tests
This commit is contained in:
parent
860ffa98e0
commit
e8d899928e
@ -63,10 +63,16 @@ xomrk {
|
||||
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
compileOnly(kotlinStdlibDependency)
|
||||
implementation(kotlinStdlibDependency)
|
||||
implementation("ru.landgrafhomyak.utility:highlevel-try-finally:0.5")
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-test:${this@kotlin.coreLibrariesVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
val jvmMain by getting {
|
||||
dependsOn(commonMain)
|
||||
dependencies {
|
||||
|
||||
@ -10,7 +10,7 @@ import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
||||
|
||||
@OptIn(ManualStateManipulation::class)
|
||||
@JvmName("use\$kt")
|
||||
public inline fun <R> CloseableState.use(block: () -> R): R {
|
||||
public inline fun <R> CloseableState.withUse(block: () -> R): R {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
package ru.landgrafhomyak.utility.closeable_state
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
internal class ErrorOnConcurrentAccessStateTest: _CloseableStateExternallySynchronizedAbstractTestSet() {
|
||||
override fun createState(): CloseableState = ErrorOnConcurrentAccessState()
|
||||
|
||||
@Test
|
||||
fun test() {}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
package ru.landgrafhomyak.utility.closeable_state
|
||||
|
||||
internal class TestThrowable: Throwable("If this throwable isn't caught then test is bad written") {
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package ru.landgrafhomyak.utility.closeable_state
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
internal class UsagesCounterTest: _CloseableStateAllowsConcurrencyAbstractTestSet() {
|
||||
override fun createState(): CloseableState = UsagesCounter()
|
||||
|
||||
@Test
|
||||
fun test() {}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package ru.landgrafhomyak.utility.closeable_state
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
@OptIn(ManualStateManipulation::class)
|
||||
internal abstract class _CloseableStateAbstractTestSet {
|
||||
abstract fun createState(): CloseableState
|
||||
|
||||
@Test
|
||||
fun testInstantClose() {
|
||||
this.createState().close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOneManual() {
|
||||
val s = this.createState()
|
||||
s.startUsage()
|
||||
s.finishUsage()
|
||||
s.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOneAuto() {
|
||||
val s = this.createState()
|
||||
s.withUse { }
|
||||
s.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSubsequentManual() {
|
||||
val s = this.createState()
|
||||
s.startUsage()
|
||||
s.finishUsage()
|
||||
s.startUsage()
|
||||
s.finishUsage()
|
||||
s.startUsage()
|
||||
s.finishUsage()
|
||||
s.close()
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testSubsequentAuto() {
|
||||
val s = this.createState()
|
||||
s.withUse { }
|
||||
s.withUse { }
|
||||
s.withUse { }
|
||||
s.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTryStartSuccess() {
|
||||
val s = this.createState()
|
||||
s.tryStartUsage { }
|
||||
s.finishUsage()
|
||||
s.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTryStartFailed() {
|
||||
val s = this.createState()
|
||||
try {
|
||||
s.tryStartUsage { throw TestThrowable() }
|
||||
} catch (_: TestThrowable) {
|
||||
}
|
||||
s.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTryFinishSuccess() {
|
||||
val s = this.createState()
|
||||
s.startUsage()
|
||||
s.tryFinishUsage { }
|
||||
s.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTryFinishFailed() {
|
||||
val s = this.createState()
|
||||
s.startUsage()
|
||||
try {
|
||||
s.tryFinishUsage { throw TestThrowable() }
|
||||
} catch (_: TestThrowable) {
|
||||
}
|
||||
try {
|
||||
s.close()
|
||||
} catch (_: Throwable) {}
|
||||
s.finishUsage()
|
||||
s.close()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package ru.landgrafhomyak.utility.closeable_state
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
@OptIn(ManualStateManipulation::class)
|
||||
internal abstract class _CloseableStateAllowsConcurrencyAbstractTestSet: _CloseableStateAbstractTestSet() {
|
||||
abstract override fun createState(): CloseableState
|
||||
|
||||
@Test
|
||||
fun testRecursionManual() {
|
||||
val s = this.createState()
|
||||
s.startUsage()
|
||||
s.startUsage()
|
||||
s.finishUsage()
|
||||
s.finishUsage()
|
||||
s.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRecursionAuto() {
|
||||
val s = this.createState()
|
||||
s.withUse { s.withUse { } }
|
||||
s.close()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package ru.landgrafhomyak.utility.closeable_state
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
@OptIn(ManualStateManipulation::class)
|
||||
internal abstract class _CloseableStateExternallySynchronizedAbstractTestSet : _CloseableStateAbstractTestSet() {
|
||||
abstract override fun createState(): CloseableState
|
||||
|
||||
@Test
|
||||
fun testRecursionManual() {
|
||||
val s = this.createState()
|
||||
s.startUsage()
|
||||
try {
|
||||
s.startUsage()
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
s.finishUsage()
|
||||
s.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRecursionAuto() {
|
||||
val s = this.createState()
|
||||
s.withUse {
|
||||
try {
|
||||
s.withUse {}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
s.close()
|
||||
}
|
||||
}
|
||||
@ -4,9 +4,9 @@ import org.testng.annotations.Test
|
||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||
import ru.landgrafhomyak.utility.closeable_state.ManualStateManipulation
|
||||
import ru.landgrafhomyak.utility.closeable_state.UsagesCounter
|
||||
import ru.landgrafhomyak.utility.closeable_state.use
|
||||
import ru.landgrafhomyak.utility.closeable_state.withUse
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)
|
||||
class KotlinStdlibDependencyTest {
|
||||
@Test
|
||||
fun testNoKotlinStdlib() {
|
||||
@ -52,11 +52,11 @@ class KotlinStdlibDependencyTest {
|
||||
fun testWithRef() {
|
||||
try {
|
||||
val refcnt = UsagesCounter()
|
||||
refcnt.use {
|
||||
return@use CustomUnit
|
||||
refcnt.withUse {
|
||||
return@withUse CustomUnit
|
||||
}
|
||||
refcnt.use w1@{
|
||||
return@w1 refcnt.use w2@{
|
||||
refcnt.withUse w1@{
|
||||
return@w1 refcnt.withUse w2@{
|
||||
return@w2 CustomUnit
|
||||
}
|
||||
}
|
||||
@ -70,7 +70,7 @@ class KotlinStdlibDependencyTest {
|
||||
fun testWithRef_Err() {
|
||||
try {
|
||||
val refcnt = UsagesCounter()
|
||||
refcnt.use {
|
||||
refcnt.withUse {
|
||||
throw CustomTestException()
|
||||
}
|
||||
} catch (_: CustomTestException) {
|
||||
|
||||
@ -1,8 +1,77 @@
|
||||
@file:Suppress("USELESS_CAST", "NOTHING_TO_INLINE")
|
||||
@file:JvmName("AtomicsKt")
|
||||
|
||||
package ru.landgrafhomyak.utility.closeable_state.internal
|
||||
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlinx.atomicfu.atomic
|
||||
import kotlinx.atomicfu.AtomicLong as kAtomicLong
|
||||
import kotlinx.atomicfu.AtomicRef as kAtomicRef
|
||||
import kotlinx.atomicfu.update
|
||||
import kotlinx.atomicfu.getAndUpdate
|
||||
|
||||
|
||||
internal actual typealias AtomicLong = kotlinx.atomicfu.AtomicLong
|
||||
internal actual typealias AtomicReference<T> = kotlinx.atomicfu.AtomicRef<T>
|
||||
internal actual typealias AtomicLong = kAtomicLong
|
||||
internal actual typealias AtomicReference<T> = kAtomicRef<T>
|
||||
|
||||
|
||||
internal actual inline fun newAtomicLong(initial: Long): AtomicLong =
|
||||
atomic(initial)
|
||||
|
||||
internal actual inline fun <T> newAtomicRef(initial: T): AtomicReference<T> =
|
||||
atomic(initial)
|
||||
|
||||
|
||||
internal actual inline fun AtomicLong.get(): Long =
|
||||
(this as kAtomicLong).value
|
||||
|
||||
internal actual inline fun <T> AtomicReference<T>.get(): T =
|
||||
(this as kAtomicRef).value
|
||||
|
||||
|
||||
internal actual inline fun AtomicLong.update(operator: (Long) -> Long) =
|
||||
(this as kAtomicLong).update(operator)
|
||||
|
||||
internal actual inline fun <T> AtomicReference<T>.update(operator: (T) -> T) =
|
||||
(this as kAtomicRef).update(operator)
|
||||
|
||||
internal actual inline fun AtomicLong.getAndUpdate(operator: (Long) -> Long): Long =
|
||||
(this as kAtomicLong).getAndUpdate(operator)
|
||||
|
||||
internal actual inline fun <T> AtomicReference<T>.getAndUpdate(operator: (T) -> T): T =
|
||||
(this as kAtomicRef).getAndUpdate(operator)
|
||||
|
||||
|
||||
internal actual inline fun AtomicLong.compareAndSet(expected: Long, newValue: Long): Boolean =
|
||||
(this as kAtomicLong).compareAndSet(expected, newValue)
|
||||
|
||||
internal actual inline fun <T> AtomicReference<T>.compareAndSet(expected: T, newValue: T): Boolean =
|
||||
(this as kAtomicRef).compareAndSet(expected, newValue)
|
||||
|
||||
|
||||
private fun AtomicLong.compareAndExchange_impl(expected: Long, newValue: Long): Long {
|
||||
val a = (this as kAtomicLong)
|
||||
return Misc._compareAndExchange(
|
||||
get = a::get,
|
||||
cas = a::compareAndSet,
|
||||
expected = expected, newValue = newValue
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun <T> AtomicReference<T>.compareAndExchange_impl(expected: T, newValue: T): T {
|
||||
val a = (this as kAtomicRef)
|
||||
return Misc._compareAndExchange(
|
||||
get = a::get,
|
||||
cas = a::compareAndSet,
|
||||
expected = expected, newValue = newValue
|
||||
)
|
||||
}
|
||||
|
||||
internal actual inline fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long {
|
||||
return this.compareAndExchange_impl(expected, newValue)
|
||||
}
|
||||
|
||||
internal actual inline fun <T> AtomicReference<T>.compareAndExchange(expected: T, newValue: T): T {
|
||||
return this.compareAndExchange_impl(expected, newValue)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user