I noticed some unexpected behaviour of SameValuesAsAssertion.
Consider the following test:
var sue = new SingleUseEnumerable<int>(new int[] {});
sue.Should().Have.SameValuesAs(new int[]{});
with
class SingleUseEnumerable<T> : IEnumerable<T>
{
private readonly IEnumerable<T> _component;
private bool _used;
public SingleUseEnumerable(IEnumerable<T> component)
{
_component = component;
}
public IEnumerator<T> GetEnumerator()
{
if (_used)
throw new InvalidOperationException("Enumerator can only be retrieved once.");
_used = true;
return _component.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
This test always throws an InvalidOperationException, because SameValuesAsAssertion calls Enumerable.GetEnumerator twice.
From my point of view, I would not expect this behaviour.
A possible fix would be to rewrite line 20 of SameValuesAsAssertion to this:
a = a.ToArray(); // only call GetEnumerator once!
return !a.Except(expected).Concat(expected.Except(a)).Any();
Comments: Fixed thanks for the test
Consider the following test:
var sue = new SingleUseEnumerable<int>(new int[] {});
sue.Should().Have.SameValuesAs(new int[]{});
with
class SingleUseEnumerable<T> : IEnumerable<T>
{
private readonly IEnumerable<T> _component;
private bool _used;
public SingleUseEnumerable(IEnumerable<T> component)
{
_component = component;
}
public IEnumerator<T> GetEnumerator()
{
if (_used)
throw new InvalidOperationException("Enumerator can only be retrieved once.");
_used = true;
return _component.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
This test always throws an InvalidOperationException, because SameValuesAsAssertion calls Enumerable.GetEnumerator twice.
From my point of view, I would not expect this behaviour.
A possible fix would be to rewrite line 20 of SameValuesAsAssertion to this:
a = a.ToArray(); // only call GetEnumerator once!
return !a.Except(expected).Concat(expected.Except(a)).Any();
Comments: Fixed thanks for the test