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

Allow logical operations on assertions #991

Closed
nakulj opened this issue Jun 7, 2022 · 4 comments
Closed

Allow logical operations on assertions #991

nakulj opened this issue Jun 7, 2022 · 4 comments

Comments

@nakulj
Copy link

nakulj commented Jun 7, 2022

It would be nice if there was some way of performing logical operations on assertions, whether fluently or not.

// fluent version
assertThat(foo).isEqualTo(3).orThat(bar).isEqualTo(5);

assertAtLeastOneOf(
  that(foo).isEqualTo(3),
  that(bar).isEqualTo(4)
);
@amalloy
Copy link

amalloy commented Jun 10, 2022

The fluent version would be a very big API change to pretty much every Subject. It couldn't work as you propose, because isEqualTo(3) has to throw an exception for non-3 subjects. I don't expect we would make a change like that anytime soon.

I see no huge technical barriers to implementing assertAtLeastOneOf, but it doesn't seem like a hugely important feature to have. A disjunction like this would tend to be useful only in tests that are already complicated enough to merit some concern (since tests should be simple). And in the worst case, you can emulate this behavior with an assertion on ordinary booleans.

@amalloy amalloy closed this as completed Jun 10, 2022
@cpovirk
Copy link
Member

cpovirk commented Jun 13, 2022

I likewise don't expect us to add this. One minor reason for that is that the "failure path" for assertions can be pretty slow, like when it constructs very long failure messages. If we wanted to support logical operations "properly," we'd design an API that allowed deferring that work until later.

That said, it should be possible to implement this as an external extension if you want: You'd have to implement a custom FailureStrategy that collected failures from the sub-assertions, along with a bunch of custom that(...) methods that counted how many assertions had been performed (so that you can compare that to the number of failures). Then you'd expose some kind of API to the multiple assertions, likely either having the user implement a lambda or write a try-with-resources block. [edit: This turns out not to work in the general case; see below.]

One additional downside that that will expose is that the only way to fail with full information will be to dump the whole list of failure messages, which may be quite long.

The alternative way to do this would be for us to implement "Fuzzy Truth for single objects." I forget whether we have an external feature request open about that yet. But it would address any concerns around performance or failure messaging.

@cpovirk
Copy link
Member

cpovirk commented Jun 14, 2022

a bunch of custom that(...) methods that counted how many assertions had been performed (so that you can compare that to the number of failures)

That assumes that callers perform a single assertion per that(...) call. That's almost always going to be a reasonable assumption: Few users are going to write...

StringSubject a = holds.that(myString);
a.startsWith("http:");
a.startsWith("https:");

...when they could just write...

holds.that(myString).startsWith("http:");
holds.that(myString).startsWith("https:");

But we could imagine seeing multiple assertions on the same Subject instance in the case of Kotlin users, as discussed in #572.

@nakulj
Copy link
Author

nakulj commented Jul 15, 2022

Fuzzy Truth for single objects.

I think this is actually what I really wanted :)
I understand that failure messaging for fuzzy truth is hard- but it would be nice for it to be handled once, at the library level, rather than multiple times by everyone who writes a fuzzy test.

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

3 participants