Roukanken
05/19/2022, 1:56 PMI wonder if there’s a way to preventI don't think there is a way to prevent it compile time, but you can always just half-botch it by having the assert always fail whenif the generic type of the function has its own generic typeisA
T::class.typeParameters
is non-empty (eg, the reified class has some generic parameters on it's own)Eric
08/05/2022, 5:39 PMwithCaptured
(mockk) breaks assertion chaining if the slot has not been captured. It throws Mapping 'captured value %s' failed with: lateinit property captured has not been initialized
. Not sure if this is known or intentional. Would be nice if instead of throwing it would short circuit the block and fail.Eric
09/21/2022, 5:32 PMcompareTo
which is useful for things like BigDecimal
maybe add this?
fun <T : Comparable<T>> Assertion.Builder<T>.compareToEqual(expected: T) =
assert("is equal using compareTo to %s", expected) {
if (it.compareTo(expected) == 0) pass() else fail()
}
Eric
10/28/2022, 4:13 PMpropertiesAreEqualTo
that doesn’t require other
to be the same type as the subject. Just a couple minor tweaks.
fun <T : Any> Assertion.Builder<T>.reflectionEquals(
other: Any,
ignoredPropertyNames: List<String> = emptyList()
): Assertion.Builder<T> = compose("is equal field-by-field to %s", other) { subject ->
val otherBeanInfo = Introspector.getBeanInfo(other.javaClass)
val beanInfo = Introspector.getBeanInfo(subject.javaClass)
beanInfo.propertyDescriptors
.filter { it.name != "class" && it.name !in ignoredPropertyNames }
.forEach { property ->
val mappedAssertion = get("value of property ${property.name}") {
property.readMethod(this)
}
val otherProperty = otherBeanInfo.propertyDescriptors.firstOrNull { it.name == property.name }
val otherValue = otherProperty?.let { it.readMethod(other) }
// the rest is the same as propertiesAreEqualTo
dave08
12/08/2022, 2:36 PMBlock assertions do _not_ fail fast.
but if I use:
expectThat(result) {
get(Foo::prop1)...
get(Foo::prop2)...
}
It seems to only print out the first check's result... 🤔dave08
01/02/2023, 4:34 PMexpectThat(...)
was an inline fun
with reified type param, you could technically pass that type down to the assertions and it could be a great help for things like collections... currently if I pass a List<Foo>
to expectThat
I can pass a List<Baz>
that doesn't inherit from Foo
to contains
and that simply doesn't make sense... meaning refactoring to passing another type in the list could easily have the tests pass even though they shouldn't...robfletcher
01/06/2023, 4:36 PMdmcg
01/06/2023, 6:33 PMDan Rusu
01/08/2023, 3:12 AMArrayAssertions
but am getting strange failures where it's complaining about differing strings that appear to be equal so I wonder if I'm running into some sort of character encoding issue:
▼ Expect that "▼ Expect that ['f', 'n', 'o', 'r', 'd']:
| ✗ array content equals ['d', 'i', 's', 'c', 'o', 'r', 'd']":
✗ is equal to "▼ Expect that ['f', 'n', 'o', 'r', 'd']:
| ✗ array content equals ['d', 'i', 's', 'c', 'o', 'r', 'd']"
found "▼ Expect that ['f', 'n', 'o', 'r', 'd']:
| ✗ array content equals ['d', 'i', 's', 'c', 'o', 'r', 'd']"
The way the tests are written makes it very difficult (and frustrating) to deal with test failures because:
1. Double-clicking on a failed test in IntelliJ doesn't navigate to the failing test
2. Clicking the Rerun Failed Tests
button makes it seem like they all pass because it doesn't actually rerun any tests
I don't have these issues when I use Strikt for testing my own project so I wonder if this is caused by using contexts instead of a separate test method per scenarioDan Rusu
01/10/2023, 10:31 PMDan Rusu
01/11/2023, 11:30 PMDan Rusu
01/11/2023, 11:55 PMDan Rusu
01/13/2023, 11:25 PMline.separator
system property is anything other than \n
. This is because raw / triple-quoted strings are hard-coded to always be compiled with \n
line separators so they can't possibly match output that uses the line.separator
system property.
I didn't find any official documentation about this but found this:
https://stackoverflow.com/questions/48933641/kotlin-add-carriage-return-into-multiline-string#:~:text=Kotlin%20multiline%20strings%20are%20always,separator%22))%20.
and also found that the Kotlin standard library hardcoded \n
in the reindent
function (which is used by the trimIndent
& trimMargin
functions that are used throughout the tests):
https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/text/Indent.kt#:~:text=.joinTo(StringBuild[…]eEstimate)%2C%20%22%5Cn%22)
So this brings up 2 issues:
1. The github action to run on windows doesn't seem to represent a regular windows environment. Perhaps something is overwriting the line.separator
system property.
2. Either the EOL
value in DefaultResultWriter
should be set to \n
(which makes the tests pass) or all the tests that assert against multi-line triple-quoted strings need to be fixed.dave08
01/26/2023, 4:55 PMEric
05/31/2023, 2:11 PM.isA<Ok<Foo>>().get { value }
with .isSuccess<Foo>()
but I'm having trouble w/ the generic signatures.
fun <V> Assertion.Builder<Result<V, *>>.isSuccess(): Assertion.Builder<V> = isA<Ok<V>>().get { value }
fun <E> Assertion.Builder<Result<*, E>>.isFailure(): Assertion.Builder<E> = isA<Err<E>>().get { error }
IntelliJ is yelling at me. Any ideas on what these ext funs should look like? Thanks.Eric
06/08/2023, 1:01 PMpropertiesAreEqualToIgnoring
doesn't support nullable attributes as currently written
this should work, though
fun <T : Any> Assertion.Builder<T>.propertiesAreEqualToIgnoring(
other: T,
vararg ignoredProperties: KProperty1<T, Any?>,
): Assertion.Builder<T> = compareFieldByField(
other,
ignoredProperties.map(KProperty1<T, Any?>::name)
)
Just changed KProperty1<T, Any>
-> KProperty1<T, Any?>
dave08
06/20/2023, 12:55 PMget()
using Arrow Optics? It might avoid a bunch of gets to drill down a hierarchy and get { }
that inspects the source code itself...Pihentagy
06/27/2023, 4:01 PMexpectThat(result) {
get { statusCode }.isEqualTo(HttpStatus.OK)
get { body }.isNotNull().and {
get { elements }.and {
hasSize(1)
expectThat(first().subject) {
get { coordinates }.isEqualTo(listOf(coord))
get { networkType }.isEqualTo(NetworkType.SWITCH)
}
}
}
}
Eric
07/05/2023, 1:05 PMsingle
on a Map
every once in a while, like there is for Collection
Might be worth dropping in your std assertions
fun <T : Map<K, V>, K, V> Assertion.Builder<T>.single(): Assertion.Builder<Pair<K, V>> =
assert("has only one entry") {
if (it.size == 1) pass(it.size) else fail(it.size)
}.get("single entry %s") { entries.first().toPair() }
Klitos Kyriacou
07/19/2023, 2:13 PMcontainsOnly
(or Kotest's shouldContainOnly
)?
Description from AssertK: "Asserts the iterable contains only the expected elements, in any order. Duplicate values in the expected and actual are ignored."Saharath Kleips
07/19/2023, 5:08 PMEric
07/21/2023, 1:33 PMcompareToEqual
again.
https://kotlinlang.slack.com/archives/CAR7KJ96J/p1663781526609259
This time passing in a comparator:
fun <T : Comparable<T>> Assertion.Builder<T>.compareToEqual(
expected: T,
comparator: Comparator<T> = Comparator.naturalOrder(),
) = assert("is equal using Comparator to %s", expected) {
if (comparator.compare(subject, expected) == 0) pass() else fail()
}
christophsturm
09/27/2023, 9:29 AMEric
12/20/2023, 7:16 PM@PreAuthorize
annotation or have it as a meta-annotation.
that(methods).all {
get { annotations.toList() }.any {
get { annotationClass }.isEqualTo(PreAuthorize::class)
// or...
get { annotationClass.annotations }.any { get { annotationClass }.isEqualTo(PreAuthorize::class) }
}
}
Jakub Gwóźdź
01/22/2024, 10:04 AMinternal fun formatValue(value: Any?): Any =
when (value) {
null -> "null"
is CharSequence -> "\"$value\""
is Char -> "'$value'"
is Iterable<*> -> if (value.javaClass.preferToString()) value.toString() else value.map(::formatValue)
is Byte -> "0x${value.toString(16)}"
is ByteArray -> "0x${value.toHex()}".truncate()
...
Is there a reason why if (value.javaClass.preferToString()...
is only in Iterable<*> and not on any class?
Reason I’m asking is because I have things like expectThat(jsonObject1).isEqualTo(jsonObject2)
(from kotlinx.serialization) and it works just fine, but whenever there is a fail, I don’t see beautiful json (like from jsonObject2.toString()
), but rather a mess with the =
chars (caused by line 42).Eric
02/08/2024, 3:15 PMval
attributes are annotated with either @Column(updatable = false)
or @JoinColumn(updatable = false)
Just testing 1 right now
expectThat(immutableProperties).all {
get { getAnnotation(Column::class.java) }.isNotNull().get { updatable }.isFalse()
}
juliocbcotta
03/05/2024, 4:53 PMDavid Hamilton
06/23/2024, 12:51 PMrobfletcher
06/23/2024, 5:12 PM