mirror of
https://github.com/jlengrand/atrium.git
synced 2026-03-10 08:01:19 +00:00
Merge pull request #381 from robstoll/feature-new-infix-api
add feature to the new infix API
This commit is contained in:
@@ -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 The newly created [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
|
||||
*/
|
||||
@@ -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 The newly created [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
|
||||
*/
|
||||
@@ -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 The newly created [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
|
||||
*/
|
||||
@@ -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 The newly created [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
|
||||
*/
|
||||
@@ -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 The newly created [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
|
||||
*/
|
||||
|
||||
@@ -4,21 +4,16 @@ 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::toThrow,
|
||||
("toThrow" to ::toThrowFeature).withFeatureSuffix(),
|
||||
"toThrow" to ::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() }
|
||||
}
|
||||
|
||||
@Suppress("unused", "UNUSED_VALUE", "UNUSED_VARIABLE")
|
||||
private fun ambiguityTest() {
|
||||
val a1: Expect<() -> Any?> = notImplemented()
|
||||
@@ -37,3 +32,9 @@ class Fun0AssertionsSpec : ch.tutteli.atrium.specs.integration.Fun0AssertionsSpe
|
||||
val r8: Expect<Int> = a2.notToThrow {}
|
||||
}
|
||||
}
|
||||
|
||||
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() }
|
||||
|
||||
@@ -3,10 +3,11 @@ 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")
|
||||
|
||||
@@ -2,46 +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 ch.tutteli.atrium.specs.*
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.reflect.KFunction3
|
||||
|
||||
private fun <K, V, T> mfun2(
|
||||
f: KFunction3<Expect<Map<out K, V>>, Pair<K, T>, Array<out Pair<K, T>>, Expect<Map<out K, V>>>
|
||||
) = fun2(f)
|
||||
|
||||
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>(::contains).adjustName { "$it ${KeyValue::class.simpleName}" },
|
||||
mfun2<String?, Int?, (Expect<Int>.() -> Unit)?>(::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(
|
||||
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)
|
||||
}
|
||||
|
||||
fun containsNullable(
|
||||
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")
|
||||
private fun ambiguityTest() {
|
||||
@@ -208,3 +188,20 @@ class MapAssertionsSpec : ch.tutteli.atrium.specs.integration.MapAssertionsSpec(
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@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)
|
||||
}
|
||||
|
||||
@@ -171,10 +171,11 @@ inline infix fun <T> Expect<T>.and(@Suppress("UNUSED_PARAMETER") o: o): Expect<T
|
||||
*
|
||||
* @return An [Expect] for the current subject of the assertion.
|
||||
*/
|
||||
infix fun <T> Expect<T>.and(assertionCreator: Expect<T>.() -> Unit) = addAssertionsCreatedBy(assertionCreator)
|
||||
infix fun <T> Expect<T>.and(assertionCreator: Expect<T>.() -> Unit): Expect<T> =
|
||||
addAssertionsCreatedBy(assertionCreator)
|
||||
|
||||
/**
|
||||
* Inline property referring actually to `this` and allows to write nicer sub-assertions.
|
||||
* Inline property referring actually to `this` and allows to write infix assertions within an assertion group block
|
||||
*
|
||||
* For instance, instead of:
|
||||
* ```
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.feature
|
||||
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
/**
|
||||
* Parameter object which contains a [description] of a feature along with an [extractor]
|
||||
* which actually extracts the feature out of a subject of an assertion.
|
||||
*
|
||||
* Use `of(K..., ...) { ... }` to create this representation where the first argument is the extractor in form of a
|
||||
* [KProperty1] or a `KFunctionX` and the remaining arguments are the required arguments in case of a `KFunctionX`
|
||||
* where `X` > 1.
|
||||
*
|
||||
* @property description The description of the feature.
|
||||
* @property extractor The extractor which extracts the feature out of the subject of the assertion.
|
||||
|
||||
* @since 0.10.0
|
||||
*/
|
||||
data class Feature<T, R>(val description: String, val extractor: (T) -> R)
|
||||
@@ -0,0 +1,25 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.feature
|
||||
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
/**
|
||||
* Parameter object which contains a [description] of a feature along with an [extractor]
|
||||
* which actually extracts the feature out of a subject of an assertion + an [assertionCreator]
|
||||
* which defines assertions for the feature.
|
||||
*
|
||||
* Use `of(K..., ...) { ... }` to create this representation where the first argument is the extractor in form of a
|
||||
* [KProperty1] or a `KFunctionX`, the last an [assertionCreator]-lambda and the remaining arguments in-between the
|
||||
* required arguments in case of a `KFunctionX` where `X` > 1.
|
||||
*
|
||||
* @property description The description of the feature.
|
||||
* @property extractor The extractor which extracts the feature out of the subject of the assertion.
|
||||
* @property assertionCreator The `assertionCreator`-lambda which defines assertions for the feature.
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
data class FeatureWithCreator<T, R>(
|
||||
val description: String,
|
||||
val extractor: (T) -> R,
|
||||
val assertionCreator: Expect<R>.() -> Unit
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.feature
|
||||
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.domain.builders.creating.MetaFeatureOption
|
||||
import ch.tutteli.atrium.domain.creating.MetaFeature
|
||||
|
||||
/**
|
||||
* Parameter object which combines a lambda with a [MetaFeatureOption] receiver (called [provider])
|
||||
* and an [assertionCreator].
|
||||
*
|
||||
* Use the function `of({ ... }) { ... }` to create this representation where the first
|
||||
* argument is a lambda with a [MetaFeatureOption] as receiver which has to create a [MetaFeature]
|
||||
* where the subject of the assertion is available via implicit parameter `it`.
|
||||
* Usually you use [f][MetaFeatureOption.f] to create a [MetaFeature],
|
||||
* e.g. `feature of({ f(it::size) }) { o toBe 3 }`
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
data class MetaFeatureOptionWithCreator<T, R>(
|
||||
val provider: MetaFeatureOption<T>.(T) -> MetaFeature<R>,
|
||||
val assertionCreator: Expect<R>.() -> Unit
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.list
|
||||
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
|
||||
|
||||
/**
|
||||
* Parameter object which combines an [index] of type [Int] with an [assertionCreator] which defines assertions for
|
||||
* a resulting feature of type [E].
|
||||
*
|
||||
* Use the function `index(Int) { ... }` to create this representation.
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
data class IndexWithCreator<E>(val index: Int, val assertionCreator: Expect<E>.() -> Unit)
|
||||
@@ -1,40 +0,0 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.list.get.builders
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.list.get.builders.impl.ListGetStepImpl
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
|
||||
/**
|
||||
* Represents the extension point for another step after a `get index`-step within a
|
||||
* sophisticated `get` assertion building process for [List].
|
||||
*
|
||||
* @param E The element type of the [List].
|
||||
* @param T A subtype of [List].
|
||||
*/
|
||||
interface ListGetStep<E, T : List<E>> {
|
||||
/**
|
||||
* The [Expect] for which this assertion is created
|
||||
*/
|
||||
val expect: Expect<T>
|
||||
|
||||
/**
|
||||
* The given index which will be used to perform the [List.get].
|
||||
*/
|
||||
val index: Int
|
||||
|
||||
/**
|
||||
* Makes the assertion that the given [index] is within the bounds of [Expect.subject] and that
|
||||
* the corresponding entry holds all assertions the given [assertionCreator] might create for it.
|
||||
*
|
||||
* @return An [Expect] for the current subject of the assertion.
|
||||
* @throws AssertionError Might throw an [AssertionError] if a created [Expect]s (by calling [assertionCreator])
|
||||
* does not hold.
|
||||
* @throws IllegalArgumentException in case the given [assertionCreator] did not create a single assertion.
|
||||
*/
|
||||
infix fun assertIt(assertionCreator: Expect<E>.() -> Unit): Expect<T>
|
||||
|
||||
companion object {
|
||||
fun <E, T : List<E>> create(expect: Expect<T>, index: Int): ListGetStep<E, T> =
|
||||
ListGetStepImpl(expect, index)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.list.get.builders.impl
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.list.get.builders.ListGetStep
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.domain.builders.ExpectImpl
|
||||
|
||||
internal class ListGetStepImpl<E, T: List<E>>(
|
||||
override val expect: Expect<T>,
|
||||
override val index: Int
|
||||
) : ListGetStep<E, T> {
|
||||
|
||||
override infix fun assertIt(assertionCreator: Expect<E>.() -> Unit): Expect<T>
|
||||
= expect.addAssertion(ExpectImpl.list.get(expect, index).collect(assertionCreator))
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.map
|
||||
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
|
||||
/**
|
||||
* Parameter object which combines an [key] of type [K] with an [assertionCreator] which defines assertions for
|
||||
* a resulting feature of type [V].
|
||||
*
|
||||
* Use the function `key(...) { ... }` to create this representation where the first parameter corresponds
|
||||
* to the [key] and the second is the [assertionCreator]
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
data class KeyWithCreator<out K, V>(val key: K, val assertionCreator: Expect<V>.() -> Unit)
|
||||
@@ -1,47 +0,0 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.map.get.builders
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.map.get.builders.impl.MapGetOptionImpl
|
||||
import ch.tutteli.atrium.assertions.Assertion
|
||||
import ch.tutteli.atrium.creating.AssertionPlant
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.creating.SubjectProvider
|
||||
|
||||
/**
|
||||
* Represents the extension point for another option after a `get key`-step within a
|
||||
* sophisticated `get` assertion building process for [Map].
|
||||
*
|
||||
* @param K The key type of the [Map].
|
||||
* @param V the value type of the [Map].
|
||||
* @param T A subtype of [Map].
|
||||
*/
|
||||
interface MapGetOption<K, V, T : Map<out K, V>> {
|
||||
/**
|
||||
* The [AssertionPlant] for which this assertion is created
|
||||
*/
|
||||
val expect: Expect<T>
|
||||
|
||||
/**
|
||||
* The given key which will be used to perform the [Map.get].
|
||||
*/
|
||||
val key: K
|
||||
|
||||
/**
|
||||
* Makes the assertion that the [Assert.subject][SubjectProvider.subject] contains the previously specified [key] and that the
|
||||
* corresponding value holds all assertions the given [assertionCreator] might create for it.
|
||||
*
|
||||
* @return This expect to support a fluent API.
|
||||
* @throws AssertionError Might throw an [AssertionError] if a created [Assertion]s (by calling [assertionCreator])
|
||||
* does not hold.
|
||||
* @throws IllegalArgumentException in case the given [assertionCreator] did not create a single assertion.
|
||||
*/
|
||||
infix fun assertIt(assertionCreator: Expect<V>.() -> Unit): Expect<T>
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates a [MapGetOption] based on the given [expect] and [key].
|
||||
*/
|
||||
fun <K, V, T : Map<out K, V>> create(expect: Expect<T>, key: K): MapGetOption<K, V, T> =
|
||||
MapGetOptionImpl(expect, key)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.creating.map.get.builders.impl
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.map.get.builders.MapGetOption
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.domain.builders.ExpectImpl
|
||||
|
||||
internal class MapGetOptionImpl<K, V, T : Map<out K, V>>(
|
||||
override val expect: Expect<T>,
|
||||
override val key: K
|
||||
) : MapGetOption<K, V, T> {
|
||||
|
||||
override infix fun assertIt(assertionCreator: Expect<V>.() -> Unit): Expect<T> =
|
||||
expect.addAssertion(ExpectImpl.map.getExisting(expect, key).collect(assertionCreator))
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.feature.Feature
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.feature.FeatureWithCreator
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.feature.MetaFeatureOptionWithCreator
|
||||
import ch.tutteli.atrium.assertions.AssertionGroup
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.creating.FeatureExpect
|
||||
import ch.tutteli.atrium.domain.builders.ExpectImpl
|
||||
import ch.tutteli.atrium.domain.builders.creating.MetaFeatureOption
|
||||
import ch.tutteli.atrium.domain.creating.MetaFeature
|
||||
import kotlin.reflect.*
|
||||
|
||||
/**
|
||||
* Extracts the [property] out of the current subject of the assertion,
|
||||
* creates a new [Expect] for it and
|
||||
* returns it so that subsequent calls are based on the feature.
|
||||
*
|
||||
* @return The newly created [Expect] for the given [property].
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
infix fun <T, R> Expect<T>.feature(property: KProperty1<T, R>): FeatureExpect<T, R> =
|
||||
ExpectImpl.feature.property(this, property).getExpectOfFeature()
|
||||
|
||||
/**
|
||||
* Extracts the value which is returned when calling the method [f] on the current subject of the assertion,
|
||||
* creates a new [Expect] for it and
|
||||
* returns it so that subsequent calls are based on the feature.
|
||||
*
|
||||
* Use `feature of(...)` in case the method requires parameters or in case you want to define
|
||||
* an assertion group block for it.
|
||||
*
|
||||
* @return The newly created [Expect] for the return value of calling the method [f]
|
||||
* on the current subject of the assertion.
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
infix fun <T, R> Expect<T>.feature(f: KFunction1<T, R>): FeatureExpect<T, R> =
|
||||
ExpectImpl.feature.f0(this, f).getExpectOfFeature()
|
||||
|
||||
/**
|
||||
* Extracts a feature out of the current subject of the assertion using the given [Feature.extractor],
|
||||
* creates a new [Expect] for it and
|
||||
* returns it so that subsequent calls are based on the feature.
|
||||
*
|
||||
* Use `of(K..., ...)` to create a [Feature] where the first argument is the extractor in form of a
|
||||
* [KProperty1] or a `KFunctionX` and potentially the required arguments for a `KFunctionX` where `X` > 1.
|
||||
*
|
||||
* @param of Use `of(K..., ...)` to create a [Feature] where the first argument is the extractor in form of a
|
||||
* [KProperty1] or a `KFunctionX` and potentially the required arguments for a `KFunctionX` where `X` > 1.
|
||||
*
|
||||
* @return The newly created [Expect] for the extracted feature.
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
infix fun <T, R> Expect<T>.feature(of: Feature<T, R>): FeatureExpect<T, R> =
|
||||
ExpectImpl.feature.manualFeature(this, of.description, of.extractor).getExpectOfFeature()
|
||||
|
||||
/**
|
||||
* Extracts a feature out of the current subject of the assertion using the given [FeatureWithCreator.extractor],
|
||||
* creates a new [Expect] for it,
|
||||
* applies an assertion group based on the given [FeatureWithCreator.assertionCreator] for the feature and
|
||||
* returns the initial [Expect] with the current subject.
|
||||
*
|
||||
* Use `of(K..., ...) { ... }` to create a [FeatureWithCreator] where the first argument is the extractor in
|
||||
* form of a [KProperty1] or a `KFunctionX`, the last an `assertionCreator`-lambda and the remaining arguments
|
||||
* in-between the required arguments in case of a `KFunctionX` where `X` > 1.
|
||||
*
|
||||
* @param of Use `of(K..., ...) { ... }` to create a [FeatureWithCreator] where the first argument is the extractor in
|
||||
* form of a [KProperty1] or a `KFunctionX`, the last an `assertionCreator`-lambda and the remaining arguments
|
||||
* in-between the required arguments in case of a `KFunctionX` where `X` > 1.
|
||||
*
|
||||
* @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.10.0
|
||||
*/
|
||||
infix fun <T, R> Expect<T>.feature(of: FeatureWithCreator<T, R>): Expect<T> =
|
||||
ExpectImpl.feature.manualFeature(this, of.description, of.extractor).addToInitial(of.assertionCreator)
|
||||
|
||||
|
||||
/**
|
||||
* Extracts a feature out of the current subject of the assertion,
|
||||
* based on the given [provider],
|
||||
* creates a new [Expect] for it and
|
||||
* returns it so that subsequent calls are based on the feature.
|
||||
*
|
||||
* @param provider Creates a [MetaFeature] where the subject of the assertion is available via
|
||||
* implicit parameter `it`. Usually you use [f][MetaFeatureOption.f] to create a [MetaFeature],
|
||||
* e.g. `feature { f(it::size) }`
|
||||
*
|
||||
* @return The newly created [Expect] for the extracted feature.
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
infix fun <T, R> Expect<T>.feature(provider: MetaFeatureOption<T>.(T) -> MetaFeature<R>): FeatureExpect<T, R> =
|
||||
ExpectImpl.feature.genericSubjectBasedFeature(this) { MetaFeatureOption(this).provider(it) }.getExpectOfFeature()
|
||||
|
||||
/**
|
||||
* Extracts a feature out of the current subject of the assertion,
|
||||
* based on the given [MetaFeatureOptionWithCreator]
|
||||
* creates a new [Expect] for it,
|
||||
* applies an assertion group based on the given [MetaFeatureOptionWithCreator.assertionCreator] for the feature and
|
||||
* returns the initial [Expect] with the current subject.
|
||||
*
|
||||
* Note that you need to enable the new type inference of Kotlin (or use Kotlin 1.4 and above) in order that Kotlin
|
||||
* is able to infer the types.
|
||||
* As workaround you can use the overload which expects `MetaFeatureOption<T>.(T) -> MetaFeature<R>`
|
||||
* and use `it` after the call (import from the package workaround). For instance:
|
||||
*
|
||||
* ```
|
||||
* // use
|
||||
* expect(person) feature { f(it::age) } it { o toBe 20 }
|
||||
*
|
||||
* // instead of (which causes problems with Kotlin < 1.4)
|
||||
* expect(person) feature of({ f(it::age) }) { o toBe 20 }
|
||||
* ```
|
||||
*
|
||||
* @param of Use the function `of({ ... }) { ... }` to create the [MetaFeatureOptionWithCreator] where the first
|
||||
* argument is a lambda with a [MetaFeatureOption] as receiver which has to create a [MetaFeature]
|
||||
* where the subject of the assertion is available via implicit parameter `it`.
|
||||
* Usually you use [f][MetaFeatureOption.f] to create a [MetaFeature],
|
||||
* e.g. `feature of({ f(it::size) }) { o toBe 3 }`
|
||||
*
|
||||
* @return An [Expect] for the current subject of the assertion.
|
||||
* @since 0.10.0
|
||||
*/
|
||||
infix fun <T, R> Expect<T>.feature(of: MetaFeatureOptionWithCreator<T, R>): Expect<T> =
|
||||
ExpectImpl.feature.genericSubjectBasedFeature(this) {
|
||||
MetaFeatureOption(this).(of.provider)(it)
|
||||
}.addToInitial(of.assertionCreator)
|
||||
|
||||
/**
|
||||
* Creates a [MetaFeature] using the given [provider] and [description].
|
||||
*
|
||||
* This can be used to create complex features with a custom description or as workaround where Kotlin is not able to
|
||||
* infer the types properly.
|
||||
*
|
||||
* For instance:
|
||||
* ```
|
||||
* expect(person) feature { f("first underage child", it.children.first { it < 18 }) }
|
||||
* ```
|
||||
*
|
||||
* @return The newly created [MetaFeature].
|
||||
*/
|
||||
@Suppress("unused" /* unused receiver, but that's fine */)
|
||||
fun <T, R> MetaFeatureOption<T>.f(description: String, provider: R): MetaFeature<R> =
|
||||
MetaFeature(description, provider)
|
||||
|
||||
//@formatter:off
|
||||
/**
|
||||
* Helper function to create a [Feature] based on a [KFunction2] + arguments.
|
||||
*/
|
||||
fun <T, A1, R> of(f: KFunction2<T, A1, R>, a1: A1): Feature<T, R> =
|
||||
Feature(f.name) { f.invoke(it, a1) }
|
||||
|
||||
/**
|
||||
* Helper function to create a [Feature] based on a [KFunction3] + arguments.
|
||||
*/
|
||||
fun <T, A1, A2, R > of(f: KFunction3<T, A1, A2, R>, a1: A1, a2: A2): Feature<T, R> =
|
||||
Feature(f.name) { f.invoke(it, a1, a2) }
|
||||
|
||||
/**
|
||||
* Helper function to create a [Feature] based on a [KFunction4] + arguments.
|
||||
*/
|
||||
fun <T, A1, A2, A3, R> of(f: KFunction4<T, A1, A2, A3, R>, a1: A1, a2: A2, a3: A3): Feature<T, R> =
|
||||
Feature(f.name) { f.invoke(it, a1, a2, a3) }
|
||||
|
||||
/**
|
||||
* Helper function to create a [Feature] based on a [KFunction5] + arguments.
|
||||
*/
|
||||
fun <T, A1, A2, A3, A4, R> of(f: KFunction5<T, A1, A2, A3, A4, R>, a1: A1, a2: A2, a3: A3, a4: A4): Feature<T, R> =
|
||||
Feature(f.name) { f.invoke(it, a1, a2, a3, a4) }
|
||||
|
||||
/**
|
||||
* Helper function to create a [Feature] based on a [KFunction5] + arguments.
|
||||
*/
|
||||
fun <T, A1, A2, A3, A4, A5, R> of(f: KFunction6<T, A1, A2, A3, A4, A5, R>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): Feature<T, R> =
|
||||
Feature(f.name) { f.invoke(it, a1, a2, a3, a4, a5) }
|
||||
|
||||
/**
|
||||
* Helper function to create a [FeatureWithCreator] based on a [KProperty1] + [assertionCreator].
|
||||
*/
|
||||
fun <T, R> of(property: KProperty1<T, R>, assertionCreator: Expect<R>.() -> Unit): FeatureWithCreator<T, R> =
|
||||
FeatureWithCreator(property.name, { property.invoke(it) }, assertionCreator)
|
||||
|
||||
/**
|
||||
* Helper function to create a [FeatureWithCreator] based on a [KFunction1] + [assertionCreator].
|
||||
*/
|
||||
fun <T, R> of(f: KFunction1<T, R>, assertionCreator: Expect<R>.() -> Unit): FeatureWithCreator<T, R> =
|
||||
FeatureWithCreator(f.name, { f.invoke(it) }, assertionCreator)
|
||||
|
||||
/**
|
||||
* Helper function to create a [FeatureWithCreator] based on a [KFunction2] + arguments + [assertionCreator].
|
||||
*/
|
||||
fun <T, A1, R> of(f: KFunction2<T, A1, R>, a1: A1, assertionCreator: Expect<R>.() -> Unit): FeatureWithCreator<T, R> =
|
||||
FeatureWithCreator(f.name, { f.invoke(it, a1) }, assertionCreator)
|
||||
|
||||
/**
|
||||
* Helper function to create a [FeatureWithCreator] based on a [KFunction3] + arguments + [assertionCreator].
|
||||
*/
|
||||
fun <T, A1, A2, R > of(f: KFunction3<T, A1, A2, R>, a1: A1, a2: A2, assertionCreator: Expect<R>.() -> Unit): FeatureWithCreator<T, R> =
|
||||
FeatureWithCreator(f.name, { f.invoke(it, a1, a2) }, assertionCreator)
|
||||
|
||||
/**
|
||||
* Helper function to create a [FeatureWithCreator] based on a [KFunction4] + arguments + [assertionCreator].
|
||||
*/
|
||||
fun <T, A1, A2, A3, R> of(f: KFunction4<T, A1, A2, A3, R>, a1: A1, a2: A2, a3: A3, assertionCreator: Expect<R>.() -> Unit): FeatureWithCreator<T, R> =
|
||||
FeatureWithCreator(f.name, { f.invoke(it, a1, a2, a3) }, assertionCreator)
|
||||
|
||||
/**
|
||||
* Helper function to create a [FeatureWithCreator] based on a [KFunction5] + arguments + [assertionCreator].
|
||||
*/
|
||||
fun <T, A1, A2, A3, A4, R> of(f: KFunction5<T, A1, A2, A3, A4, R>, a1: A1, a2: A2, a3: A3, a4: A4, assertionCreator: Expect<R>.() -> Unit): FeatureWithCreator<T, R> =
|
||||
FeatureWithCreator(f.name, { f.invoke(it, a1, a2, a3, a4) }, assertionCreator)
|
||||
//@formatter:on
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to create a [MetaFeatureOptionWithCreator] based on a lambda with
|
||||
* [MetaFeatureOption] receiver (has to return a [MetaFeature]) and an [assertionCreator].
|
||||
*/
|
||||
fun <T, R> of(
|
||||
provider: MetaFeatureOption<T>.(T) -> MetaFeature<R>,
|
||||
assertionCreator: Expect<R>.() -> Unit
|
||||
): MetaFeatureOptionWithCreator<T, R> =
|
||||
MetaFeatureOptionWithCreator(
|
||||
provider,
|
||||
assertionCreator
|
||||
)
|
||||
@@ -27,40 +27,48 @@ object Blank : Keyword
|
||||
|
||||
/**
|
||||
* Represents the pseudo keyword `contain` as in [to] `contain`.
|
||||
* It can be used for a parameter less function so that it has one parameter and thus can be used as infix function.
|
||||
*/
|
||||
object contain : Keyword
|
||||
|
||||
/**
|
||||
* Represents the pseudo keyword `case` as in [ignoring] `case`.
|
||||
* It can be used for a parameter less function so that it has one parameter and thus can be used as infix function.
|
||||
*/
|
||||
object case : Keyword
|
||||
|
||||
/**
|
||||
* Represents the pseudo keyword `entries` as in [grouped] `entries`.
|
||||
* It can be used for a parameter less function so that it has one parameter and thus can be used as infix function.
|
||||
*/
|
||||
object entries : Keyword
|
||||
|
||||
/**
|
||||
* Represents the pseudo keyword `group` as in [within] `group`.
|
||||
* It can be used for a parameter less function so that it has one parameter and thus can be used as infix function.
|
||||
*/
|
||||
object group : Keyword
|
||||
|
||||
/**
|
||||
* Represents a filler, a pseudo keyword where there isn't really a good keyword.
|
||||
* A reader should skip this filler without reading it. For instance, `contains o atleast 1...` should be read as
|
||||
* A reader should skip this filler without reading it. For instance, `contains o atLeast 1...` should be read as
|
||||
* `contains at least once...`
|
||||
*
|
||||
* It can be used for a parameter less function so that it has one parameter and thus can be used as infix function.
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
object o : Keyword
|
||||
|
||||
/**
|
||||
* Represents the pseudo keyword `only` as in [and] `only`.
|
||||
* It can be used for a parameter less function so that it has one parameter and thus can be used as infix function.
|
||||
*/
|
||||
object only : Keyword
|
||||
|
||||
/**
|
||||
* Represents the pseudo keyword `order` as in [inAny] `order`.
|
||||
* It can be used for a parameter less function so that it has one parameter and thus can be used as infix function.
|
||||
*/
|
||||
object order : Keyword
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.list.get.builders.ListGetStep
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.list.IndexWithCreator
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.domain.builders.ExpectImpl
|
||||
|
||||
@@ -9,15 +9,26 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl
|
||||
* returns an [Expect] for the element at that position.
|
||||
*
|
||||
* @return The newly created [Expect] for the element at position [index].
|
||||
* @throws AssertionError if the given [index] is out of bound.
|
||||
* @throws AssertionError Might throw an [AssertionError] if the given [index] is out of bound.
|
||||
*/
|
||||
infix fun <E, T : List<E>> Expect<T>.get(index: Int): Expect<E> =
|
||||
ExpectImpl.list.get(this, index).getExpectOfFeature()
|
||||
|
||||
/**
|
||||
* Prepares the assertion about the return value of calling [get][List.get] with the given [index].
|
||||
* Expects that the given [index][IndexWithCreator.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
|
||||
* [IndexWithCreator.assertionCreator] creates for it.
|
||||
*
|
||||
* @return A fluent builder to finish the assertion.
|
||||
* Use the function `index(Int) { ... }` to create an [IndexWithCreator].
|
||||
*
|
||||
* @return This assertion container to support a fluent API.
|
||||
* @throws AssertionError Might throw an [AssertionError] if the given [index] is out of bound or
|
||||
* if the assertion made is not correct.
|
||||
*/
|
||||
infix fun <E, T : List<E>> Expect<T>.get(index: Index): ListGetStep<E, T> =
|
||||
ListGetStep.create(this, index.index)
|
||||
infix fun <E, T : List<E>> Expect<T>.get(index: IndexWithCreator<E>): Expect<T> =
|
||||
ExpectImpl.list.get(this, index.index).addToInitial(index.assertionCreator)
|
||||
|
||||
/**
|
||||
* Helper function to create an [IndexWithCreator] based on the given [index] and [assertionCreator].
|
||||
*/
|
||||
fun <E> index(index: Int, assertionCreator: Expect<E>.() -> Unit) = IndexWithCreator(index, assertionCreator)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.map.get.builders.MapGetOption
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.map.KeyWithCreator
|
||||
import ch.tutteli.atrium.assertions.Assertion
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.domain.builders.ExpectImpl
|
||||
|
||||
@@ -87,12 +88,23 @@ infix fun <K, V, T : Map<out K, V>> Expect<T>.getExisting(key: K): Expect<V> =
|
||||
ExpectImpl.map.getExisting(this, key).getExpectOfFeature()
|
||||
|
||||
/**
|
||||
* Prepares the assertion about the return value of calling [get][Map.get] with the given [key].
|
||||
* Expects that the subject of the assertion (a [Map]) contains the given [key] and that
|
||||
* the corresponding value holds all assertions the given [KeyWithCreator.assertionCreator] creates for it.
|
||||
*
|
||||
* @return A fluent builder to finish the assertion.
|
||||
* */
|
||||
infix fun <K, V, T : Map<out K, V>> Expect<T>.getExisting(key: Key<K>): MapGetOption<K, V, T> =
|
||||
MapGetOption.create(this, key.key)
|
||||
* @param key Use the function `key(...) { ... }` to create a [KeyWithCreator] where the first parameter corresponds
|
||||
* to the key and the second is the `assertionCreator`-lambda
|
||||
*
|
||||
* @return An [Expect] for the current subject of the assertion.
|
||||
* @throws AssertionError Might throw an [AssertionError] the given [key] does not exist or
|
||||
* if the assertion made is not correct.
|
||||
*/
|
||||
infix fun <K, V, T : Map<out K, V>> Expect<T>.getExisting(key: KeyWithCreator<K, V>): Expect<T> =
|
||||
ExpectImpl.map.getExisting(this, key.key).addToInitial(key.assertionCreator)
|
||||
|
||||
/**
|
||||
* Helper function to create an [KeyWithCreator] based on the given [key] and [assertionCreator].
|
||||
*/
|
||||
fun <K, V> key(key: K, assertionCreator: Expect<V>.() -> Unit) = KeyWithCreator(key, assertionCreator)
|
||||
|
||||
|
||||
/**
|
||||
@@ -178,3 +190,4 @@ fun <K, V, T : Map<out K, V>> Expect<T>.asEntries(): Expect<Set<Map.Entry<K, V>>
|
||||
infix fun <K, V, T : Map<out K, V>> Expect<T>.asEntries(
|
||||
assertionCreator: Expect<Set<Map.Entry<K, V>>>.() -> Unit
|
||||
): Expect<T> = apply { asEntries().addAssertionsCreatedBy(assertionCreator) }
|
||||
|
||||
|
||||
@@ -4,31 +4,24 @@ import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.domain.builders.utils.VarArgHelper
|
||||
|
||||
/**
|
||||
* Wrapper for a single index -- can be used as distinguishable type for an overload where Int is already in use.
|
||||
*/
|
||||
data class Index(val index: Int)
|
||||
|
||||
data class Key<out K>(val key: K)
|
||||
/**
|
||||
* Parameter object to express `T, vararg T` in the infix-api.
|
||||
* Parameter object to express `T, vararg T`.
|
||||
*/
|
||||
class All<out T>(override val expected: T, override vararg val otherExpected: T) : VarArgHelper<T>
|
||||
|
||||
/**
|
||||
* Parameter object to express `Pair<K, V>, vararg Pair<K, V>` in the infix-api.
|
||||
*/
|
||||
class Pairs<out K, out V>(
|
||||
override val expected: Pair<K, V>,
|
||||
override vararg val otherExpected: Pair<K, V>
|
||||
) : VarArgHelper<Pair<K, V>>
|
||||
|
||||
|
||||
/**
|
||||
* Parameter object to express a key/value [Pair] whose value type is a lambda with an
|
||||
* [Assert][AssertionPlant] receiver, which means one can either pass a lambda or `null`.
|
||||
* Parameter object to express a key/value [Pair] whose value type is a nullable lambda with an
|
||||
* [Expect] receiver, which means one can either pass a lambda or `null`.
|
||||
*/
|
||||
data class KeyValue<out K, V : Any>(val key: K, val valueAssertionCreatorOrNull: (Expect<V>.() -> Unit)?) {
|
||||
fun toPair(): Pair<K, (Expect<V>.() -> Unit)?> = key to valueAssertionCreatorOrNull
|
||||
override fun toString(): String =
|
||||
"KeyValue(key=$key, value=${if (valueAssertionCreatorOrNull == null) "null" else "lambda"})"
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameter object to express `Pair<K, V>, vararg Pair<K, V>`.
|
||||
*/
|
||||
class Pairs<out K, out V>(
|
||||
override val expected: Pair<K, V>,
|
||||
override vararg val otherExpected: Pair<K, V>
|
||||
) : VarArgHelper<Pair<K, V>>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB
|
||||
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.domain.builders.ExpectImpl.changeSubject
|
||||
|
||||
@@ -9,8 +11,8 @@ import ch.tutteli.atrium.domain.builders.ExpectImpl.changeSubject
|
||||
*
|
||||
* @return The newly created [Expect] for the transformed subject.
|
||||
*/
|
||||
fun <E, T : Sequence<E>> Expect<T>.asIterable(): Expect<Iterable<E>>
|
||||
= changeSubject(this).unreported { it.asIterable() }
|
||||
fun <E, T : Sequence<E>> Expect<T>.asIterable(): Expect<Iterable<E>> =
|
||||
changeSubject(this).unreported { it.asIterable() }
|
||||
|
||||
/**
|
||||
* Expects that the subject of the assertion holds all assertions the given [assertionCreator] creates for
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB.workaround
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.and
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
|
||||
/**
|
||||
* Can be used to create a group of sub assertions when using the fluent API.
|
||||
*
|
||||
* Intended to be used in combination with feature assertions where Kotlin < 1.4 is not able to infer the correct type.
|
||||
* For instance:
|
||||
* ```
|
||||
* // use
|
||||
* expect(person) feature { f(it::age) } it { o toBe 20 }
|
||||
*
|
||||
* // instead of (which causes problems with Kotlin < 1.4)
|
||||
* expect(person) feature of({ f(it::age) }) { o toBe 20 }
|
||||
* ```
|
||||
*
|
||||
* Note that this workaround will be removed in some minor version after a major version with Kotlin 1.4 support
|
||||
* (most likely with Atrium v1.1.0 where Atrium v1.0.0 requires Kotlin 1.4)
|
||||
*
|
||||
* @return An [Expect] for the current subject of the assertion.
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE" /* inline so that one does not actually call `it` on binary level */)
|
||||
inline infix fun <T> Expect<T>.it(noinline assertionCreator: Expect<T>.() -> Unit): Expect<T> = and(assertionCreator)
|
||||
@@ -81,7 +81,7 @@ class AnyAssertionsSpec : ch.tutteli.atrium.specs.integration.AnyAssertionsSpec(
|
||||
|
||||
//regression for #298, should compile without the need for E : Any or List<E?>
|
||||
@Suppress("unused")
|
||||
fun <E> Expect<List<E>>.firstIs(value: E) = o get Index(0) assertIt { o toBe value }
|
||||
fun <E> Expect<List<E>>.firstIs(value: E) = o get index(0) { o toBe value }
|
||||
}
|
||||
|
||||
private fun toBeNull(expect: Expect<Int?>) = expect toBe null
|
||||
|
||||
@@ -6,7 +6,7 @@ import ch.tutteli.atrium.specs.testutils.WithAsciiReporter
|
||||
|
||||
class CollectionAssertionsSpec : ch.tutteli.atrium.specs.integration.CollectionAssertionsSpec(
|
||||
"toBe ${Empty::class.simpleName}" to ::isEmpty,
|
||||
"toBe ${Empty::class.simpleName}" to ::isNotEmpty
|
||||
"notToBe ${Empty::class.simpleName}" to ::isNotEmpty
|
||||
) {
|
||||
companion object : WithAsciiReporter()
|
||||
|
||||
@@ -28,5 +28,5 @@ class CollectionAssertionsSpec : ch.tutteli.atrium.specs.integration.CollectionA
|
||||
}
|
||||
}
|
||||
|
||||
fun isEmpty(expect: Expect<Collection<Int>>) = expect toBe Empty
|
||||
fun isNotEmpty(expect: Expect<Collection<Int>>) = expect notToBe Empty
|
||||
private fun isEmpty(expect: Expect<Collection<Int>>) = expect toBe Empty
|
||||
private fun isNotEmpty(expect: Expect<Collection<Int>>) = expect notToBe Empty
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB
|
||||
|
||||
import ch.tutteli.atrium.specs.testutils.WithAsciiReporter
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.specs.fun1
|
||||
import ch.tutteli.atrium.specs.name
|
||||
import ch.tutteli.atrium.specs.notImplemented
|
||||
import ch.tutteli.atrium.specs.testutils.WithAsciiReporter
|
||||
import ch.tutteli.atrium.specs.withNullableSuffix
|
||||
|
||||
class IterableAllAssertionsSpec : ch.tutteli.atrium.specs.integration.IterableAllAssertionsSpec(
|
||||
fun1(Expect<Iterable<Double>>::all).name to ::all,
|
||||
fun1(Expect<Iterable<Double?>>::all).withNullableSuffix().name to ::allNullable,
|
||||
fun1(Expect<Iterable<Double>>::all),
|
||||
fun1(Expect<Iterable<Double?>>::all).withNullableSuffix(),
|
||||
"* ", "(!) ", "- ", "» ", ">> ", "=> "
|
||||
) {
|
||||
companion object : WithAsciiReporter()
|
||||
@@ -21,17 +20,11 @@ class IterableAllAssertionsSpec : ch.tutteli.atrium.specs.integration.IterableAl
|
||||
|
||||
var star: Expect<Iterable<*>> = notImplemented()
|
||||
|
||||
a1 = a1.all {}
|
||||
a1 = a1 all {}
|
||||
|
||||
a1b = a1b.all {}
|
||||
a1b = a1b.all(null)
|
||||
a1b = a1b all {}
|
||||
a1b = a1b all null
|
||||
|
||||
star = star.all {}
|
||||
star = star all {}
|
||||
}
|
||||
}
|
||||
|
||||
private fun all(expect: Expect<Iterable<Double>>, assertionCreator: Expect<Double>.() -> Unit) =
|
||||
expect all assertionCreator
|
||||
|
||||
private fun allNullable(expect: Expect<Iterable<Double?>>, assertionCreator: (Expect<Double>.() -> Unit)?) =
|
||||
expect all assertionCreator
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package ch.tutteli.atrium.api.infix.en_GB
|
||||
|
||||
import ch.tutteli.atrium.api.infix.en_GB.creating.list.get.builders.ListGetStep
|
||||
import ch.tutteli.atrium.specs.testutils.WithAsciiReporter
|
||||
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.testutils.WithAsciiReporter
|
||||
import ch.tutteli.atrium.specs.withNullableSuffix
|
||||
import kotlin.reflect.KFunction2
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
class ListFeatureAssertionsSpec : ch.tutteli.atrium.specs.integration.ListFeatureAssertionsSpec(
|
||||
feature1<List<Int>, Int, Int>(Expect<List<Int>>::get),
|
||||
getIndexPair(),
|
||||
fun2<List<Int>, Int, Expect<Int>.() -> Unit>(::get),
|
||||
feature1<List<Int?>, Int, Int?>(Expect<List<Int?>>::get).withNullableSuffix(),
|
||||
getIndexNullablePair()
|
||||
fun2<List<Int?>, Int, Expect<Int?>.() -> Unit>(::get).withNullableSuffix()
|
||||
) {
|
||||
companion object : WithAsciiReporter()
|
||||
|
||||
@@ -24,29 +24,22 @@ class ListFeatureAssertionsSpec : ch.tutteli.atrium.specs.integration.ListFeatur
|
||||
var star: Expect<out List<*>> = notImplemented()
|
||||
|
||||
a1 get 1
|
||||
a1 = a1 get Index(1) assertIt { }
|
||||
a1 = a1 get index(1) { }
|
||||
|
||||
a1b get 1
|
||||
a1b = a1b get Index(1) assertIt { }
|
||||
a1b = a1b get index(1) { }
|
||||
|
||||
star get 1
|
||||
star = star get Index(1) assertIt { }
|
||||
star = star get index(1) { }
|
||||
}
|
||||
}
|
||||
|
||||
private val getIndexFun: KFunction2<Expect<List<Int>>, Index, ListGetStep<Int, List<Int>>> = Expect<List<Int>>::get
|
||||
private fun getIndexPair() = getIndexFun.name to ::getIndex
|
||||
private fun get(expect: Expect<List<Int>>, index: Int, assertionCreator: Expect<Int>.() -> Unit) =
|
||||
expect get index(index) { assertionCreator() }
|
||||
|
||||
private fun getIndex(expect: Expect<List<Int>>, index: Int, assertionCreator: Expect<Int>.() -> Unit) =
|
||||
expect get Index(index) assertIt { assertionCreator() }
|
||||
|
||||
private val getIndexNullableFun: KFunction2<Expect<List<Int?>>, Index, ListGetStep<Int?, List<Int?>>> =
|
||||
Expect<List<Int?>>::get
|
||||
|
||||
private fun getIndexNullablePair() = getIndexNullableFun.name to ::getIndexNullable
|
||||
|
||||
private fun getIndexNullable(
|
||||
@JvmName("getNullable")
|
||||
private fun get(
|
||||
expect: Expect<List<Int?>>,
|
||||
index: Int,
|
||||
assertionCreator: Expect<Int?>.() -> Unit
|
||||
) = expect get Index(index) assertIt { assertionCreator() }
|
||||
) = expect get index(index) { assertionCreator() }
|
||||
|
||||
@@ -3,86 +3,27 @@ package ch.tutteli.atrium.api.infix.en_GB
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.domain.builders.utils.mapArguments
|
||||
import ch.tutteli.atrium.specs.*
|
||||
import ch.tutteli.atrium.specs.testutils.WithAsciiReporter
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.reflect.KFunction3
|
||||
|
||||
private fun <K, V, T> mfun2(
|
||||
f: KFunction3<Expect<Map<out K, V>>, Pair<K, T>, Array<out Pair<K, T>>, Expect<Map<out K, V>>>
|
||||
) = fun2(f)
|
||||
|
||||
class MapAssertionsSpec : ch.tutteli.atrium.specs.integration.MapAssertionsSpec(
|
||||
fun2(Companion::contains),
|
||||
fun2(Companion::contains).name to Companion::containsNullable,
|
||||
"${fun2(Companion::contains).name} ${KeyValue::class.simpleName}" to Companion::containsKeyWithValueAssertions,
|
||||
"${fun2(Companion::contains).name} ${KeyValue::class.simpleName}" to Companion::containsKeyWithNullableValueAssertions,
|
||||
fun1(Companion::containsKey),
|
||||
fun1(Companion::containsNullableKey),
|
||||
fun1(Companion::containsNotKey),
|
||||
fun1(Companion::containsNotNullableKey),
|
||||
/* string toBe, notToBe to avoid ambiguity error */
|
||||
"toBe ${Empty::class.simpleName}" to Companion::isEmpty,
|
||||
"notToBe ${Empty::class.simpleName}" to Companion::isNotEmpty
|
||||
mfun2<String, Int, Int>(::contains),
|
||||
mfun2<String?, Int?, Int?>(::contains).withNullableSuffix(),
|
||||
mfun2<String, Int, Expect<Int>.() -> Unit>(::contains).adjustName { "$it ${KeyValue::class.simpleName}" },
|
||||
mfun2<String?, Int?, (Expect<Int>.() -> Unit)?>(::contains).adjustName { "$it ${KeyValue::class.simpleName}" }.withNullableSuffix(),
|
||||
fun1<Map<out String, *>, String>(::containsKey),
|
||||
fun1<Map<out String?, *>, String?>(::containsKey).withNullableSuffix(),
|
||||
fun1<Map<out String, *>, String>(::containsNotKey),
|
||||
fun1<Map<out String?, *>, String?>(::containsNotKey).withNullableSuffix(),
|
||||
"toBe ${Empty::class.simpleName}" to ::isEmpty,
|
||||
"notToBe ${Empty::class.simpleName}" to ::isNotEmpty
|
||||
) {
|
||||
companion object {
|
||||
private fun contains(
|
||||
expect: Expect<Map<out String, Int>>,
|
||||
pair: Pair<String, Int>,
|
||||
otherPairs: Array<out Pair<String, Int>>
|
||||
): Expect<Map<out String, Int>> {
|
||||
return if (otherPairs.isEmpty()) {
|
||||
expect contains (pair.first to pair.second)
|
||||
} else {
|
||||
expect contains Pairs(pair, *otherPairs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun containsNullable(
|
||||
expect: Expect<Map<out String?, Int?>>,
|
||||
pair: Pair<String?, Int?>,
|
||||
otherPairs: Array<out Pair<String?, Int?>>
|
||||
): Expect<Map<out String?, Int?>> {
|
||||
return if (otherPairs.isEmpty()) {
|
||||
expect contains (pair.first to pair.second)
|
||||
} else {
|
||||
expect contains Pairs(pair, *otherPairs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun containsKeyWithValueAssertions(
|
||||
expect: Expect<Map<out String, Int>>,
|
||||
keyValue: Pair<String, Expect<Int>.() -> Unit>,
|
||||
otherKeyValues: Array<out Pair<String, Expect<Int>.() -> Unit>>
|
||||
): Expect<Map<out String, Int>> {
|
||||
return if (otherKeyValues.isEmpty()) {
|
||||
expect contains KeyValue(keyValue.first, keyValue.second)
|
||||
} else {
|
||||
mapArguments(keyValue, otherKeyValues).to { KeyValue(it.first, it.second) }.let { (first, others) ->
|
||||
expect contains All(first, *others)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun containsKeyWithNullableValueAssertions(
|
||||
expect: Expect<Map<out String?, Int?>>,
|
||||
keyValue: Pair<String?, (Expect<Int>.() -> Unit)?>,
|
||||
otherKeyValues: Array<out Pair<String?, (Expect<Int>.() -> Unit)?>>
|
||||
): Expect<Map<out String?, Int?>> {
|
||||
return if (otherKeyValues.isEmpty()) {
|
||||
expect contains KeyValue(keyValue.first, keyValue.second)
|
||||
} else {
|
||||
mapArguments(keyValue, otherKeyValues).to { KeyValue(it.first, it.second) }.let { (first, others) ->
|
||||
expect contains All(first, *others)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun containsKey(expect: Expect<Map<out String, *>>, key: String) = expect containsKey key
|
||||
|
||||
private fun containsNullableKey(expect: Expect<Map<out String?, *>>, key: String?) = expect containsKey key
|
||||
|
||||
private fun containsNotKey(expect: Expect<Map<out String, *>>, key: String) = expect containsNotKey key
|
||||
|
||||
private fun containsNotNullableKey(expect: Expect<Map<out String?, *>>, key: String?) =
|
||||
expect containsNotKey key
|
||||
|
||||
private fun isEmpty(expect: Expect<Map<*, *>>) = expect toBe Empty
|
||||
|
||||
private fun isNotEmpty(expect: Expect<Map<*, *>>) = expect notToBe Empty
|
||||
}
|
||||
companion object : WithAsciiReporter()
|
||||
|
||||
@Suppress("unused", "UNUSED_VALUE")
|
||||
private fun ambiguityTest() {
|
||||
@@ -249,3 +190,76 @@ class MapAssertionsSpec : ch.tutteli.atrium.specs.integration.MapAssertionsSpec(
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun contains(
|
||||
expect: Expect<Map<out String, Int>>,
|
||||
pair: Pair<String, Int>,
|
||||
otherPairs: Array<out Pair<String, Int>>
|
||||
): Expect<Map<out String, Int>> {
|
||||
return if (otherPairs.isEmpty()) {
|
||||
expect contains (pair.first to pair.second)
|
||||
} else {
|
||||
expect contains Pairs(pair, *otherPairs)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmName("containsNullable")
|
||||
private fun contains(
|
||||
expect: Expect<Map<out String?, Int?>>,
|
||||
pair: Pair<String?, Int?>,
|
||||
otherPairs: Array<out Pair<String?, Int?>>
|
||||
): Expect<Map<out String?, Int?>> {
|
||||
return if (otherPairs.isEmpty()) {
|
||||
expect contains (pair.first to pair.second)
|
||||
} else {
|
||||
expect contains Pairs(pair, *otherPairs)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmName("containsKeyWithValueAssertions")
|
||||
private fun contains(
|
||||
expect: Expect<Map<out String, Int>>,
|
||||
keyValue: Pair<String, Expect<Int>.() -> Unit>,
|
||||
otherKeyValues: Array<out Pair<String, Expect<Int>.() -> Unit>>
|
||||
): Expect<Map<out String, Int>> {
|
||||
return if (otherKeyValues.isEmpty()) {
|
||||
expect contains KeyValue(keyValue.first, keyValue.second)
|
||||
} else {
|
||||
mapArguments(keyValue, otherKeyValues).to { KeyValue(it.first, it.second) }.let { (first, others) ->
|
||||
expect contains All(first, *others)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmName("containsKeyWithNullableValueAssertions")
|
||||
private fun contains(
|
||||
expect: Expect<Map<out String?, Int?>>,
|
||||
keyValue: Pair<String?, (Expect<Int>.() -> Unit)?>,
|
||||
otherKeyValues: Array<out Pair<String?, (Expect<Int>.() -> Unit)?>>
|
||||
): Expect<Map<out String?, Int?>> {
|
||||
return if (otherKeyValues.isEmpty()) {
|
||||
expect contains KeyValue(keyValue.first, keyValue.second)
|
||||
} else {
|
||||
mapArguments(keyValue, otherKeyValues).to { KeyValue(it.first, it.second) }.let { (first, others) ->
|
||||
expect contains All(first, *others)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun containsKey(expect: Expect<Map<out String, *>>, key: String) =
|
||||
expect containsKey key
|
||||
|
||||
@JvmName("containsKeyNullable")
|
||||
private fun containsKey(expect: Expect<Map<out String?, *>>, key: String?) =
|
||||
expect containsKey key
|
||||
|
||||
private fun containsNotKey(expect: Expect<Map<out String, *>>, key: String) =
|
||||
expect containsNotKey key
|
||||
|
||||
@JvmName("containsNotKeyNullable")
|
||||
private fun containsNotKey(expect: Expect<Map<out String?, *>>, key: String?) =
|
||||
expect containsNotKey key
|
||||
|
||||
private fun isEmpty(expect: Expect<Map<*, *>>) = expect toBe Empty
|
||||
|
||||
private fun isNotEmpty(expect: Expect<Map<*, *>>) = expect notToBe Empty
|
||||
|
||||
@@ -2,6 +2,8 @@ package ch.tutteli.atrium.api.infix.en_GB
|
||||
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.specs.*
|
||||
import ch.tutteli.atrium.specs.testutils.WithAsciiReporter
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
class MapFeatureAssertionsSpec : ch.tutteli.atrium.specs.integration.MapFeatureAssertionsSpec(
|
||||
property<Map<String, Int>, Set<String>>(Expect<Map<String, Int>>::keys),
|
||||
@@ -9,23 +11,11 @@ class MapFeatureAssertionsSpec : ch.tutteli.atrium.specs.integration.MapFeatureA
|
||||
property<Map<String, Int>, Collection<Int>>(Expect<Map<String, Int>>::values),
|
||||
fun1<Map<String, Int>, Expect<Collection<Int>>.() -> Unit>(Expect<Map<String, Int>>::values),
|
||||
feature1<Map<String, Int>, String, Int>(Expect<Map<String, Int>>::getExisting),
|
||||
fun2<Map<String, Int>, String, Expect<Int>.() -> Unit>(Companion::getExisting),
|
||||
fun2<Map<String, Int>, String, Expect<Int>.() -> Unit>(::getExisting),
|
||||
feature1<Map<String?, Int?>, String?, Int?>(Expect<Map<String?, Int?>>::getExisting).withNullableSuffix(),
|
||||
fun2(Companion::getExisting).name to Companion::getExistingNullable
|
||||
fun2<Map<String?, Int?>, String?, Expect<Int?>.() -> Unit>(::getExisting).withNullableSuffix()
|
||||
) {
|
||||
companion object {
|
||||
private fun getExisting(
|
||||
expect: Expect<Map<String, Int>>,
|
||||
key: String,
|
||||
assertionCreator: Expect<Int>.() -> Unit
|
||||
): Expect<Map<String, Int>> = expect getExisting Key(key) assertIt { assertionCreator() }
|
||||
|
||||
private fun getExistingNullable(
|
||||
expect: Expect<Map<String?, Int?>>,
|
||||
key: String?,
|
||||
assertionCreator: Expect<Int?>.() -> Unit
|
||||
): Expect<Map<String?, Int?>> = expect getExisting Key(key) assertIt { assertionCreator() }
|
||||
}
|
||||
companion object : WithAsciiReporter()
|
||||
|
||||
@Suppress("unused", "UNUSED_VALUE")
|
||||
private fun ambiguityTest() {
|
||||
@@ -40,9 +30,22 @@ class MapFeatureAssertionsSpec : ch.tutteli.atrium.specs.integration.MapFeatureA
|
||||
a3 getExisting null as String?
|
||||
star getExisting "a"
|
||||
|
||||
a1 = a1 getExisting Key("a") assertIt { }
|
||||
a2 = a2 getExisting Key(1) assertIt { }
|
||||
a3 = a3 getExisting Key(null) assertIt { }
|
||||
star = star getExisting Key("a") assertIt { }
|
||||
a1 = a1 getExisting key("a") { }
|
||||
a2 = a2 getExisting key(1) { }
|
||||
a3 = a3 getExisting key(null) { }
|
||||
star = star getExisting key("a") { }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getExisting(
|
||||
expect: Expect<Map<String, Int>>,
|
||||
key: String,
|
||||
assertionCreator: Expect<Int>.() -> Unit
|
||||
): Expect<Map<String, Int>> = expect getExisting key(key) { assertionCreator() }
|
||||
|
||||
@JvmName("getExistingNullable")
|
||||
private fun getExisting(
|
||||
expect: Expect<Map<String?, Int?>>,
|
||||
key: String?,
|
||||
assertionCreator: Expect<Int?>.() -> Unit
|
||||
): Expect<Map<String?, Int?>> = expect getExisting key(key) { assertionCreator() }
|
||||
|
||||
@@ -80,23 +80,16 @@ object NewFeatureAssertionsBuilder : NewFeatureAssertions {
|
||||
description: Translatable,
|
||||
provider: T.() -> R
|
||||
): ExtractedFeaturePostStep<T, R> =
|
||||
genericFeature(expect, createMetaFeature(expect, description, provider))
|
||||
genericFeature(expect, ExpectImpl.feature.meta.create(expect, description, provider))
|
||||
|
||||
fun <T, R> genericSubjectBasedFeature(
|
||||
expect: Expect<T>,
|
||||
provider: (T) -> MetaFeature<R>
|
||||
): ExtractedFeaturePostStep<T, R> = ExpectImpl.feature.genericFeature(
|
||||
expect,
|
||||
expect.maybeSubject.fold(this::createFeatureSubjectNotDefined) { provider(it) }
|
||||
ExpectImpl.feature.meta.createSubjectBased(expect, provider)
|
||||
)
|
||||
|
||||
private fun <R> createFeatureSubjectNotDefined(): MetaFeature<R> =
|
||||
MetaFeature(
|
||||
ErrorMessages.DEDSCRIPTION_BASED_ON_SUBJECT,
|
||||
RawString.create(ErrorMessages.REPRESENTATION_BASED_ON_SUBJECT_NOT_DEFINED),
|
||||
None
|
||||
)
|
||||
|
||||
override inline fun <T, R> genericFeature(
|
||||
expect: Expect<T>,
|
||||
metaFeature: MetaFeature<R>
|
||||
@@ -107,30 +100,7 @@ object NewFeatureAssertionsBuilder : NewFeatureAssertions {
|
||||
description: String,
|
||||
provider: (T) -> R
|
||||
): ExtractedFeaturePostStep<T, R> =
|
||||
genericFeature(expect, createMetaFeature(expect, description, provider))
|
||||
|
||||
private fun <T, R> createMetaFeature(
|
||||
expect: Expect<T>,
|
||||
description: String,
|
||||
provider: (T) -> R
|
||||
): MetaFeature<R> = createMetaFeature(expect, Untranslatable(description), provider)
|
||||
|
||||
private fun <T, R> createMetaFeature(
|
||||
expect: Expect<T>,
|
||||
description: Translatable,
|
||||
provider: (T) -> R
|
||||
): MetaFeature<R> {
|
||||
return expect.maybeSubject.fold({
|
||||
MetaFeature(
|
||||
description,
|
||||
RawString.create(ErrorMessages.REPRESENTATION_BASED_ON_SUBJECT_NOT_DEFINED),
|
||||
None
|
||||
)
|
||||
}) {
|
||||
val prop = provider(it)
|
||||
MetaFeature(description, prop, Some(prop))
|
||||
}
|
||||
}
|
||||
genericFeature(expect, ExpectImpl.feature.meta.create(expect, description, provider))
|
||||
|
||||
/**
|
||||
* Returns [MetaFeatureBuilder] which helps to create a [MetaFeature].
|
||||
@@ -143,6 +113,7 @@ object NewFeatureAssertionsBuilder : NewFeatureAssertions {
|
||||
* into an overload ambiguity, then either [p] (for property) or one of the `fN` functions (e.g. [f2] for
|
||||
* a function which expects 2 arguments).
|
||||
*/
|
||||
//TODO move to API, this could potentially be different per API
|
||||
class MetaFeatureOption<T>(private val expect: Expect<T>) {
|
||||
|
||||
/**
|
||||
@@ -338,4 +309,43 @@ object MetaFeatureBuilder {
|
||||
fun <A1, A2, A3, A4, A5, R> f5(expect: Expect<*>, f: KFunction5<A1, A2, A3, A4, A5, R>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) =
|
||||
MetaFeature(coreFactory.newMethodCallFormatter().formatCall(f.name, arrayOf(a1, a2, a3, a4, a5)), f.invoke(a1, a2, a3, a4, a5))
|
||||
//@formatter:on
|
||||
|
||||
/**
|
||||
* creates a [MetaFeature] which is entirely based on the subject (i.e. also the description).
|
||||
*/
|
||||
fun <T, R> createSubjectBased(
|
||||
expect: Expect<T>,
|
||||
provider: (T) -> MetaFeature<R>
|
||||
): MetaFeature<R> = expect.maybeSubject.fold(this::createFeatureSubjectNotDefined) { provider(it) }
|
||||
|
||||
private fun <R> createFeatureSubjectNotDefined(): MetaFeature<R> =
|
||||
MetaFeature(
|
||||
ErrorMessages.DEDSCRIPTION_BASED_ON_SUBJECT,
|
||||
RawString.create(ErrorMessages.REPRESENTATION_BASED_ON_SUBJECT_NOT_DEFINED),
|
||||
None
|
||||
)
|
||||
|
||||
fun <T, R> create(
|
||||
expect: Expect<T>,
|
||||
description: String,
|
||||
provider: (T) -> R
|
||||
): MetaFeature<R> = create(expect, Untranslatable(description), provider)
|
||||
|
||||
fun <T, R> create(
|
||||
expect: Expect<T>,
|
||||
description: Translatable,
|
||||
provider: (T) -> R
|
||||
): MetaFeature<R> {
|
||||
return expect.maybeSubject.fold({
|
||||
MetaFeature(
|
||||
description,
|
||||
RawString.create(ErrorMessages.REPRESENTATION_BASED_ON_SUBJECT_NOT_DEFINED),
|
||||
None
|
||||
)
|
||||
}) {
|
||||
val feature = provider(it)
|
||||
MetaFeature(description, feature, Some(feature))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import ch.tutteli.atrium.core.None
|
||||
import ch.tutteli.atrium.core.Option
|
||||
import ch.tutteli.atrium.core.Some
|
||||
import ch.tutteli.atrium.creating.Expect
|
||||
import ch.tutteli.atrium.creating.FeatureExpect
|
||||
import ch.tutteli.atrium.domain.builders.creating.changers.FeatureExtractorBuilder
|
||||
import ch.tutteli.atrium.domain.builders.creating.changers.FeatureOptions
|
||||
import ch.tutteli.atrium.domain.creating.changers.ExtractedFeaturePostStep
|
||||
@@ -68,13 +69,13 @@ class FinalStepImpl<T, R>(
|
||||
extractAndApply = { assertionCreator -> extractIt(this, Some(assertionCreator)) }
|
||||
)
|
||||
|
||||
private fun extractIt(expect: Expect<T>, subAssertions: Option<Expect<R>.() -> Unit>) =
|
||||
private fun extractIt(expect: Expect<T>, maybeSubAssertions: Option<Expect<R>.() -> Unit>): FeatureExpect<T, R> =
|
||||
featureExtractor.extract(
|
||||
expect,
|
||||
featureOptions?.description ?: featureExtractionStep.description,
|
||||
featureExtractionStep.representationForFailure,
|
||||
featureExtraction,
|
||||
subAssertions,
|
||||
maybeSubAssertions,
|
||||
featureOptions?.representationInsteadOfFeature
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ interface VarArgHelper<out T> {
|
||||
/**
|
||||
* Creates an [ArgumentMapperBuilder] which allows to map [expected] and [otherExpected].
|
||||
*/
|
||||
val mapArguments get() = ArgumentMapperBuilder(expected, otherExpected)
|
||||
val mapArguments: ArgumentMapperBuilder<T> get() = ArgumentMapperBuilder(expected, otherExpected)
|
||||
|
||||
/**
|
||||
* Returns the arguments as [List].
|
||||
|
||||
Reference in New Issue
Block a user