Skip to content

Commit

Permalink
Add UnitFunRelaxer
Browse files Browse the repository at this point in the history
  • Loading branch information
bitPogo committed Feb 26, 2022
1 parent 09351ee commit 191d365
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ class AsyncFunMockery<ReturnValue, SideEffect : Function<ReturnValue>>(
id: String,
collector: Collector = Collector { _, _ -> Unit },
relaxer: Relaxer<ReturnValue>? = null,
unitFunRelaxer: Relaxer<ReturnValue>? = null,
freeze: Boolean = true,
spyOn: SideEffect? = null
) : KMockContract.AsyncFunMockery<ReturnValue, SideEffect>,
FunMockery<ReturnValue, SideEffect>(id, collector, relaxer, freeze, spyOn) {
FunMockery<ReturnValue, SideEffect>(
id = id,
collector = collector,
relaxer = relaxer,
unitFunRelaxer = unitFunRelaxer,
freeze = freeze,
spyOn = spyOn
) {
private suspend fun execute(
function: suspend () -> ReturnValue,
spy: (suspend () -> ReturnValue)?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ abstract class FunMockery<ReturnValue, SideEffect : Function<ReturnValue>>(
override val id: String,
collector: Collector = Collector { _, _ -> Unit },
relaxer: Relaxer<ReturnValue>?,
unitFunRelaxer: Relaxer<ReturnValue>?,
private val freeze: Boolean,
protected val spyOn: SideEffect?
) : KMockContract.FunMockery<ReturnValue, SideEffect> {
Expand All @@ -46,6 +47,8 @@ abstract class FunMockery<ReturnValue, SideEffect : Function<ReturnValue>>(
private val arguments: IsoMutableList<Array<out Any?>?> = sharedMutableListOf()
private val relaxer: AtomicRef<Relaxer<ReturnValue>?> = atomic(relaxer)

private val unitFunRelaxer: AtomicRef<Relaxer<ReturnValue>?> = atomic(unitFunRelaxer)

private val _verificationBuilder: AtomicRef<KMockContract.VerificationChainBuilder?> = atomic(null)
override var verificationBuilderReference: KMockContract.VerificationChainBuilder? by _verificationBuilder

Expand Down Expand Up @@ -170,7 +173,8 @@ abstract class FunMockery<ReturnValue, SideEffect : Function<ReturnValue>>(
}

protected fun invokeRelaxerOrFail(): ReturnValue {
return relaxer.value?.relax(id)
return unitFunRelaxer.value?.relax(id)
?: relaxer.value?.relax(id)
?: throw MockError.MissingStub("Missing stub value for $id")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ class SyncFunMockery<ReturnValue, SideEffect : Function<ReturnValue>>(
id: String,
collector: Collector = Collector { _, _ -> Unit },
relaxer: Relaxer<ReturnValue>? = null,
unitFunRelaxer: Relaxer<ReturnValue>? = null,
freeze: Boolean = true,
spyOn: SideEffect? = null
) : KMockContract.SyncFunMockery<ReturnValue, SideEffect>,
FunMockery<ReturnValue, SideEffect>(id, collector, relaxer, freeze, spyOn) {
FunMockery<ReturnValue, SideEffect>(
id = id,
collector = collector,
relaxer = relaxer,
unitFunRelaxer = unitFunRelaxer,
freeze = freeze,
spyOn = spyOn
) {
private fun execute(
function: () -> ReturnValue,
spy: (() -> ReturnValue)?,
Expand Down
15 changes: 15 additions & 0 deletions kmock/src/commonMain/kotlin/tech/antibytes/kmock/UnitFunRelaxer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2022 Matthias Geisler (bitPogo) / All rights reserved.
*
* Use of this source code is governed by Apache v2.0
*/

package tech.antibytes.kmock

inline fun <reified T> relaxUnitFun(): T? {
return if (T::class == Unit::class) {
Unit as T
} else {
null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,32 @@ class AsyncFunMockerySpec {

@Test
@JsName("fn6b")
fun `Given invoke is called it uses the given UnitFunRelaxer if no ReturnValue Provider is set`(): AsyncTestReturnValue {
// Given
val name: String = fixture.fixture()
val value = AtomicReference(fixture.fixture<Any>())
val capturedId = AtomicReference<String?>(null)
val mockery = SyncFunMockery<Any, () -> Unit>(
name,
unitFunRelaxer = { givenId ->
capturedId.set(givenId)

value
}
)

return runBlockingTestInContext(testScope1.coroutineContext) {
// When
val actual = mockery.invoke()

// Then
actual mustBe value
capturedId.value mustBe name
}
}

@Test
@JsName("fn6c")
fun `Given invoke is called it uses the given Implementation if no ReturnValue Provider is set`(): AsyncTestReturnValue {
// Given
val name: String = fixture.fixture()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import tech.antibytes.kmock.KMockContract.Collector
import tech.antibytes.util.test.MockError
import tech.antibytes.util.test.annotations.IgnoreJs
import tech.antibytes.util.test.annotations.JsOnly
import tech.antibytes.util.test.coroutine.AsyncTestReturnValue
import tech.antibytes.util.test.coroutine.runBlockingTest
import tech.antibytes.util.test.fixture.fixture
import tech.antibytes.util.test.fixture.kotlinFixture
Expand Down Expand Up @@ -138,6 +139,30 @@ class AsyncFunMockeryUnfrozenSpec {

@Test
@JsName("fn6b")
fun `Given invoke is called it uses the given UnitFunRelaxer if no ReturnValue Provider is set`(): AsyncTestReturnValue = runBlockingTest {
// Given
val name: String = fixture.fixture()
val value = AtomicReference(fixture.fixture<Any>())
val capturedId = AtomicReference<String?>(null)
val mockery = AsyncFunMockery<Any, suspend () -> Unit>(
name,
unitFunRelaxer = { givenId ->
capturedId.set(givenId)

value
}
)

// When
val actual = mockery.invoke()

// Then
actual mustBe value
capturedId.value mustBe name
}

@Test
@JsName("fn6c")
fun `Given invoke is called it uses the given Implementation if no ReturnValue Provider is set`() = runBlockingTest {
// Given
val name: String = fixture.fixture()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,32 @@ class SyncFunMockerySpec {

@Test
@JsName("fn6b")
fun `Given invoke is called it uses the given UnitFunRelaxer if no ReturnValue Provider is set`(): AsyncTestReturnValue {
// Given
val name: String = fixture.fixture()
val value = AtomicReference(fixture.fixture<Any>())
val capturedId = AtomicReference<String?>(null)
val mockery = AsyncFunMockery<Any, suspend () -> Unit>(
name,
unitFunRelaxer = { givenId ->
capturedId.set(givenId)

value
}
)

return runBlockingTestInContext(testScope1.coroutineContext) {
// When
val actual = mockery.invoke()

// Then
actual mustBe value
capturedId.value mustBe name
}
}

@Test
@JsName("fn6c")
fun `Given invoke is called it uses the given Implementation if no ReturnValue Provider is set`(): AsyncTestReturnValue {
// Given
val name: String = fixture.fixture()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,30 @@ class SyncFunMockeryUnfrozenSpec {

@Test
@JsName("fn6b")
fun `Given invoke is called it uses the given UnitFunRelaxer if no ReturnValue Provider is set`() {
// Given
val name: String = fixture.fixture()
val value = AtomicReference(fixture.fixture<Any>())
val capturedId = AtomicReference<String?>(null)
val mockery = SyncFunMockery<Any, () -> Unit>(
name,
unitFunRelaxer = { givenId ->
capturedId.set(givenId)

value
}
)

// When
val actual = mockery.invoke()

// Then
actual mustBe value
capturedId.value mustBe name
}

@Test
@JsName("fn6c")
fun `Given invoke is called it uses the given Implementation if no ReturnValue Provider is set`() {
// Given
val name: String = fixture.fixture()
Expand Down

0 comments on commit 191d365

Please sign in to comment.