Merge branch 'master' into improve-gradle

# Conflicts:
#	.github/workflows/java-windows.yml
#	build.gradle
This commit is contained in:
Joshua Gleitze
2020-04-12 19:19:25 +02:00
474 changed files with 14273 additions and 3618 deletions

View File

@@ -96,7 +96,16 @@ Please write a comment such as `I am working on this` in the issue,
this way we can assign the task to you (so that others know there is already someone working on the issue)
and it gives us the chance to have a look at the description again and revise if necessary.
*Architecture*
The following diagram illustrates the current architecture of Atrium and what it meant to add a shortcut for `Throwable.cause`. Many times, especially in [good first issues](https://github.com/robstoll/atrium/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) we refer to this names and they are also reflected in the directory structure of the project.
![Component diagram](https://raw.githubusercontent.com/robstoll/atrium/gh-pages/components.png?sanitize=true6)
<a name="git"></a>
*Git*
Dealing with Git for the first time? Here are some recommendations for how to set up Git when working on an issue:
- create a new branch for the issue using `git checkout -b <branch-name>` (preferrably, the branch name
should be descriptive of the issue or the change being made, e.g `#108-path-exists`.) Working

View File

@@ -1,4 +1,4 @@
----
______________________________________
I confirm that I have read the [Contributor Agreements v1.0](https://github.com/robstoll/atrium/blob/master/.github/Contributor%20Agreements%20v1.0.txt), agree to be bound on them and confirm that my contribution is compliant.

View File

@@ -18,9 +18,14 @@ jobs:
java-version: ${{ matrix.java_version }}
- name: Build buildNonDeprecatedJvm
run: ./gradlew buildNonDeprecatedJvm
env:
CI: true
- name: build sample atrium+spek project
run: samples\jvm\spek\gradlew -p samples\jvm\spek build
- name: Build sample atrium+junit5 project
run: samples\jvm\junit5\gradlew -p samples\jvm\junit5 build
- name: Build sample atrium+mpp kotlin project
run: samples\multiplatform\gradlew -p samples\multiplatform build

View File

@@ -0,0 +1,10 @@
name: "Validate Gradle Wrapper"
on: [push, pull_request]
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1

View File

@@ -32,6 +32,7 @@ jobs:
script:
- samples/jvm/spek/gradlew -p ./samples/jvm/spek build
- samples/jvm/junit5/gradlew -p ./samples/jvm/junit5 build
- samples/multiplatform/gradlew -p ./samples/multiplatform/ build
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock

View File

@@ -1,4 +1,4 @@
Atrium © Copyright Robert Stoll <rstoll@tutteli.ch> 2017, 2019
Atrium © Copyright Robert Stoll <rstoll@tutteli.ch> 2017, 2020
EUROPEAN UNION PUBLIC LICENCE v. 1.2
EUPL © the European Union 2007, 2016

View File

@@ -1,11 +1,21 @@
<!-- for master -->
[![Download](https://api.bintray.com/packages/robstoll/tutteli-jars/atrium/images/download.svg)](https://bintray.com/robstoll/tutteli-jars/atrium/_latestVersion "Download from Bintray")
[![EUPL](https://img.shields.io/badge/%E2%9A%96-EUPL%201.2-%230b45a6)](https://joinup.ec.europa.eu/collection/eupl/eupl-text-11-12 "License")
[![atrium @ kotlinlang.slack.com](https://img.shields.io/static/v1?label=kotlinlang&message=atrium&color=blue&logo=slack)](https://kotlinlang.slack.com/messages/C887ZKGCQ "See invitation link under section FAQ")
[![Build Status Travis](https://travis-ci.org/robstoll/atrium.svg?branch=master)](https://travis-ci.org/robstoll/atrium/branches)
[![Build Status GitHub Actions](https://github.com/robstoll/atrium/workflows/Windows/badge.svg)](https://github.com/robstoll/atrium/actions/)
[![Coverage](https://codecov.io/gh/robstoll/atrium/branch/master/graph/badge.svg)](https://codecov.io/github/robstoll/atrium/branch/master)
[![Coverage](https://codecov.io/gh/robstoll/atrium/branch/master/graph/badge.svg)](https://codecov.io/github/robstoll/atrium/branch/master)
[![Newcomers Welcome](https://img.shields.io/badge/%F0%9F%91%8B-Newcomers%20Welcome-blueviolet)](https://github.com/robstoll/atrium/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22 "Ask in slack for help")
<!-- for a specific release -->
<!--
[![Download](https://img.shields.io/badge/Download-0.10.0-%23007ec6)](https://bintray.com/robstoll/tutteli-jars/atrium/0.10.0 "Download 0.10.0 from Bintray")
[![EUPL](https://img.shields.io/badge/%E2%9A%96-EUPL%201.2-%230b45a6)](https://joinup.ec.europa.eu/collection/eupl/eupl-text-11-12 "License")
[![atrium @ kotlinlang.slack.com](https://img.shields.io/static/v1?label=kotlinlang&message=atrium&color=blue&logo=slack)](https://kotlinlang.slack.com/messages/C887ZKGCQ "See invitation link under section FAQ")
[![Newcomers Welcome](https://img.shields.io/badge/%F0%9F%91%8B-Newcomers%20Welcome-blueviolet)](https://github.com/robstoll/atrium/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22 "Ask in slack for help")
-->
# <img src="https://raw.githubusercontent.com/robstoll/atrium/gh-pages/logo.svg?sanitize=true" alt="Atrium" title="Atrium"/>
Atrium is an open-source multiplatform assertion library for Kotlin with support for JVM, JS and Android.
It is designed to support multiple [APIs](#api-styles), different error reporting styles and [Internationalization](#internationalization-1) (i18n).
@@ -20,10 +30,10 @@ Atrium currently provides two [API Styles](#api-styles):
pure fluent and infix where both of them have their design focus on usability in conjunction with code completion functionality provided by your IDE.
See [Examples](#examples) below to get a feel for how you could benefit from Atrium.
----
---
❗ You are taking a *sneak peek* at the next version.
Please have a look at the README of the git tag in case you are looking for the documentation of the corresponding version.
For instance, the [README of v0.9.0](https://github.com/robstoll/atrium/tree/v0.9.0/README.md).
For instance, the [README of v0.10.0](https://github.com/robstoll/atrium/tree/v0.10.0/README.md).
----
@@ -63,7 +73,6 @@ For instance, the [README of v0.9.0](https://github.com/robstoll/atrium/tree/v0.
- [KDoc - Code Documentation](#kdoc---code-documentation)
- [Known Limitations](#known-limitations)
- [FAQ](#faq)
- [Kotlin Bugs](#kotlin-bugs)
- [Roadmap](#roadmap)
- [Contributors and contribute](#contributors-and-contribute)
- [Sponsors](#sponsors)
@@ -79,7 +88,7 @@ but can also be retrieved directly from [bintray](https://bintray.com/robstoll/t
*gradle*:
```
buildscript {
ext { atrium_version='0.9.0' }
ext { atrium_version='0.10.0' }
}
repositories {
mavenCentral()
@@ -103,6 +112,7 @@ You can enable them as follows:
dependencies {
testImplementation "ch.tutteli.atrium:atrium-api-fluent-en_GB-jdk8:$atrium_version"
testImplementation "ch.tutteli.atrium:atrium-api-fluent-en_GB-kotlin_1_3:$atrium_version"
testRuntimeOnly "ch.tutteli.atrium:atrium-domain-robstoll-kotlin_1_3:$atrium_version"
}
```
@@ -110,7 +120,7 @@ dependencies {
<summary>click to see how the setup for the infix API looks like</summary>
The new infix API which is based on `Expect` and no longer on `Assert` is not yet available in v0.9.0.
The new infix API which is based on `Expect` and no longer on `Assert` is not yet available in v0.10.0.
[Your help](https://github.com/robstoll/atrium/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3A%22good+first+issue%22++new+infix)
in bringing the new infix API forward is appreciated.
@@ -147,7 +157,7 @@ That is all, you are all set. Jump to [Examples](#examples) which shows how to u
```
buildscript {
ext { atrium_version='0.9.0' }
ext { atrium_version='0.10.0' }
}
repositories {
mavenCentral()
@@ -193,6 +203,7 @@ You can enable them as follows:
```
dependencies {
testImplementation "ch.tutteli.atrium:atrium-api-fluent-en_GB-kotlin_1_3-js:$atrium_version"
testRuntimeOnly "ch.tutteli.atrium:atrium-domain-robstoll-kotlin_1_3-js:$atrium_version"
}
```
@@ -200,7 +211,7 @@ dependencies {
<summary>click to see how the setup for the infix API looks like</summary>
The new infix API which is based on `Expect` and no longer on `Assert` is not yet available in v0.9.0.
The new infix API which is based on `Expect` and no longer on `Assert` is not yet available in v0.10.0.
[Your help](https://github.com/robstoll/atrium/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3A%22good+first+issue%22++new+infix)
in bringing the new infix API forward is appreciated.
@@ -506,7 +517,7 @@ expected that subject: Person(firstName=Robert, lastName=Stoll, isStudent=false)
<sub>We are sorry that the syntax is not yet the nicest one.
We admit that one has to get used to it first and that is a pity.
Yet, it is due to many [Kotlin Bugs](#kotlin-bugs) standing in the way --
Yet, it is due to many [Kotlin Bugs](https://github.com/robstoll/atrium/wiki/Kotlin-Bugs-and-missing-features) standing in the way --
we hope we can provide a better API once Kotlin 1.4 is out (the new type inference respectively).</sub>
`feature` has several overloads, we are looking at the one expecting a lambda in which you have to provide a `MetaFeature`.
@@ -581,7 +592,7 @@ if the property as such is renamed (e.g., as part of an IDE refactoring).
As you can see, you would need to keep the property name and the name of the assertion function in sync to be meaningful
(otherwise one gets quickly confused or has to remember two names for the same thing).
Writing assertion functions for methods is a different story though, especially due to [overload bugs in Kotlin](#kotlin-bugs).
Writing assertion functions for methods is a different story though, especially due to [overload bugs in Kotlin](https://github.com/robstoll/atrium/wiki/Kotlin-Bugs-and-missing-features).
Also, code completion is not yet as good as it should be when it comes to methods.
Last but not least, in case it is not always safe to call a method (e.g. `List.get` => IndexOutOfBound) then it makes
sense to wrap it into an assertion function and use `ExpectImpl.feature.extractor` instead.
@@ -712,7 +723,7 @@ Also this version of `feature` provides to kind of overloads, one without and on
### Ambiguity Problems
Unfortunately there are several Kotlin bugs when it comes to overloading, especially in conjunction with `KFunction`
(see [Kotlin Bugs](#kotlin-bugs) and upvote in case you run into one).
(see [Kotlin Bugs](https://github.com/robstoll/atrium/wiki/Kotlin-Bugs-and-missing-features) and upvote in case you run into one).
However, Atrium provides alternative functions next to `f` within the `MetaFeature`-provider-lambda to disambiguate the situation.
Use `p` for properties and `f0` to `f5` for methods.
Likely you need to specify the type parameters manually as Kotlin is not able to infer them correctly.
@@ -1460,7 +1471,7 @@ expected that subject: "calling myFun with ..." <1234789>
The example should be self explanatory.
One detail to note though is the usage of `subExpect`.
It is a helper function which circumvents certain [Kotlin type inference bugs](#kotlin-bugs) (upvote them please).
It is a helper function which circumvents certain [Kotlin type inference bugs](https://github.com/robstoll/atrium/wiki/Kotlin-Bugs-and-missing-features) (upvote them please).
Writing the same as `mapOf<Int, Expect<Char>.() -> Unit>( 1 to { ... } )` would not work as the type for a lambda
involved in a `Pair` is not (yet) inferred correctly by Kotlin.
@@ -2425,49 +2436,6 @@ Deprecated APIs:
See [Ambiguity Problems](#ambiguity-problems) and [Property does not exist](#property-does-not-exist).
# Kotlin Bugs
The following issues hinder Atrium to progress in certain areas or they are the reason that we cannot use Atrium as intended in all cases.
Please upvote them (especially if you encounter them yourself):
- [Symbol is declared in unnamed module](https://youtrack.jetbrains.com/issue/KT-35343)
- [Gradle runtimeOnly bug](https://youtrack.jetbrains.com/issue/KT-21685) (reason that you see functions from package cc.en_GB when using cc.infix.en_GB)
- [navigate to source or show KDoc for overloaded extension function](https://youtrack.jetbrains.com/issue/KT-24836)
- [Lower bounds](https://youtrack.jetbrains.com/issue/KT-209), i.a. that functions intended for nullable subject do not show up on non-nullable subjects.
- [CTRL+P shows extension functions of unrelated type](https://youtrack.jetbrains.com/issue/KT-29133)
- [Expose @OnlyInputTypes to restrict e.g. toBe](https://youtrack.jetbrains.com/issue/KT-13198)
- [Type inference KFunction overload bug 1](https://youtrack.jetbrains.com/issue/KT-17340)
- [Type inference KFunction overload bug 2](https://youtrack.jetbrains.com/issue/KT-19884)
- [Type inference KProperty/KFunction ambiguity bug](https://youtrack.jetbrains.com/issue/KT-17341)
- [Type inference fails to infer T of KFunction0 for most types](https://youtrack.jetbrains.com/issue/KT-29515)
- [Type inference type parameter bug](https://youtrack.jetbrains.com/issue/KT-12963)
- [Type inference return type bug](https://youtrack.jetbrains.com/issue/KT-24918)
- [Type inference out type parameter bug](https://youtrack.jetbrains.com/issue/KT-18401)
- [Type inference explicit type and overloads](https://youtrack.jetbrains.com/issue/KT-23791)
- [Type inference Pair with receiver type](https://youtrack.jetbrains.com/issue/KT-29129)
- [Type inference unable to infer primitive type](https://youtrack.jetbrains.com/issue/KT-33290)
- [Overload resolution null bug](https://youtrack.jetbrains.com/issue/KT-6591) (reason why you need to specify what type `null` is in the infix API when using `assert(listOf(...)) contains null`)
- [Extension resolution null as receiver bug](https://youtrack.jetbrains.com/issue/KT-30496) (reason why you need to define that `null to null` is a Pair in the infix API)
- [Overload resolution nullable bug](https://youtrack.jetbrains.com/issue/KT-23768)
- [Overload resolution primitive type bug](https://youtrack.jetbrains.com/issue/KT-24230)
- [Overload resolution function type bug](https://youtrack.jetbrains.com/issue/KT-23883)
- [Overload resolution generic upper bound bug](https://youtrack.jetbrains.com/issue/KT-30235)
- [Overload ambiguity between val and fun](https://youtrack.jetbrains.com/issue/KT-32958)
- [false positive: remove explicit type arguments](https://youtrack.jetbrains.com/issue/KT-32869)
- [Wrong JS generated in case of name clash](https://youtrack.jetbrains.com/issue/KT-33294)
- [forbid function types as substitute of reified types ](https://youtrack.jetbrains.com/issue/KT-27846)
- [forbid parameterised types as substitute of reified types](https://youtrack.jetbrains.com/issue/KT-27826)
- [ReplaceWith does not add type parameter](https://youtrack.jetbrains.com/issue/KT-33685)
- [Wrong warning about predetermined type parameter](https://youtrack.jetbrains.com/issue/KT-34257)
And some features which would be handy
- [hide function with deprecation level error in code completion](https://youtrack.jetbrains.com/issue/KT-25263)
- [Method reference without `this`](https://youtrack.jetbrains.com/issue/KT-22920)
- [Infix function call with type parameters](https://youtrack.jetbrains.com/issue/KT-21593)
- [Extensibility for infix API](https://youtrack.jetbrains.com/issue/KT-27659)
- [Summarising overloads in code completion](https://youtrack.jetbrains.com/issue/KT-25079)
- [vararg for lambdas](https://youtrack.jetbrains.com/issue/KT-24287)
- [delegate with inline modifier](https://youtrack.jetbrains.com/issue/KT-23241)
# Roadmap
The roadmap is maintained at [atrium-roadmap](https://github.com/robstoll/atrium-roadmap).

View File

@@ -164,14 +164,5 @@ val <T : Any> AssertionPlant<T>.and: AssertionPlant<T> get() = this
*
* @return This plant to support a fluent API.
*/
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().and(assertionCreator).asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.and"
)
)
infix fun <T : Any> AssertionPlant<T>.and(assertionCreator: Assert<T>.() -> Unit) =
addAssertionsCreatedBy(assertionCreator)

View File

@@ -17,10 +17,10 @@ import kotlin.jvm.JvmName
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
fun <E> Assert<Array<out E>>.asIterable(): Assert<Iterable<E>> =
@@ -38,10 +38,10 @@ fun <E> Assert<Array<out E>>.asIterable(): Assert<Iterable<E>> =
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
fun <E> Assert<Array<out E>>.asIterable(assertionCreator: Assert<Iterable<E>>.() -> Unit): Assert<Iterable<E>> =
@@ -59,10 +59,10 @@ fun <E> Assert<Array<out E>>.asIterable(assertionCreator: Assert<Iterable<E>>.()
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("byteArrAsIterable")
@@ -81,10 +81,10 @@ fun Assert<ByteArray>.asIterable(): Assert<Iterable<Byte>> =
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("byteArrAsIterable")
@@ -103,10 +103,10 @@ fun Assert<ByteArray>.asIterable(assertionCreator: Assert<Iterable<Byte>>.() ->
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("charArrAsIterable")
@@ -125,10 +125,10 @@ fun Assert<CharArray>.asIterable(): Assert<Iterable<Char>> =
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("charArrAsIterable")
@@ -147,10 +147,10 @@ fun Assert<CharArray>.asIterable(assertionCreator: Assert<Iterable<Char>>.() ->
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("shortArrAsIterable")
@@ -169,10 +169,10 @@ fun Assert<ShortArray>.asIterable(): Assert<Iterable<Short>> =
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("shortArrAsIterable")
@@ -191,10 +191,10 @@ fun Assert<ShortArray>.asIterable(assertionCreator: Assert<Iterable<Short>>.() -
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("intArrAsIterable")
@@ -212,10 +212,10 @@ fun Assert<IntArray>.asIterable(): Assert<Iterable<Int>> = ExpectImpl.changeSubj
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("intArrAsIterable")
@@ -234,10 +234,10 @@ fun Assert<IntArray>.asIterable(assertionCreator: Assert<Iterable<Int>>.() -> Un
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("longArrAsIterable")
@@ -256,10 +256,10 @@ fun Assert<LongArray>.asIterable(): Assert<Iterable<Long>> =
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("longArrAsIterable")
@@ -278,10 +278,10 @@ fun Assert<LongArray>.asIterable(assertionCreator: Assert<Iterable<Long>>.() ->
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("floatArrAsIterable")
@@ -300,10 +300,10 @@ fun Assert<FloatArray>.asIterable(): Assert<Iterable<Float>> =
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("floatArrAsIterable")
@@ -322,10 +322,10 @@ fun Assert<FloatArray>.asIterable(assertionCreator: Assert<Iterable<Float>>.() -
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("doubleArrAsIterable")
@@ -344,10 +344,10 @@ fun Assert<DoubleArray>.asIterable(): Assert<Iterable<Double>> =
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("doubleArrAsIterable")
@@ -366,10 +366,10 @@ fun Assert<DoubleArray>.asIterable(assertionCreator: Assert<Iterable<Double>>.()
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert()",
"this.asExpect().asList().asAssert()",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("boolArrAsIterable")
@@ -388,10 +388,10 @@ fun Assert<BooleanArray>.asIterable(): Assert<Iterable<Boolean>> =
@Deprecated(
"Switch from Assert to Expect; will be removed with 1.0.0",
ReplaceWith(
"this.asExpect().asIterable().asAssert(assertionCreator)",
"this.asExpect().asList().asAssert(assertionCreator)",
"ch.tutteli.atrium.domain.builders.migration.asExpect",
"ch.tutteli.atrium.domain.builders.migration.asAssert",
"ch.tutteli.atrium.api.fluent.en_GB.asIterable"
"ch.tutteli.atrium.api.fluent.en_GB.asList"
)
)
@JvmName("boolArrAsIterable")

View File

@@ -5,6 +5,7 @@ dependencies {
api prefixedProject('domain-builders-android')
testImplementation prefixedProject('verbs-internal-android')
testImplementation prefixedProject('api-infix-en_GB-android')
}
srcAndResourcesFromJvmProject(project)

View File

@@ -13,6 +13,7 @@ dependencies {
api prefixedProject('domain-builders-jvm')
testImplementation prefixedProject('verbs-internal-jvm')
testImplementation prefixedProject('api-infix-en_GB-jvm')
}
//TODO should not be necessary https://youtrack.jetbrains.com/issue/KT-28124

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.creating.Assert
import ch.tutteli.atrium.creating.AssertionPlantNullable
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class AnyAssertionsSpec : ch.tutteli.atrium.spec.integration.AnyAssertionsSpec(
AssertionVerbFactory,
AnyAssertionsSpecFunFactory(),

View File

@@ -4,6 +4,7 @@ package ch.tutteli.atrium.api.cc.infix.en_GB
import ch.tutteli.atrium.creating.Assert
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
//TODO remove with 1.0.0, no need to migrate to Spek 2
class ArrayAsIterableAssertionsSpec : ch.tutteli.atrium.spec.integration.ArrayAsIterableAssertionsSpec(
AssertionVerbFactory,
"asIterable",

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.creating.Assert
import java.math.BigDecimal
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class BigDecimalAssertionsSpec : ch.tutteli.atrium.spec.integration.BigDecimalAssertionsSpec(
AssertionVerbFactory,
toBePair(),

View File

@@ -5,6 +5,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import ch.tutteli.atrium.creating.Assert
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class BooleanAssertionsSpec : ch.tutteli.atrium.spec.integration.BooleanAssertionsSpec(
AssertionVerbFactory,
toBeName() to Companion::toBeTrue,

View File

@@ -7,6 +7,7 @@ import ch.tutteli.atrium.creating.Assert
import ch.tutteli.atrium.reporting.translating.Translatable
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CharSequenceAssertionsSpec : ch.tutteli.atrium.spec.integration.CharSequenceAssertionsSpec(
AssertionVerbFactory,
getContainsDefaultTranslationOfPair(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.case
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CharSequenceContainsAtLeastAssertionsSpec : ch.tutteli.atrium.spec.integration.CharSequenceContainsAtLeastAssertionsSpec(
AssertionVerbFactory,
getAtLeastTriple(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.case
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CharSequenceContainsAtMostAssertionsSpec : ch.tutteli.atrium.spec.integration.CharSequenceContainsAtMostAssertionsSpec(
AssertionVerbFactory,
getAtMostTriple(),

View File

@@ -5,6 +5,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import ch.tutteli.atrium.creating.Assert
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CharSequenceContainsContainsNotAssertionsSpec : ch.tutteli.atrium.spec.integration.CharSequenceContainsContainsNotAssertionsSpec(
AssertionVerbFactory,
getContainsPair(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.case
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CharSequenceContainsExactlyAssertionsSpec : ch.tutteli.atrium.spec.integration.CharSequenceContainsExactlyAssertionsSpec(
AssertionVerbFactory,
getExactlyTriple(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.case
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CharSequenceContainsNotAssertionsSpec : ch.tutteli.atrium.spec.integration.CharSequenceContainsNotAssertionsSpec(
AssertionVerbFactory,
getContainsNotTriple(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.case
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CharSequenceContainsNotOrAtMostAssertionsSpec : ch.tutteli.atrium.spec.integration.CharSequenceContainsNotOrAtMostAssertionsSpec(
AssertionVerbFactory,
getNotOrAtMostTriple(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.case
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CharSequenceContainsRegexAssertionsSpec : ch.tutteli.atrium.spec.integration.CharSequenceContainsRegexAssertionsSpec(
AssertionVerbFactory,
getNameContainsRegex(),

View File

@@ -9,6 +9,7 @@ import ch.tutteli.atrium.domain.creating.charsequence.contains.CharSequenceConta
import ch.tutteli.atrium.domain.creating.charsequence.contains.searchbehaviours.NoOpSearchBehaviour
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
abstract class CharSequenceContainsSpecBase {
private val containsNotFun: KFunction2<Assert<String>, Any, Assert<String>> = Assert<String>::containsNot
protected val toContain = "${Assert<String>::to.name} ${contain::class.simpleName}"

View File

@@ -5,6 +5,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.Empty
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CollectionAssertionsSpec : ch.tutteli.atrium.spec.integration.CollectionAssertionsSpec(
AssertionVerbFactory,
Assert<Collection<Int>>::hasSize.name to Companion::hasSize,

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import kotlin.reflect.KProperty1
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class CollectionFeatureAssertionsSpec : ch.tutteli.atrium.spec.integration.CollectionFeatureAssertionsSpec(
AssertionVerbFactory,
sizeVal.name to sizeVal,

View File

@@ -4,6 +4,7 @@ package ch.tutteli.atrium.api.cc.infix.en_GB
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class ComparableAssertionsSpec : ch.tutteli.atrium.spec.integration.ComparableAssertionsSpec(
AssertionVerbFactory,
Assert<Int>::isLessThan.name to Companion::isLessThan,

View File

@@ -7,6 +7,7 @@ import ch.tutteli.atrium.spec.integration.TestData
internal typealias F = Assert<TestData>.() -> Unit
//TODO remove with 1.0.0, no need to migrate to Spek 2
class FeatureAssertionsBoundedReferenceSpec : ch.tutteli.atrium.spec.integration.FeatureAssertionsSpec(
AssertionVerbFactory,
propertyImmediate,

View File

@@ -5,6 +5,7 @@ import ch.tutteli.atrium.creating.CollectingAssertionPlant
import ch.tutteli.atrium.spec.integration.TestData
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
//TODO remove with 1.0.0, no need to migrate to Spek 2
class FeatureAssertionsBoundedReferenceWhenCollectingPlantSpec : ch.tutteli.atrium.spec.integration.FeatureAssertionsBoundedReferenceWhenCollectingPlantSpec(
AssertionVerbFactory,
propertyImmediate,

View File

@@ -5,6 +5,7 @@ import ch.tutteli.atrium.domain.builders.utils.subAssert
import ch.tutteli.atrium.spec.integration.TestData
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
//TODO remove with 1.0.0, no need to migrate to Spek 2
class FeatureAssertionsClassReferenceSpec : ch.tutteli.atrium.spec.integration.FeatureAssertionsSpec(
AssertionVerbFactory,
propertyImmediate,

View File

@@ -7,6 +7,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableAllAssertionsSpec: Spek({
include(PredicateSpec)
}) {

View File

@@ -10,6 +10,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableAnyAssertionsSpec : Spek({
include(PredicateSpec)
include(BuilderSpec)

View File

@@ -9,6 +9,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInAnyOrderAtLeast1EntriesAssertionsSpec : Spek({
include(BuilderSpec)
include(ShortcutSpec)

View File

@@ -9,6 +9,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInAnyOrderAtLeast1ValuesAssertionsSpec : Spek({
include(BuilderSpec)
include(ShortcutSpec)

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.order
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInAnyOrderAtLeastValuesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsInAnyOrderAtLeastValuesAssertionSpec(
AssertionVerbFactory,
getAtLeastTriple(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.order
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInAnyOrderAtMostValuesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsInAnyOrderAtMostValuesAssertionSpec(
AssertionVerbFactory,
getAtMostTriple(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.order
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInAnyOrderExactlyValuesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsInAnyOrderExactlyValuesAssertionsSpec(
AssertionVerbFactory,
getExactlyTriple(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.order
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInAnyOrderNotOrAtMostValuesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsInAnyOrderNotOrAtMostValuesAssertionsSpec(
AssertionVerbFactory,
getNotOrAtMostTriple(),

View File

@@ -7,6 +7,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.only
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.order
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInAnyOrderOnlyEntriesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsInAnyOrderOnlyEntriesAssertionsSpec(
AssertionVerbFactory,
getContainsPair(),

View File

@@ -7,6 +7,7 @@ import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.only
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.order
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInAnyOrderOnlyValuesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsInAnyOrderOnlyValuesAssertionsSpec(
AssertionVerbFactory,
getContainsPair(),

View File

@@ -10,6 +10,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInOrderOnlyEntriesAssertionsSpec : Spek({
include(BuilderSpec)

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.creating.Assert
import ch.tutteli.atrium.domain.builders.utils.Group
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInOrderOnlyGroupedEntriesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsInOrderOnlyGroupedEntriesAssertionsSpec(
AssertionVerbFactory,
getContainsPair(),

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.creating.Assert
import ch.tutteli.atrium.domain.builders.utils.Group
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInOrderOnlyGroupedValuesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsInOrderOnlyGroupedValuesAssertionsSpec(
AssertionVerbFactory,
getContainsPair(),

View File

@@ -10,6 +10,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsInOrderOnlyValuesAssertionsSpec : Spek({
include(BuilderSpec)

View File

@@ -5,6 +5,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import ch.tutteli.atrium.api.cc.infix.en_GB.keywords.contain
import ch.tutteli.atrium.creating.Assert
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsNotEntriesAssertionsSpec : ch.tutteli.atrium.spec.integration.IterableContainsNotEntriesAssertionsSpec(
AssertionVerbFactory,
getContainsNotPair(),

View File

@@ -8,6 +8,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableContainsNotValuesAssertionsSpec : Spek({
include(BuilderSpec)

View File

@@ -15,6 +15,7 @@ import ch.tutteli.atrium.domain.creating.iterable.contains.searchbehaviours.*
import ch.tutteli.atrium.verbs.internal.assert
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
abstract class IterableContainsSpecBase {
protected val Values = Values::class.simpleName
private val Entries = Entries::class.simpleName

View File

@@ -8,6 +8,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class IterableNoneAssertionsSpec : Spek({
include(PredicateSpec)

View File

@@ -12,6 +12,7 @@ import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.include
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class ListFeatureAssertionsSpec : Spek({
include(AtriumFeatureAssertionsSpec)

View File

@@ -4,6 +4,7 @@ package ch.tutteli.atrium.api.cc.infix.en_GB
import ch.tutteli.atrium.creating.Assert
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
//TODO remove with 1.0.0, no need to migrate to Spek 2
class MapAsEntriesAssertionsSpec : ch.tutteli.atrium.spec.integration.MapAsEntriesAssertionsSpec(
AssertionVerbFactory,
"asEntries",

View File

@@ -8,6 +8,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import ch.tutteli.atrium.verbs.internal.assert
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class MapAssertionsSpec : ch.tutteli.atrium.spec.integration.MapAssertionsSpec(
AssertionVerbFactory,
containsFun.name to Companion::contains,

View File

@@ -4,6 +4,7 @@ package ch.tutteli.atrium.api.cc.infix.en_GB
import ch.tutteli.atrium.creating.Assert
import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
//TODO remove with 1.0.0, no need to migrate to Spek 2
class MapEntryAssertionsSpec : ch.tutteli.atrium.spec.integration.MapEntryAssertionsSpec(
AssertionVerbFactory,
isKeyValueFun.name to Companion::isKeyValue

View File

@@ -7,6 +7,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import kotlin.reflect.KFunction2
import kotlin.reflect.KProperty1
//TODO remove with 1.0.0, no need to migrate to Spek 2
class MapEntryFeatureAssertionsSpec : ch.tutteli.atrium.spec.integration.MapEntryFeatureAssertionsSpec(
AssertionVerbFactory,
keyVal.name to keyVal,

View File

@@ -15,6 +15,7 @@ import kotlin.reflect.KProperty1
import ch.tutteli.atrium.verbs.internal.assert
import java.lang.IllegalArgumentException
//TODO remove with 1.0.0, no need to migrate to Spek 2
class MapFeatureAssertionsSpec : Spek({
include(AtriumMapFeatureAssertionsSpec)

View File

@@ -7,6 +7,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import kotlin.reflect.KFunction2
import kotlin.reflect.KProperty1
//TODO remove with 1.0.0, no need to migrate to Spek 2
class PairFeatureAssertionsSpec : ch.tutteli.atrium.spec.integration.PairFeatureAssertionsSpec(
AssertionVerbFactory,
firstVal.name to firstVal,

View File

@@ -5,6 +5,7 @@ import ch.tutteli.atrium.verbs.internal.AssertionVerbFactory
import ch.tutteli.atrium.creating.Assert
import ch.tutteli.atrium.domain.creating.throwable.thrown.ThrowableThrown
//TODO remove with 1.0.0, no need to migrate to Spek 2
class ThrowableAssertionsSpec : ch.tutteli.atrium.spec.integration.ThrowableAssertionsSpec(
AssertionVerbFactory,
getToThrowTriple(),

View File

@@ -8,6 +8,7 @@ import kotlin.reflect.KFunction
import kotlin.reflect.KFunction2
//TODO remove with 1.0.0, no need to migrate to Spek 2
class TypeTransformationAssertionsSpec : ch.tutteli.atrium.spec.integration.TypeTransformationAssertionsSpec(
AssertionVerbFactory,
getNotToBeNullPair(),

View File

@@ -14,19 +14,18 @@ These modules bundle:
Following a list of the available bundle-modules.
The links point to the KDoc of their included API where you find an overview of all available assertion functions of the API.
- [atrium-cc-de_CH-robstoll](https://robstoll.github.io/atrium/latest#/doc/ch.tutteli.atrium.api.cc.de_-c-h/index.html)
- [atrium-cc-en_GB-robstoll](https://robstoll.github.io/atrium/latest#/doc/ch.tutteli.atrium.api.cc.en_-g-b/index.html)
- [atrium-cc-infix-en_GB-robstoll](https://robstoll.github.io/atrium/latest#/doc/ch.tutteli.atrium.api.cc.infix.en_-g-b/index.html)
- [atrium-fluent-en_GB](https://robstoll.github.io/atrium/latest#/doc/ch.tutteli.atrium.api.fluent.en_-g-b/index.html)
- [atrium-infix-en_GB](https://robstoll.github.io/atrium/latest#/doc/ch.tutteli.atrium.api.infix.en_-g-b/index.html)
----
Following an excerpt of a build.gradle file which uses two APIs (see
Following an excerpt of a build.gradle file which uses twit APIs (see
[README#Installation](https://github.com/robstoll/atrium/tree/master/README.md#installation)
for the rest):
```
dependencies {
testCompile "ch.tutteli:atrium-cc-en_GB-robstoll:$atrium_version"
testCompile "ch.tutteli:atrium-api-cc-infix-en_GB-jvm:$atrium_version"
testCompile "ch.tutteli:atrium-fluent-en_GB:$atrium_version"
testCompile "ch.tutteli:atrium-api-infix-en_GB:$atrium_version"
}
```
@@ -34,25 +33,24 @@ The first dependency points to a bundle-module, the second one just adds the inf
:warning: if you want to use the same API in different languages,
then you have to make sure that you exclude all translation modules but one (I suggest you keep the one which is your primary language).
If you forget to do it, then the compiler will complain that you have the same enums multiple times on your classpath.
If you forget to dit it, then the compiler will complain that you have the same enums multiple times on your classpath.
# Different API styles
Atrium provides different APIs where the API differ in its style and the language in which it is written.
This site focuses on the different styles of APIs and compares their en_GB versions.
We do not show every single difference but merely where the APIs differ in naming.
For instance, the assertion function `Assert<Any>.toBe`:
Atrium currently provides two API styles: fluent and infix.
We dit not show every single difference but merely where the APIs differ in naming.
For instance, the assertion function `Expect<T>.toBe`:
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).toBe(2)
expect(x).toBe(2)
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) toBe 2
expect(x) toBe 2
```
is too similar, we will not list it here (ok, we did now but I guess you get the point).
is toit similar, we will not list it here (ok, we did now but I guess you get the point).
## Table of Content
- [Empty CharSequence / Collection](#empty-charsequence--collection)
@@ -69,42 +67,47 @@ is too similar, we will not list it here (ok, we did now but I guess you get the
## Empty CharSequence / Collection
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).isEmpty()
assert(x).isNotEmpty()
expect(x).isEmpty()
expect(x).isNotEmpty()
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) toBe Empty
assert(x) notToBe Empty
expect(x) toBe empty
expect(x) notToBe empty
```
## `and` property
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).isGreaterThan(1).and.isLessThan(10)
assert(x) { /*...*/ } and { /*...*/ }
expect(x).isGreaterThan(1).and.isLessThan(10)
expect(x) { /*...*/ } and { /*...*/ }
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
// does only support the group syntax
assert(x) { /*...*/ } and { /*...*/ }
expect(x) isGreaterThan 1 and o isLessThan 10
expect(x) { /*...*/ } and { /*...*/ }
```
Note that `o` is a filler object which is only there so that we can turn extension methods without parameters into
a method with one parameter and thus make it available as infix method.
## CharSequence contains
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).contains("hello", "world")
assert(x).contains.atLeast(1).butAtMost(2).value("hello")
assert(x).contains.exactly(1).values("hello", "robert")
assert(x).contains.atMost(2).regex("h(e|a)llo")
assert(x).contains.ignoringCase.notOrAtMost(1).regex("h(e|a)llo", "[Rr]obert")
expect(x).contains("hello", "world")
expect(x).contains.atLeast(1).butAtMost(2).value("hello")
expect(x).contains.exactly(1).values("hello", "robert")
expect(x).contains.atMost(2).regex("h(e|a)llo")
expect(x).contains.atMost(2).regex(Regex("h(e|a)llo"))
expect(x).contains.ignoringCase.regex("h(e|a)llo", "[Rr]obert")
expect(x).contains.ignoringCase.notOrAtMost(1).elementsOf(anIterable)
```
Notice that the final steps
`value`, `values` and `regex`
@@ -113,39 +116,41 @@ are applicable to all shown examples
(e.g. `exactly(1).values("hello", "robert")` could have been finished with `exactly(1).regex("h(e|a)llo")` as well).
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) contains Values("hello", "world")
assert(x) to contain atLeast 1 butAtMost 2 value "hello"
assert(x) to contain exactly 1 the Values("hello", "robert")
assert(x) to contain atMost 2 regex "h(e|a)llo"
assert(x) to contain ignoring case notOrAtMost 1 the RegexPatterns("h(e|a)llo", "[Rr]obert")
expect(x) contains values("hello", "world")
expect(x) contains o atLeast 1 butAtMost 2 value "hello"
expect(x) contains o exactly 1 the values("hello", "robert")
expect(x) contains o atMost 2 regex "h(e|a)llo"
expect(x) contains o atMost 2 matchFor Regex("h(e|a)llo")
expect(x) contains o ignoring case notOrAtMost 1 the regexPatterns("h(e|a)llo", "[Rr]obert")
expect(x) contains o ignoring case notOrAtMost 1 elementsOf anIterable
```
Notice that the final steps
`value`, `Values(...)`, `regex` and `RegexPatterns(..)`
`value`, `values(...)`, `regex` and `regexPatterns(..)`
in the sophisticated assertion building process
are applicable to all shown examples
(e.g. `exactly(1).values("hello", "robert")` could have been finished with `exactly(1).regex("h(e|a)llo")` as well).
(e.g. `exactly 1 values("hello", "robert")` could have been finished with `exactly 1 regex "h(e|a)llo"` as well).
## Iterable contains
### Iterable contains in any order
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).contains(1.2)
assert(x).contains(1.2, 5.7)
assert(x).contains { isLessThan(2) }
assert(x).contains({ isLessThan(2) }, { isGreaterThan 5 })
expect(x).contains(1.2)
expect(x).contains(1.2, 5.7)
expect(x).contains { isLessThan(2) }
expect(x).contains({ isLessThan(2) }, { isGreaterThan(5) })
assert(x).contains.inAnyOrder.atLeast(1).butAtMost(2).value(3.2)
assert(x).contains.inAnyOrder.exactly(1).values("hello", "robert")
assert(x).contains.inAnyOrder.atMost(2).entry { isLessOrEquals(2) }
assert(x).contains.inAnyOrder.notOrAtMost(2).entries({ notToBe(3) }, { isGreaterOrEquals(2) })
assert(x).contains.inAnyOrder.only.value("hello")
assert(x).contains.inAnyOrder.only.values(personA, personB)
assert(x).contains.inAnyOrder.only.entry { isLessThan(2) }
assert(x).contains.inAnyOrder.only.entries({ toBe(3) }, { isLessThan(2) })
expect(x).contains.inAnyOrder.atLeast(1).butAtMost(2).value(3.2)
expect(x).contains.inAnyOrder.exactly(1).values("hello", "robert")
expect(x).contains.inAnyOrder.atMost(2).entry { isLessOrEquals(2) }
expect(x).contains.inAnyOrder.notOrAtMost(2).entries({ notToBe(3) }, { isGreaterOrEquals(2) })
expect(x).contains.inAnyOrder.only.value("hello")
expect(x).contains.inAnyOrder.only.values(personA, personB)
expect(x).contains.inAnyOrder.only.entry { isLessThan(2) }
expect(x).contains.inAnyOrder.only.entries({ toBe(3) }, { isLessThan(2) })
```
Notice that the final steps
`value`, `values`, `entry` and `entries`
@@ -153,198 +158,203 @@ in the sophisticated assertion building process
are applicable to all shown examples
(e.g. `butAtMost(2).value(3.2)` could have been finished with `entries(...)` as well)
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) contains 1.2
assert(x) contains Values(1.2, 5.7) // or Objects as alternative
assert(x) contains { o isLessThan 2 }
assert(x) contains Entries({ o isLessThan 2 }, { o isGreaterThan 5 })
expect(x) contains 1.2
expect(x) contains values(1.2, 5.7) // or Objects as alternative
expect(x) contains { it isLessThan 2 }
expect(x) contains entries({ it isLessThan 2 }, { it isGreaterThan 5 })
assert(x) to contain inAny order atLeast 1 butAtMost 2 value 3.2
assert(x) to contain inAny order exactly 1 the Values("hello", "robert")
assert(x) to contain inAny order atMost 2 entry { o isLessOrEquals 2 }
assert(x) to contain inAny order notOrAtMost 2 the Entries({ o notToBe 3 }, { o isGreaterOrEquals 2 })
assert(x) to contain inAny order but only value "hello")
assert(x) to contain inAny order but only the Values(personA, personB)
assert(x) to contain inAny order but only entry { o isLessThan 2 }
assert(x) to contain inAny order but only the Entries({ o toBe 3 }, { o isLessThan 2 })
expect(x) contains o inAny order atLeast 1 butAtMost 2 value 3.2
expect(x) contains o inAny order exactly 1 the values("hello", "robert")
expect(x) contains o inAny order atMost 2 entry { it isLessOrEquals 2 }
expect(x) contains o inAny order notOrAtMost 2 the entries({ it notToBe 3 }, { it isGreaterOrEquals 2 })
expect(x) contains o inAny order but only value "hello"
expect(x) contains o inAny order but only the values(personA, personB)
expect(x) contains o inAny order but only entry { it isLessThan 2 }
expect(x) contains o inAny order but only the entries({ it toBe 3 }, { it isLessThan 2 })
```
Notice that the final steps
`value`, `Values(...)`, `entry` and `Entries(...)`
Note that `o` is a filler object which is only there so that we can turn extension methods without parameters into
a method with one parameter and thus make it available as infix method.
The final steps `value`, `values(...)`, `entry` and `entries(...)`
in the sophisticated assertion building process,
are applicable to all shown examples
(e.g. `butAtMost 2 value 3.2` could have been finished with `Entries(...)` as well)
(e.g. `butAtMost 2 value 3.2` could have been finished with `entries(...)` as well)
### Iterable contains in order
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).containsExactly(1.2)
assert(x).containsExactly(1.2, 5.7)
assert(x).containsExactly({ isLessThan(2) })
assert(x).containsExactly({ isLessThan(2) }, { isGreaterThan 5 })
expect(x).containsExactly(1.2)
expect(x).containsExactly(1.2, 5.7)
expect(x).containsExactly({ isLessThan(2) })
expect(x).containsExactly({ isLessThan(2) }, { isGreaterThan 5 })
assert(x).contains.inOrder.only.value("hello")
assert(x).contains.inOrder.only.values("hello", "world")
assert(x).contains.inOrder.only.entry { isLessThan(2) }
assert(x).contains.inOrder.only.entries({ toBe(3) }, { isLessThan(2) })
assert(x).contains.inOrder.only.grouped.within.inAnyOrder(
Value(1),
Values(1, 2),
Values(3, 4)
expect(x).contains.inOrder.only.value("hello")
expect(x).contains.inOrder.only.values("hello", "world")
expect(x).contains.inOrder.only.entry { isLessThan(2) }
expect(x).contains.inOrder.only.entries({ toBe(3) }, { isLessThan(2) })
expect(x).contains.inOrder.only.grouped.within.inAnyOrder(
value(1),
values(1, 2),
values(3, 4)
)
assert(x).contains.inOrder.only.grouped.within.inAnyOrder(
Entry({ toBe(1) }),
Entries({ isLessThan(2) },{ isGreaterThan(2) }),
Entries({ toBe(3) }, { toBe(4) })
expect(x).contains.inOrder.only.grouped.within.inAnyOrder(
entry { toBe(1) },
entries({ isLessThan(2) },{ isGreaterThan(2) }),
entries({ toBe(3) }, { toBe(4) })
)
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) containsExactly 1.2
assert(x) containsExactly Values(1.2, 5.7) // or Objects as alternative
assert(x) containsExactly { o isLessThan 2 }
assert(x) containsExactly Entries({ o isLessThan 2 }, { o isGreaterThan 5 })
expect(x) containsExactly 1.2
expect(x) containsExactly values(1.2, 5.7) // or Objects as alternative
expect(x) containsExactly { it isLessThan 2 }
expect(x) containsExactly entries({ it isLessThan 2 }, { it isGreaterThan 5 })
assert(x) contains inGiven order and only value "hello"
assert(x) contains inGiven order and only the Values("hello", "world")
assert(x) contains inGiven order and only entry { o isLessThan 2 }
assert(x) contains inGiven order and only the Entries({ o toBe 3 }, { o isLessThan 2 })
assert(x) contains inGiven order and only grouped entries within group inAny Order(
Value(1),
Values(1, 2),
Values(3, 4)
expect(x) contains o inGiven order and only value "hello"
expect(x) contains o inGiven order and only the values("hello", "world")
expect(x) contains o inGiven order and only entry { it isLessThan 2 }
expect(x) contains o inGiven order and only the entries({ it toBe 3 }, { it isLessThan 2 })
expect(x) contains o inGiven order and only grouped entries within group inAny Order(
value(1),
values(1, 2),
values(3, 4)
)
assert(x) contains inGiven order and only grouped entries within group inAny Order(
Entry({ o toBe(1) }),
Entries({ o isLessThan(2) },{ o isGreaterThan(2) }),
Entries({ o toBe(3) }, { o toBe(4) })
expect(x) contains o inGiven order and only grouped entries within group inAny Order(
entry { it toBe 1 },
entries({ it isLessThan 2 },{ it isGreaterThan 2 }),
entries({ it toBe 3 }, { it toBe 4 })
)
```
Note that `o` is a filler object which is only there so that we can turn extension methods without parameters into
a method with one parameter and thus make it available as infix method.
## Iterable contains not
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).containsNot(1.2)
assert(x).containsNot(1.2, 5.7)
expect(x).containsNot(1.2)
expect(x).containsNot(1.2, 5.7)
assert(x).containsNot.value(null)
assert(x).containsNot.values(null, 1)
assert(x).containsNot.entry { isLessThan(2) }
assert(x).containsNot.entries(null, { isLessThan(2) }, { isGreaterThan 5 })
expect(x).containsNot.value(null)
expect(x).containsNot.values(null, 1)
expect(x).containsNot.entry { isLessThan(2) }
expect(x).containsNot.entries(null, { isLessThan(2) }, { isGreaterThan 5 })
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) containsNot 1.2
assert(x) containsNot Values(1.2, 5.7)
expect(x) containsNot 1.2
expect(x) containsNot values(1.2, 5.7)
assert(x) notTo contain value null
assert(x) notTo contain the Values(null, 1)
assert(x) notTo contain entry { o isLessThan 2 }
assert(x) notTo contain the Entries(null, { o isLessThan 2 }, { o isGreaterThan 5 })
expect(x) containsNot o value null
expect(x) containsNot o the values(null, 1)
expect(x) containsNot o entry { it isLessThan 2 }
expect(x) containsNot o the entries(null, { it isLessThan 2 }, { it isGreaterThan 5 })
```
# Iterable predicate-like assertions
For more sophisticated assertions such as "there should be two matches", use the sophisticated assertion builder `contains.inAnyOrder`
-&gt; see [Iterable contains in any order](#iterable-contains-in-any-order) for more information
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).any { startsWith("hello") }
assert(x).none { endsWith(".") }
assert(x).all { isNumericallyEqualTo(12.2) }
expect(x).any { startsWith("hello") }
expect(x).none { endsWith(".") }
expect(x).all { isNumericallyEqualTo(12.2) }
assert(x).any(null)
assert(x).none(null)
assert(x).all(null)
expect(x).any(null)
expect(x).none(null)
expect(x).all(null)
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) any { o startsWith "hello" }
assert(x) none { o endsWith "." }
assert(x) all { o isNumericallyEqualTo 12.2 }
expect(x) any { it startsWith "hello" }
expect(x) none { it endsWith "." }
expect(x) all { it isNumericallyEqualTo 12.2 }
assert(x) any null
assert(x) none null
assert(x) all null
expect(x) any null
expect(x) none null
expect(x) all null
```
# List get
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).get(0).isLessThan(1)
assert(x).get(0) { isGreaterThan(1) }
expect(x).get(0).isLessThan(1)
expect(x).get(0) { isGreaterThan(1) }
//in case of a nullable element type
assert(x).get(0).toBe(null)
expect(x).get(0).toBe(null)
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) get 0 isLessThan 1
assert(x) get Index(0) assertIt { o isGreaterThan 1 }
expect(x) get 0 isLessThan 1
expect(x) get index(0) { it isGreaterThan 1 }
//in case of a nullable element type
assert(x) get 0 toBe null
expect(x) get 0 toBe null
```
# Map getExisting
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).getExisting("a").isLessThan(1)
assert(x).getExisting("a") { isGreaterThan(1) }
expect(x).getExisting("a").isLessThan(1)
expect(x).getExisting("a") { isGreaterThan(1) }
//in case of a nullable value type
assert(x).getExisting("a").notToBeNull { isGreaterThan(1) }
expect(x).getExisting("a").notToBeNull { isGreaterThan(1) }
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) getExisting "a" isLessThan 1
assert(x) getExisting Key("a") assertIt { o isGreaterThan 1 }
expect(x) getExisting "a" isLessThan 1
expect(x) getExisting key("a") { it isGreaterThan 1 }
//in case of a nullable value type
assert(x) getExisting Key("a") notToBeNull { o isGreaterThan 1 }
expect(x) getExisting "a" notToBeNull { it isGreaterThan 1 }
```
# Map contains
*atrium-api-cc-en_GB*
*atrium-api-fluent-en_GB*
```kotlin
assert(x).contains("a" to 1)
assert(x).contains("a" to 1, "b" to 2)
assert(x).contains(KeyValue("a") { isGreaterThan(3).and.isLessThan(10) })
assert(x).contains(KeyValue("a") { toBe(2) }, KeyValue("b") { isLessThan(3) })
expect(x).contains("a" to 1)
expect(x).contains("a" to 1, "b" to 2)
expect(x).contains(KeyValue("a") { isGreaterThan(3).and.isLessThan(10) })
expect(x).contains(KeyValue("a") { toBe(2) }, KeyValue("b") { isLessThan(3) })
//in case of a nullable value type
assert(x).contains("a" to null)
assert(x).contains("a" to null, "b" to 2)
assert(x).contains(KeyValue("a", null))
assert(x).contains(
expect(x).contains("a" to null)
expect(x).contains("a" to null, "b" to 2)
expect(x).contains(KeyValue("a", null))
expect(x).contains(
KeyValue("a", null)
KeyValue("b") { isLessThan(2) }
)
```
*atrium-api-cc-infix-en_GB*
*atrium-api-infix-en_GB*
```kotlin
assert(x) contains ("a" to 1)
assert(x) contains Pairs("a" to 1, "b" to 2)
assert(x) contains KeyValue("a") {
o isGreaterThan 3
o isLessThan 10
expect(x) contains ("a" to 1)
expect(x) contains pairs("a" to 1, "b" to 2)
expect(x) contains keyValue("a") {
it isGreaterThan 3
it isLessThan 10
}
assert(x) contains All(KeyValue("a") { o toBe 2 }, KeyValue("b") { o isLessThan 3 })
expect(x) contains all(keyValue("a") { it toBe 2 }, keyValue("b") { it isLessThan 3 })
//in case of a nullable value type
assert(x) contains ("a" to null)
assert(x) contains Pairs("a" to null, "b" to 2)
assert(x) contains KeyValue("a", null)
assert(x) contains All(
KeyValue("a", null),
KeyValue("b") { o isLessThan 2 }
expect(x) contains ("a" to null)
expect(x) contains pairs("a" to null, "b" to 2)
expect(x) contains keyValue("a", null)
expect(x) contains all(
keyValue("a", null),
keyValue("b") { it isLessThan 2 }
)
```

View File

@@ -8,7 +8,7 @@ import ch.tutteli.atrium.reporting.Reporter
/**
* Expects that the subject of the assertion is (equal to) [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T> Expect<T>.toBe(expected: T) = addAssertion(ExpectImpl.any.toBe(this, expected))
@@ -16,7 +16,7 @@ fun <T> Expect<T>.toBe(expected: T) = addAssertion(ExpectImpl.any.toBe(this, exp
/**
* Expects that the subject of the assertion is not (equal to) [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T> Expect<T>.notToBe(expected: T) = addAssertion(ExpectImpl.any.notToBe(this, expected))
@@ -24,7 +24,7 @@ fun <T> Expect<T>.notToBe(expected: T) = addAssertion(ExpectImpl.any.notToBe(thi
/**
* Expects that the subject of the assertion is the same instance as [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T> Expect<T>.isSameAs(expected: T) = addAssertion(ExpectImpl.any.isSame(this, expected))
@@ -32,7 +32,7 @@ fun <T> Expect<T>.isSameAs(expected: T) = addAssertion(ExpectImpl.any.isSame(thi
/**
* Expects that the subject of the assertion is not the same instance as [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T> Expect<T>.isNotSameAs(expected: T) = addAssertion(ExpectImpl.any.isNotSame(this, expected))
@@ -47,7 +47,7 @@ fun <T> Expect<T>.isNotSameAs(expected: T) = addAssertion(ExpectImpl.any.isNotSa
* else notToBeNull(assertionCreatorOrNull)
* ```
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
inline fun <reified T : Any> Expect<T?>.toBeNullIfNullGivenElse(
@@ -59,7 +59,7 @@ inline fun <reified T : Any> Expect<T?>.toBeNullIfNullGivenElse(
*
* It delegates to [isA] with [T] as type.
*
* @return An assertion container with the non-nullable type [T] (was `T?` before).
* @return An [Expect] with the non-nullable type [T] (was `T?` before).
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
@Suppress(/* less magic */ "RemoveExplicitTypeArguments")
@@ -71,7 +71,7 @@ inline fun <reified T : Any> Expect<T?>.notToBeNull(): Expect<T> = isA<T>()
*
* It delegates to [isA] with [T] as type.
*
* @return An assertion container with the non-nullable type [T] (was `T?` before)
* @return An [Expect] with the non-nullable type [T] (was `T?` before)
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
@Suppress(/* less magic */ "RemoveExplicitTypeArguments")
@@ -94,7 +94,7 @@ inline fun <reified T : Any> Expect<T?>.notToBeNull(noinline assertionCreator: E
* the element type is actually `String`. Or in other words
* `assert(listOf(1, 2)).isA<List<String>>{}` holds, even though `List<Int>` is clearly not a `List<String>`.
*
* @return An assertion container with the new type [TSub].
* @return An [Expect] with the new type [TSub].
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
inline fun <reified TSub : Any> Expect<*>.isA(): Expect<TSub> =
@@ -138,7 +138,7 @@ inline fun <reified TSub : Any> Expect<*>.isA(): Expect<TSub> =
* the element type is actually `String`. Or in other words
* `assert(listOf(1, 2)).isA<List<String>>{}` holds, even though `List<Int>` is clearly not a `List<String>`.
*
* @return An assertion container with the new type [TSub].
* @return An [Expect] with the new type [TSub].
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
inline fun <reified TSub : Any> Expect<*>.isA(noinline assertionCreator: Expect<TSub>.() -> Unit): Expect<TSub> =
@@ -152,7 +152,7 @@ inline fun <reified TSub : Any> Expect<*>.isA(noinline assertionCreator: Expect<
* asserts that 1 is greater than 0. If the first assertion fails, then usually (depending on the configured
* [AssertionChecker]) the second assertion is not evaluated.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
*/
inline val <T> Expect<T>.and: Expect<T> get() = this
@@ -164,6 +164,6 @@ inline val <T> Expect<T>.and: Expect<T> get() = this
* second one is evaluated as a whole. Meaning, even though 1 is not even, it still evaluates that 1 is greater than 1.
* Hence the reporting might (depending on the configured [Reporter]) contain both failing sub-assertions.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
*/
infix fun <T> Expect<T>.and(assertionCreator: Expect<T>.() -> Unit) = addAssertionsCreatedBy(assertionCreator)

View File

@@ -11,6 +11,8 @@ import kotlin.jvm.JvmName
* Use `feature(Array<out E>::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
fun <E> Expect<out Array<out E>>.asList(): Expect<List<E>> =
ExpectImpl.changeSubject(this).unreported { it.asList() }
@@ -23,6 +25,8 @@ fun <E> Expect<out Array<out E>>.asList(): Expect<List<E>> =
* Use `feature(Array<out E>::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
fun <E> Expect<Array<E>>.asList(assertionCreator: Expect<List<E>>.() -> Unit): Expect<Array<E>> =
apply { asList().addAssertionsCreatedBy(assertionCreator) }
@@ -35,6 +39,8 @@ fun <E> Expect<Array<E>>.asList(assertionCreator: Expect<List<E>>.() -> Unit): E
* Use `feature(Array<out E>::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("asListEOut")
fun <E> Expect<Array<out E>>.asList(assertionCreator: Expect<List<E>>.() -> Unit): Expect<Array<out E>> =
@@ -47,6 +53,8 @@ fun <E> Expect<Array<out E>>.asList(assertionCreator: Expect<List<E>>.() -> Unit
* Use `feature(ByteArray::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("byteArrAsList")
fun Expect<ByteArray>.asList(): Expect<List<Byte>> =
@@ -60,6 +68,8 @@ fun Expect<ByteArray>.asList(): Expect<List<Byte>> =
* Use `feature(ByteArray::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("byteArrAsList")
fun Expect<ByteArray>.asList(assertionCreator: Expect<List<Byte>>.() -> Unit): Expect<ByteArray> =
@@ -73,6 +83,8 @@ fun Expect<ByteArray>.asList(assertionCreator: Expect<List<Byte>>.() -> Unit): E
* Use `feature(CharArray::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("charArrAsList")
fun Expect<CharArray>.asList(): Expect<List<Char>> =
@@ -86,6 +98,8 @@ fun Expect<CharArray>.asList(): Expect<List<Char>> =
* Use `feature(CharArray::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("charArrAsList")
fun Expect<CharArray>.asList(assertionCreator: Expect<List<Char>>.() -> Unit): Expect<CharArray> =
@@ -99,6 +113,8 @@ fun Expect<CharArray>.asList(assertionCreator: Expect<List<Char>>.() -> Unit): E
* Use `feature(ShortArray::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("shortArrAsList")
fun Expect<ShortArray>.asList(): Expect<List<Short>> =
@@ -112,6 +128,8 @@ fun Expect<ShortArray>.asList(): Expect<List<Short>> =
* Use `feature(ShortArray::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("shortArrAsList")
fun Expect<ShortArray>.asList(assertionCreator: Expect<List<Short>>.() -> Unit): Expect<ShortArray> =
@@ -125,6 +143,8 @@ fun Expect<ShortArray>.asList(assertionCreator: Expect<List<Short>>.() -> Unit):
* Use `feature(IntArray::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("intArrAsList")
fun Expect<IntArray>.asList(): Expect<List<Int>> = ExpectImpl.changeSubject(this).unreported { it.asList() }
@@ -137,6 +157,8 @@ fun Expect<IntArray>.asList(): Expect<List<Int>> = ExpectImpl.changeSubject(this
* Use `feature(IntArray::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("intArrAsList")
fun Expect<IntArray>.asList(assertionCreator: Expect<List<Int>>.() -> Unit): Expect<IntArray> =
@@ -150,6 +172,8 @@ fun Expect<IntArray>.asList(assertionCreator: Expect<List<Int>>.() -> Unit): Exp
* Use `feature(LongArray::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("longArrAsList")
fun Expect<LongArray>.asList(): Expect<List<Long>> =
@@ -163,6 +187,8 @@ fun Expect<LongArray>.asList(): Expect<List<Long>> =
* Use `feature(LongArray::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("longArrAsList")
fun Expect<LongArray>.asList(assertionCreator: Expect<List<Long>>.() -> Unit): Expect<LongArray> =
@@ -176,6 +202,8 @@ fun Expect<LongArray>.asList(assertionCreator: Expect<List<Long>>.() -> Unit): E
* Use `feature(FloatArray::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("floatArrAsList")
fun Expect<FloatArray>.asList(): Expect<List<Float>> =
@@ -189,6 +217,8 @@ fun Expect<FloatArray>.asList(): Expect<List<Float>> =
* Use `feature(FloatArray::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("floatArrAsList")
fun Expect<FloatArray>.asList(assertionCreator: Expect<List<Float>>.() -> Unit): Expect<FloatArray> =
@@ -202,6 +232,8 @@ fun Expect<FloatArray>.asList(assertionCreator: Expect<List<Float>>.() -> Unit):
* Use `feature(DoubleArray::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("doubleArrAsList")
fun Expect<DoubleArray>.asList(): Expect<List<Double>> =
@@ -215,6 +247,8 @@ fun Expect<DoubleArray>.asList(): Expect<List<Double>> =
* Use `feature(DoubleArray::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("doubleArrAsList")
fun Expect<DoubleArray>.asList(assertionCreator: Expect<List<Double>>.() -> Unit): Expect<DoubleArray> =
@@ -228,6 +262,8 @@ fun Expect<DoubleArray>.asList(assertionCreator: Expect<List<Double>>.() -> Unit
* Use `feature(BooleanArray::asList)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("boolArrAsList")
fun Expect<BooleanArray>.asList(): Expect<List<Boolean>> =
@@ -241,6 +277,8 @@ fun Expect<BooleanArray>.asList(): Expect<List<Boolean>> =
* Use `feature(BooleanArray::asList, assertionCreator)` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
*
* @since 0.9.0
*/
@JvmName("boolArrAsList")
fun Expect<BooleanArray>.asList(assertionCreator: Expect<List<Boolean>>.() -> Unit): Expect<BooleanArray> =

View File

@@ -35,19 +35,19 @@ val <T : CharSequence> Expect<T>.containsNot: NotCheckerOption<T, NotSearchBehav
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'a'` and [expected]
* is defined as `'a'` and one [otherExpected] is defined as `'a'` as well, then both match, even though they match the
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"a"` and [expected]
* is defined as `"a"` and one [otherExpected] is defined as `"a"` as well, then both match, even though they match the
* same sequence in the input of the search. Use the property `contains` to create a more sophisticated `contains`
* assertion where you can use options such as [atLeast], [atMost] and [exactly] to control the number of occurrences
* you expect.
*
* Meaning you might want to use:
* `contains.exactly(2).value('a')`
* `contains.exactly(2).value("a")`
* instead of:
* `contains('a', 'a')`
* `contains("a", "a")`
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expected] or one of the [otherExpected] is not a
* [CharSequence], [Number] or [Char].
@@ -64,7 +64,7 @@ fun <T : CharSequence> Expect<T>.contains(expected: Any, vararg otherExpected: A
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.containsNot(expected: Any, vararg otherExpected: Any) =
@@ -76,9 +76,9 @@ fun <T : CharSequence> Expect<T>.containsNot(expected: Any, vararg otherExpected
*
* It is a shortcut for `contains.atLeast(1).regex(pattern, *otherPatterns)`.
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'ab'` and [pattern]
* is defined as `'a(b)?'` and one of the [otherPatterns] is defined as `'a(b)?'` as well, then both match, even though
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"ab"` and [pattern]
* is defined as `"a(b)?"` and one of the [otherPatterns] is defined as `"a(b)?"` as well, then both match, even though
* they match the same sequence in the input of the search. Use an option such as [atLeast], [atMost] and [exactly] to
* control the number of occurrences you expect.
*
@@ -90,7 +90,7 @@ fun <T : CharSequence> Expect<T>.containsNot(expected: Any, vararg otherExpected
* @param pattern The pattern which is expected to have a match against the input of the search.
* @param otherPatterns Additional patterns which are expected to have a match against the input of the search.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.containsRegex(pattern: String, vararg otherPatterns: String): Expect<T> =
@@ -102,9 +102,9 @@ fun <T : CharSequence> Expect<T>.containsRegex(pattern: String, vararg otherPatt
*
* It is a shortcut for `contains.atLeast(1).regex(pattern, *otherPatterns)`.
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'ab'` and [pattern]
* is defined as `'a(b)?'` and one of the [otherPatterns] is defined as `'a(b)?'` as well, then both match, even though
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"ab"` and [pattern]
* is defined as `"a(b)?"` and one of the [otherPatterns] is defined as `"a(b)?"` as well, then both match, even though
* they match the same sequence in the input of the search. Use an option such as [atLeast], [atMost] and [exactly] to
* control the number of occurrences you expect.
*
@@ -116,7 +116,7 @@ fun <T : CharSequence> Expect<T>.containsRegex(pattern: String, vararg otherPatt
* @param pattern The pattern which is expected to have a match against the input of the search.
* @param otherPatterns Additional patterns which are expected to have a match against the input of the search.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
@@ -127,7 +127,7 @@ fun <T : CharSequence> Expect<T>.containsRegex(pattern: Regex, vararg otherPatte
/**
* Expects that the subject of the assertion (a [CharSequence]) starts with [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.startsWith(expected: CharSequence) =
@@ -136,7 +136,7 @@ fun <T : CharSequence> Expect<T>.startsWith(expected: CharSequence) =
/**
* Expects that the subject of the assertion (a [CharSequence]) starts with [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
@@ -146,7 +146,7 @@ fun <T : CharSequence> Expect<T>.startsWith(expected: Char) = startsWith(expecte
/**
* Expects that the subject of the assertion (a [CharSequence]) does not start with [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.startsNotWith(expected: CharSequence) =
@@ -155,7 +155,7 @@ fun <T : CharSequence> Expect<T>.startsNotWith(expected: CharSequence) =
/**
* Expects that the subject of the assertion (a [CharSequence]) does not start with [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
@@ -166,7 +166,7 @@ fun <T : CharSequence> Expect<T>.startsNotWith(expected: Char) = startsNotWith(e
/**
* Expects that the subject of the assertion (a [CharSequence]) ends with [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.endsWith(expected: CharSequence) =
@@ -175,7 +175,7 @@ fun <T : CharSequence> Expect<T>.endsWith(expected: CharSequence) =
/**
* Expects that the subject of the assertion (a [CharSequence]) ends with [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
@@ -185,7 +185,7 @@ fun <T : CharSequence> Expect<T>.endsWith(expected: Char) = endsWith(expected.to
/**
* Expects that the subject of the assertion (a [CharSequence]) does not end with [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.endsNotWith(expected: CharSequence) =
@@ -194,7 +194,7 @@ fun <T : CharSequence> Expect<T>.endsNotWith(expected: CharSequence) =
/**
* Expects that the subject of the assertion (a [CharSequence]) does not end with [expected].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
@@ -205,7 +205,7 @@ fun <T : CharSequence> Expect<T>.endsNotWith(expected: Char) = endsNotWith(expec
/**
* Expects that the subject of the assertion (a [CharSequence]) [CharSequence].[kotlin.text.isEmpty].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.isEmpty() = addAssertion(ExpectImpl.charSequence.isEmpty(this))
@@ -213,7 +213,7 @@ fun <T : CharSequence> Expect<T>.isEmpty() = addAssertion(ExpectImpl.charSequenc
/**
* Expects that the subject of the assertion (a [CharSequence]) [CharSequence].[kotlin.text.isNotEmpty].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.isNotEmpty() = addAssertion(ExpectImpl.charSequence.isNotEmpty(this))
@@ -221,7 +221,7 @@ fun <T : CharSequence> Expect<T>.isNotEmpty() = addAssertion(ExpectImpl.charSequ
/**
* Expects that the subject of the assertion (a [CharSequence]) [CharSequence].[kotlin.text.isNotBlank].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> Expect<T>.isNotBlank() = addAssertion(ExpectImpl.charSequence.isNotBlank(this))
@@ -229,7 +229,9 @@ fun <T : CharSequence> Expect<T>.isNotBlank() = addAssertion(ExpectImpl.charSequ
/**
* Expects that the subject of the assertion (a [CharSequence]) matches the given [expected] [Regex].
*
* @return This assertion container to support a fluent API.
* In contrast to [containsRegex] it does not look for a partial match but for an entire match.
*
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
@@ -240,7 +242,9 @@ fun <T : CharSequence> Expect<T>.matches(expected: Regex) =
/**
* Expects that the subject of the assertion (a [CharSequence]) mismatches the given [expected] [Regex].
*
* @return This assertion container to support a fluent API.
* In contrast to `containsNot.regex` it does not look for a partial match but for an entire match.
*
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0

View File

@@ -3,7 +3,9 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.builders.ExpectImpl
import ch.tutteli.atrium.domain.builders.creating.basic.contains.addAssertion
import ch.tutteli.atrium.domain.builders.utils.toVarArg
import ch.tutteli.atrium.domain.creating.charsequence.contains.CharSequenceContains
import ch.tutteli.atrium.domain.creating.charsequence.contains.CharSequenceContains.*
import ch.tutteli.atrium.domain.creating.charsequence.contains.searchbehaviours.IgnoringCaseSearchBehaviour
import ch.tutteli.atrium.domain.creating.charsequence.contains.searchbehaviours.NoOpSearchBehaviour
import ch.tutteli.kbox.glue
@@ -18,15 +20,15 @@ import kotlin.jvm.JvmName
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that 'aa' in 'aaaa' is found three times and not only two times.
* By non disjoint is meant that "aa" in "aaaa" is found three times and not only two times.
*
* @param expected The value which is expected to be contained within the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expected] is not a [CharSequence], [Number] or [Char].
*/
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour>.value(expected: Any): Expect<T> =
fun <T : CharSequence> CheckerOption<T, NoOpSearchBehaviour>.value(expected: Any): Expect<T> =
values(expected)
/**
@@ -36,26 +38,26 @@ fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'a'` and [expected]
* is defined as `'a'` and one [otherExpected] is defined as `'a'` as well, then both match, even though they match the
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"a"` and [expected]
* is defined as `"a"` and one [otherExpected] is defined as `"a"` as well, then both match, even though they match the
* same sequence in the input of the search. Use an option such as [atLeast], [atMost] and [exactly] to control
* the number of occurrences you expect.
*
* Meaning you might want to use:
* `contains.exactly(2).value('a')`
* `contains.exactly(2).value("a")`
* instead of:
* `contains.atLeast(1).values('a', 'a')`
* `contains.atLeast(1).values("a", "a")`
*
* @param expected The value which is expected to be contained within the input of the search.
* @param otherExpected Additional values which are expected to be contained within the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expected] or one of the [otherExpected] is not a
* [CharSequence], [Number] or [Char].
*/
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour>.values(
fun <T : CharSequence> CheckerOption<T, NoOpSearchBehaviour>.values(
expected: Any,
vararg otherExpected: Any
): Expect<T> = addAssertion(ExpectImpl.charSequence.contains.values(this, expected glue otherExpected))
@@ -70,16 +72,16 @@ fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that 'aa' in 'aaaa' is found three times and not only two times.
* By non disjoint is meant that "aa" in "aaaa" is found three times and not only two times.
*
* @param expected The value which is expected to be contained within the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expected] is not a [CharSequence], [Number] or [Char].
*/
@JvmName("valueIgnoringCase")
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, IgnoringCaseSearchBehaviour>.value(
fun <T : CharSequence> CheckerOption<T, IgnoringCaseSearchBehaviour>.value(
expected: Any
): Expect<T> = values(expected)
@@ -90,27 +92,27 @@ fun <T : CharSequence> CharSequenceContains.CheckerOption<T, IgnoringCaseSearchB
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'a'` and [expected]
* is defined as `'a'` and one [otherExpected] is defined as `'a'` as well, then both match, even though they match the
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"a"` and [expected]
* is defined as `"a"` and one [otherExpected] is defined as `"a"` as well, then both match, even though they match the
* same sequence in the input of the search. Use an option such as [atLeast], [atMost] and [exactly] to control
* the number of occurrences you expect.
*
* Meaning you might want to use:
* `contains.ignoringCase.exactly(2).value('a')`
* `contains.ignoringCase.exactly(2).value("a")`
* instead of:
* `contains.ignoringCase.atLeast(1).values('a', 'a')`
* `contains.ignoringCase.atLeast(1).values("a", "a")`
*
* @param expected The value which is expected to be contained within the input of the search.
* @param otherExpected Additional values which are expected to be contained within the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expected] or one of the [otherExpected] is not a
* [CharSequence], [Number] or [Char].
*/
@JvmName("valuesIgnoringCase")
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, IgnoringCaseSearchBehaviour>.values(
fun <T : CharSequence> CheckerOption<T, IgnoringCaseSearchBehaviour>.values(
expected: Any,
vararg otherExpected: Any
): Expect<T> = addAssertion(ExpectImpl.charSequence.contains.valuesIgnoringCase(this, expected glue otherExpected))
@@ -120,20 +122,20 @@ fun <T : CharSequence> CharSequenceContains.CheckerOption<T, IgnoringCaseSearchB
* Finishes the specification of the sophisticated `contains` assertion where the [expected] value shall be searched
* (ignoring case), using a non disjoint search where it needs to be contained at least once.
*
* Delegates to `atLeast(1).values(expected)`.
* Delegates to `atLeast(1).value(expected)`.
*
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that 'aa' in 'aaaa' is found three times and not only two times.
* By non disjoint is meant that "aa" in "aaaa" is found three times and not only two times.
*
* @param expected The value which is expected to be contained within the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expected] is not a [CharSequence], [Number] or [Char].
*/
fun <T : CharSequence> CharSequenceContains.Builder<T, IgnoringCaseSearchBehaviour>.value(expected: Any): Expect<T> =
fun <T : CharSequence> Builder<T, IgnoringCaseSearchBehaviour>.value(expected: Any): Expect<T> =
atLeast(1).value(expected)
/**
@@ -146,20 +148,20 @@ fun <T : CharSequence> CharSequenceContains.Builder<T, IgnoringCaseSearchBehavio
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'a'` and [expected]
* is defined as `'a'` and one [otherExpected] is defined as `'a'` as well, then both match, even though they match the
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"a"` and [expected]
* is defined as `"a"` and one [otherExpected] is defined as `"a"` as well, then both match, even though they match the
* same sequence in the input of the search.
*
* @param expected The value which is expected to be contained within the input of the search.
* @param otherExpected Additional values which are expected to be contained within the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expected] or one of the [otherExpected] is not a
* [CharSequence], [Number] or [Char].
*/
fun <T : CharSequence> CharSequenceContains.Builder<T, IgnoringCaseSearchBehaviour>.values(
fun <T : CharSequence> Builder<T, IgnoringCaseSearchBehaviour>.values(
expected: Any,
vararg otherExpected: Any
): Expect<T> = atLeast(1).values(expected, *otherExpected)
@@ -168,9 +170,9 @@ fun <T : CharSequence> CharSequenceContains.Builder<T, IgnoringCaseSearchBehavio
* Finishes the specification of the sophisticated `contains` assertion where the given regular expression [pattern]
* as well as the [otherPatterns] are expected to have a match, using a non disjoint search.
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'ab'` and [pattern]
* is defined as `'a(b)?'` and one of the [otherPatterns] is defined as `'a(b)?'` as well, then both match, even though
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"ab"` and [pattern]
* is defined as `"a(b)?"` and one of the [otherPatterns] is defined as `"a(b)?"` as well, then both match, even though
* they match the same sequence in the input of the search. Use an option such as [atLeast], [atMost] and [exactly] to
* control the number of occurrences you expect.
*
@@ -182,21 +184,21 @@ fun <T : CharSequence> CharSequenceContains.Builder<T, IgnoringCaseSearchBehavio
* @param pattern The pattern which is expected to have a match against the input of the search.
* @param otherPatterns Additional patterns which are expected to have a match against the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour>.regex(
fun <T : CharSequence> CheckerOption<T, NoOpSearchBehaviour>.regex(
pattern: String,
vararg otherPatterns: String
): Expect<T> = addAssertion(ExpectImpl.charSequence.contains.regex(this, pattern glue otherPatterns))
/**
* Finishes the specification of the sophisticated `contains` assertion where the given regular expression [pattern]
* Finishes the specification of the sophisticated `contains` assertion where the given [Regex] [pattern]
* as well as the [otherPatterns] are expected to have a match, using a non disjoint search.
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'ab'` and [pattern]
* is defined as `'a(b)?'` and one of the [otherPatterns] is defined as `'a(b)?'` as well, then both match, even though
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"ab"` and [pattern]
* is defined as `"a(b)?"` and one of the [otherPatterns] is defined as `"a(b)?"` as well, then both match, even though
* they match the same sequence in the input of the search. Use an option such as [atLeast], [atMost] and [exactly] to
* control the number of occurrences you expect.
*
@@ -208,12 +210,13 @@ fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour
* @param pattern The pattern which is expected to have a match against the input of the search.
* @param otherPatterns Additional patterns which are expected to have a match against the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
*/
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour>.regex(
//TODO rename to `matchFor` with 1.0.0
fun <T : CharSequence> CheckerOption<T, NoOpSearchBehaviour>.regex(
pattern: Regex,
vararg otherPatterns: Regex
): Expect<T> = addAssertion(ExpectImpl.charSequence.contains.regex(this, pattern glue otherPatterns))
@@ -222,25 +225,25 @@ fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour
* Finishes the specification of the sophisticated `contains` assertion where the given regular expression [pattern]
* as well as the [otherPatterns] are expected to have a match (ignoring case), using a non disjoint search.
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'ab'` and [pattern]
* is defined as `'a(b)?'` and one of the [otherPatterns] is defined as `'a(b)?'` as well, then both match, even though
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"ab"` and [pattern]
* is defined as `"a(b)?"` and one of the [otherPatterns] is defined as `"a(b)?"` as well, then both match, even though
* they match the same sequence in the input of the search. Use an option such as [atLeast], [atMost] and [exactly] to
* control the number of occurrences you expect.
*
* Meaning you might want to use:
* `contains.ignoringCase.exactly(2).regex('a(b)?')`
* `contains.ignoringCase.exactly(2).regex("a(b)?")`
* instead of:
* `contains.ignoringCase.atLeast(1).regex('a(b)?', 'a(b)?')`
* `contains.ignoringCase.atLeast(1).regex("a(b)?", "a(b)?")`
*
* @param pattern The pattern which is expected to have a match against the input of the search.
* @param otherPatterns Additional patterns which are expected to have a match against the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
@JvmName("regexIgnoringCase")
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, IgnoringCaseSearchBehaviour>.regex(
fun <T : CharSequence> CheckerOption<T, IgnoringCaseSearchBehaviour>.regex(
pattern: String,
vararg otherPatterns: String
): Expect<T> = addAssertion(ExpectImpl.charSequence.contains.regexIgnoringCase(this, pattern glue otherPatterns))
@@ -252,24 +255,24 @@ fun <T : CharSequence> CharSequenceContains.CheckerOption<T, IgnoringCaseSearchB
*
* Delegates to `atLeast(1).regex(pattern, otherPatterns)`
*
* By non disjoint is meant that `'aa'` in `'aaaa'` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `'ab'` and [pattern]
* is defined as `'a(b)?'` and one of the [otherPatterns] is defined as `'a(b)?'` as well, then both match, even though
* By non disjoint is meant that `"aa"` in `"aaaa"` is found three times and not only two times.
* Also notice, that it does not search for unique matches. Meaning, if the input of the search is `"ab"` and [pattern]
* is defined as `"a(b)?"` and one of the [otherPatterns] is defined as `"a(b)?"` as well, then both match, even though
* they match the same sequence in the input of the search. Use an option such as [atLeast], [atMost] and [exactly]
* to control the number of occurrences you expect.
*
* Meaning you might want to use:
* `contains.ignoringCase.exactly(2).regex('a(b)?')`
* `contains.ignoringCase.exactly(2).regex("a(b)?")`
* instead of:
* `contains.ignoringCase.atLeast(1).regex('a(b)?', 'a(b)?')`
* `contains.ignoringCase.atLeast(1).regex("a(b)?", "a(b)?")`
*
* @param pattern The pattern which is expected to have a match against the input of the search.
* @param otherPatterns Additional patterns which are expected to have a match against the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : CharSequence> CharSequenceContains.Builder<T, IgnoringCaseSearchBehaviour>.regex(
fun <T : CharSequence> Builder<T, IgnoringCaseSearchBehaviour>.regex(
pattern: String,
vararg otherPatterns: String
): Expect<T> = atLeast(1).regex(pattern, *otherPatterns)
@@ -284,21 +287,22 @@ fun <T : CharSequence> CharSequenceContains.Builder<T, IgnoringCaseSearchBehavio
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that 'aa' in 'aaaa' is found three times and not only two times.
* By non disjoint is meant that "aa" in "aaaa" is found three times and not only two times.
*
* @param expectedIterable The [Iterable] whose elements are expected to be contained within the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expectedIterable] is not a [CharSequence], [Number] or [Char] or the given
* [expectedIterable] does not have elements (is empty).
*
* @since 0.9.0
*/
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour>.elementsOf(
fun <T : CharSequence> CheckerOption<T, NoOpSearchBehaviour>.elementsOf(
expectedIterable: Iterable<Any>
): Expect<T> {
require(expectedIterable.iterator().hasNext()) { "Iterable without elements are not allowed." }
return values(expectedIterable.first(), *expectedIterable.drop(1).toTypedArray())
val (first, rest) = toVarArg(expectedIterable)
return values(first, *rest)
}
/**
@@ -311,20 +315,29 @@ fun <T : CharSequence> CharSequenceContains.CheckerOption<T, NoOpSearchBehaviour
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed (this
* function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* By non disjoint is meant that 'aa' in 'aaaa' is found three times and not only two times.
* By non disjoint is meant that "aa" in "aaaa" is found three times and not only two times.
*
* @param expectedIterable The [Iterable] whose elements are expected to be contained within the input of the search.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case [expectedIterable] is not a [CharSequence], [Number] or [Char] or the given
* [expectedIterable] does not have elements (is empty).
*
* @since 0.9.0
*/
@JvmName("elementsOfIgnoringCase")
fun <T : CharSequence> CharSequenceContains.CheckerOption<T, IgnoringCaseSearchBehaviour>.elementsOf(
fun <T : CharSequence> CheckerOption<T, IgnoringCaseSearchBehaviour>.elementsOf(
expectedIterable: Iterable<Any>
): Expect<T> {
require(expectedIterable.iterator().hasNext()) { "Iterable without elements are not allowed." }
return values(expectedIterable.first(), *expectedIterable.drop(1).toTypedArray())
val (first, rest) = toVarArg(expectedIterable)
return values(first, *rest)
}
@JvmName("elementsOfIgnoringCase")
fun <T : CharSequence> CharSequenceContains.Builder<T, IgnoringCaseSearchBehaviour>.elementsOf(
expectedIterable: Iterable<Any>
): Expect<T> {
val (first, rest) = toVarArg(expectedIterable)
return values(first, *rest)
}

View File

@@ -6,7 +6,7 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl
/**
* Expects that the subject of the assertion (a [Collection]) is an empty [Collection].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Collection<*>> Expect<T>.isEmpty() = addAssertion(ExpectImpl.collection.isEmpty(this))
@@ -14,7 +14,7 @@ fun <T : Collection<*>> Expect<T>.isEmpty() = addAssertion(ExpectImpl.collection
/**
* Expects that the subject of the assertion (a [Collection]) is not an empty [Collection].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Collection<*>> Expect<T>.isNotEmpty() = addAssertion(ExpectImpl.collection.isNotEmpty(this))
@@ -22,9 +22,9 @@ fun <T : Collection<*>> Expect<T>.isNotEmpty() = addAssertion(ExpectImpl.collect
/**
* Expects that the subject of the assertion (a [Collection]) has the given [expected] size.
*
* Shortcut for `expected.toBe(expectedSize)`.
* Shortcut for `size.toBe(expected)`.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Collection<*>> Expect<T>.hasSize(expected: Int) = size { toBe(expected) }
@@ -33,16 +33,17 @@ fun <T : Collection<*>> Expect<T>.hasSize(expected: Int) = size { toBe(expected)
* Creates an [Expect] for the property [Collection.size] of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect].
* @return The newly created [Expect] for the extracted feature.
*/
val <T : Collection<*>> Expect<T>.size: Expect<Int>
get() = ExpectImpl.collection.size(this).getExpectOfFeature()
/**
* Expects that the property [Collection.size] of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Collection<E>> Expect<T>.size(assertionCreator: Expect<Int>.() -> Unit): Expect<T> =

View File

@@ -7,7 +7,7 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl
* Expects that the subject of the assertion is less than [expected].
* The comparison is carried out with [Comparable.compareTo].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Comparable<T>> Expect<T>.isLessThan(expected: T) =
@@ -17,7 +17,7 @@ fun <T : Comparable<T>> Expect<T>.isLessThan(expected: T) =
* Expects that the subject of the assertion is less than or equal [expected].
* The comparison is carried out with [Comparable.compareTo].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Comparable<T>> Expect<T>.isLessThanOrEqual(expected: T) =
@@ -27,7 +27,7 @@ fun <T : Comparable<T>> Expect<T>.isLessThanOrEqual(expected: T) =
* Expects that the subject of the assertion is greater than [expected].
* The comparison is carried out with [Comparable.compareTo].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Comparable<T>> Expect<T>.isGreaterThan(expected: T) =
@@ -37,7 +37,7 @@ fun <T : Comparable<T>> Expect<T>.isGreaterThan(expected: T) =
* Expects that the subject of the assertion is greater than or equal [expected].
* The comparison is carried out with [Comparable.compareTo].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Comparable<T>> Expect<T>.isGreaterThanOrEqual(expected: T) =

View File

@@ -1,5 +1,6 @@
package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.core.None
import ch.tutteli.atrium.core.coreFactory
import ch.tutteli.atrium.creating.*
import ch.tutteli.atrium.domain.builders.creating.changers.FeatureExtractorBuilder
@@ -9,55 +10,109 @@ import ch.tutteli.atrium.domain.builders.reporting.ExpectOptions
import ch.tutteli.atrium.reporting.RawString
import ch.tutteli.atrium.reporting.reporter
@Suppress("DEPRECATION" /* RequiresOptIn is only available since 1.3.70 which we cannot use if we want to support 1.2 */)
@Experimental
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION)
annotation class ExperimentalWithOptions
/**
* Uses the given [textRepresentation] as representation of the subject instead of the current representation
* (which defaults to the subject itself).
* Wraps the given [textRepresentation] into a [RawString] and uses it as representation of the subject
* instead of the representation that has been defined so far (which defaults to the subject itself).
*
* In case [Expect.maybeSubject] is not defined i.e. [None], then the previous representation is used.
*
* @return An [Expect] for the current subject of the assertion.
*/
@ExperimentalWithOptions
fun <T> RootExpect<T>.withOptions(textRepresentation: String): Expect<T> =
withOptions(ExpectOptions(representation = RawString.create(textRepresentation)))
fun <T> RootExpect<T>.withRepresentation(textRepresentation: String): Expect<T> =
withOptions { withRepresentation(textRepresentation) }
/**
* Uses the given [representationProvider] to retrieve a representation which can be based on the current
* subject where it is used as new representation of the subject
* instead of the representation that has been defined so far (which defaults to the subject itself).
*
* Notice, if you want to use text (e.g. a [String]) as representation,
* then wrap it into a [RawString] via [RawString.create] and pass the [RawString] instead.
* If your text does not include the current subject, then we recommend to use the other overload which expects
* a `String` and does the wrapping for you.
*
* In case [Expect.maybeSubject] is not defined i.e. [None], then the previous representation is used.
*
* @return An [Expect] for the current subject of the assertion.
*/
@ExperimentalWithOptions
fun <T> RootExpect<T>.withRepresentation(representationProvider: (T) -> Any): Expect<T> =
withOptions { withRepresentation(representationProvider) }
/**
* Uses the given [configuration]-lambda to create an [ExpectOptions] which in turn is used
* to override (parts) of the existing configuration.
*
* @return An [Expect] for the current subject of the assertion.
*/
@ExperimentalWithOptions
fun <T> RootExpect<T>.withOptions(configuration: ExpectBuilder.OptionsChooser.() -> Unit): Expect<T> =
fun <T> RootExpect<T>.withOptions(configuration: ExpectBuilder.OptionsChooser<T>.() -> Unit): Expect<T> =
withOptions(ExpectBuilder.OptionsChooser.createAndBuild(configuration))
//TODO #280 get rid of AssertionChecker, that's one root of a bug (which is more a nice to have but still) roadmap#11
//in the same go we should get rid of ReportingAssertionContainer.AssertionCheckerDecorator, rename it respectively.
/**
* Uses the given [options] to override (parts) of the existing configuration.
*
* @return An [Expect] for the current subject of the assertion.
*/
@ExperimentalWithOptions
@Suppress("DEPRECATION" /* OptIn is only available since 1.3.70 which we cannot use if we want to support 1.2 */)
@UseExperimental(ExperimentalExpectConfig::class)
fun <T> RootExpect<T>.withOptions(options: ExpectOptions): Expect<T> = coreFactory.newReportingAssertionContainer(
fun <T> RootExpect<T>.withOptions(options: ExpectOptions<T>): Expect<T> = coreFactory.newReportingAssertionContainer(
ReportingAssertionContainer.AssertionCheckerDecorator.create(
options.assertionVerb ?: this.config.description,
this.maybeSubject,
options.representation ?: this.config.representation,
options.representationInsteadOfSubject?.let { provider ->
this.maybeSubject.fold({ null }) { provider(it) }
} ?: this.config.representation,
//TODO #280 reporter should be configurable as well
coreFactory.newThrowingAssertionChecker(options.reporter ?: reporter)
)
)
/**
* Uses the given [textRepresentation] as representation of the subject instead of the current representation
* (which defaults to the subject itself).
* Wraps the given [textRepresentation] into a [RawString] and uses it as representation of the subject
* instead of the representation that has been defined so far (which defaults to the subject itself).
*
* In case [Expect.maybeSubject] is not defined i.e. [None], then the previous representation is used.
*
* @return An [Expect] for the current subject of the assertion.
*/
@ExperimentalWithOptions
fun <T, R> FeatureExpect<T, R>.withOptions(textRepresentation: String): Expect<R> =
withOptions { withTextRepresentation(textRepresentation) }
fun <T, R> FeatureExpect<T, R>.withRepresentation(textRepresentation: String): Expect<R> =
withOptions { withRepresentation(textRepresentation) }
/**
* Uses the given [representationProvider] to retrieve a representation which can be based on the current
* subject where it is used as new representation of the subject
* instead of the representation that has been defined so far (which defaults to the subject itself).
*
* Notice, if you want to use text (e.g. a [String]) as representation,
* then wrap it into a [RawString] via [RawString.create] and pass the [RawString] instead.
* If your text does not include the current subject, then we recommend to use the other overload which expects
* a `String` and does the wrapping for you.
*
* In case [Expect.maybeSubject] is not defined i.e. [None], then the previous representation is used.
*
* @return An [Expect] for the current subject of the assertion.
*/
@ExperimentalWithOptions
fun <T, R> FeatureExpect<T, R>.withRepresentation(representationProvider: (R) -> Any): Expect<R> =
withOptions { withRepresentation(representationProvider) }
/**
* Uses the given [configuration]-lambda to create an [ExpectOptions] which in turn is used
* to override (parts) of the existing configuration.
*
* @return An [Expect] for the current subject of the assertion.
*/
@ExperimentalWithOptions
fun <T, R> FeatureExpect<T, R>.withOptions(configuration: FeatureExtractorBuilder.OptionsChooser<R>.() -> Unit): Expect<R> =
@@ -65,8 +120,11 @@ fun <T, R> FeatureExpect<T, R>.withOptions(configuration: FeatureExtractorBuilde
/**
* Uses the given [options] to override (parts) of the existing configuration.
*
* @return An [Expect] for the current subject of the assertion.
*/
@ExperimentalWithOptions
@Suppress("DEPRECATION" /* OptIn is only available since 1.3.70 which we cannot use if we want to support 1.2 */)
@UseExperimental(ExperimentalExpectConfig::class)
fun <T, R> FeatureExpect<T, R>.withOptions(options: FeatureOptions<R>): Expect<R> =
coreFactory.newFeatureExpect(
@@ -74,10 +132,9 @@ fun <T, R> FeatureExpect<T, R>.withOptions(options: FeatureOptions<R>): Expect<R
maybeSubject,
FeatureExpectConfig.create(
options.description ?: config.description,
maybeSubject.fold(
{ config.representation },
{ subject -> options.representationInsteadOfFeature?.invoke(subject) ?: config.representation }
)
options.representationInsteadOfFeature?.let { provider ->
this.maybeSubject.fold({ null }) { provider(it) }
} ?: this.config.representation
),
getAssertions()
)

View File

@@ -13,7 +13,7 @@ import kotlin.reflect.*
* creates a new [Expect] for it and
* returns it so that subsequent calls are based on the feature.
*
* @return An [Expect] for the given [property].
* @return The newly created [Expect] for the given [property].
*
* @since 0.9.0
*/
@@ -26,7 +26,7 @@ fun <T, R> Expect<T>.feature(property: KProperty1<in T, R>): FeatureExpect<T, R>
* applies an assertion group based on the given [assertionCreator] for the feature and
* returns the initial [Expect] with the current subject.
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0
@@ -42,7 +42,8 @@ fun <T, R> Expect<T>.feature(
* creates a new [Expect] for it and
* returns it so that subsequent calls are based on the feature.
*
* @return An [Expect] for the return value of calling [f] on the current subject of the assertion.
* @return The newly created [Expect] for the return value of calling the method [f]
* on the current subject of the assertion.
*
* @since 0.9.0
*/
@@ -55,7 +56,7 @@ fun <T, R> Expect<T>.feature(f: KFunction1<T, R>): FeatureExpect<T, R> =
* applies an assertion group based on the given [assertionCreator] for the feature and
* returns the initial [Expect] with the current subject.
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0
@@ -72,7 +73,8 @@ fun <T, R> Expect<T>.feature(
* creates a new [Expect] for it and
* returns it so that subsequent calls are based on the feature.
*
* @return An [Expect] for the return value of calling [f] on the current subject of the assertion.
* @return The newly created [Expect] for the return value of calling the method [f]
* on the current subject of the assertion.
*
* @since 0.9.0
*/
@@ -88,7 +90,7 @@ fun <T, A1, R> Expect<T>.feature(
* applies an assertion group based on the given [assertionCreator] for the feature and
* returns the initial [Expect] with the current subject.
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0
@@ -106,7 +108,8 @@ fun <T, A1, R> Expect<T>.feature(
* creates a new [Expect] for it and
* returns it so that subsequent calls are based on the feature.
*
* @return An [Expect] for the return value of calling [f] on the current subject of the assertion.
* @return The newly created [Expect] for the return value of calling the method [f]
* on the current subject of the assertion.
*
* @since 0.9.0
*/
@@ -122,7 +125,7 @@ fun <T, A1, A2, R> Expect<T>.feature(
* applies an assertion group based on the given [assertionCreator] for the feature and
* returns the initial [Expect] with the current subject.
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0
@@ -140,7 +143,8 @@ fun <T, A1, A2, R> Expect<T>.feature(
* creates a new [Expect] for it and
* returns it so that subsequent calls are based on the feature.
*
* @return An [Expect] for the return value of calling [f] on the current subject of the assertion.
* @return The newly created [Expect] for the return value of calling the method [f]
* on the current subject of the assertion.
*
* @since 0.9.0
*/
@@ -156,7 +160,7 @@ fun <T, A1, A2, A3, R> Expect<T>.feature(
* applies an assertion group based on the given [assertionCreator] for the feature and
* returns the initial [Expect] with the current subject.
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0
@@ -174,7 +178,8 @@ fun <T, A1, A2, A3, R> Expect<T>.feature(
* creates a new [Expect] for it and
* returns it so that subsequent calls are based on the feature.
*
* @return An [Expect] for the return value of calling [f] on the current subject of the assertion.
* @return The newly created [Expect] for the return value of calling the method [f]
* on the current subject of the assertion.
*
* @since 0.9.0
*/
@@ -190,7 +195,7 @@ fun <T, A1, A2, A3, A4, R> Expect<T>.feature(
* applies an assertion group based on the given [assertionCreator] for the feature and
* returns the initial [Expect] with the current subject.
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0
@@ -208,7 +213,7 @@ fun <T, A1, A2, A3, A4, R> Expect<T>.feature(
* creates a new [Expect] for it and
* returns it so that subsequent calls are based on the feature.
*
* @return An [Expect] for the return value of calling [f] on the current subject of the assertion.
* @return The newly [Expect] for the return value of calling [f] on the current subject of the assertion.
*
* @since 0.9.0
*/
@@ -224,7 +229,7 @@ fun <T, A1, A2, A3, A4, A5, R> Expect<T>.feature(
* applies an assertion group based on the given [assertionCreator] for the feature and
* returns the initial [Expect] with the current subject.
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0
@@ -245,7 +250,7 @@ fun <T, A1, A2, A3, A4, A5, R> Expect<T>.feature(
* @param provider Extracts the feature where the subject of the assertion is available via
* implicit parameter `it`.
*
* @return An [Expect] for the extracted feature.
* @return The newly created [Expect] for the extracted feature.
*
* @since 0.9.0
*/
@@ -262,7 +267,7 @@ fun <T, R> Expect<T>.feature(description: String, provider: T.() -> R): FeatureE
* @param provider Extracts the feature where the subject of the assertion is available via
* implicit parameter `it`.
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0
@@ -284,7 +289,7 @@ fun <T, R> Expect<T>.feature(
* implicit parameter `it`. Usually you use [f][MetaFeatureOption.f] to create a [MetaFeature],
* e.g. `feature { f(it::size) }`
*
* @return An [Expect] for the extracted feature.
* @return The newly created [Expect] for the extracted feature.
*
* @since 0.9.0
*/
@@ -301,7 +306,7 @@ fun <T, R> Expect<T>.feature(provider: MetaFeatureOption<T>.(T) -> MetaFeature<R
* @param provider You need to create a [MetaFeature] where the subject of the assertion is available via
* implicit parameter `it`. Usually you use [MetaFeatureOption.f] to create a [MetaFeature], e.g. `f(it::size)`
*
* @return The current [Expect].
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] in case the created [AssertionGroup] does not hold.
*
* @since 0.9.0

View File

@@ -18,7 +18,7 @@ import kotlin.jvm.JvmName
*
* | `subject of the assertion` - [expected] | ≤ [tolerance]
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun Expect<Float>.toBeWithErrorTolerance(expected: Float, tolerance: Float) =
@@ -34,7 +34,7 @@ fun Expect<Float>.toBeWithErrorTolerance(expected: Float, tolerance: Float) =
*
* | `subject of the assertion` - [expected] | ≤ [tolerance]
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun Expect<Double>.toBeWithErrorTolerance(expected: Double, tolerance: Double) =

View File

@@ -10,7 +10,7 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl
* For instance `toThrow<MyException<String>>` would only check if the subject is a `MyException` without checking if
* the element type is actually `String`.
*
* @return An assertion container with the new type [TExpected].
* @return An [Expect] with the new type [TExpected].
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
inline fun <reified TExpected : Throwable> Expect<out () -> Any?>.toThrow(): Expect<TExpected> =
@@ -46,7 +46,7 @@ inline fun <reified TExpected : Throwable> Expect<out () -> Any?>.toThrow(): Exp
* For instance `toThrow<MyException<String>>` would only check if the subject is a `MyException` without checking if
* the element type is actually `String`.
*
* @return An assertion container with the new type [TExpected].
* @return An [Expect] with the new type [TExpected].
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
inline fun <reified TExpected : Throwable> Expect<out () -> Any?>.toThrow(
@@ -58,6 +58,7 @@ inline fun <reified TExpected : Throwable> Expect<out () -> Any?>.toThrow(
* Expects that no [Throwable] is thrown at all when calling the subject (a lambda with arity 0, i.e. without arguments)
* and changes the subject of the assertion to the return value of type [R].
*
* @return An [Expect] with the new type [R].
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <R, T : () -> R> Expect<T>.notToThrow(): Expect<R> = ExpectImpl.fun0.isNotThrowing(this).getExpectOfFeature()
@@ -66,6 +67,7 @@ fun <R, T : () -> R> Expect<T>.notToThrow(): Expect<R> = ExpectImpl.fun0.isNotTh
* Expects that no [Throwable] is thrown at all when calling the subject (a lambda with arity 0, i.e. without arguments)
* and that the corresponding return value holds all assertions the given [assertionCreator] creates.
*
* @return An [Expect] with the new type [R].
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <R, T : () -> R> Expect<T>.notToThrow(

View File

@@ -27,45 +27,54 @@ val <E, T : Iterable<E>> Expect<T>.containsNot: NotCheckerOption<E, T, NotSearch
get() = NotCheckerOptionImpl(ExpectImpl.iterable.containsNotBuilder(this))
/**
* Expects that the property min of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* Creates an [Expect] for the result of calling `min()` on the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return This assertion container to support a fluent API.
* @return The newly created [Expect] for the extracted feature.
*
* @since 0.9.0
*/
fun <E : Comparable<E>, T : Iterable<E>> Expect<T>.min(): Expect<E> =
ExpectImpl.iterable.min(this).getExpectOfFeature()
/**
* Expects that the result of calling `min()` on the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
*/
fun <E : Comparable<E>, T : Iterable<E>> Expect<T>.min(assertionCreator: Expect<E>.() -> Unit): Expect<T> =
ExpectImpl.iterable.min(this).addToInitial(assertionCreator)
/**
* Creates an [Expect] for the property min of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect].
* @since 0.9.0
*/
fun <E : Comparable<E>, T : Iterable<E>> Expect<T>.min(): Expect<E> = ExpectImpl.iterable.min(this).getExpectOfFeature()
/**
* Expects that the property max of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* Creates an [Expect] for the result of calling `max()` on the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return This assertion container to support a fluent API.
* @return The newly created [Expect] for the extracted feature.
*
* @since 0.9.0
*/
fun <E : Comparable<E>, T : Iterable<E>> Expect<T>.max(): Expect<E> =
ExpectImpl.iterable.max(this).getExpectOfFeature()
/**
* Expects that the result of calling `max()` on the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
*/
fun <E : Comparable<E>, T : Iterable<E>> Expect<T>.max(assertionCreator: Expect<E>.() -> Unit): Expect<T> =
ExpectImpl.iterable.max(this).addToInitial(assertionCreator)
/**
* Creates an [Expect] for the property max of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect].
* @since 0.9.0
*/
fun <E : Comparable<E>, T : Iterable<E>> Expect<T>.max(): Expect<E> = ExpectImpl.iterable.max(this).getExpectOfFeature()
/**
* Expects that the subject of the assertion (an [Iterable]) contains the
* [expected] value and the [otherExpected] values (if given).
@@ -81,7 +90,7 @@ fun <E : Comparable<E>, T : Iterable<E>> Expect<T>.max(): Expect<E> = ExpectImpl
* instead of:
* `contains('a', 'a')`
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> Expect<T>.contains(expected: E, vararg otherExpected: E): Expect<T> =
@@ -98,7 +107,7 @@ fun <E, T : Iterable<E>> Expect<T>.contains(expected: E, vararg otherExpected: E
* for has to hold; or in other words, the function which defines whether an entry is the one we are looking for
* or not. In case it is defined as `null`, then an entry is identified if it is `null` as well.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> Expect<T>.contains(assertionCreatorOrNull: (Expect<E>.() -> Unit)?): Expect<T> =
@@ -118,7 +127,7 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.contains(assertionCreatorOrNull: (Expe
* @param otherAssertionCreatorsOrNulls Additional identification lambdas which each identify (separately) an entry
* which we are looking for (see [assertionCreatorOrNull] for more information).
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> Expect<T>.contains(
@@ -136,7 +145,7 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.contains(
* which will cause a binary backward compatibility break (see
* [#292](https://github.com/robstoll/atrium/issues/292) for more information)
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> Expect<T>.containsExactly(expected: E, vararg otherExpected: E): Expect<T> =
@@ -157,7 +166,7 @@ fun <E, T : Iterable<E>> Expect<T>.containsExactly(expected: E, vararg otherExpe
* for has to hold; or in other words, the function which defines whether an entry is the one we are looking for
* or not. In case it is defined as `null`, then an entry is identified if it is `null` as well.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> Expect<T>.containsExactly(assertionCreatorOrNull: (Expect<E>.() -> Unit)?): Expect<T> =
@@ -181,7 +190,7 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.containsExactly(assertionCreatorOrNull
* @param otherAssertionCreatorsOrNulls Additional identification lambdas which each identify (separately) an entry
* which we are looking for (see [assertionCreatorOrNull] for more information).
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> Expect<T>.containsExactly(
@@ -196,7 +205,7 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.containsExactly(
*
* It is a shortcut for `containsNot.values(expected, *otherExpected)`
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> Expect<T>.containsNot(expected: E, vararg otherExpected: E) =
@@ -209,7 +218,7 @@ fun <E, T : Iterable<E>> Expect<T>.containsNot(expected: E, vararg otherExpected
*
* It is a shortcut for `contains.inAnyOrder.atLeast(1).entry(assertionCreatorOrNull)`
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> Expect<T>.any(assertionCreatorOrNull: (Expect<E>.() -> Unit)?): Expect<T> =
@@ -223,7 +232,7 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.any(assertionCreatorOrNull: (Expect<E>
*
* It is a shortcut for `containsNot.entry(assertionCreatorOrNull)`
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> Expect<T>.none(assertionCreatorOrNull: (Expect<E>.() -> Unit)?) =
@@ -235,7 +244,7 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.none(assertionCreatorOrNull: (Expect<E
* that every element holds all assertions created by the [assertionCreatorOrNull] or that all elements are `null`
* in case [assertionCreatorOrNull] is defined as `null`.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> Expect<T>.all(assertionCreatorOrNull: (Expect<E>.() -> Unit)?) =
@@ -244,7 +253,7 @@ fun <E : Any, T : Iterable<E?>> Expect<T>.all(assertionCreatorOrNull: (Expect<E>
/**
* Expects that the subject of the assertion (an [Iterable]) has at least one element.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0
@@ -254,7 +263,7 @@ fun <E, T : Iterable<E>> Expect<T>.hasNext() = addAssertion(ExpectImpl.iterable.
/**
* Expects that the subject of the assertion (an [Iterable]) does not have next element.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.9.0

View File

@@ -3,7 +3,8 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.builders.ExpectImpl
import ch.tutteli.atrium.domain.builders.creating.basic.contains.addAssertion
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains
import ch.tutteli.atrium.domain.builders.utils.toVarArg
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains.CheckerOption
import ch.tutteli.atrium.domain.creating.iterable.contains.searchbehaviours.InAnyOrderSearchBehaviour
import ch.tutteli.kbox.glue
@@ -15,10 +16,10 @@ import ch.tutteli.kbox.glue
*
* @param expected The value which is expected to be contained within this [Iterable].
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> IterableContains.CheckerOption<E, T, InAnyOrderSearchBehaviour>.value(expected: E): Expect<T> =
fun <E, T : Iterable<E>> CheckerOption<E, T, InAnyOrderSearchBehaviour>.value(expected: E): Expect<T> =
values(expected)
/**
@@ -38,10 +39,10 @@ fun <E, T : Iterable<E>> IterableContains.CheckerOption<E, T, InAnyOrderSearchBe
* @param expected The object which is expected to be contained within this [Iterable].
* @param otherExpected Additional objects which are expected to be contained within this [Iterable].
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> IterableContains.CheckerOption<E, T, InAnyOrderSearchBehaviour>.values(
fun <E, T : Iterable<E>> CheckerOption<E, T, InAnyOrderSearchBehaviour>.values(
expected: E,
vararg otherExpected: E
): Expect<T> = addAssertion(ExpectImpl.iterable.contains.valuesInAnyOrder(this, expected glue otherExpected))
@@ -57,10 +58,10 @@ fun <E, T : Iterable<E>> IterableContains.CheckerOption<E, T, InAnyOrderSearchBe
* for has to hold; or in other words, the function which defines whether an entry is the one we are looking for
* or not. In case it is defined as `null`, then an entry is identified if it is `null` as well.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> IterableContains.CheckerOption<E?, T, InAnyOrderSearchBehaviour>.entry(
fun <E : Any, T : Iterable<E?>> CheckerOption<E?, T, InAnyOrderSearchBehaviour>.entry(
assertionCreatorOrNull: (Expect<E>.() -> Unit)?
): Expect<T> = entries(assertionCreatorOrNull)
@@ -76,10 +77,10 @@ fun <E : Any, T : Iterable<E?>> IterableContains.CheckerOption<E?, T, InAnyOrder
* @param otherAssertionCreatorsOrNulls Additional identification lambdas which each identify (separately) an entry
* which we are looking for (see [assertionCreatorOrNull] for more information).
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> IterableContains.CheckerOption<E?, T, InAnyOrderSearchBehaviour>.entries(
fun <E : Any, T : Iterable<E?>> CheckerOption<E?, T, InAnyOrderSearchBehaviour>.entries(
assertionCreatorOrNull: (Expect<E>.() -> Unit)?,
vararg otherAssertionCreatorsOrNulls: (Expect<E>.() -> Unit)?
): Expect<T> = addAssertion(
@@ -98,15 +99,15 @@ fun <E : Any, T : Iterable<E?>> IterableContains.CheckerOption<E?, T, InAnyOrder
*
* @param expectedIterable The [Iterable] whose elements are expected to be contained within this [Iterable].
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case the given [expectedIterable] does not have elements (is empty).
*
* @since 0.9.0
*/
inline fun <reified E, T : Iterable<E>> IterableContains.CheckerOption<E, T, InAnyOrderSearchBehaviour>.elementsOf(
inline fun <reified E, T : Iterable<E>> CheckerOption<E, T, InAnyOrderSearchBehaviour>.elementsOf(
expectedIterable: Iterable<E>
): Expect<T> {
require(expectedIterable.iterator().hasNext()) { "Iterable without elements are not allowed." }
return values(expectedIterable.first(), *expectedIterable.drop(1).toTypedArray())
val (first, rest) = toVarArg(expectedIterable)
return values(first, *rest)
}

View File

@@ -3,7 +3,8 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.builders.ExpectImpl
import ch.tutteli.atrium.domain.builders.creating.basic.contains.addAssertion
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains
import ch.tutteli.atrium.domain.builders.utils.toVarArg
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains.Builder
import ch.tutteli.atrium.domain.creating.iterable.contains.searchbehaviours.InAnyOrderOnlySearchBehaviour
import ch.tutteli.kbox.glue
@@ -19,10 +20,10 @@ import ch.tutteli.kbox.glue
*
* @param expected The value which is expected to be contained within the [Iterable].
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InAnyOrderOnlySearchBehaviour>.value(expected: E): Expect<T> =
fun <E, T : Iterable<E>> Builder<E, T, InAnyOrderOnlySearchBehaviour>.value(expected: E): Expect<T> =
values(expected)
/**
@@ -38,10 +39,10 @@ fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InAnyOrderOnlySearchBeha
* @param expected The value which is expected to be contained within the [Iterable].
* @param otherExpected Additional values which are expected to be contained within [Iterable].
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InAnyOrderOnlySearchBehaviour>.values(
fun <E, T : Iterable<E>> Builder<E, T, InAnyOrderOnlySearchBehaviour>.values(
expected: E,
vararg otherExpected: E
): Expect<T> = addAssertion(ExpectImpl.iterable.contains.valuesInAnyOrderOnly(this, expected glue otherExpected))
@@ -61,10 +62,10 @@ fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InAnyOrderOnlySearchBeha
* for has to hold; or in other words, the function which defines whether an entry is the one we are looking for
* or not. In case it is defined as `null`, then an entry is identified if it is `null` as well.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InAnyOrderOnlySearchBehaviour>.entry(
fun <E : Any, T : Iterable<E?>> Builder<E?, T, InAnyOrderOnlySearchBehaviour>.entry(
assertionCreatorOrNull: (Expect<E>.() -> Unit)?
): Expect<T> = entries(assertionCreatorOrNull)
@@ -93,10 +94,10 @@ fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InAnyOrderOnlySe
* @param otherAssertionCreatorsOrNulls Additional identification lambdas which each identify (separately) an entry
* which we are looking for (see [assertionCreatorOrNull] for more information).
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InAnyOrderOnlySearchBehaviour>.entries(
fun <E : Any, T : Iterable<E?>> Builder<E?, T, InAnyOrderOnlySearchBehaviour>.entries(
assertionCreatorOrNull: (Expect<E>.() -> Unit)?,
vararg otherAssertionCreatorsOrNulls: (Expect<E>.() -> Unit)?
): Expect<T> = addAssertion(
@@ -119,15 +120,15 @@ fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InAnyOrderOnlySe
*
* @param expectedIterable The [Iterable] whose elements are expected to be contained within this [Iterable]
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case the given [expectedIterable] does not have elements (is empty).
*
* @since 0.9.0
*/
inline fun <reified E, T : Iterable<E>> IterableContains.Builder<E, T, InAnyOrderOnlySearchBehaviour>.elementsOf(
inline fun <reified E, T : Iterable<E>> Builder<E, T, InAnyOrderOnlySearchBehaviour>.elementsOf(
expectedIterable: Iterable<E>
): Expect<T> {
require(expectedIterable.iterator().hasNext()) { "Iterable without elements are not allowed" }
return values(expectedIterable.first(), *expectedIterable.drop(1).toTypedArray())
val (first, rest) = toVarArg(expectedIterable)
return values(first, *rest)
}

View File

@@ -3,7 +3,8 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.builders.ExpectImpl
import ch.tutteli.atrium.domain.builders.creating.basic.contains.addAssertion
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains
import ch.tutteli.atrium.domain.builders.utils.toVarArg
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains.Builder
import ch.tutteli.atrium.domain.creating.iterable.contains.searchbehaviours.InOrderOnlySearchBehaviour
import ch.tutteli.kbox.glue
@@ -19,10 +20,10 @@ import ch.tutteli.kbox.glue
*
* @param expected The value which is expected to be contained within the [Iterable].
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlySearchBehaviour>.value(expected: E): Expect<T> =
fun <E, T : Iterable<E>> Builder<E, T, InOrderOnlySearchBehaviour>.value(expected: E): Expect<T> =
values(expected)
/**
@@ -37,10 +38,10 @@ fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlySearchBehavio
* @param expected The value which is expected to be contained within the [Iterable].
* @param otherExpected Additional values which are expected to be contained within [Iterable].
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlySearchBehaviour>.values(
fun <E, T : Iterable<E>> Builder<E, T, InOrderOnlySearchBehaviour>.values(
expected: E,
vararg otherExpected: E
): Expect<T> = addAssertion(ExpectImpl.iterable.contains.valuesInOrderOnly(this, expected glue otherExpected))
@@ -60,10 +61,10 @@ fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlySearchBehavio
* for has to hold; or in other words, the function which defines whether an entry is the one we are looking for
* or not. In case it is defined as `null`, then an entry is identified if it is `null` as well.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InOrderOnlySearchBehaviour>.entry(
fun <E : Any, T : Iterable<E?>> Builder<E?, T, InOrderOnlySearchBehaviour>.entry(
assertionCreatorOrNull: (Expect<E>.() -> Unit)?
): Expect<T> = entries(assertionCreatorOrNull)
@@ -83,10 +84,10 @@ fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InOrderOnlySearc
* @param otherAssertionCreatorsOrNulls Additional identification lambdas which each identify (separately) an entry
* which we are looking for (see [assertionCreatorOrNull] for more information).
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InOrderOnlySearchBehaviour>.entries(
fun <E : Any, T : Iterable<E?>> Builder<E?, T, InOrderOnlySearchBehaviour>.entries(
assertionCreatorOrNull: (Expect<E>.() -> Unit)?,
vararg otherAssertionCreatorsOrNulls: (Expect<E>.() -> Unit)?
): Expect<T> = addAssertion(
@@ -109,15 +110,15 @@ fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InOrderOnlySearc
*
* @param expectedIterable The [Iterable] whose elements are expected to be contained within this [Iterable].
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
* @throws IllegalArgumentException in case the given [expectedIterable] does not have elements (is empty).
*
* @since 0.9.0
*/
inline fun <reified E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlySearchBehaviour>.elementsOf(
inline fun <reified E, T : Iterable<E>> Builder<E, T, InOrderOnlySearchBehaviour>.elementsOf(
expectedIterable: Iterable<E>
): Expect<T> {
require(expectedIterable.iterator().hasNext()) { "Iterable without elements are not allowed." }
return values(expectedIterable.first(), *expectedIterable.drop(1).toTypedArray())
val (first, rest) = toVarArg(expectedIterable)
return values(first, *rest)
}

View File

@@ -5,7 +5,7 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl
import ch.tutteli.atrium.domain.builders.creating.basic.contains.addAssertion
import ch.tutteli.atrium.domain.builders.utils.Group
import ch.tutteli.atrium.domain.builders.utils.groupsToList
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains.Builder
import ch.tutteli.atrium.domain.creating.iterable.contains.searchbehaviours.InOrderOnlyGroupedWithinSearchBehaviour
import kotlin.jvm.JvmName
@@ -19,10 +19,10 @@ import kotlin.jvm.JvmName
* @param otherExpectedGroups Additional groups of values which are expected to appear after the [secondGroup] within
* [Iterable] whereas the groups have to appear in the given order.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlyGroupedWithinSearchBehaviour>.inAnyOrder(
fun <E, T : Iterable<E>> Builder<E, T, InOrderOnlyGroupedWithinSearchBehaviour>.inAnyOrder(
firstGroup: Group<E>,
secondGroup: Group<E>,
vararg otherExpectedGroups: Group<E>
@@ -48,11 +48,11 @@ fun <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlyGroupedWithin
* @param otherExpectedGroups Additional groups of values which are expected to appear after the [secondGroup] within
* [Iterable] whereas the groups have to appear in the given order.
*
* @return The [Expect] for which the assertion was built to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
@JvmName("inAnyOrderEntries")
fun <E : Any, T : Iterable<E?>> IterableContains.Builder<E?, T, InOrderOnlyGroupedWithinSearchBehaviour>.inAnyOrder(
fun <E : Any, T : Iterable<E?>> Builder<E?, T, InOrderOnlyGroupedWithinSearchBehaviour>.inAnyOrder(
firstGroup: Group<(Expect<E>.() -> Unit)?>,
secondGroup: Group<(Expect<E>.() -> Unit)?>,
vararg otherExpectedGroups: Group<(Expect<E>.() -> Unit)?>

View File

@@ -1,7 +1,7 @@
package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.domain.builders.ExpectImpl
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains
import ch.tutteli.atrium.domain.creating.iterable.contains.IterableContains.Builder
import ch.tutteli.atrium.domain.creating.iterable.contains.searchbehaviours.*
import kotlin.jvm.JvmName
@@ -11,7 +11,7 @@ import kotlin.jvm.JvmName
*
* @return The newly created builder.
*/
val <E, T : Iterable<E>> IterableContains.Builder<E, T, NoOpSearchBehaviour>.inAnyOrder
val <E, T : Iterable<E>> Builder<E, T, NoOpSearchBehaviour>.inAnyOrder
get() = ExpectImpl.iterable.contains.searchBehaviours.inAnyOrder(this)
/**
@@ -20,7 +20,7 @@ val <E, T : Iterable<E>> IterableContains.Builder<E, T, NoOpSearchBehaviour>.inA
*
* @return The newly created builder.
*/
val <E, T : Iterable<E>> IterableContains.Builder<E, T, InAnyOrderSearchBehaviour>.only
val <E, T : Iterable<E>> Builder<E, T, InAnyOrderSearchBehaviour>.only
@JvmName("butOnly")
get() = ExpectImpl.iterable.contains.searchBehaviours.inAnyOrderOnly(this)
@@ -31,7 +31,7 @@ val <E, T : Iterable<E>> IterableContains.Builder<E, T, InAnyOrderSearchBehaviou
*
* @return The newly created builder.
*/
val <E, T : Iterable<E>> IterableContains.Builder<E, T, NoOpSearchBehaviour>.inOrder
val <E, T : Iterable<E>> Builder<E, T, NoOpSearchBehaviour>.inOrder
get() = ExpectImpl.iterable.contains.searchBehaviours.inOrder(this)
/**
@@ -40,7 +40,7 @@ val <E, T : Iterable<E>> IterableContains.Builder<E, T, NoOpSearchBehaviour>.inO
*
* @return The newly created builder.
*/
val <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderSearchBehaviour>.only
val <E, T : Iterable<E>> Builder<E, T, InOrderSearchBehaviour>.only
@JvmName("andOnly")
get() = ExpectImpl.iterable.contains.searchBehaviours.inOrderOnly(this)
@@ -50,7 +50,7 @@ val <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderSearchBehaviour>.
*
* @return The newly created builder.
*/
val <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlySearchBehaviour>.grouped
val <E, T : Iterable<E>> Builder<E, T, InOrderOnlySearchBehaviour>.grouped
get() = ExpectImpl.iterable.contains.searchBehaviours.inOrderOnlyGrouped(this)
/**
@@ -58,5 +58,5 @@ val <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlySearchBehavio
*
* @return The newly created builder.
*/
val <E, T : Iterable<E>> IterableContains.Builder<E, T, InOrderOnlyGroupedSearchBehaviour>.within
val <E, T : Iterable<E>> Builder<E, T, InOrderOnlyGroupedSearchBehaviour>.within
get() = ExpectImpl.iterable.contains.searchBehaviours.inOrderOnlyGroupedWithin(this)

View File

@@ -10,13 +10,14 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl
* @return The newly created [Expect] for the element at position [index].
* @throws AssertionError Might throw an [AssertionError] if the given [index] is out of bound.
*/
fun <E, T : List<E>> Expect<T>.get(index: Int): Expect<E> = ExpectImpl.list.get(this, index).getExpectOfFeature()
fun <E, T : List<E>> Expect<T>.get(index: Int): Expect<E> =
ExpectImpl.list.get(this, index).getExpectOfFeature()
/**
* Expects that the given [index] is within the bounds of the subject of the assertion (a [List]) and that
* the element at that position holds all assertions the given [assertionCreator] creates for it.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the given [index] is out of bound.
*/
fun <E, T : List<E>> Expect<T>.get(index: Int, assertionCreator: Expect<E>.() -> Unit): Expect<T> =

View File

@@ -14,7 +14,7 @@ import ch.tutteli.kbox.glue
* defined as `'a' to 1` and one of the [otherPairs] is defined as `'a' to 1` as well, then both match,
* even though they match the same entry.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, V, T : Map<out K, V>> Expect<T>.contains(
@@ -33,7 +33,7 @@ fun <K, V, T : Map<out K, V>> Expect<T>.contains(
* defined as `Key('a') { isGreaterThan(0) }` and one of the [otherKeyValues] is defined as `Key('a') { isLessThan(2) }`
* , then both match, even though they match the same entry.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
inline fun <K, reified V : Any, T : Map<out K, V?>> Expect<T>.contains(
@@ -46,7 +46,7 @@ inline fun <K, reified V : Any, T : Map<out K, V?>> Expect<T>.contains(
/**
* Expects that the subject of the assertion (a [Map]) contains the given [key].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, T : Map<out K, *>> Expect<T>.containsKey(key: K) = addAssertion(ExpectImpl.map.containsKey(this, key))
@@ -54,7 +54,7 @@ fun <K, T : Map<out K, *>> Expect<T>.containsKey(key: K) = addAssertion(ExpectIm
/**
* Expects that the subject of the assertion (a [Map]) does not contain the given [key].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, T : Map<out K, *>> Expect<T>.containsNotKey(key: K) = addAssertion(ExpectImpl.map.containsNotKey(this, key))
@@ -63,7 +63,7 @@ fun <K, T : Map<out K, *>> Expect<T>.containsNotKey(key: K) = addAssertion(Expec
/**
* Expects that the subject of the assertion (a [Map]) is an empty [Map].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Map<*, *>> Expect<T>.isEmpty() = addAssertion(ExpectImpl.map.isEmpty(this))
@@ -71,7 +71,7 @@ fun <T : Map<*, *>> Expect<T>.isEmpty() = addAssertion(ExpectImpl.map.isEmpty(th
/**
* Expects that the subject of the assertion (a [Map]) is not an empty [Map].
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Map<*, *>> Expect<T>.isNotEmpty() = addAssertion(ExpectImpl.map.isNotEmpty(this))
@@ -82,7 +82,7 @@ fun <T : Map<*, *>> Expect<T>.isNotEmpty() = addAssertion(ExpectImpl.map.isNotEm
* creates an [Expect] for the corresponding value and returns the newly created assertion container,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect] for the feature.
* @return The newly created [Expect] for the extracted feature.
* @throws AssertionError Might throw an [AssertionError] if the given [key] does not exist.
*/
fun <K, V, T : Map<out K, V>> Expect<T>.getExisting(key: K): Expect<V> =
@@ -92,7 +92,7 @@ fun <K, V, T : Map<out K, V>> Expect<T>.getExisting(key: K): Expect<V> =
* Expects that the subject of the assertion (a [Map]) contains the given [key] and that
* the corresponding value holds all assertions the given [assertionCreator] creates for it.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if a created [Assertion]s (by calling [assertionCreator])
* does not hold.
*/
@@ -103,43 +103,41 @@ fun <K, V, T : Map<out K, V>> Expect<T>.getExisting(key: K, assertionCreator: Ex
* Creates an [Expect] for the property [Map.keys] of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect] for the feature.
* @return The newly created [Expect] for the extracted feature.
*/
val <K, T : Map<out K, *>> Expect<T>.keys: Expect<Set<K>>
get() = keys(this).getExpectOfFeature()
get() = ExpectImpl.feature.property(this, Map<out K, *>::keys).getExpectOfFeature()
/**
* Expects that the property [Map.keys] of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, V, T : Map<out K, V>> Expect<T>.keys(assertionCreator: Expect<Set<K>>.() -> Unit): Expect<T> =
keys(this).addToInitial(assertionCreator)
private fun <K, T : Map<out K, *>> keys(e: Expect<T>) = ExpectImpl.feature.property(e, Map<out K, *>::keys)
ExpectImpl.feature.property(this, Map<out K, *>::keys).addToInitial(assertionCreator)
/**
* Creates an [Expect] for the property [Map.values] of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect] for the feature.
* @return The newly created [Expect] for the extracted feature.
*/
val <V, T : Map<*, V>> Expect<T>.values: Expect<Collection<V>>
get() = values().getExpectOfFeature()
get() = ExpectImpl.feature.property(this, Map<out Any?, V>::values).getExpectOfFeature()
/**
* Expects that the property [Map.keys] of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, V, T : Map<K, V>> Expect<T>.values(assertionCreator: Expect<Collection<V>>.() -> Unit): Expect<T> =
values().addToInitial(assertionCreator)
private fun <K, V, T : Map<out K, V>> Expect<T>.values() = ExpectImpl.feature.property(this, Map<out K, V>::values)
ExpectImpl.feature.property(this, Map<out K, V>::values).addToInitial(assertionCreator)
/**
* Turns `Expect<Map<K, V>>` into `Expect<Set<Map.Entry<K, V>>>`.
@@ -154,12 +152,12 @@ fun <K, V, T : Map<out K, V>> Expect<T>.asEntries(): Expect<Set<Map.Entry<K, V>>
/**
* Turns `Expect<Map<K, V>>` into `Expect<Set<Map.Entry<K, V>>>` and expects that it holds all assertions the given
* [assertionCreator] creates.
* [assertionCreator] creates for it.
*
* The transformation as such is not reflected in reporting.
* Use `feature { f(it::entries) }` if you want to show the transformation in reporting.
*
* @return The newly created [Expect] for the transformed subject.
* @return An [Expect] for the current subject of the assertion.
*/
fun <K, V, T : Map<out K, V>> Expect<T>.asEntries(
assertionCreator: Expect<Set<Map.Entry<K, V>>>.() -> Unit

View File

@@ -11,7 +11,7 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl
* block. Yet, the actual behaviour depends on implementation - could also be fail fast for instance or augment
* reporting etc.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, V, T : Map.Entry<K, V>> Expect<T>.isKeyValue(key: K, value: V): Expect<T> =
@@ -21,16 +21,17 @@ fun <K, V, T : Map.Entry<K, V>> Expect<T>.isKeyValue(key: K, value: V): Expect<T
* Creates an [Expect] for the property [Map.Entry.key] of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect].
* @return The newly created [Expect] for the extracted feature.
*/
val <K, T : Map.Entry<K, *>> Expect<T>.key: Expect<K>
get() = ExpectImpl.map.entry.key(this).getExpectOfFeature()
/**
* Expects that the property [Map.Entry.key] of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, V, T : Map.Entry<K, V>> Expect<T>.key(assertionCreator: Expect<K>.() -> Unit): Expect<T> =
@@ -40,16 +41,17 @@ fun <K, V, T : Map.Entry<K, V>> Expect<T>.key(assertionCreator: Expect<K>.() ->
* Creates an [Expect] for the property [Map.Entry.value] of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect].
* @return The newly created [Expect] for the extracted feature.
*/
val <V, T : Map.Entry<*, V>> Expect<T>.value: Expect<V>
get() = ExpectImpl.map.entry.value(this).getExpectOfFeature()
/**
* Expects that the property [Map.Entry.value] of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, V, T : Map.Entry<K, V>> Expect<T>.value(assertionCreator: Expect<V>.() -> Unit): Expect<T> =

View File

@@ -7,16 +7,17 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl
* Creates an [Expect] for the property [Pair.first] of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect].
* @return The newly created [Expect] for the extracted feature.
*/
val <K, T : Pair<K, *>> Expect<T>.first: Expect<K>
get() = ExpectImpl.pair.first(this).getExpectOfFeature()
val <K, T : Pair<K, *>> Expect<T>.first
get() : Expect<K> = ExpectImpl.pair.first(this).getExpectOfFeature()
/**
* Expects that the property [Pair.first] of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, V, T : Pair<K, V>> Expect<T>.first(assertionCreator: Expect<K>.() -> Unit): Expect<T> =
@@ -26,16 +27,17 @@ fun <K, V, T : Pair<K, V>> Expect<T>.first(assertionCreator: Expect<K>.() -> Uni
* Creates an [Expect] for the property [Pair.second] of the subject of the assertion,
* so that further fluent calls are assertions about it.
*
* @return The newly created [Expect].
* @return The newly created [Expect] for the extracted feature.
*/
val <V, T : Pair<*, V>> Expect<T>.second: Expect<V>
get() = ExpectImpl.pair.second(this).getExpectOfFeature()
val <V, T : Pair<*, V>> Expect<T>.second
get() : Expect<V> = ExpectImpl.pair.second(this).getExpectOfFeature()
/**
* Expects that the property [Pair.second] of the subject of the assertion
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <K, V, T : Pair<K, V>> Expect<T>.second(assertionCreator: Expect<V>.() -> Unit): Expect<T> =

View File

@@ -21,7 +21,7 @@ fun <E, T : Sequence<E>> Expect<T>.asIterable(): Expect<Iterable<E>> =
* The transformation as such is not reflected in reporting.
* Use `feature(Sequence::asIterable, assertionCreator)` if you want to show the transformation in reporting.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
*/
fun <E, T : Sequence<E>> Expect<T>.asIterable(assertionCreator: Expect<Iterable<E>>.() -> Unit): Expect<T> =
apply { asIterable().addAssertionsCreatedBy(assertionCreator) }

View File

@@ -1,12 +1,13 @@
package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.builders.ExpectImpl
/**
* Expects that the property [Throwable.message] of the subject of the assertion is not null,
* creates an [Expect] for it and returns it.
*
* @return The newly created [Expect] for the property [Throwable.message] of the subject of the assertion
* @return The newly created [Expect] for the property [Throwable.message] of the subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
val <T : Throwable> Expect<T>.message: Expect<String>
@@ -14,9 +15,10 @@ val <T : Throwable> Expect<T>.message: Expect<String>
/**
* Expects that the property [Throwable.message] of the subject of the assertion is not null and
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
* holds all assertions the given [assertionCreator] creates for it and
* returns an [Expect] for the current subject of the assertion.
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Throwable> Expect<T>.message(assertionCreator: Expect<String>.() -> Unit): Expect<T> =
@@ -33,8 +35,39 @@ fun <T : Throwable> Expect<T>.message(assertionCreator: Expect<String>.() -> Uni
* Notice that a runtime check applies which assures that only [CharSequence], [Number] and [Char] are passed
* (this function expects `Any` for your convenience, so that you can mix [String] and [Int] for instance).
*
* @return This assertion container to support a fluent API.
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*/
fun <T : Throwable> Expect<T>.messageContains(expected: Any, vararg otherExpected: Any): Expect<T> =
message { contains(expected, *otherExpected) }
/**
* Expects that the property [Throwable.cause] of the subject *is a* [TExpected] (the same type or a sub-type),
* creates an [Expect] of the [TExpected] type for it and returns it.
*
* @return The newly created [Expect] for the property [Throwable.cause] of the subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.10.0
*/
inline fun <reified TExpected : Throwable> Expect<out Throwable>.cause(): Expect<TExpected> =
ExpectImpl.throwable.cause(this, TExpected::class).getExpectOfFeature()
/**
*
* Expects that the property [Throwable.cause] of the subject *is a* [TExpected] (the same type or a sub-type) and
* holds all assertions the given [assertionCreator] creates for it and returns this assertion container.
*
* Notice, in contrast to other assertion functions which expect an [assertionCreator], this function returns not
* [Expect] of the initial type, which was some type `T `, but an [Expect] of the specified type [TExpected].
*
* @return An [Expect] for the current subject of the assertion.
* @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct.
*
* @since 0.10.0
*/
inline fun <reified TExpected : Throwable> Expect<out Throwable>.cause(
noinline assertionCreator: Expect<TExpected>.() -> Unit
): Expect<TExpected> =
ExpectImpl.throwable.cause(this, TExpected::class).addToFeature(assertionCreator)

View File

@@ -2,6 +2,7 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.withNullableSuffix
import kotlin.reflect.KFunction2
import kotlin.reflect.KProperty1
@@ -12,16 +13,16 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
fun1<DataClass?, DataClass?>(Expect<DataClass?>::toBe),
fun1(Expect<Int>::notToBe),
fun1(Expect<DataClass>::notToBe),
fun1(Expect<Int?>::notToBe, suffix = " nullable"),
fun1(Expect<DataClass?>::notToBe, suffix = " nullable"),
fun1(Expect<Int?>::notToBe).withNullableSuffix(),
fun1(Expect<DataClass?>::notToBe).withNullableSuffix(),
fun1(Expect<Int>::isSameAs),
fun1(Expect<DataClass>::isSameAs),
fun1(Expect<Int?>::isSameAs, suffix = " nullable"),
fun1(Expect<DataClass?>::isSameAs, suffix = " nullable"),
fun1(Expect<Int?>::isSameAs).withNullableSuffix(),
fun1(Expect<DataClass?>::isSameAs).withNullableSuffix(),
fun1(Expect<Int>::isNotSameAs),
fun1(Expect<DataClass>::isNotSameAs),
fun1(Expect<Int?>::isNotSameAs, suffix = " nullable"),
fun1(Expect<DataClass?>::isNotSameAs, suffix = " nullable"),
fun1(Expect<Int?>::isNotSameAs).withNullableSuffix(),
fun1(Expect<DataClass?>::isNotSameAs).withNullableSuffix(),
"${Expect<Int?>::toBe.name}(null)" to Companion::toBeNull,
fun1(Expect<Int?>::toBeNullIfNullGivenElse),
@@ -43,7 +44,8 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
companion object {
private fun toBeNull(expect: Expect<Int?>) = expect.toBe(null)
private fun isAFeature(expect: Expect<Int?>): Expect<Int> = expect.isA()
@Suppress("RemoveExplicitTypeArguments")
private fun isAFeature(expect: Expect<Int?>): Expect<Int> = expect.isA<Int>()
private val andImmediate: KProperty1<Expect<Int>, Expect<Int>> = Expect<Int>::and
fun getAndImmediatePair(): Pair<String, Expect<Int>.() -> Expect<Int>> = andImmediate.name to Expect<Int>::and

View File

@@ -3,8 +3,9 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.fun0
import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.notImplemented
object CharSequenceAssertionsSpec : ch.tutteli.atrium.specs.integration.CharSequenceAssertionsSpec(
class CharSequenceAssertionsSpec : ch.tutteli.atrium.specs.integration.CharSequenceAssertionsSpec(
fun0(Expect<CharSequence>::isEmpty),
fun0(Expect<CharSequence>::isNotEmpty),
fun0(Expect<CharSequence>::isNotBlank),
@@ -18,4 +19,26 @@ object CharSequenceAssertionsSpec : ch.tutteli.atrium.specs.integration.CharSequ
fun1<CharSequence, Char>(Expect<CharSequence>::endsNotWith),
fun1<CharSequence, Regex>(Expect<CharSequence>::matches),
fun1<CharSequence, Regex>(Expect<CharSequence>::mismatches)
)
) {
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
val a1: Expect<String> = notImplemented()
a1.isEmpty()
a1.isNotEmpty()
a1.isNotBlank()
a1.startsWith("expected")
a1.startsNotWith("expected")
a1.endsWith("expected")
a1.endsNotWith("expected")
a1.startsWith('a')
a1.startsNotWith('a')
a1.endsWith('a')
a1.endsNotWith('a')
a1.matches(Regex("a"))
a1.mismatches(Regex("a"))
}
}

View File

@@ -29,20 +29,27 @@ class CharSequenceContainsAtLeastAssertionsSpec : Spek({
) {})
include(object : Spek({
describe("elementsOf") {
describe("atLeast(1).elementsOf") {
it("passing an empty iterable throws an IllegalArgumentException") {
expect {
expect("test").contains.atLeast(1).elementsOf(emptyList())
}.toThrow<IllegalArgumentException> { messageContains("Iterable without elements are not allowed") }
}
}
describe("elementsOf ignoring case") {
describe("ignoringCase.atLeast(1).elementsOf") {
it("passing an empty iterable throws an IllegalArgumentException") {
expect {
expect("test").contains.ignoringCase.atLeast(1).elementsOf(emptyList())
}.toThrow<IllegalArgumentException> { messageContains("Iterable without elements are not allowed") }
}
}
describe("ignoringCase.elementsOf") {
it("passing an empty iterable throws an IllegalArgumentException") {
expect {
expect("test").contains.ignoringCase.elementsOf(emptyList())
}.toThrow<IllegalArgumentException> { messageContains("Iterable without elements are not allowed") }
}
}
}) {})
}) {
@@ -101,7 +108,13 @@ class CharSequenceContainsAtLeastAssertionsSpec : Spek({
a: Any,
aX: Array<out Any>
): Expect<CharSequence> =
expect.contains.ignoringCase.atLeast(atLeast).elementsOf(listOf(a, *aX))
if (aX.isEmpty()) {
if (atLeast == 1) expect.contains.ignoringCase.elementsOf(listOf(a))
else expect.contains.ignoringCase.atLeast(atLeast).elementsOf(listOf(a))
} else {
if (atLeast == 1) expect.contains.ignoringCase.elementsOf(listOf(a, *aX))
else expect.contains.ignoringCase.atLeast(atLeast).elementsOf(listOf(a, *aX))
}
private val atLeastButAtMostDescr = { what: String, timesAtLeast: String, timesAtMost: String ->
"$contains $what $atLeast $timesAtLeast $butAtMost $timesAtMost"
@@ -155,7 +168,7 @@ class CharSequenceContainsAtLeastAssertionsSpec : Spek({
aX: Array<out Any>
) = expect.contains.ignoringCase.atLeast(atLeast).butAtMost(butAtMost).elementsOf(listOf(a, *aX))
private fun getContainsNotPair() = containsNot to Companion::getErrorMsgContainsNot
private fun getContainsNotPair() = containsNot to ::getErrorMsgContainsNot
private fun getErrorMsgContainsNot(times: Int) = "use $containsNot instead of $atLeast($times)"

View File

@@ -1,28 +1,52 @@
package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import kotlin.reflect.KFunction3
import ch.tutteli.atrium.specs.fun2
import ch.tutteli.atrium.specs.notImplemented
import org.spekframework.spek2.Spek
class CharSequenceContainsContainsNotAssertionsSpec :
ch.tutteli.atrium.specs.integration.CharSequenceContainsContainsNotAssertionsSpec(
class CharSequenceContainsContainsNotAssertionsSpec : Spek({
include(object : ch.tutteli.atrium.specs.integration.CharSequenceContainsContainsNotAssertionsSpec(
getContainsPair(),
getContainsNotPair(),
"◆ ", "", "▶ "
) {
"◆ ", "", "▶ ",
"[Atrium][Builder]"
) {})
include(object : ch.tutteli.atrium.specs.integration.CharSequenceContainsContainsNotAssertionsSpec(
getContainsShortcutPair(),
getContainsNotShortcutPair(),
"◆ ", "", "▶ ",
"[Atrium][Shortcut]"
) {})
}) {
companion object : CharSequenceContainsSpecBase() {
private val containsFun: KFunction3<Expect<CharSequence>, Any, Array<out Any>, Expect<CharSequence>> =
Expect<CharSequence>::contains
private fun getContainsPair() = "$contains.$atLeast(1).values" to Companion::containsValues
fun getContainsPair() = containsFun.name to Companion::containsShortcut
private fun containsValues(expect: Expect<CharSequence>, a: Any, aX: Array<out Any>) =
if (aX.isEmpty()) expect.contains.atLeast(1).value(a)
else expect.contains.atLeast(1).values(a, *aX)
private fun containsShortcut(expect: Expect<CharSequence>, a: Any, aX: Array<out Any>) = expect.contains(a, *aX)
private fun getContainsNotPair() =
"${super.containsNot} o $atLeast 1 value/the Values" to Companion::containsNotValues
private val containsNotFun: KFunction3<Expect<CharSequence>, Any, Array<out Any>, Expect<CharSequence>> =
Expect<CharSequence>::containsNot
private fun containsNotValues(expect: Expect<CharSequence>, a: Any, aX: Array<out Any>) =
if (aX.isEmpty()) expect.containsNot.value(a)
else expect.containsNot.values(a, *aX)
private fun getContainsNotPair() = containsNotFun.name to Companion::containsNotShortcut
private fun getContainsShortcutPair() =
fun2<CharSequence, Any, Array<out Any>>(Expect<CharSequence>::contains)
private fun containsNotShortcut(expect: Expect<CharSequence>, a: Any, aX: Array<out Any>) =
expect.containsNot(a, *aX)
private fun getContainsNotShortcutPair() =
fun2<CharSequence, Any, Array<out Any>>(Expect<CharSequence>::containsNot)
}
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
val a1: Expect<String> = notImplemented()
a1.contains(1, "a", 'c')
a1.containsNot(1, "a", 'c')
}
}

View File

@@ -6,6 +6,7 @@ import ch.tutteli.atrium.domain.creating.charsequence.contains.CharSequenceConta
import ch.tutteli.atrium.domain.creating.charsequence.contains.searchbehaviours.NoOpSearchBehaviour
import ch.tutteli.atrium.specs.fun2
import ch.tutteli.atrium.specs.name
import ch.tutteli.atrium.specs.notImplemented
import kotlin.reflect.KFunction3
import kotlin.reflect.KProperty
@@ -28,4 +29,55 @@ abstract class CharSequenceContainsSpecBase {
> = CharSequenceContains.CheckerOption<*, NoOpSearchBehaviour>::regex
protected val regex = regexKFun.name
protected val ignoringCase = CharSequenceContains.Builder<*, NoOpSearchBehaviour>::ignoringCase.name
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
val a1: Expect<String> = notImplemented()
a1.contains.atLeast(1).value(1)
a1.contains.atMost(2).values("a", 1)
a1.contains.notOrAtMost(2).regex("h|b")
a1.contains.exactly(2).regex("h|b", "b")
a1.contains.atLeast(2).regex(Regex("bla"))
a1.contains.atLeast(2).regex(Regex("bla"), Regex("b"))
a1.contains.atLeast(2).elementsOf(listOf("a", 2))
a1.containsNot.value(1)
a1.containsNot.values("a", 1)
a1.containsNot.regex("h|b", "b")
a1.containsNot.regex(Regex("bla"))
a1.containsNot.regex(Regex("bla"), Regex("b"))
a1.containsNot.elementsOf(listOf("a", 2))
a1.contains.ignoringCase.atLeast(1).value("a")
a1.contains.ignoringCase.atLeast(1).values("a", 'b')
a1.contains.ignoringCase.atLeast(1).regex("a")
a1.contains.ignoringCase.atLeast(1).regex("a", "bl")
// not supported on purpose as one can specify an ignore case flag for Regex
// and hence these would be a second way to do the same thing
//a1.contains.ignoringCase.atLeast(1).regex(Regex("a"))
//a1.contains.ignoringCase.atLeast(1).regex(Regex("a"), Regex("bl"))
a1.contains.ignoringCase.atLeast(1).elementsOf(listOf(1, 2))
a1.containsNot.ignoringCase.value("a")
a1.containsNot.ignoringCase.values("a", 'b')
a1.containsNot.ignoringCase.regex("a")
a1.containsNot.ignoringCase.regex("a", "bl")
// not supported on purpose as one can specify an ignore case flag for Regex
// and hence these would be a second way to do the same thing
//a1.containsNot.ignoringCase.regex(Regex("a"))
//a1.containsNot.ignoringCase.regex(Regex("a"), Regex("bl"))
a1.containsNot.ignoringCase.elementsOf(listOf(1, 2))
// skip atLeast
a1.contains.ignoringCase.value("a")
a1.contains.ignoringCase.values("a", 'b')
a1.contains.ignoringCase.regex("a")
a1.contains.ignoringCase.regex("a", "bl")
// not supported on purpose as one can specify an ignore case flag for Regex
// and hence these would be a second way to do the same thing
//a1.contains.ignoringCase.regex(Regex("a"))
//a1.contains.ignoringCase.regex(Regex("a"), Regex("bl"))
a1.contains.ignoringCase.elementsOf(listOf("a", 2))
}
}

View File

@@ -10,8 +10,8 @@ object CollectionAssertionsSpec : ch.tutteli.atrium.specs.integration.Collection
) {
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
val a1: Expect<Collection<Int>> = notImplemented()
val a1b: Expect<Collection<Int?>> = notImplemented()
val a1: Expect<List<Int>> = notImplemented()
val a1b: Expect<Set<Int?>> = notImplemented()
val star: Expect<Collection<*>> = notImplemented()

View File

@@ -11,10 +11,10 @@ object CollectionFeatureAssertionsSpec : ch.tutteli.atrium.specs.integration.Col
) {
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
var a1: Expect<Collection<Int>> = notImplemented()
var a1b: Expect<Collection<Int?>> = notImplemented()
var a1: Expect<AbstractList<Int>> = notImplemented()
var a1b: Expect<AbstractSet<Int?>> = notImplemented()
var star: Expect<Collection<*>> = notImplemented()
var star: Expect<AbstractCollection<*>> = notImplemented()
a1.size
a1 = a1.size { }

View File

@@ -1,10 +1,11 @@
package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.adjustName
import ch.tutteli.atrium.specs.fun2
class FloatingPointWithErrorToleranceAssertionsSpec :
ch.tutteli.atrium.specs.integration.FloatingPointWithErrorToleranceAssertionsSpec(
fun2(Expect<Float>::toBeWithErrorTolerance, suffix = " for Float"),
fun2(Expect<Double>::toBeWithErrorTolerance, suffix = " for Double")
fun2(Expect<Float>::toBeWithErrorTolerance).adjustName { "$it for Float" },
fun2(Expect<Double>::toBeWithErrorTolerance).adjustName { "$it for Double" }
)

View File

@@ -4,19 +4,23 @@ import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.feature0
import ch.tutteli.atrium.specs.feature1
import ch.tutteli.atrium.specs.notImplemented
import ch.tutteli.atrium.specs.withFeatureSuffix
class Fun0AssertionsSpec : ch.tutteli.atrium.specs.integration.Fun0AssertionsSpec(
"toThrow" to Companion::toThrowFeature,
("toThrow" to Companion::toThrowFeature).withFeatureSuffix(),
"toThrow" to Companion::toThrow,
feature0<() -> Int, Int>(Expect<() -> Int>::notToThrow),
feature1<() -> Int, Expect<Int>.() -> Unit, Int>(Expect<() -> Int>::notToThrow),
"", "» "
) {
companion object {
fun toThrowFeature(expect: Expect<out () -> Any?>) = expect.toThrow<IllegalArgumentException>()
fun toThrow(expect: Expect<out () -> Any?>, assertionCreator: Expect<IllegalArgumentException>.() -> Unit) =
expect.toThrow<IllegalArgumentException> { assertionCreator() }
private fun toThrowFeature(expect: Expect<out () -> Any?>) =
expect.toThrow<IllegalArgumentException>()
private fun toThrow(
expect: Expect<out () -> Any?>,
assertionCreator: Expect<IllegalArgumentException>.() -> Unit
) = expect.toThrow<IllegalArgumentException> { assertionCreator() }
}
@Suppress("unused", "UNUSED_VALUE", "UNUSED_VARIABLE")
@@ -37,3 +41,4 @@ class Fun0AssertionsSpec : ch.tutteli.atrium.specs.integration.Fun0AssertionsSpe
val r8: Expect<Int> = a2.notToThrow {}
}
}

View File

@@ -3,18 +3,19 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.notImplemented
import ch.tutteli.atrium.specs.withNullableSuffix
object IterableAllAssertionsSpec : ch.tutteli.atrium.specs.integration.IterableAllAssertionsSpec(
fun1(Expect<Iterable<Double>>::all),
fun1(Expect<Iterable<Double?>>::all),
fun1(Expect<Iterable<Double?>>::all).withNullableSuffix(),
"◆ ", "❗❗ ", "", "» ", "▶ ", "◾ "
) {
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
var a1: Expect<Iterable<Double>> = notImplemented()
var a1b: Expect<Iterable<Double?>> = notImplemented()
var a1: Expect<List<Double>> = notImplemented()
var a1b: Expect<Set<Double?>> = notImplemented()
var star: Expect<Iterable<*>> = notImplemented()
var star: Expect<Collection<*>> = notImplemented()
a1 = a1.all {}

View File

@@ -4,9 +4,9 @@ import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.builders.ExpectImpl
import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.notImplemented
import ch.tutteli.atrium.specs.withNullableSuffix
import org.spekframework.spek2.Spek
import kotlin.reflect.KFunction2
import kotlin.reflect.KFunction3
class IterableAnyAssertionsSpec : Spek({
include(PredicateSpec)
@@ -16,75 +16,75 @@ class IterableAnyAssertionsSpec : Spek({
}) {
object PredicateSpec : ch.tutteli.atrium.specs.integration.IterableAnyAssertionsSpec(
fun1(Expect<Iterable<Double>>::any),
fun1(Expect<Iterable<Double?>>::any),
fun1(Expect<Iterable<Double?>>::any).withNullableSuffix(),
"◆ ",
"[Atrium][Predicate] "
)
object BuilderSpec : ch.tutteli.atrium.specs.integration.IterableAnyAssertionsSpec(
getContainsPair(),
getContainsNullablePair(),
getContainsNullablePair().withNullableSuffix(),
"◆ ",
"[Atrium][Builder] "
)
object ShortcutSpec : ch.tutteli.atrium.specs.integration.IterableAnyAssertionsSpec(
getContainsShortcutPair(),
getContainsNullableShortcutPair(),
getContainsNullableShortcutPair().withNullableSuffix(),
"◆ ",
"[Atrium][Shortcut] "
)
object SequenceSpec : ch.tutteli.atrium.specs.integration.IterableAnyAssertionsSpec(
getContainsSequencePair(),
getContainsNullableSequencePair(),
getContainsNullableSequencePair().withNullableSuffix(),
"◆ ",
"[Atrium][Sequence] "
)
companion object : IterableContainsSpecBase() {
fun getContainsPair() =
"$contains.$inAnyOrder.$atLeast(1).$inAnyOrderEntries" to Companion::containsInAnyOrderEntries
"$contains.$inAnyOrder.$atLeast(1).$inAnyOrderEntries" to Companion::containsInAnyOrderEntry
private fun containsInAnyOrderEntries(expect: Expect<Iterable<Double>>, a: Expect<Double>.() -> Unit) =
private fun containsInAnyOrderEntry(expect: Expect<Iterable<Double>>, a: Expect<Double>.() -> Unit) =
expect.contains.inAnyOrder.atLeast(1).entry(a)
fun getContainsNullablePair() =
"$contains.$inAnyOrder.$atLeast(1).$inAnyOrderEntries" to Companion::containsNullableEntries
"$contains.$inAnyOrder.$atLeast(1).$inAnyOrderEntries" to Companion::containsNullableEntry
private fun containsNullableEntries(expect: Expect<Iterable<Double?>>, a: (Expect<Double>.() -> Unit)?) =
private fun containsNullableEntry(expect: Expect<Iterable<Double?>>, a: (Expect<Double>.() -> Unit)?) =
expect.contains.inAnyOrder.atLeast(1).entry(a)
private val containsShortcutFun: KFunction3<Expect<Iterable<Double>>, Expect<Double>.() -> Unit, Array<out Expect<Double>.() -> Unit>, Expect<Iterable<Double>>> =
private val containsShortcutFun: KFunction2<Expect<Iterable<Double>>, Expect<Double>.() -> Unit, Expect<Iterable<Double>>> =
Expect<Iterable<Double>>::contains
fun getContainsShortcutPair() = containsShortcutFun.name to Companion::containsInAnyOrderEntriesShortcut
fun getContainsShortcutPair() = containsShortcutFun.name to Companion::containsInAnyOrderEntryShortcut
private fun containsInAnyOrderEntriesShortcut(expect: Expect<Iterable<Double>>, a: Expect<Double>.() -> Unit) =
private fun containsInAnyOrderEntryShortcut(expect: Expect<Iterable<Double>>, a: Expect<Double>.() -> Unit) =
expect.contains(a)
private val containsShortcutNullableFun: KFunction2<Expect<Iterable<Double?>>, (Expect<Double>.() -> Unit)?, Expect<Iterable<Double?>>> =
Expect<Iterable<Double?>>::contains
fun getContainsNullableShortcutPair() =
containsShortcutNullableFun.name to Companion::containsNullableEntriesShortcut
containsShortcutNullableFun.name to Companion::containsNullableEntryShortcut
private fun containsNullableEntriesShortcut(
private fun containsNullableEntryShortcut(
expect: Expect<Iterable<Double?>>,
a: (Expect<Double>.() -> Unit)?
) = expect.contains(a)
private fun getContainsSequencePair() =
"asSequence().${Sequence<*>::asIterable.name}().${containsShortcutFun.name}" to Companion::containsInAnyOrderEntriesSequence
"asSequence().${Sequence<*>::asIterable.name}().${containsShortcutFun.name}" to Companion::containsInAnyOrderEntrySequence
private fun containsInAnyOrderEntriesSequence(expect: Expect<Iterable<Double>>, a: Expect<Double>.() -> Unit) =
private fun containsInAnyOrderEntrySequence(expect: Expect<Iterable<Double>>, a: Expect<Double>.() -> Unit) =
ExpectImpl.changeSubject(expect).unreported { it.asSequence() }.asIterable().contains(a)
fun getContainsNullableSequencePair() =
"asSequence().${Sequence<*>::asIterable.name}().${containsShortcutNullableFun.name}" to Companion::containsNullableEntriesSequence
"asSequence().${Sequence<*>::asIterable.name}().${containsShortcutNullableFun.name}" to Companion::containsNullableEntrySequence
private fun containsNullableEntriesSequence(
private fun containsNullableEntrySequence(
expect: Expect<Iterable<Double?>>,
a: (Expect<Double>.() -> Unit)?
) = ExpectImpl.changeSubject(expect).unreported { it.asSequence() }.asIterable().contains(a)
@@ -92,10 +92,10 @@ class IterableAnyAssertionsSpec : Spek({
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
var a1: Expect<Iterable<Double>> = notImplemented()
var a1b: Expect<Iterable<Double?>> = notImplemented()
var a1: Expect<List<Double>> = notImplemented()
var a1b: Expect<Set<Double?>> = notImplemented()
var star: Expect<Iterable<*>> = notImplemented()
var star: Expect<Collection<*>> = notImplemented()
a1 = a1.any {}
a1 = a1.contains {}

View File

@@ -11,10 +11,9 @@ object IterableAssertionsSpec : ch.tutteli.atrium.specs.integration.IterableAsse
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
var a1: Expect<Iterable<Double>> = notImplemented()
var a1b: Expect<Iterable<Double?>> = notImplemented()
var star: Expect<Iterable<*>> = notImplemented()
var a1: Expect<List<Double>> = notImplemented()
var a1b: Expect<Set<Double?>> = notImplemented()
var star: Expect<Collection<*>> = notImplemented()
a1 = a1.hasNext()
a1 = a1.hasNotNext()

View File

@@ -59,7 +59,7 @@ class IterableContainsInAnyOrderAtLeast1ValuesAssertionsSpec : Spek({
else expect.contains(a, *aX)
private val containsNullableFun: KFunction3<Expect<Iterable<Double?>>, Double, Array<out Double?>, Expect<Iterable<Double?>>> =
private val containsNullableFun: KFunction3<Expect<Iterable<Double?>>, Double?, Array<out Double?>, Expect<Iterable<Double?>>> =
Expect<Iterable<Double?>>::contains
fun getContainsNullableShortcutPair() = containsNullableFun.name to Companion::containsNullableValuesShortcut

View File

@@ -21,9 +21,7 @@ class IterableContainsInOrderOnlyGroupedValuesAssertionsSpec :
a1: Group<Double>,
a2: Group<Double>,
aX: Array<out Group<Double>>
): Expect<Iterable<Double>> {
return expect.contains.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX)
}
): Expect<Iterable<Double>> = expect.contains.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX)
private fun groupFactory(groups: Array<out Double>): Group<Double> =
when (groups.size) {
@@ -43,9 +41,7 @@ class IterableContainsInOrderOnlyGroupedValuesAssertionsSpec :
a1: Group<Double?>,
a2: Group<Double?>,
aX: Array<out Group<Double?>>
): Expect<Iterable<Double?>> {
return expect.contains.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX)
}
): Expect<Iterable<Double?>> = expect.contains.inOrder.only.grouped.within.inAnyOrder(a1, a2, *aX)
private fun nullableGroupFactory(groups: Array<out Double?>): Group<Double?> =
when (groups.size) {

View File

@@ -43,30 +43,69 @@ abstract class IterableContainsSpecBase {
@Suppress("unused")
private fun ambiguityTest() {
val list: Expect<List<Number>> = notImplemented()
val nullableList: Expect<List<Number?>> = notImplemented()
val nullableList: Expect<Set<Number?>> = notImplemented()
val subList: Expect<ArrayList<out Number>> = notImplemented()
val star: Expect<Collection<*>> = notImplemented()
list.contains(1)
list.contains(1f)
list.contains(1, 2)
list.contains(1, 2f)
list.contains {}
list.contains({}, {})
list.containsNot(1)
list.containsNot(1f)
list.containsNot(1, 2f)
list.containsNot.entry {}
list.containsNot.entries({}, {})
subList.contains(1)
subList.contains(1f)
subList.contains(1, 2)
subList.contains(1, 2f)
subList.contains {}
subList.contains({}, {})
subList.containsNot(1)
subList.containsNot(1f)
subList.containsNot(1, 2f)
subList.containsNot.entry {}
subList.containsNot.entries({}, {})
nullableList.contains(1)
nullableList.contains(1f)
nullableList.contains(1, 2)
nullableList.contains(1, 2f)
nullableList.contains {}
nullableList.contains({}, {})
nullableList.containsNot(1)
nullableList.containsNot(1f)
nullableList.containsNot(1, 2f)
nullableList.containsNot.entry {}
nullableList.containsNot.entries({}, {})
nullableList.contains(null)
nullableList.contains({}, null)
nullableList.contains({}, {})
nullableList.contains(null, {})
nullableList.contains(null, null)
nullableList.containsNot(null)
nullableList.containsNot.entries({}, null)
nullableList.containsNot.entries(null, {})
nullableList.containsNot.entries(null, null)
star.contains(1)
star.contains(1f)
star.contains(1, 2f)
star.contains {}
star.contains({}, {})
star.containsNot(1)
star.containsNot(1f)
star.containsNot(1, 2f)
star.containsNot.entry {}
star.containsNot.entries({}, {})
star.contains(null)
star.contains({}, null)
star.contains(null, {})
star.contains(null, null)
star.containsNot(null)
star.containsNot.entries({}, null)
star.containsNot.entries(null, {})
star.containsNot.entries(null, null)
list.containsExactly(1)
list.containsExactly(1, 2f)
@@ -85,67 +124,162 @@ abstract class IterableContainsSpecBase {
nullableList.containsExactly(null, {})
list.contains.inAnyOrder.atLeast(1).value(1)
list.contains.inAnyOrder.atLeast(1).value(null)
list.contains.inAnyOrder.atLeast(1).values(2, 1)
list.contains.inAnyOrder.atLeast(1).entry {}
list.contains.inAnyOrder.atLeast(1).entry(null)
list.contains.inAnyOrder.atLeast(1).entries({}, {})
list.contains.inAnyOrder.atLeast(1).elementsOf(listOf(1, 2))
subList.contains.inAnyOrder.atLeast(1).value(1)
subList.contains.inAnyOrder.atLeast(1).value(null)
subList.contains.inAnyOrder.atLeast(1).values(2, 1)
subList.contains.inAnyOrder.atLeast(1).entry {}
subList.contains.inAnyOrder.atLeast(1).entry(null)
subList.contains.inAnyOrder.atLeast(1).entries({}, {})
subList.contains.inAnyOrder.atLeast(1).elementsOf(listOf(1, 2))
nullableList.contains.inAnyOrder.atLeast(1).value(1)
nullableList.contains.inAnyOrder.atLeast(1).values(2, 1)
nullableList.contains.inAnyOrder.atLeast(1).entry {}
nullableList.contains.inAnyOrder.atLeast(1).entries({}, {})
nullableList.contains.inAnyOrder.atLeast(1).elementsOf(listOf(1, 2))
nullableList.contains.inAnyOrder.atLeast(1).value(null)
nullableList.contains.inAnyOrder.atLeast(1).values(null, 1)
nullableList.contains.inAnyOrder.atLeast(1).values(2, null)
nullableList.contains.inAnyOrder.atLeast(1).values(null, null)
nullableList.contains.inAnyOrder.atLeast(1).entry(null)
nullableList.contains.inAnyOrder.atLeast(1).entries(null, {})
nullableList.contains.inAnyOrder.atLeast(1).entries({}, null)
nullableList.contains.inAnyOrder.atLeast(1).entries(null, null)
star.contains.inAnyOrder.atLeast(1).value(1)
star.contains.inAnyOrder.atLeast(1).values(2, 1)
star.contains.inAnyOrder.atLeast(1).entry {}
star.contains.inAnyOrder.atLeast(1).entries({}, {})
star.contains.inAnyOrder.atLeast(1).elementsOf(listOf(1, 2))
star.contains.inAnyOrder.atLeast(1).value(null)
star.contains.inAnyOrder.atLeast(1).values(null, 1)
star.contains.inAnyOrder.atLeast(1).values(2, null)
star.contains.inAnyOrder.atLeast(1).values(null, null)
star.contains.inAnyOrder.atLeast(1).entry(null)
star.contains.inAnyOrder.atLeast(1).entries(null, {})
star.contains.inAnyOrder.atLeast(1).entries({}, null)
star.contains.inAnyOrder.atLeast(1).entries(null, null)
list.contains.inAnyOrder.only.value(1)
list.contains.inAnyOrder.only.value(null)
list.contains.inAnyOrder.only.values(2, 1)
list.contains.inAnyOrder.only.entry {}
list.contains.inAnyOrder.only.entry(null)
list.contains.inAnyOrder.only.entries({}, {})
list.contains.inAnyOrder.only.elementsOf(listOf(1, 2))
subList.contains.inAnyOrder.only.value(1)
subList.contains.inAnyOrder.only.value(null)
subList.contains.inAnyOrder.only.values(2, 1)
subList.contains.inAnyOrder.only.entry {}
subList.contains.inAnyOrder.only.entry(null)
subList.contains.inAnyOrder.only.entries({}, {})
subList.contains.inAnyOrder.only.elementsOf(listOf(1, 2))
nullableList.contains.inAnyOrder.only.value(1)
nullableList.contains.inAnyOrder.only.values(2, 1)
nullableList.contains.inAnyOrder.only.entry {}
nullableList.contains.inAnyOrder.only.entries({}, {})
nullableList.contains.inAnyOrder.only.elementsOf(listOf(1, 2))
nullableList.contains.inAnyOrder.only.value(null)
nullableList.contains.inAnyOrder.only.values(null, 1)
nullableList.contains.inAnyOrder.only.values(2, null)
nullableList.contains.inAnyOrder.only.values(null, null)
nullableList.contains.inAnyOrder.only.entry(null)
nullableList.contains.inAnyOrder.only.entries(null, {})
nullableList.contains.inAnyOrder.only.entries({}, null)
nullableList.contains.inAnyOrder.only.entries(null, null)
star.contains.inAnyOrder.only.value(1)
star.contains.inAnyOrder.only.values(2, 1)
star.contains.inAnyOrder.only.entry {}
star.contains.inAnyOrder.only.entries({}, {})
star.contains.inAnyOrder.only.elementsOf(listOf(1, 2))
star.contains.inAnyOrder.only.value(null)
star.contains.inAnyOrder.only.values(null, 1)
star.contains.inAnyOrder.only.values(2, null)
star.contains.inAnyOrder.only.values(null, null)
star.contains.inAnyOrder.only.entry(null)
star.contains.inAnyOrder.only.entries(null, {})
star.contains.inAnyOrder.only.entries({}, null)
star.contains.inAnyOrder.only.entries(null, null)
list.contains.inOrder.only.value(1)
list.contains.inOrder.only.value(null)
list.contains.inOrder.only.values(2, 1)
list.contains.inOrder.only.entry {}
list.contains.inOrder.only.entry(null)
list.contains.inOrder.only.entries({}, {})
list.contains.inOrder.only.elementsOf(listOf(1, 2))
subList.contains.inOrder.only.value(1)
subList.contains.inOrder.only.value(null)
subList.contains.inOrder.only.values(2, 1)
subList.contains.inOrder.only.entry {}
subList.contains.inOrder.only.entry(null)
subList.contains.inOrder.only.entries({}, {})
subList.contains.inOrder.only.elementsOf(listOf(1, 2))
nullableList.contains.inOrder.only.value(1)
nullableList.contains.inOrder.only.values(2, 1)
nullableList.contains.inOrder.only.entry {}
nullableList.contains.inOrder.only.entries({}, {})
nullableList.contains.inOrder.only.elementsOf(listOf(1, 2))
nullableList.contains.inOrder.only.value(null)
nullableList.contains.inOrder.only.values(null, 1)
nullableList.contains.inOrder.only.values(2, null)
nullableList.contains.inOrder.only.values(null, null)
nullableList.contains.inOrder.only.entry(null)
nullableList.contains.inOrder.only.entries(null, {})
nullableList.contains.inOrder.only.entries({}, null)
nullableList.contains.inOrder.only.entries(null, null)
star.contains.inOrder.only.value(1)
star.contains.inOrder.only.values(2, 1)
star.contains.inOrder.only.entry {}
star.contains.inOrder.only.entries({}, {})
star.contains.inOrder.only.elementsOf(listOf(1, 2))
star.contains.inOrder.only.value(null)
star.contains.inOrder.only.values(null, 1)
star.contains.inOrder.only.values(2, null)
star.contains.inOrder.only.values(null, null)
star.contains.inOrder.only.entry(null)
star.contains.inOrder.only.entries(null, {})
star.contains.inOrder.only.entries({}, null)
star.contains.inOrder.only.entries(null, null)
list.contains.inOrder.only.grouped.within.inAnyOrder(
Value(1),
Value(null),
Values(1f),
Values(null),
Values(1f, 1),
Values(1, null),
Values(null, null)
Values(1f, 1)
)
subList.contains.inOrder.only.grouped.within.inAnyOrder(
Value(1),
Value(null),
Values(1f),
Values(1f, 1)
)
nullableList.contains.inOrder.only.grouped.within.inAnyOrder(
Value(null),
Values(null),
Values(1f, 1),
Values(null, 2),
Values(1, null),
Values(null, null)
)
star.contains.inOrder.only.grouped.within.inAnyOrder(
Value(null),
Values(null),
Values(null, 2),
Values(1, null),
Values(null, null)
)
list.contains.inOrder.only.grouped.within.inAnyOrder(
Entry {},
Entry(null),
Entries({}),
Entries({}, {})
)
subList.contains.inOrder.only.grouped.within.inAnyOrder(
Entry {},
Entries({}),
Entries({}, {})
)
nullableList.contains.inOrder.only.grouped.within.inAnyOrder(
Entry(null),
Entries(null),
Entries({}, {}),
Entries(null, {}),
Entries({}, null),
Entries(null, null)
)
subList.contains.inOrder.only.grouped.within.inAnyOrder(
Entry {},
star.contains.inOrder.only.grouped.within.inAnyOrder(
Entry(null),
Entries({}),
Entries(null),
Entries({}, {}),
Entries(null, {}),
Entries({}, null),
Entries(null, null)
)

View File

@@ -6,14 +6,14 @@ import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.notImplemented
class IterableFeatureAssertionsSpec : ch.tutteli.atrium.specs.integration.IterableFeatureAssertionsSpec(
feature0<Iterable<Int>, Int>(Expect<Iterable<Int>>::min, "min"),
feature0<Iterable<Int>, Int>(Expect<Iterable<Int>>::min),
fun1<Iterable<Int>, Expect<Int>.() -> Unit>(Expect<Iterable<Int>>::min),
feature0<Iterable<Int>, Int>(Expect<Iterable<Int>>::max, "max"),
feature0<Iterable<Int>, Int>(Expect<Iterable<Int>>::max),
fun1<Iterable<Int>, Expect<Int>.() -> Unit>(Expect<Iterable<Int>>::max)
) {
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
var a1: Expect<Iterable<Int>> = notImplemented()
var a1: Expect<List<Int>> = notImplemented()
//nullable not supported by min/max or rather T : Comparable<T> does not exist for T? (one cannot implement an interface for the nullable type)
//same for Iterable<*>

View File

@@ -3,6 +3,7 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.notImplemented
import ch.tutteli.atrium.specs.withNullableSuffix
import org.spekframework.spek2.Spek
class IterableNoneAssertionsSpec : Spek({
@@ -13,14 +14,14 @@ class IterableNoneAssertionsSpec : Spek({
}) {
object PredicateSpec : ch.tutteli.atrium.specs.integration.IterableNoneAssertionsSpec(
fun1(Expect<Iterable<Double>>::none),
fun1(Expect<Iterable<Double?>>::none),
fun1(Expect<Iterable<Double?>>::none).withNullableSuffix(),
"◆ ", "✔ ", "✘ ", "", "» ", "▶ ", "◾ ",
"[Atrium][Predicate] "
)
object BuilderSpec : ch.tutteli.atrium.specs.integration.IterableNoneAssertionsSpec(
getContainsNotPair(),
getContainsNotNullablePair(),
getContainsNotNullablePair().withNullableSuffix(),
"◆ ", "✔ ", "✘ ", "", "» ", "▶ ", "◾ ",
"[Atrium][Builder] "
)
@@ -40,10 +41,10 @@ class IterableNoneAssertionsSpec : Spek({
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
var a1: Expect<Iterable<Double>> = notImplemented()
var a1b: Expect<Iterable<Double?>> = notImplemented()
var a1: Expect<List<Double>> = notImplemented()
var a1b: Expect<Set<Double?>> = notImplemented()
var star: Expect<Iterable<*>> = notImplemented()
var star: Expect<Collection<*>> = notImplemented()
a1 = a1.none {}
a1 = a1.containsNot.entry {}

View File

@@ -1,20 +1,18 @@
package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.feature1
import ch.tutteli.atrium.specs.fun2
import ch.tutteli.atrium.specs.notImplemented
import ch.tutteli.atrium.specs.*
object ListFeatureAssertionsSpec : ch.tutteli.atrium.specs.integration.ListFeatureAssertionsSpec(
feature1<List<Int>, Int, Int>(Expect<List<Int>>::get),
fun2<List<Int>, Int, Expect<Int>.() -> Unit>(Expect<List<Int>>::get),
feature1<List<Int?>, Int, Int?>(Expect<List<Int?>>::get),
fun2<List<Int?>, Int, Expect<Int?>.() -> Unit>(Expect<List<Int?>>::get)
feature1<List<Int?>, Int, Int?>(Expect<List<Int?>>::get).withNullableSuffix(),
fun2<List<Int?>, Int, Expect<Int?>.() -> Unit>(Expect<List<Int?>>::get).withNullableSuffix()
) {
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {
var a1: Expect<List<Int>> = notImplemented()
var a1b: Expect<List<Int?>> = notImplemented()
var a1: Expect<AbstractList<Int>> = notImplemented()
var a1b: Expect<MutableList<Int?>> = notImplemented()
var star: Expect<List<*>> = notImplemented()

View File

@@ -2,31 +2,26 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.domain.builders.utils.mapArguments
import ch.tutteli.atrium.specs.fun0
import ch.tutteli.atrium.specs.fun1
import ch.tutteli.atrium.specs.fun2
import ch.tutteli.atrium.specs.notImplemented
import kotlin.reflect.KFunction3
import ch.tutteli.atrium.specs.*
import ch.tutteli.atrium.specs.integration.mfun2
import kotlin.jvm.JvmName
class MapAssertionsSpec : ch.tutteli.atrium.specs.integration.MapAssertionsSpec(
fun2<Map<out String, Int>, Pair<String, Int>, Array<out Pair<String, Int>>>(Expect<Map<out String, Int>>::contains),
fun2<Map<out String?, Int?>, Pair<String?, Int?>, Array<out Pair<String?, Int?>>>(Expect<Map<out String?, Int?>>::contains),
"${containsKeyWithValueAssertionsFun.name} ${KeyValue::class.simpleName}" to Companion::containsKeyValue,
"${containsKeyWithNullableValueAssertionsFun.name} ${KeyValue::class.simpleName}" to Companion::containsNullable,
mfun2<String, Int, Int>(Expect<Map<out String, Int>>::contains),
mfun2<String?, Int?, Int?>(Expect<Map<out String?, Int?>>::contains).withNullableSuffix(),
mfun2<String, Int, Expect<Int>.() -> Unit>(Companion::contains).adjustName { "$it ${KeyValue::class.simpleName}" },
mfun2<String?, Int?, (Expect<Int>.() -> Unit)?>(Companion::contains).adjustName { "$it ${KeyValue::class.simpleName}" }
.withNullableSuffix(),
fun1(Expect<Map<out String, *>>::containsKey),
fun1(Expect<Map<out String?, *>>::containsKey),
fun1(Expect<Map<out String?, *>>::containsKey).withNullableSuffix(),
fun1(Expect<Map<out String, *>>::containsNotKey),
fun1(Expect<Map<out String?, *>>::containsNotKey),
fun1(Expect<Map<out String?, *>>::containsNotKey).withNullableSuffix(),
fun0(Expect<Map<*, *>>::isEmpty),
fun0(Expect<Map<*, *>>::isNotEmpty)
) {
companion object {
//@formatter:off
private val containsKeyWithValueAssertionsFun : KFunction3<Expect<Map<out String, Int>>, KeyValue<String, Int>, Array<out KeyValue<String, Int>>, Expect<Map<out String, Int>>> = Expect<Map<out String, Int>>::contains
private val containsKeyWithNullableValueAssertionsFun : KFunction3<Expect<Map<out String?, Int?>>, KeyValue<String?, Int>, Array<out KeyValue<String?, Int>>, Expect<Map<out String?, Int?>>> = Expect<Map<out String?, Int?>>::contains
//@formatter:on
fun containsKeyValue(
companion object {
private fun contains(
expect: Expect<Map<out String, Int>>,
keyValue: Pair<String, Expect<Int>.() -> Unit>,
otherKeyValues: Array<out Pair<String, Expect<Int>.() -> Unit>>
@@ -34,13 +29,15 @@ class MapAssertionsSpec : ch.tutteli.atrium.specs.integration.MapAssertionsSpec(
expect.contains(first, *others)
}
fun containsNullable(
@JvmName("containsNullable")
private fun contains(
expect: Expect<Map<out String?, Int?>>,
keyValue: Pair<String?, (Expect<Int>.() -> Unit)?>,
otherKeyValues: Array<out Pair<String?, (Expect<Int>.() -> Unit)?>>
) = mapArguments(keyValue, otherKeyValues).to { KeyValue(it.first, it.second) }.let { (first, others) ->
expect.contains(first, *others)
}
}
@Suppress("unused", "UNUSED_VALUE")

View File

@@ -3,10 +3,11 @@ package ch.tutteli.atrium.api.fluent.en_GB
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.fun2
import ch.tutteli.atrium.specs.notImplemented
import ch.tutteli.atrium.specs.withNullableSuffix
object MapEntryAssertionsSpec : ch.tutteli.atrium.specs.integration.MapEntryAssertionsSpec(
fun2(Expect<Map.Entry<String, Int>>::isKeyValue),
fun2(Expect<Map.Entry<String?, Int?>>::isKeyValue)
fun2(Expect<Map.Entry<String?, Int?>>::isKeyValue).withNullableSuffix()
) {
@Suppress("unused", "UNUSED_VALUE")
private fun ambiguityTest() {

Some files were not shown because too many files have changed in this diff Show More