Support for assert functions with receivers/infix functions?
LewsTherinTelescope opened this issue · 4 comments
To elaborate on the title, I like to have a function like the following for testing:
infix fun <V> V.mustEqual(expected: V): Unit = assertEquals(expected, this)
Which allows writing test functions in what to me is a bit more of a natural way:
@Test fun testAddition() {
1 + 1 mustEqual 2
}
I wanted to use it with this plugin, so I tried adding it to the list of functions to transform and implementing an overload with a message parameter as follows:
fun <V> V.mustEqual(expected: V, message: () -> String): Unit =
assertEquals(expected, this, message())
However, it appears that this does not work (neither in infix mode nor "dot mode"). It does work fine if I instead take both values as normal parameters:
fun <V> mustEqual(actual: V, expected: V): Unit = assertEquals(expected, this)
fun <V> mustEqual(actual: V, expected: V, message: () -> String): Unit =
assertEquals(expected, actual, message())
Which leads me to believe that the issue is how it uses a receiver for one of the parameters, since changing only that does fix it.
Obviously, I could just use assertEquals
, and will be doing exactly that for now because this plugin is definitely worth that very minor (and subjective) stylistic inconvenience, but figured I'd bring it up, in case it's not too time-consuming to add support for.
(It seems to me like #65 may be related to this, but having not used Kotest, I'm not sure.)
Yeah, I'll definitely take a look at this. The expected
parameter of the infix mustEqual
will to be diagramed but in your example it is a constant so nothing needs to be diagramed. If you try something like 2 mustEqual 1 + 2
you should see what I mean.
The receiver on the other hand I know is not included in the diagram right now so I can take a look at that.
Just tested your suggestion and yeah you're totally right, the parameter is diagrammed fine when it's more complex than just a constant number, which none of my failing quick checks were. Thanks for pointing that out!
Great! Glad that's working for you.
I've avoided including the receivers (dispatch and extension) because I wanted to support soft assertion use cases. But if it is an infix function, I think it's reasonable to expect the receiver should be included.
That would indeed be very handy for Kotest assertions or in fact any infix based assertions.
For now to print the whole object or some additional context, one needs to explicitly use Clues which brings quite a bit of boilerplate as otherwise an assertion like that
user.name shouldNotBe null
would just report <null> should not equal <null>
if name was null, so the context (user.name) and the state is unclear in the error message.
There is even an issue for this kotest/kotest#2241 and the author even did some experiment with a custom compiler plugin but has never finished.
Support for infix functions wouldn't make Kotest work out of the box all of a sudden but it would definitely allow one to create an infix like function that koltin-power-assert could pass the message to, and that function would then delegate to Kotest setting its Clue with the passed message so that Kotest can report it and then would delegate to Kotest own assertion function (such a function arrangement could then be contributed to Kotest itself to make it work out of the box)