I'm not sure whether it's a bug or not, but consider the following code:
[Test]
public void Dummy()
{
var items = new SomeStuff[]
{
new("Name 1"),
new("Name 2")
};
// OK
Assert.That(items, Has.Exactly(2).Items);
Assert.That(items, Has.ItemAt(0).Property(nameof(SomeStuff.Name)).EqualTo("Name 1"));
Assert.That(items, Has.ItemAt(1).Property(nameof(SomeStuff.Name)).EqualTo("Name 2"));
// OK
Assert.That(items, Has.Exactly(2).Items
.And.One.Property(nameof(SomeStuff.Name)).EqualTo("Name 1")
.And.One.Property(nameof(SomeStuff.Name)).EqualTo("Name 2"));
// NOT OK 1
Assert.That(items, Has.Exactly(2).Items
.And.ItemAt(0).Property(nameof(SomeStuff.Name)).EqualTo("Name 1")
.And.ItemAt(1).Property(nameof(SomeStuff.Name)).EqualTo("Name 2"));
// NOT OK 2
Assert.That(items, Has.Exactly(2).Items
.And.One.ItemAt(0).Property(nameof(SomeStuff.Name)).EqualTo("Name 1")
.And.One.ItemAt(1).Property(nameof(SomeStuff.Name)).EqualTo("Name 2"));
}
public sealed record SomeStuff(string Name);
How would one chain AndConstraint and use the indexer in the same Assert.That call? The NOT OK 1 assert throws:
System.InvalidOperationException : Stack empty.
at System.Collections.Generic.Stack`1.ThrowForEmptyStack()
at System.Collections.Generic.Stack`1.Pop()
at NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack.Pop()
at NUnit.Framework.Constraints.BinaryOperator.Reduce(ConstraintStack stack)
at NUnit.Framework.Constraints.ConstraintBuilder.Resolve()
at NUnit.Framework.Constraints.Constraint.NUnit.Framework.Constraints.IResolveConstraint.Resolve()
at NUnit.Framework.Assert.That[TActual](TActual actual, IResolveConstraint expression, String message, Object[] args)
at NUnit.Framework.Assert.That[TActual](TActual actual, IResolveConstraint expression)
at SomeTests.Dummy() in /path/TestFile.cs:line 115
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
The NOT OK 2 assert throws:
System.ArgumentException : Default indexer accepting arguments < 0 > was not found on SomeTests+SomeStuff.
at NUnit.Framework.Constraints.IndexerConstraint.ApplyTo[TActual](TActual actual)
at NUnit.Framework.Constraints.ExactCountConstraint.ApplyTo[TActual](TActual actual)
at NUnit.Framework.Constraints.AndConstraint.ApplyTo[TActual](TActual actual)
at NUnit.Framework.Constraints.AndConstraint.ApplyTo[TActual](TActual actual)
at NUnit.Framework.Assert.That[TActual](TActual actual, IResolveConstraint expression, String message, Object[] args)
at NUnit.Framework.Assert.That[TActual](TActual actual, IResolveConstraint expression)
at SomeTests.Dummy() in /path/TestFile.cs:line 115
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
Namespaces, file paths and test names have been changed to protect the innocent.
I'm not sure whether it's a bug or not, but consider the following code:
How would one chain
AndConstraintand use the indexer in the sameAssert.Thatcall? The NOT OK 1 assert throws:The NOT OK 2 assert throws:
Namespaces, file paths and test names have been changed to protect the innocent.