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
285 stars 26 forks source link

Support F# 4.1 Result type #131

Closed jbrestan closed 7 years ago

jbrestan commented 7 years ago

Using Unquote 3.2.0 with FSharp.Core 4.4.1.0 (F# 4.1), the following test

[<Fact>]
let ThisWillFail () =
    let actual: Result<string, string> = Ok "foo"
    test <@ match actual with
            | Ok _ -> true
            | Error _ -> false @>

where Result is Microsoft.FSharp.Core.Result, fails with

System.NotSupportedException: Evaluation of quotation pattern AddressOf not supported: expression = AddressOf (ValueWithName (Ok "foo", actual))

I think this may be related to the fact that FSharpResult is a multi-case discriminated union struct. I've just started migrating to F# 4.1, so I am really mostly guessing here.

Using this equality check seems to work test <@ actual = Ok "foo" @>, but in my actual tests the value in Result cannot have equality, so I need to use match.

stephen-swensen commented 7 years ago

@jbrestan super interesting, thanks for reporting!

I expect FSharpResult to be a pretty common type in the future of F#, especially within tests like here, so going to give this in high priority.

jbrestan commented 7 years ago

Thanks for quick response.

Let me know if you need more details to reproduce it - I've encountered this during relatively large project migration so it's possible something else is the root cause. When I use a custom Result type (just a regular DU with two cases) everything works though (with older 4.4.0.0 FSharp.Core as well as with the latest).

I'll try to look around your codebase to see if I'd be able to help

Update: Not sure if I'll be able to look into it without doing similar migration as in my project - using FSharp.Core from NuGet instead of GAC, and updating it to the latest version (yours is currently 4.3.1.0, F# 3.1). I can do this to reproduce (and hopefully fix) the issue, but since this is a significant change in the whole project, I think its scope exceeds this fix/enhancement.

dsyme commented 7 years ago

I only looked at this very briefly, but it's vaguely possible there is a bug in F# quotations here - let me know if that's the case - (I hope not of course...)

stephen-swensen commented 7 years ago

Hi @dsyme -

Unquote has never supported AddressOf evaluation, so I am not surprised by the exception itself.

However, I am not sure if it is surprising that a quotation involving pattern matching on a struct union includes an AddressOf expression like we have here:

printfn "%A" 
    <@ match actual with
       | Ok _ -> true
       | Error _ -> false @>

IfThenElse (UnionCaseTest (AddressOf (ValueWithName (Ok "foo", actual)), Error),
        Value (false), Value (true))

Notably, I get a compiler error with the following similar pattern match on a struct tuple:

let actual = struct (0,0)
let code = 
    <@ match actual with
       | struct (0,0) -> true
       | _ -> false @>

Error FS0073 internal error: Unexpected expression shape

dsyme commented 7 years ago

@stephen-swensen Can you add a bug at http://github.com/Microsoft/visualfsharp please? We'd expect these to both work, thanks

stephen-swensen commented 7 years ago

@dsyme done: https://github.com/Microsoft/visualfsharp/issues/3118

stephen-swensen commented 7 years ago

Looks like this was fixed by https://github.com/Microsoft/visualfsharp/pull/3227 , closing

dsyme commented 6 years ago

@stephen-swensen Thanks for reporting the problem