Chris Lee
01/13/2024, 7:06 PM.shouldBeRight()
and .shouldBeLeft
. Now we need extra work to establish a context to execute the code being tested.
I’ve currently been using a pattern like this:
test("UUID converter works") {
either {
val uuid = UUID.randomUUID()
converter.convert(ResolvedNodes.string(uuid.toString()), type, conversionContext())
.shouldBe(uuid)
}.shouldBeRight()
either {
converter.convert(ResolvedNodes.string(""), type, conversionContext())
}.shouldBeLeft()
.shouldBeInstanceOf<ConversionError.TypeConversionError>()
.message()
.shouldBe(
"Error converting '' into 'java.util.UUID': IllegalArgumentException: Invalid UUID string: "
)
}
…which can be cleaned up a bit with a few helper shims:
test("UUID converter works") {
shouldBeRight {
val uuid = UUID.randomUUID()
converter.convert(ResolvedNodes.string(uuid.toString()), type, conversionContext())
.shouldBe(uuid)
}
shouldBeLeft {
converter.convert(ResolvedNodes.string(""), type, conversionContext())
}.shouldBeInstanceOf<ConversionError.TypeConversionError>()
.message()
.shouldBe(
"Error converting '' into 'java.util.UUID': IllegalArgumentException: Invalid UUID string: "
)
}
public inline fun <Error, A> shouldBeRight(@BuilderInference block: Raise<Error>.() -> A): A = either(block).shouldBeRight()
public inline fun <Error, A> shouldBeLeft(@BuilderInference block: Raise<Error>.() -> A): Error = either(block).shouldBeLeft()
It seems like there are more opportunities to further improve this; ideally the semantics would be:
a) a way to execute code in a context w/o having to establish that context explicitly;
b) semantics similar to exceptions where the happy-path requires no extra code, anything raised fails the test
c) shouldRaise<ErrorType>
similar to shouldThrow<ExceptionType>
to handle the error path
Perhaps parts of this exist already and I haven’t yet tracked them down.Javier
01/14/2024, 11:52 AM