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
Implement support for IAsyncEnumerable the same way how Nunit4 implemented it #2535
base: develop
Are you sure you want to change the base?
Conversation
Qodana for .NET20 new problems were found
💡 Qodana analysis was run in the pull request mode: only the changed files were checked Contact Qodana teamContact us at qodana-support@jetbrains.com
|
070ccd7
to
d84e41e
Compare
d84e41e
to
abcff58
Compare
namespace FluentAssertions.Collections; | ||
|
||
[DebuggerNonUserCode] | ||
public class AsyncEnumerableAssertions<T> : AsyncEnumerableAssertions<IAsyncEnumerable<T>, T, AsyncEnumerableAssertions<T>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be much simpler to just have the new Should
overload enumerate the async collection and then return the existing GenericCollectionAssertions
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol yeah you're right. That also allows us to avoid taking dependency on System.Linq.Async
!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok that actually failed when we have a class that implements multiple IAsyncEnumerable
generic types. It no longer sees the interface having multiple generic types due to the use of ToBlockingEnumerable()
.
i.e. this fails.
// public class AsyncEnumerableOfStringAndObject : IAsyncEnumerable<object>, IAsyncEnumerable<string>
[Fact]
public void
When_a_object_implements_multiple_IAsyncEnumerable_interfaces_but_the_declared_type_is_assignable_to_only_one_and_runtime_checking_is_configured_it_should_fail()
{
// Arrange
IAsyncEnumerable<string> collection1 = new AsyncEnumerableOfStringAndObject();
IAsyncEnumerable<string> collection2 = new AsyncEnumerableOfStringAndObject();
// Act
Action act =
() => collection1.Should().BeEquivalentTo(collection2, opts => opts.RespectingRuntimeTypes());
// Assert
act.Should().Throw<XunitException>("the runtime type is assignable to two IAsyncEnumerable interfaces")
.WithMessage("*cannot determine which one*");
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AsyncEnumerableAssertions
is gross as it violates DRY having lots of shared code with GenericCollectionAssertions
. Would be open to any suggestions to avoid this.
Looking at the many usages of ReferenceTypeAssertions.Subject
, it is probably wise to keep Subject
the actual type which is IAsyncEnumerable
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I've updated AsyncEnumerableAssertions
to reuse GenericCollectionAssertions
where possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've had to revert the above. We lose ReferenceEquals
checks when we do that as the references are no longer the original one (due to calling ToBlockingEnumerable()
) so they are no longer "equal".
It appears code duplication here is necessary.
e5c8cd8
to
b2360c8
Compare
… GenericCollectionAssertions Otherwise, ReferenceEquals no longer works :(
…erable as the primary method
Draft PR to implement support for IAsyncEnumerable - option 3 as discussed in Issue 1213? The first commit does not take dependency on
System.Linq.Async
but does not offer strongly typedBeEquiavlentOf
. Taking dependency onSystem.Linq.Async
should be no worse thanSystem.Threading.Tasks
though.This is also the implementation NUnit4 has gone with. Yes, it does violate sync-over-async practice, but for all intents and purposes, FluentAssertion is a unit test framework. Blocking enumeration of AsyncEnumerable isn't as big a sin here vs high throughput web servers.
Note: This is a draft PR to demo a concept, not prod ready in any shape or form.
IMPORTANT
./build.sh --target spellcheck
or.\build.ps1 --target spellcheck
before pushing and check the good outcome