jmojiwat / fluentassertions.languageext Goto Github PK
View Code? Open in Web Editor NEWLanguageExt extensions for FluentAssertions
License: Apache License 2.0
LanguageExt extensions for FluentAssertions
License: Apache License 2.0
When a test project references (directly or indirectly) LanguageExt.Core
package 4.4.0 and newer, calling BeFail
on FinAssertions throws the MissingMethodException
. Calling BeSuccess
/BeBottom
doesn't cause any problems.
I suspect it's related to significant changes in Error
type released in 4.4.0.
The minimal reproducible example is here.
The easiest way to solve this would be to bump the LanguageExt.Core
dependency to 4.4.0.
Hello @jmojiwat,
Thank you for this great project idea.
Any chance that you can make it compatible with .net 5?
Hi @jmojiwat, thanks for this library!
I would like to make an enhancement proposal.
FluentAssertions provides an AndWhichConstraint
type that allows for chaining additional assertions on a sub-type of a parent assertion, similar to the Be___(action)
overloads in your API.
A potential example usage:
Prelude.Some(8)
.Should().BeSome()
.Which.Should().Be(8);
Benefits to AndWhichConstraint
:
.Which
and .And
in FluentAssertions, this will feel very familiar.Be___(action)
overloads - both options can existFor any assertion method which asserts a wrapped-value state (BeSome(), BeLeft(), etc), return an AndWhichConstraint
from the assertion rather than an AndConstraint
. It probably wouldn't make sense to do this for the Be___(action)
overloads, since they already support sub-assertions. Or the Be(expected)
method, since that also doesn't really allow additional assertions. This would just target the Be___(string, params object[])
overloads.
Since AndWhichConstraint
derives from AndConstraint
, this would be a non-breaking change.
Would you be open to this sort of change? If so, I would be happy to open a PR.
Original:
public AndConstraint<LanguageExtOptionAssertions<T>> BeSome(string because = "", params object[] becauseArgs)
{
// body ignored, no change needed in assertion logic
return new AndConstraint<LanguageExtOptionAssertions<T>>(this);
}
Modified:
public AndWhichConstraint<LanguageExtOptionAssertions<T>, T> BeSome(string because = "", params object[] becauseArgs)
{
// body ignored, no change needed in assertion logic
return new AndWhichConstraint<LanguageExtOptionAssertions<T>, T>(this, Subject);
}
When using the BeFail()
assertion on a Validation<TFail, TSucc>
, the .Which
extension returns only a single failure instance even though the Validation
type has a Seq<TFail>
. This prevents proper assertions on the failures returned from a Validation
using the .Which
extension.
This bug was introduced when I implemented #3.
using static LanguageExt.Prelude;
// Current valid usage. You can specify a single failure and assert on it just fine.
Validation<int, Unit> v1 = Fail<int, Unit>(1);
v1.Should().BeFail()
.Which.Should().Be(1); // The "Which" here wraps assertions for type "int"
// Validations can have multiple failures associated with them
Validation<int, Unit> v2 = Fail<int, Unit>(Seq(1, 2, 3));
v2.Should().BeFail()
.Which.Should().BeEquivalentTo(new[] {1, 2, 3}); // Not valid: "Which" still thinks it is of type "int" when it should be "IEnumerable<int>"
There are 2 solutions that I can think of to solve this right now.
The simplest solution would be to correct my initial mistake and change the return signature of the LanguageExtValidationAssertions<TFail, TSuccess>.BeFail()
method from AndWhichConstraint<LanguageExtValidationAssertions<TFail, TSuccess>, TFail>
to AndWhichConstraint<LanguageExtValidationAssertions<TFail, TSuccess>, Seq<TFail>>
.
This would offer the most reasonable API surface to users since this mimics the most complex signature available on the Validation<TFail, TSucc>
type. Here is an example signature: Validation<TFail, TSucc>.IfFail(Action<Seq<TFail>>)
. The downside of this is that it is a breaking change for anyone who has started using the existing .Which
extension on Validation
types.
The other solution is to introduce another assertion method to handle the case where a validation can have multiple failures.
In this case we would add the method public AndWhichConstraint<LanguageExtValidationAssertions<TFail, TSuccess>, Seq<TFail>> BeFailEnumerable(string because = "", params object[] becauseArgs)
to the LanguageExtValidationAssertions<TFail, TSuccess>
class.
Now, if someone wants to assert on a list of failures, they would do something like:
using static LanguageExt.Prelude;
// Validations can have multiple failures associated with them
Validation<int, Unit> v2 = Fail<int, Unit>(Seq(1, 2, 3));
v2.Should().BeFailEnumerable()
.Which.Should().BeEquivalentTo(new[] {1, 2, 3}); // This is now valid. "Which" knows it is an "IEnumerable<int>"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.