Skip to content

Commit

Permalink
Merge pull request #31 from lupuuss/release-2.2.0
Browse files Browse the repository at this point in the history
Release 2.2.0
  • Loading branch information
lupuuss authored Aug 8, 2024
2 parents e6ce7f1 + 0627787 commit 7d90e2d
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</br>

[![Gradle Plugin Portal Stable](https://img.shields.io/gradle-plugin-portal/v/dev.mokkery)](https://plugins.gradle.org/plugin/dev.mokkery)
[![Kotlin](https://img.shields.io/badge/kotlin-2.0.0-blue.svg?logo=kotlin)](http://kotlinlang.org)
[![Kotlin](https://img.shields.io/badge/kotlin-2.0.10-blue.svg?logo=kotlin)](http://kotlinlang.org)
[![GitHub](https://img.shields.io/github/license/lupuuss/Mokkery)](https://github.com/lupuuss/Mokkery/blob/main/LICENSE)
[![Docs](https://img.shields.io/static/v1?label=api&message=reference&labelColor=gray&color=blueviolet&logo=gitbook&logoColor=white)](https://mokkery.dev/api_reference)

Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
mokkery = "2.1.1"
mokkery = "2.2.0"
kotlin = "2.0.10"
kotlinx-coroutines = "1.8.1"
buildconfig = "4.0.4"
Expand Down
2 changes: 1 addition & 1 deletion test-mokkery/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kotlinVersion=2.0.0
mokkeryVersion=2.1.1
mokkeryVersion=2.2.0
mokkeryAllowIndirectSuperCalls=true
org.gradle.jvmargs=-Xmx1g
39 changes: 32 additions & 7 deletions website/docs/Guides/Answers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ description: Explore different answer types with clear examples!

### Essentials

To define a const answer, use `returns`:
**To define a const answer, use `returns`:**

```kotlin
everySuspend { repository.findById(id = any()) } returns Book()
```

To throw an exception, use `throws`:
**To throw an exception, use `throws`:**

```kotlin
everySuspend { repository.findById(id = any()) } throws IllegalArgumentException()
```

To provide more complex answer, use `calls`:
**To provide more complex answer, use `calls`:**

* For regular functions:

Expand All @@ -39,28 +39,53 @@ and one of two [CallDefinitionScope](pathname:///api_reference/mokkery-runtime/d

### Utilities

To return specific arg, use `returnsArgAt`:
**To return specific arg, use `returnsArgAt`:**
```kotlin
everySuspend { repository.save(book = any()) } returnsArgAt 0

repository.save(Book()) // returns Book that was passed as an argument
```

To return `Result.success` from functions that return `Result`, use `returnsSuccess`:
**To return `Result.success` from functions that return `Result`, use `returnsSuccess`:**
```kotlin
everySuspend { repository.findByIdAsResult(id = "1") } returnsSuccess Book(id = "1")

repository.findByIdAsResult("1") // returns successful Result with given Book
```

To return `Result.failure` from functions that return `Result`, use `returnsFailure`:
**To return `Result.failure` from functions that return `Result`, use `returnsFailure`:**
```kotlin
everySuspend { repository.findByIdAsResult(id = "1") } returnsFailure ElementNotFoundException(id = "1")

repository.findByIdAsResult("1") // returns failed Result with given exception
```

To throw `IllegalStateException` with specific message (just like [kotlin.error](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/error.html)), use `throwsErrorWith`:
**To return a value provided each time by a function, use `returnsBy`:**
```kotlin
private var book = Book(...)

// ...

everySuspend { repository.findById(any()) } returnsBy ::book

repository.findById("1") // returns Book provided by `book` property
book = book.copy(title = "New title")
repository.findById("1") // returns Book provided by `book` property with changed title
```

:::tip
For functions returning a `Result`, you can use `returnsSuccessBy` or `returnsFailureBy`.
:::

**To throw an exception provided each time by a function, use `throwsBy`:**
```kotlin
everySuspend { repository.findById(any()) } throwsBy ::IllegalStateException

runCatching { repository.findById("1") } // throws newly created IllegalStateException
runCatching { repository.findById("1") } // throws newly created IllegalStateException
```

**To throw `IllegalStateException` with specific message (just like [kotlin.error](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/error.html)), use `throwsErrorWith`:**
```kotlin
everySuspend { repository.findById(id = any()) } throwsErrorWith "Failed!"
```
Expand Down
105 changes: 105 additions & 0 deletions website/docs/Guides/Coroutines.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
description: Learn how to work with Coroutines efficiently!
---

# Coroutines

Mokkery supports suspendable functions out of the box, making it easy to mock them right away with the [core answers](../Guides/Answers).

```kotlin
everySuspend { repository.findById(any()) } calls { (id: String) ->
delay(1_000)
Book(id = id)
}
```

## Coroutine utils module

Starting with Mokkery `2.2.0`, the `mokkery-coroutines` module is available, featuring `kotlinx-coroutines` specific answers.

### Setup

Add `dev.mokkery:mokkery-coroutines:$version` to your dependencies:

```kotlin
dependencies {
implementation("dev.mokkery:mokkery-coroutines:$version")
}
```

Alternatively, use the `mokkery(module: String)` utility from the Mokkery Gradle plugin for easier setup:

```kotlin
import dev.mokkery.gradle.mokkery

dependencies {
implementation(mokkery("coroutines")) // defaults to the current Mokkery version
}
```

### Awaits API

**To await a [Deferred](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/), use `awaits` overload:**
```kotlin
val deferred = CompletableDeferred<Book>()
everySuspend { repository.findById("1") } awaits deferred
```

**[Deferred](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/) might be created on each call:**

```kotlin
everySuspend { repository.findById(any()) } awaits { (id: String) -> createBookDeferred(id) }
```

**To await multiple
[Deferred](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/) instances and return results as a List, use `all`:**
```kotlin
import dev.mokkery.coroutines.answering.Awaitable.Companion.all

val deferred1 = CompletableDeferred<Book>()
val deferred2 = CompletableDeferred<Book>()
val deferred3 = CompletableDeferred<Book>()

everySuspend { repository.findAll() } awaits all(deferred1, deferred2, deferred3)
```

**To suspend indefinitely until coroutine is canceled, use `awaits cancellation`:**
```kotlin
import dev.mokkery.coroutines.answering.Awaitable.Companion.cancellation

everySuspend { repository.findById(any()) } awaits cancellation
```
**To await an element from a
[Channel](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-channel/), use `awaits receive(...)`:**
```kotlin
import dev.mokkery.coroutines.answering.Awaitable.Companion.receive

val channel = Channel<Book>()

everySuspend { repository.findById(any()) } awaits receive(from = channel)
```

**For `Unit`-returning functions, you can use `awaits send(...)` to send an element to
a [Channel](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-channel/).**
```kotlin
import dev.mokkery.coroutines.answering.Awaitable.Companion.send

val channel = Channel<String>()

everySuspend { repository.deleteById(any()) } awaits send(to = channel) { it.arg(0) }
```

**To return a value after a delay, use `awaits delayed(...)`:**
```kotlin
import dev.mokkery.coroutines.answering.Awaitable.Companion.delayed

everySuspend { repository.findById(any()) } awaits delayed(value = Book(...)) // by default, the delay takes 1 second.
```

**The `delayed` also accepts a lambda:**

```kotlin
import dev.mokkery.coroutines.answering.Awaitable.Companion.delayed

everySuspend { repository.findById(any()) } awaits delayed(by = 2.seconds) { (id: String) -> Book(id = id) }
```
8 changes: 4 additions & 4 deletions website/docs/Setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import Admonition from '@theme/Admonition';
<TabItem value="k2">
```kotlin
plugins {
kotlin("multiplatform") version "2.0.0" // ...or any other Kotlin plugin
id("dev.mokkery") version "2.1.1"
kotlin("multiplatform") version "2.0.10" // ...or any other Kotlin plugin
id("dev.mokkery") version "2.2.0"
}
```
</TabItem>
Expand Down Expand Up @@ -79,7 +79,7 @@ Once the required Maven repository is connected, you will be able to successfull

```kotlin
dependencies {
implementation("dev.mokkery:mokkery-gradle:2.1.1")
implementation("dev.mokkery:mokkery-gradle:2.2.0")
}
```

Expand Down Expand Up @@ -155,6 +155,6 @@ You can refer to [this file](https://github.com/lupuuss/Mokkery/blob/master/buil
</Admonition>
| Mokkery version | Supported Kotlin versions |
|------------------------------------|--------------------------------------------------------|
| 2.0.0 – 2.1.1 | 2.0.0+ |
| 2.0.0 – 2.2.0 | 2.0.0+ |
</TabItem>
</Tabs>
1 change: 1 addition & 0 deletions website/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const sidebars = {
'Guides/Matchers',
'Guides/Spying',
'Guides/Verifying',
'Guides/Coroutines'
]
}
]
Expand Down
4 changes: 2 additions & 2 deletions website/src/versions.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const kotlinVersion = "2.0.0"
export const mokkeryVersion = "2.1.1"
export const kotlinVersion = "2.0.10"
export const mokkeryVersion = "2.2.0"

0 comments on commit 7d90e2d

Please sign in to comment.