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

Discussion for context/name String parameters #535

Open
grodin opened this issue May 2, 2024 · 2 comments
Open

Discussion for context/name String parameters #535

grodin opened this issue May 2, 2024 · 2 comments

Comments

@grodin
Copy link
Contributor

grodin commented May 2, 2024

There are a number of places in the API where it would be good to add a String parameter to name something or add some context. Some quick examples from existing open issues:

It seems like there are two main threads to these:

  1. API consistency (e.g. eachHaving() should have a name param to match having())
  2. Adding context to assertions (e.g. Naming a failure #526, )

I thought it would be useful to open an issue to kind of unify discussion around these ideas.

It would potentially be useful to go through the whole API and try to find the places where a string parameter seems to be wanted and try to design a consistent approach, rather than dealing with each request in an ad-hoc way.

Point 1. seems fairly easy to address, so I'll try to start collecting instances of that.

@evant
Copy link
Collaborator

evant commented May 2, 2024

Agreed that this could use some work. I'm going to try to explain what's there now as a starting point, which is sadly under-documented. Note: the examples below will be using some of the api's directly are usually would be implemented inside an assertion.

name

You can pass a name to assertions. They show up at the beginning and may built in assertions will append to it. Note: the api for this is fairly manual, i.e. you need to explicitly append to it when chaining, otherwise it'll only show the name you pass in.

ex:

assertThat(outer, name = "outer").assertThat(inner, name = "inner").someAssertion()
// -> [inner] assertion failed

assertThat(outer, name = "outer").run { assertThat(inner, name = appendName("inner", separator = ".")) }.someAssertion()
// -> [outer.inner] assertion failed

many built-in assertions will append to this, ex: prop does appendName(name, separator = ".") and index does appendName("[$index]")

context

This is something that's implicitly tracked and is appended to the end of the assertion. The purpose for this to know what you were originally asserting on through chaining. The logic here is that if you aren't chaining nothing will be shown, if you are, the outer subject will be carried through and appended to the message.

assertThat(outer).someAssertion()
// -> assertion failed

assertThat(outer).assertThat(inner).someAssertion()
// -> assertion failed (outer)

For completeness, you can control how this value is rendered with displayActual. The intention for this was for cases where you subject did not have a useful toString() implementation, but #513 correctly points out the behavior of this parameter is quite confusing.

assertThat(outer, displayActual = { "changed" }).someAssertion()
// -> assertion failed

assertThat(outer, displayActual = { "changed" }).assertThat(inner).someAssertion()
// -> assertion failed (changed)

@dalewking
Copy link

In assertJ they have something like this:

    assertThat(5 + 19)
        .describedAs("The sum of 5 and 9")
        .isEqualTo(14)

I think there is a library I have used that instead of adding the description to the assert it added it to the value with a wrapper class:

    val actual = (5 + 9).describedAs("The sum of 5 and 9")

    assertThat(actual).isEqualTo(14)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants