diff --git a/site/src/jbake/content/about.md b/site/src/jbake/content/about.md index 91a20faf..ef758231 100644 --- a/site/src/jbake/content/about.md +++ b/site/src/jbake/content/about.md @@ -8,6 +8,7 @@ cached=true Strikt was written by [Rob Fletcher](https://github.com/robfletcher) with contributions from: +* [Casey Brooks](https://github.com/cjbrooks12) * [Xavier Hanin](https://github.com/xhanin) * [Paul Merlin](https://github.com/eskatos) * [Christoph Sturm](https://github.com/christophsturm) diff --git a/site/src/jbake/content/user-guide/mapping.md b/site/src/jbake/content/user-guide/traversing-subjects.md similarity index 55% rename from site/src/jbake/content/user-guide/mapping.md rename to site/src/jbake/content/user-guide/traversing-subjects.md index 93430a7b..a9d633ed 100644 --- a/site/src/jbake/content/user-guide/mapping.md +++ b/site/src/jbake/content/user-guide/traversing-subjects.md @@ -1,4 +1,4 @@ -title=Mapping Over Assertion Subjects +title=Traversing Assertion Subjects type=page status=published cached=true @@ -6,7 +6,7 @@ previousPage=flow-typing.html nextPage=grouping-with-and.html ~~~~~~ -# Mapping Over Assertion Subjects +# Traversing Assertion Subjects Although you can obviously write assertions for the properties of an object with code like this: @@ -19,9 +19,9 @@ expectThat(person.name).isEqualTo("Ziggy") Sometimes it's useful to be able to transform an assertion on a subject to an assertion on a property of that subject, or the result of a method call. Particularly when using soft assertion blocks. -Strikt allows for this using the `Assertion.Builder.map` method. +Strikt allows for this using the `Assertion.Builder.chain` method. -## Mapping with lambdas +## Using _chain_ with lambdas The method takes a lambda whose parameter is the current subject and returns an `Assertion.Builder` where `R` is the type of whatever the lambda returns. @@ -30,12 +30,13 @@ This is sometimes useful for making assertions about the properties of an object ```kotlin val subject = Person(name = "David", birthDate = LocalDate.of(1947, 1, 8)) expectThat(subject) { - map { it.name }.isEqualTo("David") - map { it.birthDate.year }.isEqualTo(1947) + chain { it.name }.isEqualTo("David") + chain { it.birthDate.year }.isEqualTo(1947) } ``` -Strikt will read the test source to find out the name of the variables, so this will work just as well as property references and produce output that looks like this: +Strikt will read the test source to find out the name of the variables. +This example produces output that looks like this: ``` ▼ name: ✗ is equal to "Ziggy" : found "David" @@ -43,30 +44,44 @@ Strikt will read the test source to find out the name of the variables, so this ✗ is equal to 1971 : found 1947 ``` -## Mapping with property or method references +## Using _chain_ with property or method references It's also possible to use a method reference in place of a lambda. ```kotlin val subject = Person(name = "David", birthDate = LocalDate.of(1947, 1, 8)) expectThat(subject) { - map(Person::name).isEqualTo("David") - map(Person::birthDate).map(LocalDate::getYear).isEqualTo(1947) + chain(Person::name).isEqualTo("David") + chain(Person::birthDate).map(LocalDate::getYear).isEqualTo(1947) } ``` +## Mapping elements of collections + +If the assertion subject is an `Iterable` Strikt provides a `map` function much like the one in the Kotlin standard library. +It is effectively like using `chain` on each element of the `Iterable` subject. + +```kotlin +val subject: List = // get list from somewhere +expectThat(subject) + .map(Person::name) + .containsExactly("David", "Ziggy", "Aladdin", "Jareth") +``` + +In this case the `map` function is transforming the `Assertion.Buidler>` into an `Assertion.Builder>` by applying the `name` property to each element. + ## Re-usable mappings -If you find yourself frequently using `map` for the same properties or methods, consider defining extension property or method to make things even easier. +If you find yourself frequently using `chain` for the same properties or methods, consider defining extension property or method to make things even easier. For example: ```kotlin val Assertion.Builder.name: Assertion.Builder - get() = map(Person::name) + get() = chain(Person::name) val Assertion.Builder.yearOfBirth: Assertion.Builder - get() = map("year of birth") { it.dateOfBirth.year } + get() = chain("year of birth") { it.dateOfBirth.year } ``` You can then write the earlier example as: @@ -79,7 +94,7 @@ expectThat(subject) { } ``` -## Built-in mappings +## Built-in traversals -Strikt has a number of built in mapping properties and functions such as `Assertion.Builder>.first()` which returns an `Assertion.Builder` whose subject is the first element of the list. +Strikt has a number of built in traversal properties and functions such as `Assertion.Builder>.first()` which returns an `Assertion.Builder` whose subject is the first element of the list. See the [API docs](/api/strikt-core/strikt.api/-assertion/) for details. diff --git a/site/src/jbake/templates/navbar.ftl b/site/src/jbake/templates/navbar.ftl index f3815494..ee638ada 100644 --- a/site/src/jbake/templates/navbar.ftl +++ b/site/src/jbake/templates/navbar.ftl @@ -34,7 +34,8 @@ Expecting Exceptions Strongly Typed Assertions - Mapping Over Assertion Subjects + Traversing + Assertion Subjects Grouping Assertions with and Custom Assertions diff --git a/strikt-core/src/main/kotlin/strikt/api/Assertion.kt b/strikt-core/src/main/kotlin/strikt/api/Assertion.kt index b68527e5..e6417051 100644 --- a/strikt-core/src/main/kotlin/strikt/api/Assertion.kt +++ b/strikt-core/src/main/kotlin/strikt/api/Assertion.kt @@ -168,18 +168,20 @@ interface Assertion { * reference) the subject description will be automatically determined for * the returned assertion builder. * + * If [function] is a lambda, Strikt will make a best-effort attempt to + * determine an appropriate function / property name. + * * @param function a lambda whose receiver is the current assertion subject. * @return an assertion builder whose subject is the value returned by * [function]. */ - // TODO: not sure about this name, it's fundamentally similar to Kotlin's run. Also it might be nice to have a dedicated `map` for Assertion. - fun map(function: (T) -> R): DescribeableBuilder = + fun chain(function: (T) -> R): DescribeableBuilder = when (function) { is KProperty<*> -> - map("value of property ${function.name}", function) + chain("value of property ${function.name}", function) is KFunction<*> -> - map("return value of ${function.name}", function) - is CallableReference -> map( + chain("return value of ${function.name}", function) + is CallableReference -> chain( "value of ${function.propertyName}", function ) @@ -190,7 +192,7 @@ interface Assertion { } catch (e: Exception) { "%s" } - map(fieldName, function) + chain(fieldName, function) } } @@ -204,7 +206,10 @@ interface Assertion { * @return an assertion builder whose subject is the value returned by * [function]. */ - fun map(description: String, function: (T) -> R): DescribeableBuilder + fun chain( + description: String, + function: (T) -> R + ): DescribeableBuilder /** * Reverses any assertions chained after this method. diff --git a/strikt-core/src/main/kotlin/strikt/api/DescribeableBuilder.kt b/strikt-core/src/main/kotlin/strikt/api/DescribeableBuilder.kt index cb76b7f9..17d750a8 100644 --- a/strikt-core/src/main/kotlin/strikt/api/DescribeableBuilder.kt +++ b/strikt-core/src/main/kotlin/strikt/api/DescribeableBuilder.kt @@ -7,7 +7,7 @@ import strikt.api.Assertion.Builder * assertion subject. * * Since it doesn't make sense to do this anywhere except directly after the - * initial [expectThat] or [Assertion.Builder.map] call those methods return an + * initial [expectThat] or [Assertion.Builder.chain] call those methods return an * instance of this interface, while assertions themselves just return * [Assertion.Builder]. */ diff --git a/strikt-core/src/main/kotlin/strikt/assertions/Any.kt b/strikt-core/src/main/kotlin/strikt/assertions/Any.kt index df79017b..8f548f9d 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/Any.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/Any.kt @@ -114,7 +114,7 @@ fun Builder.propertiesAreEqualTo(other: T): Builder = .propertyDescriptors .filter { it.name != "class" } .forEach { property -> - val mappedAssertion = map("value of property ${property.name}") { + val mappedAssertion = chain("value of property ${property.name}") { property.readMethod(it) } val otherValue = property.readMethod(other) diff --git a/strikt-core/src/main/kotlin/strikt/assertions/CharSequence.kt b/strikt-core/src/main/kotlin/strikt/assertions/CharSequence.kt index db5ee67f..a77109c5 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/CharSequence.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/CharSequence.kt @@ -161,4 +161,4 @@ fun Builder.containsIgnoringCase(expected: CharSequence): * @see CharSequence.length */ val Builder.length: Builder - get() = map(CharSequence::length) + get() = chain(CharSequence::length) diff --git a/strikt-core/src/main/kotlin/strikt/assertions/Collection.kt b/strikt-core/src/main/kotlin/strikt/assertions/Collection.kt index 87f44bf2..20c82f6c 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/Collection.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/Collection.kt @@ -31,4 +31,4 @@ fun , E> Builder.isNotEmpty(): Builder = * @see Collection.size */ val > Builder.size: Builder - get() = map(Collection<*>::size) + get() = chain(Collection<*>::size) diff --git a/strikt-core/src/main/kotlin/strikt/assertions/Enum.kt b/strikt-core/src/main/kotlin/strikt/assertions/Enum.kt index e313c88f..eda997e6 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/Enum.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/Enum.kt @@ -8,7 +8,7 @@ import strikt.api.Assertion.Builder * @see Enum.name */ val > Builder.name: Builder - get() = map(Enum::name) + get() = chain(Enum::name) /** * Maps an assertion on an enum to an assertion on its ordinal. @@ -16,4 +16,4 @@ val > Builder.name: Builder * @see Enum.ordinal */ val > Builder.ordinal: Builder - get() = map(Enum::ordinal) + get() = chain(Enum::ordinal) diff --git a/strikt-core/src/main/kotlin/strikt/assertions/Iterable.kt b/strikt-core/src/main/kotlin/strikt/assertions/Iterable.kt index e4636b84..b8c7ec58 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/Iterable.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/Iterable.kt @@ -2,6 +2,13 @@ package strikt.assertions import strikt.api.Assertion.Builder +/** + * Applies [Iterable.map] with [function] to the subject and returns an + * assertion builder wrapping the result. + */ +fun , E, R> Builder.map(function: (E) -> R): Builder> = + chain { it.map(function) } + /** * Maps this assertion to an assertion over the first element in the subject * iterable. @@ -9,7 +16,7 @@ import strikt.api.Assertion.Builder * @see Iterable.first */ fun , E> Builder.first(): Builder = - map("first element %s") { it.first() } + chain("first element %s") { it.first() } /** * Maps this assertion to an assertion over the last element in the subject @@ -18,7 +25,7 @@ fun , E> Builder.first(): Builder = * @see Iterable.last */ fun , E> Builder.last(): Builder = - map("last element %s") { it.last() } + chain("last element %s") { it.last() } /** * Asserts that all elements of the subject pass the assertions in [predicate]. @@ -26,7 +33,7 @@ fun , E> Builder.last(): Builder = fun , E> Builder.all(predicate: Builder.() -> Unit): Builder = compose("all elements match:") { subject -> subject.forEach { element -> - map("%s") { element }.apply(predicate) + chain("%s") { element }.apply(predicate) } } then { if (allPassed) pass() else fail() @@ -39,7 +46,7 @@ fun , E> Builder.all(predicate: Builder.() -> Unit): Build fun , E> Builder.any(predicate: Builder.() -> Unit): Builder = compose("at least one element matches:") { subject -> subject.forEach { element -> - map("%s") { element }.apply(predicate) + chain("%s") { element }.apply(predicate) } } then { if (anyPassed) pass() else fail() @@ -51,7 +58,7 @@ fun , E> Builder.any(predicate: Builder.() -> Unit): Build fun , E> Builder.none(predicate: Builder.() -> Unit): Builder = compose("no elements match:") { subject -> subject.forEach { element -> - map("%s") { element }.apply(predicate) + chain("%s") { element }.apply(predicate) } } then { if (allFailed) pass() else fail() diff --git a/strikt-core/src/main/kotlin/strikt/assertions/List.kt b/strikt-core/src/main/kotlin/strikt/assertions/List.kt index 19a2dc4d..aa6aedbc 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/List.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/List.kt @@ -7,13 +7,13 @@ import strikt.api.Assertion.Builder * subject list. */ operator fun , E> Builder.get(i: Int): Builder = - map("element [$i] %s") { it[i] } + chain("element [$i] %s") { it[i] } /** * Maps this assertion to an assertion on the elements at the sub-list * represented by [range] in the subject list. */ operator fun , E> Builder.get(range: IntRange): Builder> = - map("elements [$range] %s") { + chain("elements [$range] %s") { it.subList(range.first, range.last + 1) } diff --git a/strikt-core/src/main/kotlin/strikt/assertions/Map.kt b/strikt-core/src/main/kotlin/strikt/assertions/Map.kt index 9f18bf1b..a8a0094e 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/Map.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/Map.kt @@ -17,7 +17,7 @@ fun , K, V> Builder.isEmpty() = * exists in the subject map. */ operator fun , K, V> Builder.get(key: K): Builder = - map("entry [${formatValue(key)}]") { it[key] } + chain("entry [${formatValue(key)}]") { it[key] } /** * Asserts that the subject map contains an entry indexed by [key]. Depending on @@ -34,7 +34,7 @@ fun , K, V> Builder.containsKey(key: K): Builder = */ fun , K, V> Builder.containsKeys(vararg keys: K): Builder = compose("has entries with the keys %s", keys.toList()) { - keys.forEach { containsKey(it) } + keys.forEach { key -> containsKey(key) } } then { if (allPassed) pass() else fail() } diff --git a/strikt-core/src/main/kotlin/strikt/assertions/TemporalAccessor.kt b/strikt-core/src/main/kotlin/strikt/assertions/TemporalAccessor.kt index d6d775aa..be87f0ec 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/TemporalAccessor.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/TemporalAccessor.kt @@ -62,7 +62,7 @@ fun Assertion.Builder.isAfter(expected: TemporalAccess * @see TemporalAccessor.get */ fun Assertion.Builder.get(field: TemporalField): Assertion.Builder = - map(field.toString()) { it.get(field) } + chain(field.toString()) { it.get(field) } /** * Maps an assertion on the subject to an assertion on the value of the @@ -74,4 +74,4 @@ fun Assertion.Builder.get(field: TemporalField): Asser * @see TemporalAccessor.getLong */ fun Assertion.Builder.getLong(field: TemporalField): Assertion.Builder = - map(field.toString()) { it.getLong(field) } + chain(field.toString()) { it.getLong(field) } diff --git a/strikt-core/src/main/kotlin/strikt/assertions/Throwable.kt b/strikt-core/src/main/kotlin/strikt/assertions/Throwable.kt index ac7519fc..55eca0d9 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/Throwable.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/Throwable.kt @@ -11,13 +11,13 @@ import strikt.api.DescribeableBuilder * @author [Xavier Hanin](https://github.com/xhanin) */ val Builder.message: Builder - get() = map(Throwable::message).isNotNull() + get() = chain(Throwable::message).isNotNull() /** * Maps an assertion on a [Throwable] to an assertion on its [Throwable.cause]. */ val Builder.cause: DescribeableBuilder - get() = map(Throwable::cause) + get() = chain(Throwable::cause) /** * Asserts that an exception is an instance of the expected type. @@ -25,6 +25,7 @@ val Builder.cause: DescribeableBuilder * * This assertion is designed for use with the [strikt.api.catching] function. */ +@Suppress("UNCHECKED_CAST") inline fun Builder.throws(): Builder = assert("threw %s", E::class.java) { when (it) { diff --git a/strikt-core/src/main/kotlin/strikt/assertions/Tuples.kt b/strikt-core/src/main/kotlin/strikt/assertions/Tuples.kt index de81b529..585ade55 100644 --- a/strikt-core/src/main/kotlin/strikt/assertions/Tuples.kt +++ b/strikt-core/src/main/kotlin/strikt/assertions/Tuples.kt @@ -7,31 +7,31 @@ import strikt.api.Assertion */ @get:JvmName("first_pair") val Assertion.Builder>.first: Assertion.Builder - get() = map(Pair::first) + get() = chain(Pair::first) /** * Maps an assertion on a [Pair] to an assertion on its [Pair.second] property. */ @get:JvmName("second_pair") val Assertion.Builder>.second: Assertion.Builder - get() = map(Pair::second) + get() = chain(Pair::second) /** * Maps an assertion on a [Triple] to an assertion on its [Triple.first] property. */ @get:JvmName("first_triple") val Assertion.Builder>.first: Assertion.Builder - get() = map(Triple::first) + get() = chain(Triple::first) /** * Maps an assertion on a [Triple] to an assertion on its [Triple.second] property. */ @get:JvmName("second_triple") val Assertion.Builder>.second: Assertion.Builder - get() = map(Triple::second) + get() = chain(Triple::second) /** * Maps an assertion on a [Triple] to an assertion on its [Triple.third] property. */ val Assertion.Builder>.third: Assertion.Builder - get() = map(Triple::third) + get() = chain(Triple::third) diff --git a/strikt-core/src/main/kotlin/strikt/internal/AssertionBuilder.kt b/strikt-core/src/main/kotlin/strikt/internal/AssertionBuilder.kt index 94823e38..568dc4e6 100644 --- a/strikt-core/src/main/kotlin/strikt/internal/AssertionBuilder.kt +++ b/strikt-core/src/main/kotlin/strikt/internal/AssertionBuilder.kt @@ -57,7 +57,7 @@ internal class AssertionBuilder( } } - override fun map( + override fun chain( description: String, function: (T) -> R ): DescribeableBuilder = diff --git a/strikt-core/src/main/kotlin/strikt/internal/peek/ParsedMapInstruction.kt b/strikt-core/src/main/kotlin/strikt/internal/peek/ParsedMapInstruction.kt index 2dcf9499..5b668515 100644 --- a/strikt-core/src/main/kotlin/strikt/internal/peek/ParsedMapInstruction.kt +++ b/strikt-core/src/main/kotlin/strikt/internal/peek/ParsedMapInstruction.kt @@ -4,7 +4,7 @@ internal class ParsedMapInstruction(line: String) { val body: String init { - val firstPossibleBracket = line.indexOf("map") + 3 + val firstPossibleBracket = line.indexOf("chain") + 3 val firstBracket = line.indexOf('{', firstPossibleBracket) + 1 val subjectEnd = findMatchingClosingBracket(line, firstBracket) body = line.substring(firstBracket, subjectEnd).trim() @@ -21,6 +21,6 @@ internal class ParsedMapInstruction(line: String) { } pos += 1 } - throw RuntimeException("could not find matching brackets in $condition") + error("could not find matching brackets in $condition") } } diff --git a/strikt-core/src/test/java/strikt/internal/peek/FilePeekTestInJavaRoot.kt b/strikt-core/src/test/java/strikt/internal/peek/FilePeekTestInJavaRoot.kt index db3a6893..ba650e8f 100644 --- a/strikt-core/src/test/java/strikt/internal/peek/FilePeekTestInJavaRoot.kt +++ b/strikt-core/src/test/java/strikt/internal/peek/FilePeekTestInJavaRoot.kt @@ -8,7 +8,7 @@ class FilePeekTestInJavaRoot { @Test fun `finds classes that have a different name than the file they are in`() { expectThat(FilePeek.getCallerFileInfo(filterMethod("finds"))) - .map { it.line } + .chain { it.line } .isEqualTo("expectThat(FilePeek.getCallerFileInfo(filterMethod(\"finds\")))") } } diff --git a/strikt-core/src/test/kotlin/strikt/Exceptions.kt b/strikt-core/src/test/kotlin/strikt/Exceptions.kt index af85ea37..cccfeda5 100644 --- a/strikt-core/src/test/kotlin/strikt/Exceptions.kt +++ b/strikt-core/src/test/kotlin/strikt/Exceptions.kt @@ -56,7 +56,7 @@ class Exceptions { " ✗ is upper case\n" + " ✓ starts with \"f\"" ) - map { it.failures } + chain { it.failures } .hasSize(1) .first() .isA() @@ -72,7 +72,7 @@ class Exceptions { fun `chains involving "and" raise a single compound exception`() { fails { expectThat("fnord") - .map(String::length) + .chain(String::length) .isGreaterThan(0) .and { isEqualTo(1) @@ -92,7 +92,7 @@ class Exceptions { " ✗ is not equal to 5" ) } - .map { it.failures } + .chain { it.failures } .hasSize(3) .and { first() @@ -131,7 +131,7 @@ class Exceptions { fun `blocks involving "and" raise a single compound exception`() { fails { expectThat("fnord") { - map(String::length) + chain(String::length) .isGreaterThan(0) .and { isEqualTo(1) @@ -152,7 +152,7 @@ class Exceptions { " ✗ is not equal to 5" ) } - .map { it.failures } + .chain { it.failures } .hasSize(1) .first() .isA() @@ -201,7 +201,7 @@ class Exceptions { .let { error -> expectThat(error) .isA() - .map { it.failures } + .chain { it.failures } .hasSize(2) .and { first() @@ -238,8 +238,8 @@ class Exceptions { expectThat(error) .isA() .and { - map(AssertionFailedError::isExpectedDefined).isFalse() - map(AssertionFailedError::isActualDefined).isFalse() + chain(AssertionFailedError::isExpectedDefined).isFalse() + chain(AssertionFailedError::isActualDefined).isFalse() } } } @@ -255,10 +255,10 @@ class Exceptions { expectThat(error) .isA() .and { - map(AssertionFailedError::isExpectedDefined).isTrue() - map { it.expected.value }.isEqualTo("something") - map(AssertionFailedError::isActualDefined).isTrue() - map { it.actual.value }.isEqualTo("something else") + chain(AssertionFailedError::isExpectedDefined).isTrue() + chain { it.expected.value }.isEqualTo("something") + chain(AssertionFailedError::isActualDefined).isTrue() + chain { it.actual.value }.isEqualTo("something else") } } } diff --git a/strikt-core/src/test/kotlin/strikt/Mapping.kt b/strikt-core/src/test/kotlin/strikt/Mapping.kt index 34c67419..f349099e 100644 --- a/strikt-core/src/test/kotlin/strikt/Mapping.kt +++ b/strikt-core/src/test/kotlin/strikt/Mapping.kt @@ -13,12 +13,21 @@ import strikt.assertions.isEqualTo import strikt.assertions.isNotNull import strikt.assertions.isNull import strikt.assertions.last +import strikt.assertions.map import strikt.assertions.message import strikt.assertions.throws import java.time.LocalDate @DisplayName("mapping assertions") internal class Mapping { + @Test + fun `map() on iterable subjects maps to an iterable`() { + val subject = listOf("catflap", "rubberplant", "marzipan") + expectThat(subject) + .map { it.toUpperCase() } + .containsExactly("CATFLAP", "RUBBERPLANT", "MARZIPAN") + } + @Test fun `first() maps to the first element of an iterable`() { val subject = listOf("catflap", "rubberplant", "marzipan") @@ -52,7 +61,7 @@ internal class Mapping { @Test fun `message maps to an exception message`() { - expectThat(catching { throw IllegalStateException("o noes") }) + expectThat(catching { error("o noes") }) .throws() .message .isEqualTo("o noes") @@ -84,24 +93,24 @@ internal class Mapping { @Test fun `can map with a closure`() { expectThat(subject) { - map { it.name }.isEqualTo("David") - map { it.birthDate.year }.isEqualTo(1947) + chain { it.name }.isEqualTo("David") + chain { it.birthDate.year }.isEqualTo(1947) } } @Test fun `can map with property and method references`() { expectThat(subject) { - map(Person::name).isEqualTo("David") - map(Person::birthDate).map(LocalDate::getYear).isEqualTo(1947) + chain(Person::name).isEqualTo("David") + chain(Person::birthDate).chain(LocalDate::getYear).isEqualTo(1947) } } @Test fun `closures can call methods`() { expectThat(subject) { - map { it.name.toUpperCase() }.isEqualTo("DAVID") - map { it.birthDate.plusYears(69).plusDays(2) } + chain { it.name.toUpperCase() }.isEqualTo("DAVID") + chain { it.birthDate.plusYears(69).plusDays(2) } .isEqualTo(LocalDate.of(2016, 1, 10)) } } @@ -110,8 +119,9 @@ internal class Mapping { fun `can be described`() { fails { expectThat(subject) { - map { it.name }.describedAs("name").isEqualTo("Ziggy") - map { it.birthDate.year }.describedAs("birth year").isEqualTo(1971) + chain { it.name }.describedAs("name").isEqualTo("Ziggy") + chain { it.birthDate.year }.describedAs("birth year") + .isEqualTo(1971) } }.let { e -> assertEquals( @@ -128,7 +138,7 @@ internal class Mapping { @Test fun `descriptions are defaulted when using property references`() { fails { - expectThat(subject).map(Person::name).isEqualTo("Ziggy") + expectThat(subject).chain(Person::name).isEqualTo("Ziggy") }.let { e -> assertEquals( "▼ Expect that Person(name=David, birthDate=1947-01-08):\n" + @@ -143,8 +153,8 @@ internal class Mapping { fun `descriptions also default for blocks`() { fails { expectThat(subject) { - map { it.name }.isEqualTo("Ziggy") - map { + chain { it.name }.isEqualTo("Ziggy") + chain { it.birthDate.year }.isEqualTo(1971) } @@ -163,7 +173,8 @@ internal class Mapping { @Test fun `descriptions are defaulted when using bean getter references`() { fails { - expectThat(subject).map(Person::birthDate).map(LocalDate::getYear) + expectThat(subject).chain(Person::birthDate) + .chain(LocalDate::getYear) .isEqualTo(1971) }.let { e -> assertEquals( diff --git a/strikt-core/src/test/kotlin/strikt/Throws.kt b/strikt-core/src/test/kotlin/strikt/Throws.kt index fe5d6e41..c7e53666 100644 --- a/strikt-core/src/test/kotlin/strikt/Throws.kt +++ b/strikt-core/src/test/kotlin/strikt/Throws.kt @@ -12,13 +12,13 @@ import strikt.assertions.throws internal class Throws { @Test fun `throws passes if the action throws the expected exception`() { - expectThat(catching { throw IllegalStateException() }) + expectThat(catching { error("o noes") }) .throws() } @Test fun `throws passes if the action throws a sub-class of the expected exception`() { - expectThat(catching { throw IllegalStateException() }) + expectThat(catching { error("o noes") }) .throws() } @@ -37,19 +37,19 @@ internal class Throws { @Test fun `throws fails if the action throws the wrong type of exception`() { fails { - expectThat(catching { throw NullPointerException() }) - .throws() + expectThat(catching { error("o noes") }) + .throws() }.let { e -> - val expected = "▼ Expect that java.lang.NullPointerException:\n" + - " ✗ threw java.lang.IllegalStateException : java.lang.NullPointerException was thrown" + val expected = "▼ Expect that java.lang.IllegalStateException:\n" + + " ✗ threw java.lang.NullPointerException : java.lang.IllegalStateException was thrown" assertEquals(expected, e.message) - assertEquals(NullPointerException::class.java, e.cause?.javaClass) + assertEquals(IllegalStateException::class.java, e.cause?.javaClass) } } @Test fun `throws returns an assertion whose subject is the exception that was caught`() { - expectThat(catching { throw IllegalStateException() }) + expectThat(catching { error("o noes") }) .throws() .isA() } diff --git a/strikt-core/src/test/kotlin/strikt/assertions/BeanPropertyAssertions.kt b/strikt-core/src/test/kotlin/strikt/assertions/BeanPropertyAssertions.kt index 3e6b7a7f..f1fed055 100644 --- a/strikt-core/src/test/kotlin/strikt/assertions/BeanPropertyAssertions.kt +++ b/strikt-core/src/test/kotlin/strikt/assertions/BeanPropertyAssertions.kt @@ -68,8 +68,8 @@ internal class BeanPropertyAssertions { expectThat(fails { expectThat(subject.name).isEqualTo("Ziggy") }).isA().and { - map { it.actual.value }.isNull() - map { it.isActualDefined }.isTrue() + chain { it.actual.value }.isNull() + chain { it.isActualDefined }.isTrue() } } diff --git a/strikt-core/src/test/kotlin/strikt/assertions/EnumAssertions.kt b/strikt-core/src/test/kotlin/strikt/assertions/EnumAssertions.kt index ffecab30..525e5f7b 100644 --- a/strikt-core/src/test/kotlin/strikt/assertions/EnumAssertions.kt +++ b/strikt-core/src/test/kotlin/strikt/assertions/EnumAssertions.kt @@ -10,7 +10,7 @@ internal class EnumAssertions { @TestFactory fun `can map to the enum name"`() { for (deity in Pantheon.values()) { - dynamicTest("Can map name on $deity") { + dynamicTest("Can chain name on $deity") { expectThat(deity).name.isEqualTo(deity.name) } } @@ -19,7 +19,7 @@ internal class EnumAssertions { @TestFactory fun `can map to the enum ordinal`() { for (deity in Pantheon.values()) { - dynamicTest("Can map ordinal on $deity") { + dynamicTest("Can chain ordinal on $deity") { expectThat(deity).ordinal.isEqualTo(deity.ordinal) } } diff --git a/strikt-core/src/test/kotlin/strikt/internal/peek/FilePeekTest.kt b/strikt-core/src/test/kotlin/strikt/internal/peek/FilePeekTest.kt index d83a2fdd..3dabd30f 100644 --- a/strikt-core/src/test/kotlin/strikt/internal/peek/FilePeekTest.kt +++ b/strikt-core/src/test/kotlin/strikt/internal/peek/FilePeekTest.kt @@ -13,9 +13,9 @@ class FilePeekTest { val fileInfo = FilePeek.getCallerFileInfo(filterMethod("can get")) expectThat(fileInfo) { - map(FileInfo::sourceFileName) + chain(FileInfo::sourceFileName) .endsWith(fileName) - map(FileInfo::line) + chain(FileInfo::line) .isEqualTo("""val fileInfo = FilePeek.getCallerFileInfo(filterMethod("can get"))""") } } @@ -25,9 +25,9 @@ class FilePeekTest { val fileInfo = { FilePeek.getCallerFileInfo(filterMethod("can get")) }() expectThat(fileInfo) { - map(FileInfo::sourceFileName) + chain(FileInfo::sourceFileName) .endsWith(fileName) - map(FileInfo::line) + chain(FileInfo::line) .isEqualTo("""val fileInfo = { FilePeek.getCallerFileInfo(filterMethod("can get")) }()""") } } @@ -42,7 +42,7 @@ class FilePeekTest { listOf(1, 2, 3).map { it } } - expectThat(fileInfo).map(FileInfo::line) + expectThat(fileInfo).chain(FileInfo::line) .isEqualTo("val fileInfo = mapMethod {/* LOL! I'm a block body*/listOf(1, 2, 3).map { it }}") } } @@ -54,7 +54,7 @@ class FilePeekTestWithDifferentNameThanItsFile { @Test fun `finds classes that have a different name than the file they are in`() { expectThat(FilePeek.getCallerFileInfo(filterMethod("finds"))) - .map { it.line } + .chain { it.line } .isEqualTo("expectThat(FilePeek.getCallerFileInfo(filterMethod(\"finds\")))") } } diff --git a/strikt-core/src/test/kotlin/strikt/internal/peek/MapInstructionTest.kt b/strikt-core/src/test/kotlin/strikt/internal/peek/MapInstructionTest.kt index 400280bc..bbf344e0 100644 --- a/strikt-core/src/test/kotlin/strikt/internal/peek/MapInstructionTest.kt +++ b/strikt-core/src/test/kotlin/strikt/internal/peek/MapInstructionTest.kt @@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test class MapInstructionTest { private val niceInstruction = - ParsedMapInstruction("""map { it.name }.isEqualTo("Ziggy")""") + ParsedMapInstruction("""chain { it.name }.isEqualTo("Ziggy")""") @Test fun `knows the body`() { diff --git a/strikt-protobuf/gradle/dependency-locks/runtimeClasspath.lockfile b/strikt-protobuf/gradle/dependency-locks/runtimeClasspath.lockfile index d2c00a93..54c7ab6f 100644 --- a/strikt-protobuf/gradle/dependency-locks/runtimeClasspath.lockfile +++ b/strikt-protobuf/gradle/dependency-locks/runtimeClasspath.lockfile @@ -4,6 +4,8 @@ com.google.protobuf:protobuf-java:3.6.1 org.jetbrains.kotlin:kotlin-reflect:1.2.70 org.jetbrains.kotlin:kotlin-stdlib-common:1.2.70 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.70 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.70 org.jetbrains.kotlin:kotlin-stdlib:1.2.70 org.jetbrains:annotations:13.0 org.opentest4j:opentest4j:1.1.1 diff --git a/strikt-protobuf/src/main/kotlin/strikt/protobuf/Any.kt b/strikt-protobuf/src/main/kotlin/strikt/protobuf/Any.kt index 0e0db6f8..c38a972d 100644 --- a/strikt-protobuf/src/main/kotlin/strikt/protobuf/Any.kt +++ b/strikt-protobuf/src/main/kotlin/strikt/protobuf/Any.kt @@ -38,4 +38,4 @@ inline fun Builder.unpacksTo(): B * @see com.google.protobuf.Any.unpack */ inline fun Builder.unpack(): Builder = - map { it.unpack(T::class.java) } + chain { it.unpack(T::class.java) } diff --git a/strikt-protobuf/src/test/kotlin/strikt/protobuf/AnyAssertions.kt b/strikt-protobuf/src/test/kotlin/strikt/protobuf/AnyAssertions.kt index d98464f4..c518eb72 100644 --- a/strikt-protobuf/src/test/kotlin/strikt/protobuf/AnyAssertions.kt +++ b/strikt-protobuf/src/test/kotlin/strikt/protobuf/AnyAssertions.kt @@ -21,7 +21,7 @@ class AnyAssertions { } .build() - expectThat(subject).map(Character::getWeapon).isEmpty() + expectThat(subject).chain(Character::getWeapon).isEmpty() } @Test @@ -35,6 +35,6 @@ class AnyAssertions { } .build() - expectThat(subject).map(Character::getWeapon).unpacksTo() + expectThat(subject).chain(Character::getWeapon).unpacksTo() } }