Thread
#strikt
    dave08

    dave08

    1 year ago
    I little point I got caught with a few times... using
    and { get(SomeClass::someProp).isEqualTo(...) }
    on a nullable type without
    isNotNull()
    allows the
    and
    , but has
    get()
    undefined... I wonder if it makes sense to have an
    and
    in this case in the first place...? What can one do with a nullable type? Also, is there anything like a
    isNotNullAnd { ... }
    or
    withNotNull { }
    ? I find myself doing
    expectThat(result).isNotNull().and { ... }
    quite often...
    christophsturm

    christophsturm

    1 year ago
    hmm but
    isNotNull().and { ... }
    is pretty short and nice to read
    maybe we should allow and only on not null receivers?
    dave08

    dave08

    1 year ago
    The thing is that the trailing
    and
    is really not an
    and
    but rather testing the not null result... it's not a side-effect like
    and
    seems to point out.
    maybe we should allow and only on not null receivers?
    That's what I was wondering... but maybe there's some use-case for that I'm not thinking of?
    It could maybe be deprecated saying
    and should only be used in not null contexts
    or something?
    For the previous suggestion, there's already a bunch of mappers like
    with
    ... couldn't
    withNotNull { }
    be such a mapper, when the main assertion is the expected non-null result's contents?
    But in cases when it only matters that the result
    isNotNull()
    then it being an assertion in itself might make more sense...
    robfletcher

    robfletcher

    1 year ago
    It would certainly be easy to add a
    withNotNull
    . I’ve never been super happy with the naming of
    and
    . It reads well in some contexts but not in others.
    christophsturm

    christophsturm

    1 year ago
    But in isnotnull().and() it fits pretty well
    robfletcher

    robfletcher

    1 year ago
    true
    dave08

    dave08

    1 year ago
    with can also be replaced by get and and.... I guess it's a bit hard to draw the line... i just find myself doing isnotnull and and pretty often. But I also don't want to pollute the library with things others might not be using.
    It's easy to add a few extension functions to my project.
    robfletcher

    robfletcher

    1 year ago
    The maintenance cost for those kind of things in the lib is pretty much zero. So long as it’s not some kind of new API direction I’m not sure about I’m happy to add it. I think
    withNotNull
    as an alias for
    .isNotNull().and { }
    is useful enough to be worth adding
    dave08

    dave08

    1 year ago
    Also, do you ever assert anything on a nullable value without isNotNull()? Is it on purpose that matchers/mappers (apart from the ones checking or mapping nulls) are available for nullables?
    robfletcher

    robfletcher

    1 year ago
    you can use
    isEqualTo
    on a null value
    dave08

    dave08

    1 year ago
    Is that good practice, or might that encourage subtle cases that aren't covered by the tests?
    robfletcher

    robfletcher

    1 year ago
    and since Kotlin makes it possible to write extension functions for nullable types it makes sense to allow for the possibility someone may want to write assertions for it
    I don’t think
    .isNotNull() isEqualTo "foo"
    is more correct than just
    isEqualTo "foo"
    dave08

    dave08

    1 year ago
    It raises awareness to have to check the null cases, but I guess it might be overkill in some cases... so
    and
    on nullables also make sense? Inside it, there's not even a get() to use to test on multiple mapped properties..., or am I missing a use case?
    robfletcher

    robfletcher

    1 year ago
    I can’t see myself using
    and
    on a nullable, but I wouldn’t like to prevent it only to find there’s a good reason for someone to want it
    dave08

    dave08

    1 year ago
    Yeah, I guess there might always be that case we would never think of... I just tripped up on it a few times, importing a get() inside such an and() from some other library - and not finding matchers on it... just to realize it was a nullable. If only matchers that can be used are available in code-complete, it would be quicker to choose the right things...
    robfletcher

    robfletcher

    1 year ago
    yeah, I sometimes wonder if the opaqueness of Strikt’s API is more trouble than it’s worth. It’s deliberate, but when I find myself mirroring every useful operation on subject classes it feels a bit clunky
    christophsturm

    christophsturm

    1 year ago
    I always type “is” and invoke autocompete to see whats possible. in this case it works pretty well:
    dave08

    dave08

    1 year ago
    I don't usually do
    isXXX
    in an
    and
    block, since those can be chained. The main use of an
    and
    block for me is to check properties of a class using
    get()
    .
    christophsturm

    christophsturm

    1 year ago
    we could add a get method for the nullable receiver that is deprecated and tells you that you need to do isNotNull.
    hmm or there could be a get receiver on nullable types that does the isNotNull for you
    dave08

    dave08

    1 year ago
    The first option was my original idea, the latter seems a bit too inexplicit (which
    withNotNull { }
    would avoid together with the first option you stated).
    But is it possible to make only the nullable reciever's get() deprecated without affecting the other one?
    christophsturm

    christophsturm

    1 year ago
    hmm i can check…
    hmm for me get actually is available in a nullable and block:
    it just complains that it cannot call the name method because of nullability
    dave08

    dave08

    1 year ago
    I don't use that syntax, I use get(SomeClass:😒omeProperty).
    You're right the other syntax is available, but I think it's a mistake too.
    christophsturm

    christophsturm

    1 year ago
    what is a mistake?
    dave08

    dave08

    1 year ago
    To allow
    get { }
    in a nullable
    and { }
    block...
    christophsturm

    christophsturm

    1 year ago
    it allows it and the warning then tells you that you have a nullability problem
    fun String?.someProperty() would be available in your syntax too
    also its the same get method, just called with a different syntax
    dave08

    dave08

    1 year ago
    I don't think
    get(SomeClass?::someProperty)
    syntax exists in Kotlin... and
    get { }
    gives you an error in the IDE...
    christophsturm

    christophsturm

    1 year ago
    get(A?::hashCode)
    works
    dave08

    dave08

    1 year ago
    hashCode
    does, but other properties don't ... that's funny!
    robfletcher

    robfletcher

    1 year ago
    I think Kotlin’s stdlib implements hashcode for nullable types
    christophsturm

    christophsturm

    1 year ago
    yes