-
Notifications
You must be signed in to change notification settings - Fork 259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide support for Kotlin extension methods on Subjects #536
Comments
This sort of relates to #204 a bit. |
Thanks very much for all the detail. I was intrigued when you mentioned using extension methods like this, so it's sad to hear that they don't quite work as is. One initial question to buy me time to think about this more: In this particular case, how much does it help to put (I'm wondering if this is going to lead us to create a separate |
I need to transform both values, so the API wouldn't be nice if |
Copying some internal discussion and thoughts. I was actually writing some Kotlin Truth subjects just as this issue got posted, so I had a couple. I think @cgruber is right that the linked issue, about reorganizing subjects, would help. Having isEqualTo on Subject definitely kind of bakes in an assumption that there's exactly one Subject per type, and they'll all e.g. have the same notion of equality. I'd personally be hesitant to expose To be clear, writing vanilla Subjects in Kotlin is quite doable and pleasant, and the ability to have top-level |
Shall we merge this with #404? |
Let's keep this one open, since it's more about extension methods. I just closed #404 along with the other requests for |
Two notes:
|
I admit to some anxiety about relying on reflective access, but I can see why you're doing it. I would suggest that in the process, that reflective access actually be through a utility which has a consistent API, to avoid having subject implementers rolling their own reflection, and insulating internal changes a bit. |
Agreed, we should provide a non-reflective API for this. (We should be able to avoid reflection even in the implementation, since there's still a package-private |
Running into this issue (somewhat). My use case is also very similar: I need to assert that certain Something like:
|
The title might be a little off. We recently converted the Point of Sale Android codebase at Square from AssertJ to Truth and used Kotlin for our custom Subjects. I try to walk you through the issues I ran into, maybe it is beneficial for your future API considerations.
Kotlin supports extension function, what allows "extending" existing Subjects easily and in a fluent way. My goal was to extend the
StringSubject
with checks that compresses multiple whitespaces into one similarignoreCase()
.From Java's point of view
compressWhitespaces()
is like a static method that hasStringSubject
as argument.The first problem I ran into is that
actual()
isprotected final
inSubject
. There wasn't a way for me to get the actual value from theStringSubject
that I'm "extending". (My solution is to use a reflective call for now)Similar to
StringSubject.CaseInsensitiveStringComparison
I planned to implement the checks in a class, that doesn't extendSubject
. This way I can add methods likeisEqualTo()
when I actually implement them. There were multiple problems with this approach:CaseInsensitiveStringComparison
is an inner class, it gets access toactual()
and other methods throughStringSubject
. My class doesn't have access to these methods. My biggest problem was that I couldn't construct failure messages easily. I have the impression thatSubject
has too many concerns: It provides the API for checks, but also gives you access to methods to create error messages. It would be helpful, if both things were separated.Subject
. I could hide the implementation behind an interface, but this wouldn't allow providing a factory method that creates theSubject.Factory
, what is necessary forassertAbout(..)
and quite useful in Java.Subject
, meaning every caller sees all the methods, that I might not have implemented. In fact, my class implementsisEqualTo()
right now, but notisNotEqualTo()
. You could treat it like a not finished implementation for the API and I could throw an exception / error when calling this method, but from an API point of view the caller doesn't know that. They shouldn't see the method at all. This leads to false positives at the moment.To summarize those are the things I wish would be available or different.
actual()
value from outside.Subject
.The text was updated successfully, but these errors were encountered: