SwensenSoftware / unquote

Write F# unit test assertions as quoted expressions, get step-by-step failure messages for free
http://www.swensensoftware.com/unquote
Apache License 2.0
287 stars 25 forks source link

test always passes when custom function is a part of the quotation #114

Closed ntr closed 9 years ago

ntr commented 9 years ago

Following test always passes for me, but it should not:

let floatEqual a b =
    abs(a-b) < 1e-6

let coordsEqual (x1,y1) (x2,y2) =
    floatEqual x1 x2 && floatEqual y1 y2

let converter2 (a, b) = 
    Some (a+1.,b+1.)

[<Fact>]
let ``demo test``() =
    test <@ coordsEqual (33.03,-119.03) (converter2( 6.0, 6.0).Value) @>

My guess is that the engine cannot evaluate converter2 function and always returns true in this case. Probably should throw some kind of exception in this case.

stephen-swensen commented 9 years ago

Perhaps surprisingly, this looks like a bug in the F# compiler itself!

Observe the output of the standalone quotation in FSI:

> <@ coordsEqual (33.03,-119.03) (converter2( 6.0, 6.0).Value) @>;;
val it : Quotations.Expr<bool> =
  Let (tupledArg, NewTuple (Value (33.03), Value (-119.03)),
     Let (tupledArg,
          PropertyGet (Some (Call (None, converter2, [Value (6.0), Value (6.0)])),
                       Value, []),
          Let (x1, TupleGet (tupledArg, 0),
               Let (y1, TupleGet (tupledArg, 1),
                    Let (x2, TupleGet (tupledArg, 0),
                         Let (y2, TupleGet (tupledArg, 1),
                              Call (None, coordsEqual, [x1, y1, x2, y2])))))))

You can see that the quotation has been incorrectly captured: the first tupledArg binding is immediately shadowed by a seconded tupledArg, such that ultimately the final, reduced expression evaluated by Unquote is coordsEqual 7.0 7.0 7.0 7.0, which is true as Unquote reports. (note that Unquote can handle "custom" functions and almost all kinds of arbitrarily complex expressions).

I have reproduced this apparent bug in VS 2010, 2013, and 2015. I will close this issue and create an issue with the visualfsharp project.

stephen-swensen commented 9 years ago

Re-opening - turns out this is an Unquote bug after all caused by a false assumption about quotation variable identity.

stephen-swensen commented 9 years ago

Fixed w/ tests

ntr commented 9 years ago

Thank you.