nunit: EqualTo on ValueTuple with Nullable unexpected
I recently observed unexpected test failure when comparing ValueTuples with nullable types.
This works:
(string name, int val) tuple = ("Hello", 3);
Assert.That(tuple, Is.EqualTo(("Hello", 3)));
Fails with msg: “Message: Expected: (Hello, 3) (Int32]) But was: (Hello, 3) (Int32]])”
(string name, int? val) tuple = ("Hello", 3)
Assert.That(tuple, Is.EqualTo(("Hello", 3)));
With correct type spec it works again:
(string name, int? val) tuple = ("Hello", 3);
Assert.That(tuple, Is.EqualTo(("Hello", (int?)3)));
I would expect one of this:
-
check succeeds
-
message shows type difference with Int32? or Nullable<Int32>
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 21 (21 by maintainers)
Commits related to this issue
- Add comparer for ValueTuples Some prettyprinting of ValueTuples still needs to be done. Relates to #2254 — committed to mikkelbu/nunit by mikkelbu 7 years ago
@nunit/framework-team I’m strongly in favor of bringing this philosophy over to NUnit from our discussions at dotnet/rosyn and dotnet/csharplang:
Tuples (the C# language feature) are intended to be as much as possible like an argument list. And, operations on a tuple should be distributive as operations on each individual value. The structure is not significant; it’s just an ordered bag of unrelated values. For example,
(a, b) == (c, d)should be synonymous witha == c && b == d(coming in C# 7.x I believe).Tuples (the language feature) are realized through the
ValueTupletype as an implementation detail. Unlike other types, theValueTupletype has no significance except in how it accomplishes the philosophy of the tuple language feature. It’s valid for the compiler to even optimize away usages of theValueTupletype even though cannot know the implementation ofValueTupleat runtime.I propose we follow the philosophy behind tuples by treating ValueTuples specially and comparing only the values, intentionally disregarding the generic type parameters on the ValueTuple.
This enables people to use tuples in assertions, thinking only in terms of the order and the actual types of the values. People shouldn’t have to additionally be considering the constructed type of the ValueTuple itself; that only detracts from the purpose of the test. In other words, @Aurelianus’ first expectation.
NUnit does not use static typing for assertions; everything is cast or boxed to
object. To treat a tuple as no more than individual ordered arguments, and to be consistent with NUnit’s dynamic approach to type inspection, each tuple value should also have the same treatment- only the actual value should matter, not the static type of the tuple field.Thoughts?
I can try to supply a PR for this.
@rprouse Wrt. the refactoring, would something like a new folder
Comparerswith one class/file per (major) comparer be appropriate? E.g. aDirectoryInfo-comparer, aArrays-comparer etc.