Skip to content
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

Predicate-accepting assertions #404

Closed
hkokocin opened this issue Jan 24, 2018 · 7 comments
Closed

Predicate-accepting assertions #404

hkokocin opened this issue Jan 24, 2018 · 7 comments

Comments

@hkokocin
Copy link

Are there any plans to add an extension for usage in Kotlin? There would be a lot of potential. I'm still quite new to Truth so I hope I did not miss sth but for example I currently use

assertThat(mapMarkers.any { it.data == myData }).isTrue()

Instead it would be great to have

assertThat(mapMarkers).containsAny{ it.data == myData }

Quite interesting for collections would also be all and none. And I think there will be more examples like that which would be very nice to have.

@kluever
Copy link
Member

kluever commented Jan 24, 2018

/cc @JakeWharton

@JakeWharton
Copy link

One could argue this has nothing to do with Kotlin as such a method could be beneficial to Java 8 consumers as well.

But since IterableSubject no longer carries a type parameter (#192), I don't see a way to achieve this with an instance method:

// No "T" to use, Object and ? aren't usable.
public void containsAny(Predicate<T> predicate) { /* .. */ }

Nor is there a way to do it yourself with a Kotlin extension method:

// Again no "T" to use and Any or * aren't usable.
fun IterableSubject.containsAny(predicate: (T) -> Boolean) = /* .. */

The best you can do with Kotlin, though, is hanging the extension off of the iterable directly:

fun <T> Iterable<T>.assertContainsAny(predicate: (T) -> Boolean) {
    assertTrue(this.any(predicate))
    // TODO better failure message
}

yielding

mapMarkers.assertContainsAny { it.data == myData }

The absence of a type parameter limits the ability to create these style helpers directly on the subject.

All that being said, there are some really handy Kotlin extensions that I use with Truth. My favorite is:

inline fun <reified T> assertThrows(block: () -> Unit): ThrowableSubject {
  try {
    block()
  } catch (e: Throwable) {
    if (e is T) {
      return assertThat(e)
    } else {
      throw e
    }
  }
  throw AssertionError("Expected ${T::class.simpleName}")
}

(source)

which lets you do:

assertThrows<IllegalArgumentException> {
  FunSpec.builder("foo")
      .addTypeVariable(TypeVariableName("T").reified())
      .build()
}.hasMessageThat().isEqualTo("only type parameters of inline functions can be reified!")

(source)

@JakeWharton
Copy link

I suppose the Java instance method and the Kotlin extension function could define their own T, but that means you can do bad things like

assertThat(listOf("Hello", "World")).containsAny<Integer> { it % 2 == 0 }

which is an unnecessary foot gun.

@PhilippWendler
Copy link

This looks like a duplicate of #206?

@hkokocin
Copy link
Author

@JakeWharton Of course you are totally right that it would be a treat to have containsAny, containsNone, containsAll as regular matchers. I was a bit caught in Kotlin APIs. The intent of this issue was to have these matchers supported natively and maybe its worth considering? Thanks a lot for your insights on how to use custom extension functions though.

@PhilippWendler The issue you linked is in fact part of what I want to archieve. Thanks for the hint.

@ultraon
Copy link

ultraon commented Dec 15, 2018

You can check this great assertion library for Kotlin https://github.com/robstoll/atrium

@cpovirk
Copy link
Member

cpovirk commented May 14, 2019

To the degree that this bug is about Predicate-accepting assertions, we're unlikely to implement it. See #206, #311, and #435.

I'm going to leave the other Kotlin bug, #435, open, as it addresses another concern about extension methods. I'll retitle it accordingly.

@cpovirk cpovirk closed this as completed May 14, 2019
@cpovirk cpovirk changed the title Kotlin support Kotlin-specific enhancements Feb 3, 2021
@cpovirk cpovirk changed the title Kotlin-specific enhancements Predicate-accepting assertions Feb 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants