Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add failIf #204

Merged
merged 1 commit into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 9 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,56 +14,15 @@


# KBox
KBox is a very small but useful utility library for Kotlin (JVM, Android and JS).
KBox is a very small but useful utility library for Kotlin (JVM, Android and JS) providing functions which are missing
in the stdlib such as:
- failIf
- takeIf
- blankToNull
- isNotNullAndNotEmpty
- identity

Current extension functions:
- [`Array/List/Iterable/Sequence.appendtoStringBuilder`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/appendToString.kt#L37)
with the ability to define a different separator for the last separation
=> handy if you want to form sentences like `a, b and c`

- [`CharSequence.blankToNull`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/blanktoNull.kt#L7)
returns the same `CharSequence` if not blank, `null` otherwise

- [`forEachIn(Array/Iterable/Sequence<E>, Array/Iterable/Sequence<E>, ..., action: (E) -> Unit)`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/forEachIn.kt#L6)
applies the given action to each entry in the given `Iterable`s.

- [`<E> forElementAndEachIn(E, Array/Iterable/Sequence<E>, action: (E) -> Unit)`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/forThisAndForEach.kt#L6)
applies the given action to `this` and each entry in Iterable

- [`Iterable<T>.forEachRemaining()`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/forEachRemaining.kt#L9)
shortcut for `while(hasNext()) yourLambda(next())`

- [`Array/List.ifWithinBound`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/ifWithinBound.kt#L13)
shortcut for `if(index < size){ thenBlock() } else { elseBlock() }`

- [`CharSequence?.isNotNullAndNotEmpty/isNotNullAndNotBlank`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/isNotNullAndNot.kt#L6)

- [`Array/List/Iterable/Sequence.joinToString`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/joinToString.kt#L31)
with the ability to define a different separator for the last separation
=> handy if you want to form sentences like `a, b and c`

- [`Map<T, T>.mapParents`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/mapParents.kt#L13)
maps child-parent relations.

- [`Iterator<T>.mapRemaining/mapRemainingWithCounter`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/mapRemaining.kt#L9)
maps remaining entries with the help of a transform function (where `mapRemainingWithCounter` passes a counter variable to the transform function).

- [`Array/Iterable/Sequence.mapWithIndex`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/mapWithIndex.kt#L11)

- [`Sequence.dynamicTraversal`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/dynamicTraversal.kt#L34)
allows to iterator over a tree/graph like structure lazily

- [`Iterator.toPeekingIterator()`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/PeekingIteratorUnsynchronized.kt)
which allows to have a look what the next element is without consuming it.

- [`varargsToList/glue`](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/varargToList.kt#L11)
creates a `List` out of a single `E` and an `Array<E>`.

- [takeIf](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/takeIf.kt#L12)
same behaviour as `takeIf` but as prefix operator and not postfix.

Moreover, the following function might come in handy for you as well:
- [identity](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/identity.kt)
and more, see the [Documentation](#documentation) for a full list.

# Installation

Expand All @@ -72,13 +31,10 @@ KBox is published to maven central.
```
repositories { mavenCentral() }
dependencies {
implementation("ch.tutteli.kbox:kbox-jvm:0.16.0")
implementation("ch.tutteli.kbox:kbox:0.16.0")
}
```

Accordingly, you can use `kbox-js` as artifactId instead of `kbox-jvm`
(or simply `kbox` in case of a MPP project in commonMain).

# Documentation

Visit [https://robstoll.github.io/kbox/kdoc](https://robstoll.github.io/kbox/kdoc/).
Expand Down
11 changes: 11 additions & 0 deletions src/commonMain/kotlin/ch/tutteli/kbox/failIf.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ch.tutteli.kbox

/**
* Delegates to [check] but inverting the [predicate], i.e. throws an [IllegalStateException] if predicate is true.
*
* @param predicate the predicate which defines if the exception should be thrown or not.
* @param errorMessage The message which as [IllegalStateException.message]
*
* @since 1.0.0
*/
inline fun failIf(predicate: Boolean, errorMessage: () -> String) = check(predicate.not(), errorMessage)
24 changes: 24 additions & 0 deletions src/commonTest/kotlin/ch/tutteli/kbox/FailIfTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ch.tutteli.kbox

import ch.tutteli.atrium.api.fluent.en_GB.messageToContain
import ch.tutteli.atrium.api.fluent.en_GB.notToThrow
import ch.tutteli.atrium.api.fluent.en_GB.toThrow
import ch.tutteli.kbox.atrium.expect
import kotlin.test.Test

class FailIfTest {
@Test
fun it_throws_an_IllegalStateException_if_predicate_is_true() {
expect {
failIf(true) { "my message" }
}.toThrow<IllegalStateException> { messageToContain("my message") }
}

@Test
fun it_does_not_throw_if_predicate_holds() {
expect {
failIf(false) { throw UnsupportedOperationException("bla") }
}.notToThrow()
}
}