FsUnit icon indicating copy to clipboard operation
FsUnit copied to clipboard

Add collection constraints from NUnit

Open CaptnCodr opened this issue 6 years ago • 18 comments

Description

I just wrote some tests and wanted to test a collection that has the equivalent item than another.

Could you please implement the collection constraints from NUnit?

Repro steps

I have to use NUnit's function with like: let areCollectionsEqual = CollectionAssert.AreEquivalent([1;2;3], [3;1;2])

It's not so "F#-ish".

Known workarounds

I "extended" FsUnit with an extra function:

module FsUnit = 
  open NUnit.Framework.Constraints

  let equalsToCollection x = CollectionEquivalentConstraint x

So I can use this function like:

let areCollectionsEqual () = [1;2;3] |> should equalsToCollection [3;1;2]

Collection contraints implemented:

  • [x] equivalent
  • [x] supersetOf
  • [x] subsetOf

CaptnCodr avatar Sep 10 '19 09:09 CaptnCodr

It should be possible to do, but we need to add support for all frameworks (as we do for other operators) - http://fsprojects.github.io/FsUnit/operators.html

sergey-tihon avatar Sep 30 '19 06:09 sergey-tihon

Hi, I want to work on this.

In NUnit assertion, we have the CollectionAssert.AreEquivalent (which order don't matter) and CollectionAssert.AreEqual (which order matter), I think both should exist in FSUnit,

We those 2 assertion functions in MSTest and NUnit, but not in XUnit, XUnit have only a function which compares considering the order.

How do you think we can handle this? Brad Wilson from xunit.net told here that one should use LINQ's OrderBy operator and afterward Assert.Equal to verify that two collections contain equal items without regarding their order.

Another option is to use something like FluentAssertions

What do you think?

lucasteles avatar Oct 11 '19 14:10 lucasteles

I guess CollectionAssert.AreEqual case should be covered by equal operator due to structured equality

[1;2;3] |> should equal [1;2;3]

(we may add such test-cases and check)

for NUnit and MSTest is make sense to wrap CollectionAssert.AreEquivalent into equivalent operator. I am not sure about xUnit, we can leave it not implemented because it is not idiomatic for framework or reimplement logic from NUnit on our side

sergey-tihon avatar Oct 15 '19 04:10 sergey-tihon

I opened a PR for NUnit in https://github.com/fsprojects/FsUnit/pull/139

Next step is to implement it for MSTest, I saw that we are not using MSTest lib for asserts, we reimplemented some of the assertions,

Should we do the same for XUnit? makes sense?

lucasteles avatar Oct 21 '19 13:10 lucasteles

Sorry for "only" commenting to this issue and the changes that @lucasteles made. I'm freshly new to F# and very unsteady to the development like this. 😄

CaptnCodr avatar Oct 21 '19 17:10 CaptnCodr

I saw that we are not using MSTest lib for asserts, we reimplemented some of the assertions, Should we do the same for XUnit? makes sense?

I believe that we should implement as less as possible, so you may reuse MSTest assertions where you can.

Also feel free to open PR that replace existing custom implementation by native assertions provided by framework (where possible)

sergey-tihon avatar Oct 21 '19 18:10 sergey-tihon

Is it possible to implement the CollectionSubsetConstraint, too?

i.e.: I want to check if a sequence ([1..10]) has the values [8;1;5] in it.

Now, I have a function: let containInCollection x = Is.SubsetOf(x)

to check it like:

[1;8;5] |> should containInCollection [1..10]

But this is not what FsUnit follows I think (from Syntax). Is it possible to have an assert like: [1..10] |> should contain [8;1;5]?

CaptnCodr avatar Oct 24 '19 12:10 CaptnCodr

Ah, I got it. I use the CollectionSupersetConstraint to check this.

let contain (x: IEnumerable<_>) = Is.SupersetOf(x)

and use it as follows:

[1..10] |> should contain [8;1;5]

May I implement this @sergey-tihon?

CaptnCodr avatar Oct 25 '19 09:10 CaptnCodr

We already have contain operator

What to you think about

[1..10] |> should be (supersetOf [8;1;5])

?

sergey-tihon avatar Oct 27 '19 10:10 sergey-tihon

Yea, sounds good. I'll try it and make a PR.

CaptnCodr avatar Oct 27 '19 19:10 CaptnCodr

I created a PR #141. I hope you like it.

CaptnCodr avatar Oct 27 '19 21:10 CaptnCodr

I would like to implement the subsetOf operator, too. To have the counterpart of supersetOf.

Like: [4;5] |> should be (subsetOf [1..10])

Is this okay?

CaptnCodr avatar Oct 30 '19 09:10 CaptnCodr

Hey @sergey-tihon, I created a PR #144 for you.

CaptnCodr avatar Oct 31 '19 17:10 CaptnCodr

@lucasteles What about your implementations?

@sergey-tihon Do we need more collection assertions?

CaptnCodr avatar Nov 02 '19 19:11 CaptnCodr

@CaptnCodr There is no goal to add all possible operators, especially if you do not need them in our own code base. We can do on demand and only those that are really needed.

If you have time you can help finish #139 PR

sergey-tihon avatar Nov 03 '19 16:11 sergey-tihon

Hey @sergey-tihon, I created #145 for you. I took the changes from @lucasteles' PR (#139) to implement the NUnit assertion and added the MsTest assertion to it. Xunit is a bit harder I think.

So I did my best. 😅

CaptnCodr avatar Nov 23 '19 01:11 CaptnCodr

Hello, nice to see that @CaptnCodr could use some of the my changes.

This issue still open and it's not clear what is the next steps of constraints to do

lucasteles avatar Oct 02 '20 23:10 lucasteles

@lucasteles Yes, it's still open because discussions about coming constraints could be made here when they are necessary to implement as mentioned by Sergey above https://github.com/fsprojects/FsUnit/issues/133#issuecomment-549156544

CaptnCodr avatar Oct 03 '20 08:10 CaptnCodr