A problem with comparing byte arrays using custom comparers

133 views
Skip to first unread message

Andrew Skalkin

unread,
Jan 25, 2011, 10:01:21 PM1/25/11
to NUnit-Discuss
Hi guys,

The following test fails with the "System.ArgumentException : Cannot
compare 1" message; is it a bug or a feature? Stack trace is below.

Regards,
Andrew

[TestFixture]
public class NUnitFeatures
{
[Test]
public void CustomArrayComparison()
{
Assert.That(new[] { 1 }, Is.EqualTo(new[] { 1 }).Using(new
ByteArrayComparer()));
}

class ByteArrayComparer : IComparer<byte[]>
{
public int Compare(byte[] x, byte[] y)
{
if (x == null && y == null)
return 0;
if (x == null)
return -1;
if (y == null)
return 1;
if (x.Length != y.Length)
return x.Length < y.Length ? -1 : 1;

var minLength = Math.Min(x.Length, y.Length);
for (int i = 0; i < minLength; i++)
{
if (x[i] != y[i])
return x[i] < y[i] ? -1 : 1;
}

return 0;
}
}
}

Stack trace:

System.ArgumentException : Cannot compare 1
at
NUnit.Framework.Constraints.ComparisonAdapter.ComparerAdapter`1.Compare(Object
expected, Object actual)
at
NUnit.Framework.Constraints.EqualityAdapter.ComparisonAdapterAdapter.ObjectsEqual(Object
x, Object y)
at
NUnit.Framework.Constraints.NUnitEqualityComparer.ObjectsEqual(Object
x, Object y)
at
NUnit.Framework.Constraints.NUnitEqualityComparer.CollectionsEqual(ICollection
x, ICollection y)
at NUnit.Framework.Constraints.NUnitEqualityComparer.ArraysEqual(Array
x, Array y)
at
NUnit.Framework.Constraints.NUnitEqualityComparer.ObjectsEqual(Object
x, Object y)
at NUnit.Framework.Constraints.EqualConstraint.Matches(Object actual)
at NUnit.Framework.Assert.That(Object actual, IResolveConstraint
expression, String message, Object[] args)
at NUnit.Framework.Assert.That(Object actual, IResolveConstraint
expression)
at RamDbUnitTests.NUnitFeatures.CustomArrayComparison() in
NUnitFeatures.cs: line 16

Charlie Poole

unread,
Jan 25, 2011, 11:32:56 PM1/25/11
to nunit-...@googlegroups.com
NUnit has it's own logic for comparing arrays, which is to compare them
element by element. The Using modifier specifies a Comparer for use
in comparing the elements of the array. In this case, when NUnit tries
to compare two ints using an IComparer<byte[]>, an exception is thrown
as per the normal behavior of the comparer.

Charlie

> --
> You received this message because you are subscribed to the Google Groups "NUnit-Discuss" group.
> To post to this group, send email to nunit-...@googlegroups.com.
> To unsubscribe from this group, send email to nunit-discus...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/nunit-discuss?hl=en.
>
>

Andrew Skalkin

unread,
Jan 26, 2011, 12:57:12 AM1/26/11
to NUnit-Discuss
I see the rationale behind it, but this approach prohibits us from
polymorphically
treating arrays just like any other types in unit tests. How would you
rewrite the
following code? Perhaps there should be a different method called
UsingItemComparer
or something like that?

Thanks!
-Andrew

[TestFixture(typeof(int))]
[TestFixture(typeof(byte))]
[TestFixture(typeof(byte[]))]
public class SerializationTest<T>
{
[Test]
public void Serialization()
{
var producer = Context.Resolve<IProducer<T>>();
var serializer = Context.Resolve<ISerializer<T>>();
var comparer = Context.Resolve<IComparer<T>>();
var value = producer.Create();
Assert.That(value,
Is.EqualTo(serializer.Deserialize(serializer.Serialize())).Using(comparer));

Charlie Poole

unread,
Jan 26, 2011, 1:41:33 AM1/26/11
to nunit-...@googlegroups.com
We have accepted feature requests to make use of an overridden Equals()
method on collection classes (1) and another to support IEquateable<T>
where it is implemented (2). For consistency, it also makes sense to
allow specifying comparers at the top level with Using as well.

Will you submit a feature request for this?

Charlie

(1) https://bugs.launchpad.net/nunit-3.0/+bug/646786
(2) https://bugs.launchpad.net/nunit-3.0/+bug/676560

Andrew Skalkin

unread,
Jan 26, 2011, 5:37:46 PM1/26/11
to NUnit-Discuss
Submitted.
https://bugs.launchpad.net/nunit-3.0/+bug/708173

On Jan 25, 8:41 pm, Charlie Poole <nunit...@gmail.com> wrote:
> We have accepted feature requests to make use of an overridden Equals()
> method on collection classes (1) and another to support IEquateable<T>
> where it is implemented (2). For consistency, it also makes sense to
> allow specifying comparers at the top level with Using as well.
>
> Will you submit a feature request for this?
>
> Charlie
>
> (1)https://bugs.launchpad.net/nunit-3.0/+bug/646786
> (2)https://bugs.launchpad.net/nunit-3.0/+bug/676560

Charlie Poole

unread,
Jan 26, 2011, 7:18:34 PM1/26/11
to nunit-...@googlegroups.com
Thanks!
Reply all
Reply to author
Forward
0 new messages