mausch / Fuchu

Functional test library for F# / C# / VB.NET
Apache License 2.0
120 stars 22 forks source link

Structural equality bug (failure despite equality) #28

Closed haf closed 10 years ago

haf commented 10 years ago

I have some code that creates a test case:

let encoding_equal<'a when 'a : equality> f_encode text expected (message : obj) =
  testCase text (fun () ->
    Assert.Equal(text, expected, f_encode (message :?> 'a)))

Getting failure like this:

Expected: {compression = Nope;
 key = seq [];
 value = seq [];}
Actual: {compression = Nope;
 key = seq [];
 value = seq [];}

Structure:

type Message =
  { compression : Compression
  ; key         : byte System.ArraySegment
  ; value       : byte System.ArraySegment }
haf commented 10 years ago

One some level though, if F# and the CLR doesn't do think they are equal, why should the test framework. Perhaps this is more of a F# problem, so if you want you can close this issue.

mausch commented 10 years ago

Yeah, equality for ArraySegment seems to be broken. More concretely, its structural equality seems to be derived from its condition as struct, and so it probably checks for offset and count to be equal. An example:

let a = ArraySegment<byte>([|2uy; 3uy|], 0, 1)
let b = ArraySegment<byte>([|2uy|])
Assert.Equal("ArraySegments are equal", a, b)

fails with:

ArraySegments are equal
Expected: seq [2uy]
Actual: seq [2uy]

Overall, equality in .NET is quite broken and unnecessarily complex (F# is no exception). If you use Seq.toArray for both sides of the assertion it should work as expected.